v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
conversions-inl.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_CONVERSIONS_INL_H_
29 #define V8_CONVERSIONS_INL_H_
30 
31 #include <limits.h> // Required for INT_MAX etc.
32 #include <float.h> // Required for DBL_MAX and on Win32 for finite()
33 #include <stdarg.h>
34 #include <cmath>
35 #include "globals.h" // Required for V8_INFINITY
36 
37 // ----------------------------------------------------------------------------
38 // Extra POSIX/ANSI functions for Win32/MSVC.
39 
40 #include "conversions.h"
41 #include "double.h"
42 #include "platform.h"
43 #include "scanner.h"
44 #include "strtod.h"
45 
46 namespace v8 {
47 namespace internal {
48 
49 inline double JunkStringValue() {
50  return BitCast<double, uint64_t>(kQuietNaNMask);
51 }
52 
53 
54 inline double SignedZero(bool negative) {
55  return negative ? uint64_to_double(Double::kSignMask) : 0.0;
56 }
57 
58 
59 // The fast double-to-unsigned-int conversion routine does not guarantee
60 // rounding towards zero, or any reasonable value if the argument is larger
61 // than what fits in an unsigned 32-bit integer.
62 inline unsigned int FastD2UI(double x) {
63  // There is no unsigned version of lrint, so there is no fast path
64  // in this function as there is in FastD2I. Using lrint doesn't work
65  // for values of 2^31 and above.
66 
67  // Convert "small enough" doubles to uint32_t by fixing the 32
68  // least significant non-fractional bits in the low 32 bits of the
69  // double, and reading them from there.
70  const double k2Pow52 = 4503599627370496.0;
71  bool negative = x < 0;
72  if (negative) {
73  x = -x;
74  }
75  if (x < k2Pow52) {
76  x += k2Pow52;
77  uint32_t result;
78  Address mantissa_ptr = reinterpret_cast<Address>(&x);
79  // Copy least significant 32 bits of mantissa.
80  OS::MemCopy(&result, mantissa_ptr, sizeof(result));
81  return negative ? ~result + 1 : result;
82  }
83  // Large number (outside uint32 range), Infinity or NaN.
84  return 0x80000000u; // Return integer indefinite.
85 }
86 
87 
88 inline double DoubleToInteger(double x) {
89  if (std::isnan(x)) return 0;
90  if (!std::isfinite(x) || x == 0) return x;
91  return (x >= 0) ? std::floor(x) : std::ceil(x);
92 }
93 
94 
96  int32_t i = FastD2I(x);
97  if (FastI2D(i) == x) return i;
98  Double d(x);
99  int exponent = d.Exponent();
100  if (exponent < 0) {
101  if (exponent <= -Double::kSignificandSize) return 0;
102  return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
103  } else {
104  if (exponent > 31) return 0;
105  return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
106  }
107 }
108 
109 
110 template <class Iterator, class EndMark>
111 bool SubStringEquals(Iterator* current,
112  EndMark end,
113  const char* substring) {
114  ASSERT(**current == *substring);
115  for (substring++; *substring != '\0'; substring++) {
116  ++*current;
117  if (*current == end || **current != *substring) return false;
118  }
119  ++*current;
120  return true;
121 }
122 
123 
124 // Returns true if a nonspace character has been found and false if the
125 // end was been reached before finding a nonspace character.
126 template <class Iterator, class EndMark>
127 inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
128  Iterator* current,
129  EndMark end) {
130  while (*current != end) {
131  if (!unicode_cache->IsWhiteSpaceOrLineTerminator(**current)) return true;
132  ++*current;
133  }
134  return false;
135 }
136 
137 
138 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
139 template <int radix_log_2, class Iterator, class EndMark>
141  Iterator current,
142  EndMark end,
143  bool negative,
144  bool allow_trailing_junk) {
145  ASSERT(current != end);
146 
147  // Skip leading 0s.
148  while (*current == '0') {
149  ++current;
150  if (current == end) return SignedZero(negative);
151  }
152 
153  int64_t number = 0;
154  int exponent = 0;
155  const int radix = (1 << radix_log_2);
156 
157  do {
158  int digit;
159  if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
160  digit = static_cast<char>(*current) - '0';
161  } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
162  digit = static_cast<char>(*current) - 'a' + 10;
163  } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
164  digit = static_cast<char>(*current) - 'A' + 10;
165  } else {
166  if (allow_trailing_junk ||
167  !AdvanceToNonspace(unicode_cache, &current, end)) {
168  break;
169  } else {
170  return JunkStringValue();
171  }
172  }
173 
174  number = number * radix + digit;
175  int overflow = static_cast<int>(number >> 53);
176  if (overflow != 0) {
177  // Overflow occurred. Need to determine which direction to round the
178  // result.
179  int overflow_bits_count = 1;
180  while (overflow > 1) {
181  overflow_bits_count++;
182  overflow >>= 1;
183  }
184 
185  int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
186  int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
187  number >>= overflow_bits_count;
188  exponent = overflow_bits_count;
189 
190  bool zero_tail = true;
191  while (true) {
192  ++current;
193  if (current == end || !isDigit(*current, radix)) break;
194  zero_tail = zero_tail && *current == '0';
195  exponent += radix_log_2;
196  }
197 
198  if (!allow_trailing_junk &&
199  AdvanceToNonspace(unicode_cache, &current, end)) {
200  return JunkStringValue();
201  }
202 
203  int middle_value = (1 << (overflow_bits_count - 1));
204  if (dropped_bits > middle_value) {
205  number++; // Rounding up.
206  } else if (dropped_bits == middle_value) {
207  // Rounding to even to consistency with decimals: half-way case rounds
208  // up if significant part is odd and down otherwise.
209  if ((number & 1) != 0 || !zero_tail) {
210  number++; // Rounding up.
211  }
212  }
213 
214  // Rounding up may cause overflow.
215  if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
216  exponent++;
217  number >>= 1;
218  }
219  break;
220  }
221  ++current;
222  } while (current != end);
223 
224  ASSERT(number < ((int64_t)1 << 53));
225  ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
226 
227  if (exponent == 0) {
228  if (negative) {
229  if (number == 0) return -0.0;
230  number = -number;
231  }
232  return static_cast<double>(number);
233  }
234 
235  ASSERT(number != 0);
236  return std::ldexp(static_cast<double>(negative ? -number : number), exponent);
237 }
238 
239 
240 template <class Iterator, class EndMark>
241 double InternalStringToInt(UnicodeCache* unicode_cache,
242  Iterator current,
243  EndMark end,
244  int radix) {
245  const bool allow_trailing_junk = true;
246  const double empty_string_val = JunkStringValue();
247 
248  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
249  return empty_string_val;
250  }
251 
252  bool negative = false;
253  bool leading_zero = false;
254 
255  if (*current == '+') {
256  // Ignore leading sign; skip following spaces.
257  ++current;
258  if (current == end) {
259  return JunkStringValue();
260  }
261  } else if (*current == '-') {
262  ++current;
263  if (current == end) {
264  return JunkStringValue();
265  }
266  negative = true;
267  }
268 
269  if (radix == 0) {
270  // Radix detection.
271  radix = 10;
272  if (*current == '0') {
273  ++current;
274  if (current == end) return SignedZero(negative);
275  if (*current == 'x' || *current == 'X') {
276  radix = 16;
277  ++current;
278  if (current == end) return JunkStringValue();
279  } else {
280  leading_zero = true;
281  }
282  }
283  } else if (radix == 16) {
284  if (*current == '0') {
285  // Allow "0x" prefix.
286  ++current;
287  if (current == end) return SignedZero(negative);
288  if (*current == 'x' || *current == 'X') {
289  ++current;
290  if (current == end) return JunkStringValue();
291  } else {
292  leading_zero = true;
293  }
294  }
295  }
296 
297  if (radix < 2 || radix > 36) return JunkStringValue();
298 
299  // Skip leading zeros.
300  while (*current == '0') {
301  leading_zero = true;
302  ++current;
303  if (current == end) return SignedZero(negative);
304  }
305 
306  if (!leading_zero && !isDigit(*current, radix)) {
307  return JunkStringValue();
308  }
309 
310  if (IsPowerOf2(radix)) {
311  switch (radix) {
312  case 2:
313  return InternalStringToIntDouble<1>(
314  unicode_cache, current, end, negative, allow_trailing_junk);
315  case 4:
316  return InternalStringToIntDouble<2>(
317  unicode_cache, current, end, negative, allow_trailing_junk);
318  case 8:
319  return InternalStringToIntDouble<3>(
320  unicode_cache, current, end, negative, allow_trailing_junk);
321 
322  case 16:
323  return InternalStringToIntDouble<4>(
324  unicode_cache, current, end, negative, allow_trailing_junk);
325 
326  case 32:
327  return InternalStringToIntDouble<5>(
328  unicode_cache, current, end, negative, allow_trailing_junk);
329  default:
330  UNREACHABLE();
331  }
332  }
333 
334  if (radix == 10) {
335  // Parsing with strtod.
336  const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308.
337  // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
338  // end.
339  const int kBufferSize = kMaxSignificantDigits + 2;
340  char buffer[kBufferSize];
341  int buffer_pos = 0;
342  while (*current >= '0' && *current <= '9') {
343  if (buffer_pos <= kMaxSignificantDigits) {
344  // If the number has more than kMaxSignificantDigits it will be parsed
345  // as infinity.
346  ASSERT(buffer_pos < kBufferSize);
347  buffer[buffer_pos++] = static_cast<char>(*current);
348  }
349  ++current;
350  if (current == end) break;
351  }
352 
353  if (!allow_trailing_junk &&
354  AdvanceToNonspace(unicode_cache, &current, end)) {
355  return JunkStringValue();
356  }
357 
358  SLOW_ASSERT(buffer_pos < kBufferSize);
359  buffer[buffer_pos] = '\0';
360  Vector<const char> buffer_vector(buffer, buffer_pos);
361  return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
362  }
363 
364  // The following code causes accumulating rounding error for numbers greater
365  // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
366  // 16, or 32, then mathInt may be an implementation-dependent approximation to
367  // the mathematical integer value" (15.1.2.2).
368 
369  int lim_0 = '0' + (radix < 10 ? radix : 10);
370  int lim_a = 'a' + (radix - 10);
371  int lim_A = 'A' + (radix - 10);
372 
373  // NOTE: The code for computing the value may seem a bit complex at
374  // first glance. It is structured to use 32-bit multiply-and-add
375  // loops as long as possible to avoid loosing precision.
376 
377  double v = 0.0;
378  bool done = false;
379  do {
380  // Parse the longest part of the string starting at index j
381  // possible while keeping the multiplier, and thus the part
382  // itself, within 32 bits.
383  unsigned int part = 0, multiplier = 1;
384  while (true) {
385  int d;
386  if (*current >= '0' && *current < lim_0) {
387  d = *current - '0';
388  } else if (*current >= 'a' && *current < lim_a) {
389  d = *current - 'a' + 10;
390  } else if (*current >= 'A' && *current < lim_A) {
391  d = *current - 'A' + 10;
392  } else {
393  done = true;
394  break;
395  }
396 
397  // Update the value of the part as long as the multiplier fits
398  // in 32 bits. When we can't guarantee that the next iteration
399  // will not overflow the multiplier, we stop parsing the part
400  // by leaving the loop.
401  const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
402  uint32_t m = multiplier * radix;
403  if (m > kMaximumMultiplier) break;
404  part = part * radix + d;
405  multiplier = m;
406  ASSERT(multiplier > part);
407 
408  ++current;
409  if (current == end) {
410  done = true;
411  break;
412  }
413  }
414 
415  // Update the value and skip the part in the string.
416  v = v * multiplier + part;
417  } while (!done);
418 
419  if (!allow_trailing_junk &&
420  AdvanceToNonspace(unicode_cache, &current, end)) {
421  return JunkStringValue();
422  }
423 
424  return negative ? -v : v;
425 }
426 
427 
428 // Converts a string to a double value. Assumes the Iterator supports
429 // the following operations:
430 // 1. current == end (other ops are not allowed), current != end.
431 // 2. *current - gets the current character in the sequence.
432 // 3. ++current (advances the position).
433 template <class Iterator, class EndMark>
434 double InternalStringToDouble(UnicodeCache* unicode_cache,
435  Iterator current,
436  EndMark end,
437  int flags,
438  double empty_string_val) {
439  // To make sure that iterator dereferencing is valid the following
440  // convention is used:
441  // 1. Each '++current' statement is followed by check for equality to 'end'.
442  // 2. If AdvanceToNonspace returned false then current == end.
443  // 3. If 'current' becomes be equal to 'end' the function returns or goes to
444  // 'parsing_done'.
445  // 4. 'current' is not dereferenced after the 'parsing_done' label.
446  // 5. Code before 'parsing_done' may rely on 'current != end'.
447  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
448  return empty_string_val;
449  }
450 
451  const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
452 
453  // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
454  const int kBufferSize = kMaxSignificantDigits + 10;
455  char buffer[kBufferSize]; // NOLINT: size is known at compile time.
456  int buffer_pos = 0;
457 
458  // Exponent will be adjusted if insignificant digits of the integer part
459  // or insignificant leading zeros of the fractional part are dropped.
460  int exponent = 0;
461  int significant_digits = 0;
462  int insignificant_digits = 0;
463  bool nonzero_digit_dropped = false;
464 
465  enum Sign {
466  NONE,
467  NEGATIVE,
468  POSITIVE
469  };
470 
471  Sign sign = NONE;
472 
473  if (*current == '+') {
474  // Ignore leading sign.
475  ++current;
476  if (current == end) return JunkStringValue();
477  sign = POSITIVE;
478  } else if (*current == '-') {
479  ++current;
480  if (current == end) return JunkStringValue();
481  sign = NEGATIVE;
482  }
483 
484  static const char kInfinityString[] = "Infinity";
485  if (*current == kInfinityString[0]) {
486  if (!SubStringEquals(&current, end, kInfinityString)) {
487  return JunkStringValue();
488  }
489 
490  if (!allow_trailing_junk &&
491  AdvanceToNonspace(unicode_cache, &current, end)) {
492  return JunkStringValue();
493  }
494 
495  ASSERT(buffer_pos == 0);
496  return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
497  }
498 
499  bool leading_zero = false;
500  if (*current == '0') {
501  ++current;
502  if (current == end) return SignedZero(sign == NEGATIVE);
503 
504  leading_zero = true;
505 
506  // It could be hexadecimal value.
507  if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
508  ++current;
509  if (current == end || !isDigit(*current, 16) || sign != NONE) {
510  return JunkStringValue(); // "0x".
511  }
512 
513  return InternalStringToIntDouble<4>(unicode_cache,
514  current,
515  end,
516  false,
517  allow_trailing_junk);
518 
519  // It could be an explicit octal value.
520  } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
521  ++current;
522  if (current == end || !isDigit(*current, 8) || sign != NONE) {
523  return JunkStringValue(); // "0o".
524  }
525 
526  return InternalStringToIntDouble<3>(unicode_cache,
527  current,
528  end,
529  false,
530  allow_trailing_junk);
531 
532  // It could be a binary value.
533  } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
534  ++current;
535  if (current == end || !isBinaryDigit(*current) || sign != NONE) {
536  return JunkStringValue(); // "0b".
537  }
538 
539  return InternalStringToIntDouble<1>(unicode_cache,
540  current,
541  end,
542  false,
543  allow_trailing_junk);
544  }
545 
546  // Ignore leading zeros in the integer part.
547  while (*current == '0') {
548  ++current;
549  if (current == end) return SignedZero(sign == NEGATIVE);
550  }
551  }
552 
553  bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
554 
555  // Copy significant digits of the integer part (if any) to the buffer.
556  while (*current >= '0' && *current <= '9') {
557  if (significant_digits < kMaxSignificantDigits) {
558  ASSERT(buffer_pos < kBufferSize);
559  buffer[buffer_pos++] = static_cast<char>(*current);
560  significant_digits++;
561  // Will later check if it's an octal in the buffer.
562  } else {
563  insignificant_digits++; // Move the digit into the exponential part.
564  nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
565  }
566  octal = octal && *current < '8';
567  ++current;
568  if (current == end) goto parsing_done;
569  }
570 
571  if (significant_digits == 0) {
572  octal = false;
573  }
574 
575  if (*current == '.') {
576  if (octal && !allow_trailing_junk) return JunkStringValue();
577  if (octal) goto parsing_done;
578 
579  ++current;
580  if (current == end) {
581  if (significant_digits == 0 && !leading_zero) {
582  return JunkStringValue();
583  } else {
584  goto parsing_done;
585  }
586  }
587 
588  if (significant_digits == 0) {
589  // octal = false;
590  // Integer part consists of 0 or is absent. Significant digits start after
591  // leading zeros (if any).
592  while (*current == '0') {
593  ++current;
594  if (current == end) return SignedZero(sign == NEGATIVE);
595  exponent--; // Move this 0 into the exponent.
596  }
597  }
598 
599  // There is a fractional part. We don't emit a '.', but adjust the exponent
600  // instead.
601  while (*current >= '0' && *current <= '9') {
602  if (significant_digits < kMaxSignificantDigits) {
603  ASSERT(buffer_pos < kBufferSize);
604  buffer[buffer_pos++] = static_cast<char>(*current);
605  significant_digits++;
606  exponent--;
607  } else {
608  // Ignore insignificant digits in the fractional part.
609  nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
610  }
611  ++current;
612  if (current == end) goto parsing_done;
613  }
614  }
615 
616  if (!leading_zero && exponent == 0 && significant_digits == 0) {
617  // If leading_zeros is true then the string contains zeros.
618  // If exponent < 0 then string was [+-]\.0*...
619  // If significant_digits != 0 the string is not equal to 0.
620  // Otherwise there are no digits in the string.
621  return JunkStringValue();
622  }
623 
624  // Parse exponential part.
625  if (*current == 'e' || *current == 'E') {
626  if (octal) return JunkStringValue();
627  ++current;
628  if (current == end) {
629  if (allow_trailing_junk) {
630  goto parsing_done;
631  } else {
632  return JunkStringValue();
633  }
634  }
635  char sign = '+';
636  if (*current == '+' || *current == '-') {
637  sign = static_cast<char>(*current);
638  ++current;
639  if (current == end) {
640  if (allow_trailing_junk) {
641  goto parsing_done;
642  } else {
643  return JunkStringValue();
644  }
645  }
646  }
647 
648  if (current == end || *current < '0' || *current > '9') {
649  if (allow_trailing_junk) {
650  goto parsing_done;
651  } else {
652  return JunkStringValue();
653  }
654  }
655 
656  const int max_exponent = INT_MAX / 2;
657  ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
658  int num = 0;
659  do {
660  // Check overflow.
661  int digit = *current - '0';
662  if (num >= max_exponent / 10
663  && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
664  num = max_exponent;
665  } else {
666  num = num * 10 + digit;
667  }
668  ++current;
669  } while (current != end && *current >= '0' && *current <= '9');
670 
671  exponent += (sign == '-' ? -num : num);
672  }
673 
674  if (!allow_trailing_junk &&
675  AdvanceToNonspace(unicode_cache, &current, end)) {
676  return JunkStringValue();
677  }
678 
679  parsing_done:
680  exponent += insignificant_digits;
681 
682  if (octal) {
683  return InternalStringToIntDouble<3>(unicode_cache,
684  buffer,
685  buffer + buffer_pos,
686  sign == NEGATIVE,
687  allow_trailing_junk);
688  }
689 
690  if (nonzero_digit_dropped) {
691  buffer[buffer_pos++] = '1';
692  exponent--;
693  }
694 
695  SLOW_ASSERT(buffer_pos < kBufferSize);
696  buffer[buffer_pos] = '\0';
697 
698  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
699  return (sign == NEGATIVE) ? -converted : converted;
700 }
701 
702 } } // namespace v8::internal
703 
704 #endif // V8_CONVERSIONS_INL_H_
byte * Address
Definition: globals.h:186
#define SLOW_ASSERT(condition)
Definition: checks.h:306
uint64_t Significand() const
Definition: double.h:110
double InternalStringToDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, int flags, double empty_string_val)
double DoubleToInteger(double x)
bool SubStringEquals(Iterator *current, EndMark end, const char *substring)
const uint64_t kQuietNaNMask
Definition: globals.h:304
int int32_t
Definition: unicode.cc:47
int Exponent() const
Definition: double.h:101
bool isBinaryDigit(int x)
Definition: conversions.h:55
bool isDigit(int x, int radix)
Definition: conversions.h:48
double InternalStringToInt(UnicodeCache *unicode_cache, Iterator current, EndMark end, int radix)
#define ASSERT(condition)
Definition: checks.h:329
static const int kSignificandSize
Definition: double.h:49
int isfinite(double x)
#define V8_INFINITY
Definition: globals.h:44
double Strtod(Vector< const char > buffer, int exponent)
Definition: strtod.cc:417
int isnan(double x)
double SignedZero(bool negative)
#define UNREACHABLE()
Definition: checks.h:52
static const uint64_t kSignMask
Definition: double.h:43
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot testing_bool_flag testing_int_flag string flag tmp file in which to serialize heap Print the time it takes to lazily compile hydrogen code stubs concurrent_recompilation concurrent_sweeping Print usage including flags
Definition: flags.cc:665
static void MemCopy(void *dest, const void *src, size_t size)
Definition: platform.h:399
unsigned int FastD2UI(double x)
double uint64_to_double(uint64_t d64)
Definition: double.h:38
double JunkStringValue()
double InternalStringToIntDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, bool negative, bool allow_trailing_junk)
bool IsPowerOf2(T x)
Definition: utils.h:51
bool AdvanceToNonspace(UnicodeCache *unicode_cache, Iterator *current, EndMark end)
const int kMaxSignificantDigits
Definition: conversions.h:45
int32_t DoubleToInt32(double x)
bool IsWhiteSpaceOrLineTerminator(unibrow::uchar c)
Definition: scanner.h:145
double FastI2D(int x)
Definition: conversions.h:81
int FastD2I(double x)
Definition: conversions.h:74
int Sign() const
Definition: double.h:139