// Copyright 2011 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/conversions.h"

#include <limits.h>
#include <stdarg.h>
#include <cmath>

#include "src/allocation.h"
#include "src/assert-scope.h"
#include "src/char-predicates-inl.h"
#include "src/dtoa.h"
#include "src/handles.h"
#include "src/heap/factory.h"
#include "src/objects-inl.h"
#include "src/objects/bigint.h"
#include "src/strtod.h"
#include "src/utils.h"

#if defined(_STLP_VENDOR_CSTD)
// STLPort doesn't import fpclassify into the std namespace.
#define FPCLASSIFY_NAMESPACE
#else
#define FPCLASSIFY_NAMESPACE std
#endif

namespace v8 {
namespace internal {

inline double JunkStringValue() {
  return bit_cast<double, uint64_t>(kQuietNaNMask);
}

inline double SignedZero(bool negative) {
  return negative ? uint64_to_double(Double::kSignMask) : 0.0;
}

inline bool isDigit(int x, int radix) {
  return (x >= '0' && x <= '9' && x < '0' + radix) ||
         (radix > 10 && x >= 'a' && x < 'a' + radix - 10) ||
         (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
}

inline bool isBinaryDigit(int x) { return x == '0' || x == '1'; }

template <class Iterator, class EndMark>
bool SubStringEquals(Iterator* current, EndMark end, const char* substring) {
  DCHECK(**current == *substring);
  for (substring++; *substring != '\0'; substring++) {
    ++*current;
    if (*current == end || **current != *substring) return false;
  }
  ++*current;
  return true;
}

// Returns true if a nonspace character has been found and false if the
// end was been reached before finding a nonspace character.
template <class Iterator, class EndMark>
inline bool AdvanceToNonspace(Iterator* current, EndMark end) {
  while (*current != end) {
    if (!IsWhiteSpaceOrLineTerminator(**current)) return true;
    ++*current;
  }
  return false;
}

// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
template <int radix_log_2, class Iterator, class EndMark>
double InternalStringToIntDouble(Iterator current, EndMark end, bool negative,
                                 bool allow_trailing_junk) {
  DCHECK(current != end);

  // Skip leading 0s.
  while (*current == '0') {
    ++current;
    if (current == end) return SignedZero(negative);
  }

  int64_t number = 0;
  int exponent = 0;
  const int radix = (1 << radix_log_2);

  int lim_0 = '0' + (radix < 10 ? radix : 10);
  int lim_a = 'a' + (radix - 10);
  int lim_A = 'A' + (radix - 10);

  do {
    int digit;
    if (*current >= '0' && *current < lim_0) {
      digit = static_cast<char>(*current) - '0';
    } else if (*current >= 'a' && *current < lim_a) {
      digit = static_cast<char>(*current) - 'a' + 10;
    } else if (*current >= 'A' && *current < lim_A) {
      digit = static_cast<char>(*current) - 'A' + 10;
    } else {
      if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
        break;
      } else {
        return JunkStringValue();
      }
    }

    number = number * radix + digit;
    int overflow = static_cast<int>(number >> 53);
    if (overflow != 0) {
      // Overflow occurred. Need to determine which direction to round the
      // result.
      int overflow_bits_count = 1;
      while (overflow > 1) {
        overflow_bits_count++;
        overflow >>= 1;
      }

      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
      number >>= overflow_bits_count;
      exponent = overflow_bits_count;

      bool zero_tail = true;
      while (true) {
        ++current;
        if (current == end || !isDigit(*current, radix)) break;
        zero_tail = zero_tail && *current == '0';
        exponent += radix_log_2;
      }

      if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
        return JunkStringValue();
      }

      int middle_value = (1 << (overflow_bits_count - 1));
      if (dropped_bits > middle_value) {
        number++;  // Rounding up.
      } else if (dropped_bits == middle_value) {
        // Rounding to even to consistency with decimals: half-way case rounds
        // up if significant part is odd and down otherwise.
        if ((number & 1) != 0 || !zero_tail) {
          number++;  // Rounding up.
        }
      }

      // Rounding up may cause overflow.
      if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
        exponent++;
        number >>= 1;
      }
      break;
    }
    ++current;
  } while (current != end);

  DCHECK(number < ((int64_t)1 << 53));
  DCHECK(static_cast<int64_t>(static_cast<double>(number)) == number);

  if (exponent == 0) {
    if (negative) {
      if (number == 0) return -0.0;
      number = -number;
    }
    return static_cast<double>(number);
  }

  DCHECK_NE(number, 0);
  return std::ldexp(static_cast<double>(negative ? -number : number), exponent);
}

// ES6 18.2.5 parseInt(string, radix) (with NumberParseIntHelper subclass);
// and BigInt parsing cases from https://tc39.github.io/proposal-bigint/
// (with StringToBigIntHelper subclass).
class StringToIntHelper {
 public:
  StringToIntHelper(Isolate* isolate, Handle<String> subject, int radix)
      : isolate_(isolate), subject_(subject), radix_(radix) {
    DCHECK(subject->IsFlat());
  }

  // Used for the StringToBigInt operation.
  StringToIntHelper(Isolate* isolate, Handle<String> subject)
      : isolate_(isolate), subject_(subject) {
    DCHECK(subject->IsFlat());
  }

  // Used for parsing BigInt literals, where the input is a Zone-allocated
  // buffer of one-byte digits, along with an optional radix prefix.
  StringToIntHelper(Isolate* isolate, const uint8_t* subject, int length)
      : isolate_(isolate), raw_one_byte_subject_(subject), length_(length) {}
  virtual ~StringToIntHelper() = default;

