Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: src/json-parser.h

Issue 7230006: Inctroduce NewStrictSubstring to avoid check for SubString(str, 0, str.length... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/json.js ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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)), isolate());
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 (AsciiAlphaToLower(c0_) == 'e') {
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
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_
OLDNEW
« no previous file with comments | « src/json.js ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698