vendor/v8/src/conversions.cc in mustang-0.0.1 vs vendor/v8/src/conversions.cc in mustang-0.1.0

- old
+ new

@@ -107,13 +107,15 @@ static const double JUNK_STRING_VALUE = OS::nan_value(); // Returns true if a nonspace found and false if the end has reached. template <class Iterator, class EndMark> -static inline bool AdvanceToNonspace(Iterator* current, EndMark end) { +static inline bool AdvanceToNonspace(ScannerConstants* scanner_constants, + Iterator* current, + EndMark end) { while (*current != end) { - if (!ScannerConstants::kIsWhiteSpace.get(**current)) return true; + if (!scanner_constants->IsWhiteSpace(**current)) return true; ++*current; } return false; } @@ -130,11 +132,12 @@ } // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. template <int radix_log_2, class Iterator, class EndMark> -static double InternalStringToIntDouble(Iterator current, +static double InternalStringToIntDouble(ScannerConstants* scanner_constants, + Iterator current, EndMark end, bool negative, bool allow_trailing_junk) { ASSERT(current != end); @@ -155,11 +158,12 @@ } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { digit = static_cast<char>(*current) - 'a' + 10; } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { digit = static_cast<char>(*current) - 'A' + 10; } else { - if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) { + if (allow_trailing_junk || + !AdvanceToNonspace(scanner_constants, &current, end)) { break; } else { return JUNK_STRING_VALUE; } } @@ -186,11 +190,12 @@ if (current == end || !isDigit(*current, radix)) break; zero_tail = zero_tail && *current == '0'; exponent += radix_log_2; } - if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) { + if (!allow_trailing_junk && + AdvanceToNonspace(scanner_constants, &current, end)) { return JUNK_STRING_VALUE; } int middle_value = (1 << (overflow_bits_count - 1)); if (dropped_bits > middle_value) { @@ -230,26 +235,35 @@ return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); } template <class Iterator, class EndMark> -static double InternalStringToInt(Iterator current, EndMark end, int radix) { +static double InternalStringToInt(ScannerConstants* scanner_constants, + Iterator current, + EndMark end, + int radix) { const bool allow_trailing_junk = true; const double empty_string_val = JUNK_STRING_VALUE; - if (!AdvanceToNonspace(&current, end)) return empty_string_val; + if (!AdvanceToNonspace(scanner_constants, &current, end)) { + return empty_string_val; + } bool negative = false; bool leading_zero = false; if (*current == '+') { // Ignore leading sign; skip following spaces. ++current; - if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE; + if (!AdvanceToNonspace(scanner_constants, &current, end)) { + return JUNK_STRING_VALUE; + } } else if (*current == '-') { ++current; - if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE; + if (!AdvanceToNonspace(scanner_constants, &current, end)) { + return JUNK_STRING_VALUE; + } negative = true; } if (radix == 0) { // Radix detection. @@ -296,25 +310,25 @@ if (IsPowerOf2(radix)) { switch (radix) { case 2: return InternalStringToIntDouble<1>( - current, end, negative, allow_trailing_junk); + scanner_constants, current, end, negative, allow_trailing_junk); case 4: return InternalStringToIntDouble<2>( - current, end, negative, allow_trailing_junk); + scanner_constants, current, end, negative, allow_trailing_junk); case 8: return InternalStringToIntDouble<3>( - current, end, negative, allow_trailing_junk); + scanner_constants, current, end, negative, allow_trailing_junk); case 16: return InternalStringToIntDouble<4>( - current, end, negative, allow_trailing_junk); + scanner_constants, current, end, negative, allow_trailing_junk); case 32: return InternalStringToIntDouble<5>( - current, end, negative, allow_trailing_junk); + scanner_constants, current, end, negative, allow_trailing_junk); default: UNREACHABLE(); } } @@ -335,11 +349,12 @@ } ++current; if (current == end) break; } - if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) { + if (!allow_trailing_junk && + AdvanceToNonspace(scanner_constants, &current, end)) { return JUNK_STRING_VALUE; } ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos] = '\0'; @@ -400,11 +415,12 @@ // Update the value and skip the part in the string. v = v * multiplier + part; } while (!done); - if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) { + if (!allow_trailing_junk && + AdvanceToNonspace(scanner_constants, &current, end)) { return JUNK_STRING_VALUE; } return negative ? -v : v; } @@ -414,11 +430,12 @@ // 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> -static double InternalStringToDouble(Iterator current, +static double InternalStringToDouble(ScannerConstants* scanner_constants, + Iterator current, EndMark end, int flags, double empty_string_val) { // To make sure that iterator dereferencing is valid the following // convention is used: @@ -426,11 +443,13 @@ // 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; + if (!AdvanceToNonspace(scanner_constants, &current, end)) { + return empty_string_val; + } const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". const int kBufferSize = kMaxSignificantDigits + 10; @@ -461,11 +480,12 @@ if (*current == kInfinitySymbol[0]) { if (!SubStringEquals(&current, end, kInfinitySymbol)) { return JUNK_STRING_VALUE; } - if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) { + if (!allow_trailing_junk && + AdvanceToNonspace(scanner_constants, &current, end)) { return JUNK_STRING_VALUE; } ASSERT(buffer_pos == 0); return negative ? -V8_INFINITY : V8_INFINITY; @@ -483,11 +503,12 @@ ++current; if (current == end || !isDigit(*current, 16)) { return JUNK_STRING_VALUE; // "0x". } - return InternalStringToIntDouble<4>(current, + return InternalStringToIntDouble<4>(scanner_constants, + current, end, negative, allow_trailing_junk); } @@ -619,19 +640,21 @@ } while (current != end && *current >= '0' && *current <= '9'); exponent += (sign == '-' ? -num : num); } - if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) { + if (!allow_trailing_junk && + AdvanceToNonspace(scanner_constants, &current, end)) { return JUNK_STRING_VALUE; } parsing_done: exponent += insignificant_digits; if (octal) { - return InternalStringToIntDouble<3>(buffer, + return InternalStringToIntDouble<3>(scanner_constants, + buffer, buffer + buffer_pos, negative, allow_trailing_junk); } @@ -647,59 +670,73 @@ return negative ? -converted : converted; } double StringToDouble(String* str, int flags, double empty_string_val) { + ScannerConstants* scanner_constants = + Isolate::Current()->scanner_constants(); StringShape shape(str); if (shape.IsSequentialAscii()) { const char* begin = SeqAsciiString::cast(str)->GetChars(); const char* end = begin + str->length(); - return InternalStringToDouble(begin, end, flags, empty_string_val); + return InternalStringToDouble(scanner_constants, begin, end, flags, + empty_string_val); } else if (shape.IsSequentialTwoByte()) { const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); const uc16* end = begin + str->length(); - return InternalStringToDouble(begin, end, flags, empty_string_val); + return InternalStringToDouble(scanner_constants, begin, end, flags, + empty_string_val); } else { StringInputBuffer buffer(str); - return InternalStringToDouble(StringInputBufferIterator(&buffer), + return InternalStringToDouble(scanner_constants, + StringInputBufferIterator(&buffer), StringInputBufferIterator::EndMarker(), flags, empty_string_val); } } double StringToInt(String* str, int radix) { + ScannerConstants* scanner_constants = + Isolate::Current()->scanner_constants(); StringShape shape(str); if (shape.IsSequentialAscii()) { const char* begin = SeqAsciiString::cast(str)->GetChars(); const char* end = begin + str->length(); - return InternalStringToInt(begin, end, radix); + return InternalStringToInt(scanner_constants, begin, end, radix); } else if (shape.IsSequentialTwoByte()) { const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); const uc16* end = begin + str->length(); - return InternalStringToInt(begin, end, radix); + return InternalStringToInt(scanner_constants, begin, end, radix); } else { StringInputBuffer buffer(str); - return InternalStringToInt(StringInputBufferIterator(&buffer), + return InternalStringToInt(scanner_constants, + StringInputBufferIterator(&buffer), StringInputBufferIterator::EndMarker(), radix); } } double StringToDouble(const char* str, int flags, double empty_string_val) { + ScannerConstants* scanner_constants = + Isolate::Current()->scanner_constants(); const char* end = str + StrLength(str); - return InternalStringToDouble(str, end, flags, empty_string_val); + return InternalStringToDouble(scanner_constants, str, end, flags, + empty_string_val); } double StringToDouble(Vector<const char> str, int flags, double empty_string_val) { + ScannerConstants* scanner_constants = + Isolate::Current()->scanner_constants(); const char* end = str.start() + str.length(); - return InternalStringToDouble(str.start(), end, flags, empty_string_val); + return InternalStringToDouble(scanner_constants, str.start(), end, flags, + empty_string_val); } const char* DoubleToCString(double v, Vector<char> buffer) { switch (fpclassify(v)) { @@ -1064,6 +1101,25 @@ builder.AddSubstring(decimal_buffer, decimal_pos); return builder.Finalize(); } +static Mutex* dtoa_lock_one = OS::CreateMutex(); +static Mutex* dtoa_lock_zero = OS::CreateMutex(); + + } } // namespace v8::internal + + +extern "C" { +void ACQUIRE_DTOA_LOCK(int n) { + ASSERT(n == 0 || n == 1); + (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock(); +} + + +void FREE_DTOA_LOCK(int n) { + ASSERT(n == 0 || n == 1); + (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)-> + Unlock(); +} +}