 protected:
  // Subclasses must implement these:
  virtual void AllocateResult() = 0;
  virtual void ResultMultiplyAdd(uint32_t multiplier, uint32_t part) = 0;

  // Subclasses must call this to do all the work.
  void ParseInt();

  // Subclasses may override this.
  virtual void HandleSpecialCases() {}

  // Subclass constructors should call these for configuration before calling
  // ParseInt().
  void set_allow_binary_and_octal_prefixes() {
    allow_binary_and_octal_prefixes_ = true;
  }
  void set_disallow_trailing_junk() { allow_trailing_junk_ = false; }

  bool IsOneByte() const {
    return raw_one_byte_subject_ != nullptr ||
           String::IsOneByteRepresentationUnderneath(*subject_);
  }

  Vector<const uint8_t> GetOneByteVector() {
    if (raw_one_byte_subject_ != nullptr) {
      return Vector<const uint8_t>(raw_one_byte_subject_, length_);
    }
    DisallowHeapAllocation no_gc;
    return subject_->GetFlatContent(no_gc).ToOneByteVector();
  }

  Vector<const uc16> GetTwoByteVector() {
    DisallowHeapAllocation no_gc;
    return subject_->GetFlatContent(no_gc).ToUC16Vector();
  }

  // Subclasses get access to internal state:
  enum State { kRunning, kError, kJunk, kEmpty, kZero, kDone };

  enum class Sign { kNegative, kPositive, kNone };

  Isolate* isolate() { return isolate_; }
  int radix() { return radix_; }
  int cursor() { return cursor_; }
  int length() { return length_; }
  bool negative() { return sign_ == Sign::kNegative; }
  Sign sign() { return sign_; }
  State state() { return state_; }
  void set_state(State state) { state_ = state; }

 private:
  template <class Char>
  void DetectRadixInternal(Char current, int length);
  template <class Char>
  void ParseInternal(Char start);

  Isolate* isolate_;
  Handle<String> subject_;
  const uint8_t* raw_one_byte_subject_ = nullptr;
  int radix_ = 0;
  int cursor_ = 0;
  int length_ = 0;
  Sign sign_ = Sign::kNone;
  bool leading_zero_ = false;
  bool allow_binary_and_octal_prefixes_ = false;
  bool allow_trailing_junk_ = true;
  State state_ = kRunning;
};

void StringToIntHelper::ParseInt() {
  {
    DisallowHeapAllocation no_gc;
    if (IsOneByte()) {
      Vector<const uint8_t> vector = GetOneByteVector();
      DetectRadixInternal(vector.begin(), vector.length());
    } else {
      Vector<const uc16> vector = GetTwoByteVector();
      DetectRadixInternal(vector.begin(), vector.length());
    }
  }
  if (state_ != kRunning) return;
  AllocateResult();
  HandleSpecialCases();
  if (state_ != kRunning) return;
  {
    DisallowHeapAllocation no_gc;
    if (IsOneByte()) {
      Vector<const uint8_t> vector = GetOneByteVector();
      DCHECK_EQ(length_, vector.length());
      ParseInternal(vector.begin());
    } else {
      Vector<const uc16> vector = GetTwoByteVector();
      DCHECK_EQ(length_, vector.length());
      ParseInternal(vector.begin());
    }
  }
  DCHECK_NE(state_, kRunning);
}

template <class Char>
void StringToIntHelper::DetectRadixInternal(Char current, int length) {
  Char start = current;
  length_ = length;
  Char end = start + length;

  if (!AdvanceToNonspace(&current, end)) {
    return set_state(kEmpty);
  }

  if (*current == '+') {
    // Ignore leading sign; skip following spaces.
    ++current;
    if (current == end) {
      return set_state(kJunk);
    }
    sign_ = Sign::kPositive;
  } else if (*current == '-') {
    ++current;
    if (current == end) {
      return set_state(kJunk);
    }
    sign_ = Sign::kNegative;
  }

  if (radix_ == 0) {
    // Radix detection.
    radix_ = 10;
    if (*current == '0') {
      ++current;
      if (current == end) return set_state(kZero);
      if (*current == 'x' || *current == 'X') {
        radix_ = 16;
        ++current;
        if (current == end) return set_state(kJunk);
      } else if (allow_binary_and_octal_prefixes_ &&
                 (*current == 'o' || *current == 'O')) {
        radix_ = 8;
        ++current;
        if (current == end) return set_state(kJunk);
      } else if (allow_binary_and_octal_prefixes_ &&
                 (*current == 'b' || *current == 'B')) {
        radix_ = 2;
        ++current;
        if (current == end) return set_state(kJunk);
      } else {
        leading_zero_ = true;
      }
    }
  } else if (radix_ == 16) {
    if (*current == '0') {
      // Allow "0x" prefix.
      ++current;
      if (current == end) return set_state(kZero);
      if (*current == 'x' || *current == 'X') {
        ++current;
        if (current == end) return set_state(kJunk);
      } else {
        leading_zero_ = true;
      }
    }
  }
  // Skip leading zeros.
  while (*current == '0') {
    leading_zero_ = true;
    ++current;
    if (current == end) return set_state(kZero);
  }

  if (!leading_zero_ && !isDigit(*current, radix_)) {
    return set_state(kJunk);
  }

  DCHECK(radix_ >= 2 && radix_ <= 36);
  STATIC_ASSERT(String::kMaxLength <= INT_MAX);
  cursor_ = static_cast<int>(current - start);
}

