OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 Handle<String> ParseJsonString() { | 102 Handle<String> ParseJsonString() { |
103 return ScanJsonString<false>(); | 103 return ScanJsonString<false>(); |
104 } | 104 } |
105 Handle<String> ParseJsonSymbol() { | 105 Handle<String> ParseJsonSymbol() { |
106 return ScanJsonString<true>(); | 106 return ScanJsonString<true>(); |
107 } | 107 } |
108 template <bool is_symbol> | 108 template <bool is_symbol> |
109 Handle<String> ScanJsonString(); | 109 Handle<String> ScanJsonString(); |
110 // Slow version for unicode support, uses the first ascii_count characters, | 110 // Slow version for unicode support, uses the first ascii_count characters, |
111 // as first part of a ConsString | 111 // as first part of a ConsString |
112 Handle<String> SlowScanJsonString(); | 112 Handle<String> SlowScanJsonString(int beg_pos); |
113 | 113 |
114 // A JSON number (production JSONNumber) is a subset of the valid JavaScript | 114 // A JSON number (production JSONNumber) is a subset of the valid JavaScript |
115 // decimal number literals. | 115 // decimal number literals. |
116 // It includes an optional minus sign, must have at least one | 116 // It includes an optional minus sign, must have at least one |
117 // digit before and after a decimal point, may not have prefixed zeros (unless | 117 // digit before and after a decimal point, may not have prefixed zeros (unless |
118 // the integer part is zero), and may include an exponent part (e.g., "e-10"). | 118 // the integer part is zero), and may include an exponent part (e.g., "e-10"). |
119 // Hexadecimal and octal numbers are not allowed. | 119 // Hexadecimal and octal numbers are not allowed. |
120 Handle<Object> ParseJsonNumber(); | 120 Handle<Object> ParseJsonNumber(); |
121 | 121 |
122 // Parse a single JSON value from input (grammar production JSONValue). | 122 // Parse a single JSON value from input (grammar production JSONValue). |
(...skipping 26 matching lines...) Expand all Loading... | |
149 inline Isolate* isolate() { return isolate_; } | 149 inline Isolate* isolate() { return isolate_; } |
150 | 150 |
151 static const int kInitialSpecialStringSize = 1024; | 151 static const int kInitialSpecialStringSize = 1024; |
152 | 152 |
153 | 153 |
154 private: | 154 private: |
155 Handle<String> source_; | 155 Handle<String> source_; |
156 int source_length_; | 156 int source_length_; |
157 Handle<SeqAsciiString> seq_source_; | 157 Handle<SeqAsciiString> seq_source_; |
158 | 158 |
159 // begin and end position of scanned string or number | |
160 int beg_pos_; | |
161 int end_pos_; | |
162 | |
163 Isolate* isolate_; | 159 Isolate* isolate_; |
164 uc32 c0_; | 160 uc32 c0_; |
165 int position_; | 161 int position_; |
166 | |
167 double number_; | |
168 }; | 162 }; |
169 | 163 |
170 template <bool seq_ascii> | 164 template <bool seq_ascii> |
171 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) { | 165 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) { |
172 isolate_ = source->map()->isolate(); | 166 isolate_ = source->map()->isolate(); |
173 source_ = Handle<String>(source->TryFlattenGetString()); | 167 source_ = Handle<String>(source->TryFlattenGetString()); |
174 source_length_ = source_->length() - 1; | 168 source_length_ = source_->length() - 1; |
175 | 169 |
176 // Optimized fast case where we only have ascii characters. | 170 // Optimized fast case where we only have ascii characters. |
177 if (seq_ascii) { | 171 if (seq_ascii) { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 for (int i = 0, n = elements.length(); i < n; i++) { | 340 for (int i = 0, n = elements.length(); i < n; i++) { |
347 fast_elements->set(i, *elements[i]); | 341 fast_elements->set(i, *elements[i]); |
348 } | 342 } |
349 return isolate()->factory()->NewJSArrayWithElements(fast_elements); | 343 return isolate()->factory()->NewJSArrayWithElements(fast_elements); |
350 } | 344 } |
351 | 345 |
352 | 346 |
353 template <bool seq_ascii> | 347 template <bool seq_ascii> |
354 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { | 348 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { |
355 bool negative = false; | 349 bool negative = false; |
356 beg_pos_ = position_; | 350 int beg_pos = position_; |
357 if (c0_ == '-') { | 351 if (c0_ == '-') { |
358 Advance(); | 352 Advance(); |
359 negative = true; | 353 negative = true; |
360 } | 354 } |
361 if (c0_ == '0') { | 355 if (c0_ == '0') { |
362 Advance(); | 356 Advance(); |
363 // Prefix zero is only allowed if it's the only digit before | 357 // Prefix zero is only allowed if it's the only digit before |
364 // a decimal point or exponent. | 358 // a decimal point or exponent. |
365 if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter(); | 359 if ('0' <= c0_ && c0_ <= '9') return ReportUnexpectedCharacter(); |
366 } else { | 360 } else { |
367 int i = 0; | 361 int i = 0; |
368 int digits = 0; | 362 int digits = 0; |
369 if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter(); | 363 if (c0_ < '1' || c0_ > '9') return ReportUnexpectedCharacter(); |
370 do { | 364 do { |
371 i = i * 10 + c0_ - '0'; | 365 i = i * 10 + c0_ - '0'; |
372 digits++; | 366 digits++; |
373 Advance(); | 367 Advance(); |
374 } while (c0_ >= '0' && c0_ <= '9'); | 368 } while (c0_ >= '0' && c0_ <= '9'); |
375 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { | 369 if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) { |
376 number_ = (negative ? -i : i); | |
377 SkipWhitespace(); | 370 SkipWhitespace(); |
378 return isolate()->factory()->NewNumber(number_); | 371 return Handle<Smi>(Smi::FromInt((negative ? -i : i))); |
Vitaly Repeshko
2011/06/22 12:45:41
Contains an implicit TLS load. Pass isolate as the
sandholm
2011/06/22 14:05:41
Done.
Thanks for catching that one.
| |
379 } | 372 } |
380 } | 373 } |
381 if (c0_ == '.') { | 374 if (c0_ == '.') { |
382 Advance(); | 375 Advance(); |
383 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); | 376 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); |
384 do { | 377 do { |
385 Advance(); | 378 Advance(); |
386 } while (c0_ >= '0' && c0_ <= '9'); | 379 } while (c0_ >= '0' && c0_ <= '9'); |
387 } | 380 } |
388 if (AsciiAlphaToLower(c0_) == 'e') { | 381 if (c0_ == 'e' || c0_ == 'E') { |
Lasse Reichstein
2011/06/22 13:05:45
Why do you think this is faster?
The AsciiAlphaToL
sandholm
2011/06/22 14:05:41
You are right. I reverted this one.
| |
389 Advance(); | 382 Advance(); |
390 if (c0_ == '-' || c0_ == '+') Advance(); | 383 if (c0_ == '-' || c0_ == '+') Advance(); |
391 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); | 384 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); |
392 do { | 385 do { |
393 Advance(); | 386 Advance(); |
394 } while (c0_ >= '0' && c0_ <= '9'); | 387 } while (c0_ >= '0' && c0_ <= '9'); |
395 } | 388 } |
396 int length = position_ - beg_pos_; | 389 int length = position_ - beg_pos; |
390 double number; | |
397 if (seq_ascii) { | 391 if (seq_ascii) { |
398 Vector<const char> chars(seq_source_->GetChars() + beg_pos_, length); | 392 Vector<const char> chars(seq_source_->GetChars() + beg_pos, length); |
399 number_ = StringToDouble(isolate()->unicode_cache(), | 393 number = StringToDouble(isolate()->unicode_cache(), |
400 chars, | 394 chars, |
401 NO_FLAGS, // Hex, octal or trailing junk. | 395 NO_FLAGS, // Hex, octal or trailing junk. |
402 OS::nan_value()); | 396 OS::nan_value()); |
403 } else { | 397 } else { |
404 Vector<char> buffer = Vector<char>::New(length); | 398 Vector<char> buffer = Vector<char>::New(length); |
405 String::WriteToFlat(*source_, buffer.start(), beg_pos_, position_); | 399 String::WriteToFlat(*source_, buffer.start(), beg_pos, position_); |
406 Vector<const char> result = | 400 Vector<const char> result = |
407 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), | 401 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), |
408 length); | 402 length); |
409 number_ = StringToDouble(isolate()->unicode_cache(), | 403 number = StringToDouble(isolate()->unicode_cache(), |
410 result, | 404 result, |
411 NO_FLAGS, // Hex, octal or trailing junk. | 405 NO_FLAGS, // Hex, octal or trailing junk. |
412 0.0); | 406 0.0); |
413 buffer.Dispose(); | 407 buffer.Dispose(); |
414 } | 408 } |
415 SkipWhitespace(); | 409 SkipWhitespace(); |
416 return isolate()->factory()->NewNumber(number_); | 410 return isolate()->factory()->NewNumber(number); |
417 } | 411 } |
418 | 412 |
419 template <bool seq_ascii> | 413 template <bool seq_ascii> |
420 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString() { | 414 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString(int beg_pos) { |
421 // The currently scanned ascii characters. | 415 // The currently scanned ascii characters. |
422 Handle<String> ascii(isolate()->factory()->NewSubString(source_, | 416 Handle<String> ascii(isolate()->factory()->NewStrictSubString(source_, |
423 beg_pos_, | 417 beg_pos, |
424 position_)); | 418 position_)); |
425 Handle<String> two_byte = | 419 Handle<String> two_byte = |
426 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize, | 420 isolate()->factory()->NewRawTwoByteString(kInitialSpecialStringSize, |
427 NOT_TENURED); | 421 NOT_TENURED); |
428 Handle<SeqTwoByteString> seq_two_byte = | 422 Handle<SeqTwoByteString> seq_two_byte = |
429 Handle<SeqTwoByteString>::cast(two_byte); | 423 Handle<SeqTwoByteString>::cast(two_byte); |
430 | 424 |
431 int allocation_count = 1; | 425 int allocation_count = 1; |
432 int count = 0; | 426 int count = 0; |
433 | 427 |
434 while (c0_ != '"') { | 428 while (c0_ != '"') { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
511 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); | 505 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); |
512 } | 506 } |
513 return isolate()->factory()->NewConsString(ascii, seq_two_byte); | 507 return isolate()->factory()->NewConsString(ascii, seq_two_byte); |
514 } | 508 } |
515 | 509 |
516 template <bool seq_ascii> | 510 template <bool seq_ascii> |
517 template <bool is_symbol> | 511 template <bool is_symbol> |
518 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { | 512 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { |
519 ASSERT_EQ('"', c0_); | 513 ASSERT_EQ('"', c0_); |
520 Advance(); | 514 Advance(); |
521 beg_pos_ = position_; | 515 int beg_pos = position_; |
522 // Fast case for ascii only without escape characters. | 516 // Fast case for ascii only without escape characters. |
523 while (c0_ != '"') { | 517 while (c0_ != '"') { |
524 // Check for control character (0x00-0x1f) or unterminated string (<0). | 518 // Check for control character (0x00-0x1f) or unterminated string (<0). |
525 if (c0_ < 0x20) return Handle<String>::null(); | 519 if (c0_ < 0x20) return Handle<String>::null(); |
526 if (c0_ != '\\' && (seq_ascii || c0_ < kMaxAsciiCharCode)) { | 520 if (c0_ != '\\' && (seq_ascii || c0_ < kMaxAsciiCharCode)) { |
527 Advance(); | 521 Advance(); |
528 } else { | 522 } else { |
529 return this->SlowScanJsonString(); | 523 return this->SlowScanJsonString(beg_pos); |
530 } | 524 } |
531 } | 525 } |
532 ASSERT_EQ('"', c0_); | 526 ASSERT_EQ('"', c0_); |
533 end_pos_ = position_; | 527 int end_pos = position_; |
534 // Advance past the last '"'. | 528 // Advance past the last '"'. |
535 AdvanceSkipWhitespace(); | 529 AdvanceSkipWhitespace(); |
536 if (seq_ascii && is_symbol) { | 530 if (seq_ascii && is_symbol) { |
537 return isolate()->factory()->LookupAsciiSymbol(seq_source_, | 531 return isolate()->factory()->LookupAsciiSymbol(seq_source_, |
538 beg_pos_, | 532 beg_pos, |
539 end_pos_ - beg_pos_); | 533 end_pos - beg_pos); |
540 } else { | 534 } else { |
541 return isolate()->factory()->NewSubString(source_, beg_pos_, end_pos_); | 535 return isolate()->factory()->NewStrictSubString(source_, |
536 beg_pos, | |
537 end_pos); | |
542 } | 538 } |
543 } | 539 } |
544 | 540 |
545 } } // namespace v8::internal | 541 } } // namespace v8::internal |
546 | 542 |
547 #endif // V8_JSON_PARSER_H_ | 543 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |