// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "lib/integers.h"
#include "vm/bootstrap_natives.h"

#include "include/dart_api.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/isolate.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/symbols.h"

namespace dart {

// Smi natives.

// Returns false if integer is in wrong representation, e.g., as is a Mint
// when it could have been a Smi.
static bool CheckInteger(const Integer& i) {
  if (i.IsMint()) {
    const Mint& mint = Mint::Cast(i);
    return !Smi::IsValid(mint.Value());
  }
  return true;
}

DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 0, 2) {
  const Integer& right =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right));
  ASSERT(CheckInteger(left));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_bitAndFromInteger %s & %s\n", right.ToCString(),
                 left.ToCString());
  }
  return left.BitOp(Token::kBIT_AND, right);
}

DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 0, 2) {
  const Integer& right =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right));
  ASSERT(CheckInteger(left));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_bitOrFromInteger %s | %s\n", left.ToCString(),
                 right.ToCString());
  }
  return left.BitOp(Token::kBIT_OR, right);
}

DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 0, 2) {
  const Integer& right =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right));
  ASSERT(CheckInteger(left));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_bitXorFromInteger %s ^ %s\n", left.ToCString(),
                 right.ToCString());
  }
  return left.BitOp(Token::kBIT_XOR, right);
}

DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 0, 2) {
  const Integer& right_int =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right_int));
  ASSERT(CheckInteger(left_int));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_addFromInteger %s + %s\n", left_int.ToCString(),
                 right_int.ToCString());
  }
  return left_int.ArithmeticOp(Token::kADD, right_int);
}

DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 0, 2) {
  const Integer& right_int =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right_int));
  ASSERT(CheckInteger(left_int));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_subFromInteger %s - %s\n", left_int.ToCString(),
                 right_int.ToCString());
  }
  return left_int.ArithmeticOp(Token::kSUB, right_int);
}

DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 0, 2) {
  const Integer& right_int =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right_int));
  ASSERT(CheckInteger(left_int));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_mulFromInteger %s * %s\n", left_int.ToCString(),
                 right_int.ToCString());
  }
  return left_int.ArithmeticOp(Token::kMUL, right_int);
}

DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 0, 2) {
  const Integer& right_int =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right_int));
  ASSERT(CheckInteger(left_int));
  ASSERT(right_int.Value() != 0);
  return left_int.ArithmeticOp(Token::kTRUNCDIV, right_int);
}

DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 0, 2) {
  const Integer& right_int =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right_int));
  ASSERT(CheckInteger(left_int));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_moduloFromInteger %s mod %s\n", left_int.ToCString(),
                 right_int.ToCString());
  }
  if (right_int.Value() == 0) {
    // Should have been caught before calling into runtime.
    UNIMPLEMENTED();
  }
  return left_int.ArithmeticOp(Token::kMOD, right_int);
}

DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 0, 2) {
  const Integer& right =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(right));
  ASSERT(CheckInteger(left));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_greaterThanFromInteger %s > %s\n", left.ToCString(),
                 right.ToCString());
  }
  return Bool::Get(left.CompareWith(right) == 1).ptr();
}

DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 0, 2) {
  const Integer& left = Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(left));
  ASSERT(CheckInteger(right));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_equalToInteger %s == %s\n", left.ToCString(),
                 right.ToCString());
  }
  return Bool::Get(left.CompareWith(right) == 0).ptr();
}

static IntegerPtr ParseInteger(const String& value) {
  // Used by both Integer_parse and Integer_fromEnvironment.
  if (value.IsOneByteString()) {
    // Quick conversion for unpadded integers in strings.
    const intptr_t len = value.Length();
    if (len > 0) {
      const char* cstr = value.ToCString();
      ASSERT(cstr != nullptr);
      char* p_end = nullptr;
      const int64_t int_value = strtoll(cstr, &p_end, 10);
      if (p_end == (cstr + len)) {
        if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) {
          return Integer::New(int_value);
        }
      }
    }
  }

  return Integer::New(value);
}

DEFINE_NATIVE_ENTRY(Integer_parse, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
  return ParseInteger(value);
}

DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 0, 3) {
  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
  GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2));
  // Call the embedder to supply us with the environment.
  const String& env_value =
      String::Handle(Api::GetEnvironmentValue(thread, name));
  if (!env_value.IsNull()) {
    const Integer& result = Integer::Handle(ParseInteger(env_value));
    if (!result.IsNull()) {
      if (result.IsSmi()) {
        return result.ptr();
      }
      return result.Canonicalize(thread);
    }
  }
  return default_value.ptr();
}

static IntegerPtr ShiftOperationHelper(Token::Kind kind,
                                       const Integer& value,
                                       const Integer& amount) {
  if (amount.Value() < 0) {
    Exceptions::ThrowArgumentError(amount);
  }
  return value.ShiftOp(kind, amount, Heap::kNew);
}

DEFINE_NATIVE_ENTRY(Integer_shrFromInteger, 0, 2) {
  const Integer& amount =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(amount));
  ASSERT(CheckInteger(value));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_shrFromInteger: %s >> %s\n", value.ToCString(),
                 amount.ToCString());
  }
  return ShiftOperationHelper(Token::kSHR, value, amount);
}

DEFINE_NATIVE_ENTRY(Integer_ushrFromInteger, 0, 2) {
  const Integer& amount =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(amount));
  ASSERT(CheckInteger(value));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_ushrFromInteger: %s >>> %s\n", value.ToCString(),
                 amount.ToCString());
  }
  return ShiftOperationHelper(Token::kUSHR, value, amount);
}

DEFINE_NATIVE_ENTRY(Integer_shlFromInteger, 0, 2) {
  const Integer& amount =
      Integer::CheckedHandle(zone, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
  ASSERT(CheckInteger(amount));
  ASSERT(CheckInteger(value));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Integer_shlFromInteger: %s << %s\n", value.ToCString(),
                 amount.ToCString());
  }
  return ShiftOperationHelper(Token::kSHL, value, amount);
}

DEFINE_NATIVE_ENTRY(Smi_bitNegate, 0, 1) {
  const Smi& operand = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Smi_bitNegate: %s\n", operand.ToCString());
  }
  intptr_t result = ~operand.Value();
  ASSERT(Smi::IsValid(result));
  return Smi::New(result);
}

DEFINE_NATIVE_ENTRY(Smi_bitLength, 0, 1) {
  const Smi& operand = Smi::CheckedHandle(zone, arguments->NativeArgAt(0));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Smi_bitLength: %s\n", operand.ToCString());
  }
  int64_t value = operand.Value();
  intptr_t result = Utils::BitLength(value);
  ASSERT(Smi::IsValid(result));
  return Smi::New(result);
}

// Should be kept in sync with il_*.cc EmitHashIntegerCodeSequence
uint32_t Multiply64Hash(int64_t ivalue) {
  const uint64_t magic_constant = /*0x1b873593cc9e*/ 0x2d51;
  uint64_t value = static_cast<uint64_t>(ivalue);
#if defined(ARCH_IS_64_BIT)
#ifdef _MSC_VER
  __int64 hi = __umulh(value, magic_constant);
  uint64_t lo = value * magic_constant;
  uint64_t hash = lo ^ hi;
#else
  const __int128 res = static_cast<__int128>(value) * magic_constant;
  uint64_t hash = res ^ static_cast<int64_t>(res >> 64);
#endif
  hash = hash ^ (hash >> 32);
#else
  uint64_t prod_lo64 = value * magic_constant;

  uint64_t value_lo32 = value & 0xffffffff;
  uint64_t value_hi32 = value >> 32;
  uint64_t carry = (((value_hi32 * magic_constant) & 0xffffffff) +
                    ((value_lo32 * magic_constant) >> 32)) >>
                   32;
  uint64_t prod_hi64 = ((value_hi32 * magic_constant) >> 32) + carry;
  uint64_t hash = prod_hi64 ^ prod_lo64;
  hash = hash ^ (hash >> 32);
#endif
  return hash & 0x3fffffff;
}

// Mint natives.

DEFINE_NATIVE_ENTRY(Mint_bitNegate, 0, 1) {
  const Mint& operand = Mint::CheckedHandle(zone, arguments->NativeArgAt(0));
  ASSERT(CheckInteger(operand));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Mint_bitNegate: %s\n", operand.ToCString());
  }
  int64_t result = ~operand.Value();
  return Integer::New(result);
}

DEFINE_NATIVE_ENTRY(Mint_bitLength, 0, 1) {
  const Mint& operand = Mint::CheckedHandle(zone, arguments->NativeArgAt(0));
  ASSERT(CheckInteger(operand));
  if (FLAG_trace_intrinsified_natives) {
    OS::PrintErr("Mint_bitLength: %s\n", operand.ToCString());
  }
  int64_t value = operand.Value();
  intptr_t result = Utils::BitLength(value);
  ASSERT(Smi::IsValid(result));
  return Smi::New(result);
}

}  // namespace dart