template <class Char>
void StringToIntHelper::ParseInternal(Char start) {
  Char current = start + cursor_;
  Char end = start + length_;

  // The following code causes accumulating rounding error for numbers greater
  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
  // 16, or 32, then mathInt may be an implementation-dependent approximation to
  // the mathematical integer value" (15.1.2.2).

  int lim_0 = '0' + (radix_ < 10 ? radix_ : 10);
  int lim_a = 'a' + (radix_ - 10);
  int lim_A = 'A' + (radix_ - 10);

  // NOTE: The code for computing the value may seem a bit complex at
  // first glance. It is structured to use 32-bit multiply-and-add
  // loops as long as possible to avoid losing precision.

  bool done = false;
  do {
    // Parse the longest part of the string starting at {current}
    // possible while keeping the multiplier, and thus the part
    // itself, within 32 bits.
    uint32_t part = 0, multiplier = 1;
    while (true) {
      uint32_t d;
      if (*current >= '0' && *current < lim_0) {
        d = *current - '0';
      } else if (*current >= 'a' && *current < lim_a) {
        d = *current - 'a' + 10;
      } else if (*current >= 'A' && *current < lim_A) {
        d = *current - 'A' + 10;
      } else {
        done = true;
        break;
      }

      // Update the value of the part as long as the multiplier fits
      // in 32 bits. When we can't guarantee that the next iteration
      // will not overflow the multiplier, we stop parsing the part
      // by leaving the loop.
      const uint32_t kMaximumMultiplier = 0xFFFFFFFFU / 36;
      uint32_t m = multiplier * static_cast<uint32_t>(radix_);
      if (m > kMaximumMultiplier) break;
      part = part * radix_ + d;
      multiplier = m;
      DCHECK(multiplier > part);

      ++current;
      if (current == end) {
        done = true;
        break;
      }
    }

    // Update the value and skip the part in the string.
    ResultMultiplyAdd(multiplier, part);
  } while (!done);

  if (!allow_trailing_junk_ && AdvanceToNonspace(&current, end)) {
    return set_state(kJunk);
  }

  return set_state(kDone);
}

class NumberParseIntHelper : public StringToIntHelper {
 public:
  NumberParseIntHelper(Isolate* isolate, Handle<String> string, int radix)
      : StringToIntHelper(isolate, string, radix) {}

  double GetResult() {
    ParseInt();
    switch (state()) {
      case kJunk:
      case kEmpty:
        return JunkStringValue();
      case kZero:
        return SignedZero(negative());
      case kDone:
        return negative() ? -result_ : result_;
      case kError:
      case kRunning:
        break;
    }
    UNREACHABLE();
  }

 protected:
  void AllocateResult() override {}
  void ResultMultiplyAdd(uint32_t multiplier, uint32_t part) override {
    result_ = result_ * multiplier + part;
  }

 private:
  void HandleSpecialCases() override {
    bool is_power_of_two = base::bits::IsPowerOfTwo(radix());
    if (!is_power_of_two && radix() != 10) return;
    DisallowHeapAllocation no_gc;
    if (IsOneByte()) {
      Vector<const uint8_t> vector = GetOneByteVector();
      DCHECK_EQ(length(), vector.length());
      result_ = is_power_of_two ? HandlePowerOfTwoCase(vector.begin())
                                : HandleBaseTenCase(vector.begin());
    } else {
      Vector<const uc16> vector = GetTwoByteVector();
      DCHECK_EQ(length(), vector.length());
      result_ = is_power_of_two ? HandlePowerOfTwoCase(vector.begin())
                                : HandleBaseTenCase(vector.begin());
    }
    set_state(kDone);
  }

  template <class Char>
  double HandlePowerOfTwoCase(Char start) {
    Char current = start + cursor();
    Char end = start + length();
    const bool allow_trailing_junk = true;
    // GetResult() will take care of the sign bit, so ignore it for now.
    const bool negative = false;
    switch (radix()) {
      case 2:
        return InternalStringToIntDouble<1>(current, end, negative,
                                            allow_trailing_junk);
      case 4:
        return InternalStringToIntDouble<2>(current, end, negative,
                                            allow_trailing_junk);
      case 8:
        return InternalStringToIntDouble<3>(current, end, negative,
                                            allow_trailing_junk);

      case 16:
        return InternalStringToIntDouble<4>(current, end, negative,
                                            allow_trailing_junk);

      case 32:
        return InternalStringToIntDouble<5>(current, end, negative,
                                            allow_trailing_junk);
      default:
        UNREACHABLE();
    }
  }

  template <class Char>
  double HandleBaseTenCase(Char start) {
    // Parsing with strtod.
    Char current = start + cursor();
    Char end = start + length();
    const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
    // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
    // end.
    const int kBufferSize = kMaxSignificantDigits + 2;
    char buffer[kBufferSize];
    int buffer_pos = 0;
    while (*current >= '0' && *current <= '9') {
      if (buffer_pos <= kMaxSignificantDigits) {
        // If the number has more than kMaxSignificantDigits it will be parsed
        // as infinity.
        DCHECK_LT(buffer_pos, kBufferSize);
        buffer[buffer_pos++] = static_cast<char>(*current);
      }
      ++current;
      if (current == end) break;
    }

    SLOW_DCHECK(buffer_pos < kBufferSize);
    buffer[buffer_pos] = '\0';
    Vector<const char> buffer_vector(buffer, buffer_pos);
    return Strtod(buffer_vector, 0);
  }

  double result_ = 0;
};

// Converts a string to a double value. Assumes the Iterator supports
// the following operations:
// 1. current == end (other ops are not allowed), current != end.
// 2. *current - gets the current character in the sequence.
// 3. ++current (advances the position).
template <class Iterator, class EndMark>
double InternalStringToDouble(Iterator current, EndMark end, int flags,
                              double empty_string_val) {
  // To make sure that iterator dereferencing is valid the following
  // convention is used:
  // 1. Each '++current' statement is followed by check for equality to 'end'.
  // 2. If AdvanceToNonspace returned false then current == end.
  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
  // 'parsing_done'.
  // 4. 'current' is not dereferenced after the 'parsing_done' label.
  // 5. Code before 'parsing_done' may rely on 'current != end'.
  if (!AdvanceToNonspace(&current, end)) {
    return empty_string_val;
  }

  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;

  // Maximum number of significant digits in decimal representation.
  // The longest possible double in decimal representation is
  // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
  // (768 digits). If we parse a number whose first digits are equal to a
  // mean of 2 adjacent doubles (that could have up to 769 digits) the result
  // must be rounded to the bigger one unless the tail consists of zeros, so
  // we don't need to preserve all the digits.
  const int kMaxSignificantDigits = 772;

  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
  const int kBufferSize = kMaxSignificantDigits + 10;
  char buffer[kBufferSize];  // NOLINT: size is known at compile time.
  int buffer_pos = 0;

  // Exponent will be adjusted if insignificant digits of the integer part
  // or insignificant leading zeros of the fractional part are dropped.
  int exponent = 0;
  int significant_digits = 0;
  int insignificant_digits = 0;
  bool nonzero_digit_dropped = false;

  enum Sign { NONE, NEGATIVE, POSITIVE };

  Sign sign = NONE;

  if (*current == '+') {
    // Ignore leading sign.
    ++current;
    if (current == end) return JunkStringValue();
    sign = POSITIVE;
  } else if (*current == '-') {
    ++current;
    if (current == end) return JunkStringValue();
    sign = NEGATIVE;
  }

  static const char kInfinityString[] = "Infinity";
  if (*current == kInfinityString[0]) {
    if (!SubStringEquals(&current, end, kInfinityString)) {
      return JunkStringValue();
    }

    if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
      return JunkStringValue();
    }

    DCHECK_EQ(buffer_pos, 0);
    return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
  }

  bool leading_zero = false;
  if (*current == '0') {
    ++current;
    if (current == end) return SignedZero(sign == NEGATIVE);

    leading_zero = true;

    // It could be hexadecimal value.
    if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
      ++current;
      if (current == end || !isDigit(*current, 16) || sign != NONE) {
        return JunkStringValue();  // "0x".
      }

      return InternalStringToIntDouble<4>(current, end, false,
                                          allow_trailing_junk);

      // It could be an explicit octal value.
    } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
      ++current;
      if (current == end || !isDigit(*current, 8) || sign != NONE) {
        return JunkStringValue();  // "0o".
      }

      return InternalStringToIntDouble<3>(current, end, false,
                                          allow_trailing_junk);

      // It could be a binary value.
    } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
      ++current;
      if (current == end || !isBinaryDigit(*current) || sign != NONE) {
        return JunkStringValue();  // "0b".
      }

      return InternalStringToIntDouble<1>(current, end, false,
                                          allow_trailing_junk);
    }

    // Ignore leading zeros in the integer part.
    while (*current == '0') {
      ++current;
      if (current == end) return SignedZero(sign == NEGATIVE);
    }
  }

  bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;

  // Copy significant digits of the integer part (if any) to the buffer.
  while (*current >= '0' && *current <= '9') {
    if (significant_digits < kMaxSignificantDigits) {
      DCHECK_LT(buffer_pos, kBufferSize);
      buffer[buffer_pos++] = static_cast<char>(*current);
      significant_digits++;
      // Will later check if it's an octal in the buffer.
    } else {
      insignificant_digits++;  // Move the digit into the exponential part.
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
    }
    octal = octal && *current < '8';
    ++current;
    if (current == end) goto parsing_done;
  }

  if (significant_digits == 0) {
    octal = false;
  }

  if (*current == '.') {
    if (octal && !allow_trailing_junk) return JunkStringValue();
    if (octal) goto parsing_done;

    ++current;
    if (current == end) {
      if (significant_digits == 0 && !leading_zero) {
        return JunkStringValue();
      } else {
        goto parsing_done;
      }
    }

    if (significant_digits == 0) {
      // octal = false;
      // Integer part consists of 0 or is absent. Significant digits start after
      // leading zeros (if any).
      while (*current == '0') {
        ++current;
        if (current == end) return SignedZero(sign == NEGATIVE);
        exponent--;  // Move this 0 into the exponent.
      }
    }

    // There is a fractional part.  We don't emit a '.', but adjust the exponent
    // instead.
    while (*current >= '0' && *current <= '9') {
      if (significant_digits < kMaxSignificantDigits) {
        DCHECK_LT(buffer_pos, kBufferSize);
        buffer[buffer_pos++] = static_cast<char>(*current);
        significant_digits++;
        exponent--;
      } else {
        // Ignore insignificant digits in the fractional part.
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
      }
      ++current;
      if (current == end) goto parsing_done;
    }
  }

  if (!leading_zero && exponent == 0 && significant_digits == 0) {
    // If leading_zeros is true then the string contains zeros.
    // If exponent < 0 then string was [+-]\.0*...
    // If significant_digits != 0 the string is not equal to 0.
    // Otherwise there are no digits in the string.
    return JunkStringValue();
  }

  // Parse exponential part.
  if (*current == 'e' || *current == 'E') {
    if (octal) return JunkStringValue();
    ++current;
    if (current == end) {
      if (allow_trailing_junk) {
        goto parsing_done;
      } else {
        return JunkStringValue();
      }
    }
    char sign = '+';
    if (*current == '+' || *current == '-') {
      sign = static_cast<char>(*current);
      ++current;
      if (current == end) {
        if (allow_trailing_junk) {
          goto parsing_done;
        } else {
          return JunkStringValue();
        }
      }
    }

    if (current == end || *current < '0' || *current > '9') {
      if (allow_trailing_junk) {
        goto parsing_done;
      } else {
        return JunkStringValue();
      }
    }

    const int max_exponent = INT_MAX / 2;
    DCHECK(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
    int num = 0;
    do {
      // Check overflow.
      int digit = *current - '0';
      if (num >= max_exponent / 10 &&
          !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
        num = max_exponent;
      } else {
        num = num * 10 + digit;
      }
      ++current;
    } while (current != end && *current >= '0' && *current <= '9');

    exponent += (sign == '-' ? -num : num);
  }

  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
    return JunkStringValue();
  }

parsing_done:
  exponent += insignificant_digits;

  if (octal) {
    return InternalStringToIntDouble<3>(buffer, buffer + buffer_pos,
                                        sign == NEGATIVE, allow_trailing_junk);
  }

  if (nonzero_digit_dropped) {
    buffer[buffer_pos++] = '1';
    exponent--;
  }

  SLOW_DCHECK(buffer_pos < kBufferSize);
  buffer[buffer_pos] = '\0';

  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
  return (sign == NEGATIVE) ? -converted : converted;
}

double StringToDouble(const char* str, int flags, double empty_string_val) {
  // We use {OneByteVector} instead of {CStrVector} to avoid instantiating the
  // InternalStringToDouble() template for {const char*} as well.
  return StringToDouble(OneByteVector(str), flags, empty_string_val);
}

double StringToDouble(Vector<const uint8_t> str, int flags,
                      double empty_string_val) {
  return InternalStringToDouble(str.begin(), str.end(), flags,
                                empty_string_val);
}

double StringToDouble(Vector<const uc16> str, int flags,
                      double empty_string_val) {
  const uc16* end = str.begin() + str.length();
  return InternalStringToDouble(str.begin(), end, flags, empty_string_val);
}

double StringToInt(Isolate* isolate, Handle<String> string, int radix) {
  NumberParseIntHelper helper(isolate, string, radix);
  return helper.GetResult();
}

class StringToBigIntHelper : public StringToIntHelper {
 public:
  enum class Behavior { kStringToBigInt, kLiteral };

  // Used for StringToBigInt operation (BigInt constructor and == operator).
  StringToBigIntHelper(Isolate* isolate, Handle<String> string)
      : StringToIntHelper(isolate, string),
        behavior_(Behavior::kStringToBigInt) {
    set_allow_binary_and_octal_prefixes();
    set_disallow_trailing_junk();
  }

  // Used for parsing BigInt literals, where the input is a buffer of
  // one-byte ASCII digits, along with an optional radix prefix.
  StringToBigIntHelper(Isolate* isolate, const uint8_t* string, int length)
      : StringToIntHelper(isolate, string, length),
        behavior_(Behavior::kLiteral) {
    set_allow_binary_and_octal_prefixes();
  }

  MaybeHandle<BigInt> GetResult() {
    ParseInt();
    if (behavior_ == Behavior::kStringToBigInt && sign() != Sign::kNone &&
        radix() != 10) {
      return MaybeHandle<BigInt>();
    }
    if (state() == kEmpty) {
      if (behavior_ == Behavior::kStringToBigInt) {
        set_state(kZero);
      } else {
        UNREACHABLE();
      }
    }
    switch (state()) {
      case kJunk:
        if (should_throw() == kThrowOnError) {
          THROW_NEW_ERROR(isolate(),
                          NewSyntaxError(MessageTemplate::kBigIntInvalidString),
                          BigInt);
        } else {
          DCHECK_EQ(should_throw(), kDontThrow);
          return MaybeHandle<BigInt>();
        }
      case kZero:
        return BigInt::Zero(isolate());
      case kError:
        DCHECK_EQ(should_throw() == kThrowOnError,
                  isolate()->has_pending_exception());
        return MaybeHandle<BigInt>();
      case kDone:
        return BigInt::Finalize(result_, negative());
      case kEmpty:
      case kRunning:
        break;
    }
    UNREACHABLE();
  }

 protected:
  void AllocateResult() override {
    // We have to allocate a BigInt that's big enough to fit the result.
    // Conseratively assume that all remaining digits are significant.
    // Optimization opportunity: Would it makes sense to scan for trailing
    // junk before allocating the result?
    int charcount = length() - cursor();
    // For literals, we pretenure the allocated BigInt, since it's about
    // to be stored in the interpreter's constants array.
    AllocationType allocation = behavior_ == Behavior::kLiteral
                                    ? AllocationType::kOld
                                    : AllocationType::kYoung;
    MaybeHandle<FreshlyAllocatedBigInt> maybe = BigInt::AllocateFor(
        isolate(), radix(), charcount, should_throw(), allocation);
    if (!maybe.ToHandle(&result_)) {
      set_state(kError);
    }
  }

  void ResultMultiplyAdd(uint32_t multiplier, uint32_t part) override {
    BigInt::InplaceMultiplyAdd(result_, static_cast<uintptr_t>(multiplier),
                               static_cast<uintptr_t>(part));
  }

 private:
  ShouldThrow should_throw() const { return kDontThrow; }

  Handle<FreshlyAllocatedBigInt> result_;
  Behavior behavior_;
};

MaybeHandle<BigInt> StringToBigInt(Isolate* isolate, Handle<String> string) {
  string = String::Flatten(isolate, string);
  StringToBigIntHelper helper(isolate, string);
  return helper.GetResult();
}

MaybeHandle<BigInt> BigIntLiteral(Isolate* isolate, const char* string) {
  StringToBigIntHelper helper(isolate, reinterpret_cast<const uint8_t*>(string),
                              static_cast<int>(strlen(string)));
  return helper.GetResult();
}

const char* DoubleToCString(double v, Vector<char> buffer) {
  switch (FPCLASSIFY_NAMESPACE::fpclassify(v)) {
    case FP_NAN: return "NaN";
    case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
    case FP_ZERO: return "0";
    default: {
      if (IsInt32Double(v)) {
        // This will trigger if v is -0 and -0.0 is stringified to "0".
        // (see ES section 7.1.12.1 #sec-tostring-applied-to-the-number-type)
        return IntToCString(FastD2I(v), buffer);
      }
      SimpleStringBuilder builder(buffer.begin(), buffer.length());
      int decimal_point;
      int sign;
      const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
      char decimal_rep[kV8DtoaBufferCapacity];
      int length;

      DoubleToAscii(v, DTOA_SHORTEST, 0,
                    Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
                    &sign, &length, &decimal_point);

      if (sign) builder.AddCharacter('-');

      if (length <= decimal_point && decimal_point <= 21) {
        // ECMA-262 section 9.8.1 step 6.
        builder.AddString(decimal_rep);
        builder.AddPadding('0', decimal_point - length);

      } else if (0 < decimal_point && decimal_point <= 21) {
        // ECMA-262 section 9.8.1 step 7.
        builder.AddSubstring(decimal_rep, decimal_point);
        builder.AddCharacter('.');
        builder.AddString(decimal_rep + decimal_point);

      } else if (decimal_point <= 0 && decimal_point > -6) {
        // ECMA-262 section 9.8.1 step 8.
        builder.AddString("0.");
        builder.AddPadding('0', -decimal_point);
        builder.AddString(decimal_rep);

      } else {
        // ECMA-262 section 9.8.1 step 9 and 10 combined.
        builder.AddCharacter(decimal_rep[0]);
        if (length != 1) {
          builder.AddCharacter('.');
          builder.AddString(decimal_rep + 1);
        }
        builder.AddCharacter('e');
        builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
        int exponent = decimal_point - 1;
        if (exponent < 0) exponent = -exponent;
        builder.AddDecimalInteger(exponent);
      }
      return builder.Finalize();
    }
  }
}


const char* IntToCString(int n, Vector<char> buffer) {
  bool negative = true;
  if (n >= 0) {
    n = -n;
    negative = false;
  }
  // Build the string backwards from the least significant digit.
  int i = buffer.length();
  buffer[--i] = '\0';
  do {
    // We ensured n <= 0, so the subtraction does the right addition.
    buffer[--i] = '0' - (n % 10);
    n /= 10;
  } while (n);
  if (negative) buffer[--i] = '-';
  return buffer.begin() + i;
}


char* DoubleToFixedCString(double value, int f) {
  const int kMaxDigitsBeforePoint = 21;
  const double kFirstNonFixed = 1e21;
  DCHECK_GE(f, 0);
  DCHECK_LE(f, kMaxFractionDigits);

  bool negative = false;
  double abs_value = value;
  if (value < 0) {
    abs_value = -value;
    negative = true;
  }

  // If abs_value has more than kMaxDigitsBeforePoint digits before the point
  // use the non-fixed conversion routine.
  if (abs_value >= kFirstNonFixed) {
    char arr[kMaxFractionDigits];
    Vector<char> buffer(arr, arraysize(arr));
    return StrDup(DoubleToCString(value, buffer));
  }

  // Find a sufficiently precise decimal representation of n.
  int decimal_point;
  int sign;
  // Add space for the '\0' byte.
  const int kDecimalRepCapacity =
      kMaxDigitsBeforePoint + kMaxFractionDigits + 1;
  char decimal_rep[kDecimalRepCapacity];
  int decimal_rep_length;
  DoubleToAscii(value, DTOA_FIXED, f,
                Vector<char>(decimal_rep, kDecimalRepCapacity),
                &sign, &decimal_rep_length, &decimal_point);

  // Create a representation that is padded with zeros if needed.
  int zero_prefix_length = 0;
  int zero_postfix_length = 0;

  if (decimal_point <= 0) {
    zero_prefix_length = -decimal_point + 1;
    decimal_point = 1;
  }

  if (zero_prefix_length + decimal_rep_length < decimal_point + f) {
    zero_postfix_length = decimal_point + f - decimal_rep_length -
                          zero_prefix_length;
  }

  unsigned rep_length =
      zero_prefix_length + decimal_rep_length + zero_postfix_length;
  SimpleStringBuilder rep_builder(rep_length + 1);
  rep_builder.AddPadding('0', zero_prefix_length);
  rep_builder.AddString(decimal_rep);
  rep_builder.AddPadding('0', zero_postfix_length);
  char* rep = rep_builder.Finalize();

  // Create the result string by appending a minus and putting in a
  // decimal point if needed.
  unsigned result_size = decimal_point + f + 2;
  SimpleStringBuilder builder(result_size + 1);
  if (negative) builder.AddCharacter('-');
  builder.AddSubstring(rep, decimal_point);
  if (f > 0) {
    builder.AddCharacter('.');
    builder.AddSubstring(rep + decimal_point, f);
  }
  DeleteArray(rep);
  return builder.Finalize();
}


static char* CreateExponentialRepresentation(char* decimal_rep,
                                             int exponent,
                                             bool negative,
                                             int significant_digits) {
  bool negative_exponent = false;
  if (exponent < 0) {
    negative_exponent = true;
    exponent = -exponent;
  }

  // Leave room in the result for appending a minus, for a period, the
  // letter 'e', a minus or a plus depending on the exponent, and a
  // three digit exponent.
  unsigned result_size = significant_digits + 7;
  SimpleStringBuilder builder(result_size + 1);

  if (negative) builder.AddCharacter('-');
  builder.AddCharacter(decimal_rep[0]);
  if (significant_digits != 1) {
    builder.AddCharacter('.');
    builder.AddString(decimal_rep + 1);
    size_t rep_length = strlen(decimal_rep);
    DCHECK_GE(significant_digits, rep_length);
    builder.AddPadding('0', significant_digits - static_cast<int>(rep_length));
  }

  builder.AddCharacter('e');
  builder.AddCharacter(negative_exponent ? '-' : '+');
  builder.AddDecimalInteger(exponent);
  return builder.Finalize();
}


char* DoubleToExponentialCString(double value, int f) {
  // f might be -1 to signal that f was undefined in JavaScript.
  DCHECK(f >= -1 && f <= kMaxFractionDigits);

  bool negative = false;
  if (value < 0) {
    value = -value;
    negative = true;
  }

  // Find a sufficiently precise decimal representation of n.
  int decimal_point;
  int sign;
  // f corresponds to the digits after the point. There is always one digit
  // before the point. The number of requested_digits equals hence f + 1.
  // And we have to add one character for the null-terminator.
  const int kV8DtoaBufferCapacity = kMaxFractionDigits + 1 + 1;
  // Make sure that the buffer is big enough, even if we fall back to the
  // shortest representation (which happens when f equals -1).
  DCHECK_LE(kBase10MaximalLength, kMaxFractionDigits + 1);
  char decimal_rep[kV8DtoaBufferCapacity];
  int decimal_rep_length;

  if (f == -1) {
    DoubleToAscii(value, DTOA_SHORTEST, 0,
                  Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
                  &sign, &decimal_rep_length, &decimal_point);
    f = decimal_rep_length - 1;
  } else {
    DoubleToAscii(value, DTOA_PRECISION, f + 1,
                  Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
                  &sign, &decimal_rep_length, &decimal_point);
  }
  DCHECK_GT(decimal_rep_length, 0);
  DCHECK(decimal_rep_length <= f + 1);

  int exponent = decimal_point - 1;
  char* result =
      CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1);

  return result;
}


char* DoubleToPrecisionCString(double value, int p) {
  const int kMinimalDigits = 1;
  DCHECK(p >= kMinimalDigits && p <= kMaxFractionDigits);
  USE(kMinimalDigits);

  bool negative = false;
  if (value < 0) {
    value = -value;
    negative = true;
  }

  // Find a sufficiently precise decimal representation of n.
  int decimal_point;
  int sign;
  // Add one for the terminating null character.
  const int kV8DtoaBufferCapacity = kMaxFractionDigits + 1;
  char decimal_rep[kV8DtoaBufferCapacity];
  int decimal_rep_length;

  DoubleToAscii(value, DTOA_PRECISION, p,
                Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
                &sign, &decimal_rep_length, &decimal_point);
  DCHECK(decimal_rep_length <= p);

  int exponent = decimal_point - 1;

  char* result = nullptr;

  if (exponent < -6 || exponent >= p) {
    result =
        CreateExponentialRepresentation(decimal_rep, exponent, negative, p);
  } else {
    // Use fixed notation.
    //
    // Leave room in the result for appending a minus, a period and in
    // the case where decimal_point is not positive for a zero in
    // front of the period.
    unsigned result_size = (decimal_point <= 0)
        ? -decimal_point + p + 3
        : p + 2;
    SimpleStringBuilder builder(result_size + 1);
    if (negative) builder.AddCharacter('-');
    if (decimal_point <= 0) {
      builder.AddString("0.");
      builder.AddPadding('0', -decimal_point);
      builder.AddString(decimal_rep);
      builder.AddPadding('0', p - decimal_rep_length);
    } else {
      const int m = Min(decimal_rep_length, decimal_point);
      builder.AddSubstring(decimal_rep, m);
      builder.AddPadding('0', decimal_point - decimal_rep_length);
      if (decimal_point < p) {
        builder.AddCharacter('.');
        const int extra = negative ? 2 : 1;
        if (decimal_rep_length > decimal_point) {
          const size_t len = strlen(decimal_rep + decimal_point);
          DCHECK_GE(kMaxInt, len);
          const int n =
              Min(static_cast<int>(len), p - (builder.position() - extra));
          builder.AddSubstring(decimal_rep + decimal_point, n);
        }
        builder.AddPadding('0', extra + (p - builder.position()));
      }
    }
    result = builder.Finalize();
  }

  return result;
}

char* DoubleToRadixCString(double value, int radix) {
  DCHECK(radix >= 2 && radix <= 36);
  DCHECK(std::isfinite(value));
  DCHECK_NE(0.0, value);
  // Character array used for conversion.
  static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";

  // Temporary buffer for the result. We start with the decimal point in the
  // middle and write to the left for the integer part and to the right for the
  // fractional part. 1024 characters for the exponent and 52 for the mantissa
  // either way, with additional space for sign, decimal point and string
  // termination should be sufficient.
  static const int kBufferSize = 2200;
  char buffer[kBufferSize];
  int integer_cursor = kBufferSize / 2;
  int fraction_cursor = integer_cursor;

  bool negative = value < 0;
  if (negative) value = -value;

  // Split the value into an integer part and a fractional part.
  double integer = std::floor(value);
  double fraction = value - integer;
  // We only compute fractional digits up to the input double's precision.
  double delta = 0.5 * (Double(value).NextDouble() - value);
  delta = std::max(Double(0.0).NextDouble(), delta);
  DCHECK_GT(delta, 0.0);
  if (fraction > delta) {
    // Insert decimal point.
    buffer[fraction_cursor++] = '.';
    do {
      // Shift up by one digit.
      fraction *= radix;
      delta *= radix;
      // Write digit.
      int digit = static_cast<int>(fraction);
      buffer[fraction_cursor++] = chars[digit];
      // Calculate remainder.
      fraction -= digit;
      // Round to even.
      if (fraction > 0.5 || (fraction == 0.5 && (digit & 1))) {
        if (fraction + delta > 1) {
          // We need to back trace already written digits in case of carry-over.
          while (true) {
            fraction_cursor--;
            if (fraction_cursor == kBufferSize / 2) {
              CHECK_EQ('.', buffer[fraction_cursor]);
              // Carry over to the integer part.
              integer += 1;
              break;
            }
            char c = buffer[fraction_cursor];
            // Reconstruct digit.
            int digit = c > '9' ? (c - 'a' + 10) : (c - '0');
            if (digit + 1 < radix) {
              buffer[fraction_cursor++] = chars[digit + 1];
              break;
            }
          }
          break;
        }
      }
    } while (fraction > delta);
  }

  // Compute integer digits. Fill unrepresented digits with zero.
  while (Double(integer / radix).Exponent() > 0) {
    integer /= radix;
    buffer[--integer_cursor] = '0';
  }
  do {
    double remainder = Modulo(integer, radix);
    buffer[--integer_cursor] = chars[static_cast<int>(remainder)];
    integer = (integer - remainder) / radix;
  } while (integer > 0);

  // Add sign and terminate string.
  if (negative) buffer[--integer_cursor] = '-';
  buffer[fraction_cursor++] = '\0';
  DCHECK_LT(fraction_cursor, kBufferSize);
  DCHECK_LE(0, integer_cursor);
  // Allocate new string as return value.
  char* result = NewArray<char>(fraction_cursor - integer_cursor);
  memcpy(result, buffer + integer_cursor, fraction_cursor - integer_cursor);
  return result;
}


// ES6 18.2.4 parseFloat(string)
double StringToDouble(Isolate* isolate, Handle<String> string, int flags,
                      double empty_string_val) {
  Handle<String> flattened = String::Flatten(isolate, string);
  {
    DisallowHeapAllocation no_gc;
    String::FlatContent flat = flattened->GetFlatContent(no_gc);
    DCHECK(flat.IsFlat());
    if (flat.IsOneByte()) {
      return StringToDouble(flat.ToOneByteVector(), flags, empty_string_val);
    } else {
      return StringToDouble(flat.ToUC16Vector(), flags, empty_string_val);
    }
  }
}

bool IsSpecialIndex(String string) {
  // Max length of canonical double: -X.XXXXXXXXXXXXXXXXX-eXXX
  const int kBufferSize = 24;
  const int length = string->length();
  if (length == 0 || length > kBufferSize) return false;
  uint16_t buffer[kBufferSize];
  String::WriteToFlat(string, buffer, 0, length);
  // If the first char is not a digit or a '-' or we can't match 'NaN' or
  // '(-)Infinity', bailout immediately.
  int offset = 0;
  if (!IsDecimalDigit(buffer[0])) {
    if (buffer[0] == '-') {
      if (length == 1) return false;  // Just '-' is bad.
      if (!IsDecimalDigit(buffer[1])) {
        if (buffer[1] == 'I' && length == 9) {
          // Allow matching of '-Infinity' below.
        } else {
          return false;
        }
      }
      offset++;
    } else if (buffer[0] == 'I' && length == 8) {
      // Allow matching of 'Infinity' below.
    } else if (buffer[0] == 'N' && length == 3) {
      // Match NaN.
      return buffer[1] == 'a' && buffer[2] == 'N';
    } else {
      return false;
    }
  }
  // Expected fast path: key is an integer.
  static const int kRepresentableIntegerLength = 15;  // (-)XXXXXXXXXXXXXXX
  if (length - offset <= kRepresentableIntegerLength) {
    const int initial_offset = offset;
    bool matches = true;
    for (; offset < length; offset++) {
      matches &= IsDecimalDigit(buffer[offset]);
    }
    if (matches) {
      // Match 0 and -0.
      if (buffer[initial_offset] == '0') return initial_offset == length - 1;
      return true;
    }
  }
  // Slow path: test DoubleToString(StringToDouble(string)) == string.
  Vector<const uint16_t> vector(buffer, length);
  double d = StringToDouble(vector, NO_FLAGS);
  if (std::isnan(d)) return false;
  // Compute reverse string.
  char reverse_buffer[kBufferSize + 1];  // Result will be /0 terminated.
  Vector<char> reverse_vector(reverse_buffer, arraysize(reverse_buffer));
  const char* reverse_string = DoubleToCString(d, reverse_vector);
  for (int i = 0; i < length; ++i) {
    if (static_cast<uint16_t>(reverse_string[i]) != buffer[i]) return false;
  }
  return true;
}
}  // namespace internal
}  // namespace v8
