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

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

Issue 7977001: Added ability to lock strings to prevent their representation or encoding from changing. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix bug in test when running threaded. Created 9 years, 2 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/heap.cc ('k') | src/objects.h » ('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 21 matching lines...) Expand all
32 32
33 #include "char-predicates-inl.h" 33 #include "char-predicates-inl.h"
34 #include "v8conversions.h" 34 #include "v8conversions.h"
35 #include "messages.h" 35 #include "messages.h"
36 #include "spaces-inl.h" 36 #include "spaces-inl.h"
37 #include "token.h" 37 #include "token.h"
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 // A simple json parser. 42 // A simple JSON parser.
43 template <bool seq_ascii> 43 template <typename StringType>
44 class JsonParser BASE_EMBEDDED { 44 class JsonParser BASE_EMBEDDED {
45 public: 45 public:
46 static Handle<Object> Parse(Handle<String> source) { 46 static Handle<Object> Parse(Handle<String> source) {
47 return JsonParser().ParseJson(source); 47 return JsonParser(Handle<StringType>::cast(source)).ParseJson();
48 } 48 }
49 49
50 static const int kEndOfString = -1; 50 static const int kEndOfString = -1;
51 51
52 private: 52 private:
53 // Parse a string containing a single JSON value. 53 typedef typename StringType::CharType SourceChar;
54 Handle<Object> ParseJson(Handle<String> source); 54
55 explicit JsonParser(Handle<StringType> source)
56 : isolate_(source->GetHeap()->isolate()),
57 source_(source),
58 characters_(NULL),
59 source_length_(source->length()),
60 position_(-1) {
61 InitializeSource();
62 }
63
64
65 // Parse the source string as containing a single JSON value.
66 Handle<Object> ParseJson();
67
68 // Set up the object so GetChar works, in case it needs more than just
69 // the constructor.
70 void InitializeSource();
71
72 inline uc32 GetChar(int position);
73 inline const SourceChar* GetChars();
55 74
56 inline void Advance() { 75 inline void Advance() {
57 position_++; 76 position_++;
58 if (position_ >= source_length_) { 77 if (position_ >= source_length_) {
59 c0_ = kEndOfString; 78 c0_ = kEndOfString;
60 } else if (seq_ascii) {
61 c0_ = seq_source_->SeqAsciiStringGet(position_);
62 } else { 79 } else {
63 c0_ = source_->Get(position_); 80 c0_ = GetChar(position_);
64 } 81 }
65 } 82 }
66 83
67 // The JSON lexical grammar is specified in the ECMAScript 5 standard, 84 // The JSON lexical grammar is specified in the ECMAScript 5 standard,
68 // section 15.12.1.1. The only allowed whitespace characters between tokens 85 // section 15.12.1.1. The only allowed whitespace characters between tokens
69 // are tab, carriage-return, newline and space. 86 // are tab, carriage-return, newline and space.
70 87
88
89 static inline bool IsJsonWhitespace(uc32 ch) {
90 const char* whitespaces = "\x20\x09\x0a\0\0\x0d\0\0";
91 return (static_cast<uc32>(whitespaces[ch & 0x07]) == ch);
92 }
93
71 inline void AdvanceSkipWhitespace() { 94 inline void AdvanceSkipWhitespace() {
72 do { 95 do {
73 Advance(); 96 Advance();
74 } while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' '); 97 } while (IsJsonWhitespace(c0_));
75 } 98 }
76 99
77 inline void SkipWhitespace() { 100 inline void SkipWhitespace() {
78 while (c0_ == '\t' || c0_ == '\r' || c0_ == '\n' || c0_ == ' ') { 101 while (IsJsonWhitespace(c0_)) {
79 Advance(); 102 Advance();
80 } 103 }
81 } 104 }
82 105
83 inline uc32 AdvanceGetChar() { 106 inline uc32 AdvanceGetChar() {
84 Advance(); 107 Advance();
85 return c0_; 108 return c0_;
86 } 109 }
87 110
88 // Checks that current charater is c. 111 // Checks that current charater is c.
(...skipping 14 matching lines...) Expand all
103 return ScanJsonString<false>(); 126 return ScanJsonString<false>();
104 } 127 }
105 Handle<String> ParseJsonSymbol() { 128 Handle<String> ParseJsonSymbol() {
106 return ScanJsonString<true>(); 129 return ScanJsonString<true>();
107 } 130 }
108 template <bool is_symbol> 131 template <bool is_symbol>
109 Handle<String> ScanJsonString(); 132 Handle<String> ScanJsonString();
110 // Creates a new string and copies prefix[start..end] into the beginning 133 // Creates a new string and copies prefix[start..end] into the beginning
111 // of it. Then scans the rest of the string, adding characters after the 134 // of it. Then scans the rest of the string, adding characters after the
112 // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char. 135 // prefix. Called by ScanJsonString when reaching a '\' or non-ASCII char.
113 template <typename StringType, typename SinkChar> 136 template <typename SinkStringType>
114 Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end); 137 Handle<String> SlowScanJsonString(Handle<String> prefix, int start, int end);
115 138
116 // A JSON number (production JSONNumber) is a subset of the valid JavaScript 139 // A JSON number (production JSONNumber) is a subset of the valid JavaScript
117 // decimal number literals. 140 // decimal number literals.
118 // It includes an optional minus sign, must have at least one 141 // It includes an optional minus sign, must have at least one
119 // digit before and after a decimal point, may not have prefixed zeros (unless 142 // digit before and after a decimal point, may not have prefixed zeros (unless
120 // the integer part is zero), and may include an exponent part (e.g., "e-10"). 143 // the integer part is zero), and may include an exponent part (e.g., "e-10").
121 // Hexadecimal and octal numbers are not allowed. 144 // Hexadecimal and octal numbers are not allowed.
122 Handle<Object> ParseJsonNumber(); 145 Handle<Object> ParseJsonNumber();
123 146
(...skipping 21 matching lines...) Expand all
145 // Mark that a parsing error has happened at the current token, and 168 // Mark that a parsing error has happened at the current token, and
146 // return a null handle. Primarily for readability. 169 // return a null handle. Primarily for readability.
147 inline Handle<Object> ReportUnexpectedCharacter() { 170 inline Handle<Object> ReportUnexpectedCharacter() {
148 return Handle<Object>::null(); 171 return Handle<Object>::null();
149 } 172 }
150 173
151 inline Isolate* isolate() { return isolate_; } 174 inline Isolate* isolate() { return isolate_; }
152 175
153 static const int kInitialSpecialStringLength = 1024; 176 static const int kInitialSpecialStringLength = 1024;
154 177
155 178 Isolate* isolate_;
156 private: 179 Handle<StringType> source_;
157 Handle<String> source_; 180 // Used for external strings, to avoid going through the resource on
181 // every access.
182 const SourceChar* characters_;
158 int source_length_; 183 int source_length_;
159 Handle<SeqAsciiString> seq_source_; 184 int position_;
160
161 Isolate* isolate_;
162 uc32 c0_; 185 uc32 c0_;
163 int position_;
164 }; 186 };
165 187
166 template <bool seq_ascii> 188 template <typename StringType>
167 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source) { 189 Handle<Object> JsonParser<StringType>::ParseJson() {
168 isolate_ = source->map()->GetHeap()->isolate(); 190 // Initial position is right before the string.
169 FlattenString(source); 191 ASSERT(position_ == -1);
170 source_ = source;
171 source_length_ = source_->length();
172
173 // Optimized fast case where we only have ASCII characters.
174 if (seq_ascii) {
175 seq_source_ = Handle<SeqAsciiString>::cast(source_);
176 }
177
178 // Set initial position right before the string.
179 position_ = -1;
180 // Advance to the first character (posibly EOS) 192 // Advance to the first character (posibly EOS)
181 AdvanceSkipWhitespace(); 193 AdvanceSkipWhitespace();
194 // ParseJsonValue also consumes following whitespace.
182 Handle<Object> result = ParseJsonValue(); 195 Handle<Object> result = ParseJsonValue();
183 if (result.is_null() || c0_ != kEndOfString) { 196 if (result.is_null() || c0_ != kEndOfString) {
184 // Parse failed. Current character is the unexpected token. 197 // Parse failed. Current character is the unexpected token.
185
186 const char* message; 198 const char* message;
187 Factory* factory = isolate()->factory(); 199 Factory* factory = isolate()->factory();
188 Handle<JSArray> array; 200 Handle<JSArray> array;
189 201
190 switch (c0_) { 202 switch (c0_) {
191 case kEndOfString: 203 case kEndOfString:
192 message = "unexpected_eos"; 204 message = "unexpected_eos";
193 array = factory->NewJSArray(0); 205 array = factory->NewJSArray(0);
194 break; 206 break;
195 case '-': 207 case '-':
(...skipping 16 matching lines...) Expand all
212 break; 224 break;
213 default: 225 default:
214 message = "unexpected_token"; 226 message = "unexpected_token";
215 Handle<Object> name = LookupSingleCharacterStringFromCode(c0_); 227 Handle<Object> name = LookupSingleCharacterStringFromCode(c0_);
216 Handle<FixedArray> element = factory->NewFixedArray(1); 228 Handle<FixedArray> element = factory->NewFixedArray(1);
217 element->set(0, *name); 229 element->set(0, *name);
218 array = factory->NewJSArrayWithElements(element); 230 array = factory->NewJSArrayWithElements(element);
219 break; 231 break;
220 } 232 }
221 233
222 MessageLocation location(factory->NewScript(source), 234 MessageLocation location(factory->NewScript(source_),
223 position_, 235 position_,
224 position_ + 1); 236 position_ + 1);
225 Handle<Object> result = factory->NewSyntaxError(message, array); 237 Handle<Object> result = factory->NewSyntaxError(message, array);
226 isolate()->Throw(*result, &location); 238 isolate()->Throw(*result, &location);
227 return Handle<Object>::null(); 239 return Handle<Object>::null();
228 } 240 }
229 return result; 241 return result;
230 } 242 }
231 243
232 244
233 // Parse any JSON value. 245 // Parse any JSON value.
234 template <bool seq_ascii> 246 template <typename StringType>
235 Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() { 247 Handle<Object> JsonParser<StringType>::ParseJsonValue() {
236 switch (c0_) { 248 switch (c0_) {
237 case '"': 249 case '"':
238 return ParseJsonString(); 250 return ParseJsonString();
239 case '-': 251 case '-':
240 case '0': 252 case '0':
241 case '1': 253 case '1':
242 case '2': 254 case '2':
243 case '3': 255 case '3':
244 case '4': 256 case '4':
245 case '5': 257 case '5':
(...skipping 30 matching lines...) Expand all
276 return ParseJsonObject(); 288 return ParseJsonObject();
277 case '[': 289 case '[':
278 return ParseJsonArray(); 290 return ParseJsonArray();
279 default: 291 default:
280 return ReportUnexpectedCharacter(); 292 return ReportUnexpectedCharacter();
281 } 293 }
282 } 294 }
283 295
284 296
285 // Parse a JSON object. Position must be right at '{'. 297 // Parse a JSON object. Position must be right at '{'.
286 template <bool seq_ascii> 298 template <typename StringType>
287 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { 299 Handle<Object> JsonParser<StringType>::ParseJsonObject() {
288 Handle<JSFunction> object_constructor( 300 Handle<JSFunction> object_constructor(
289 isolate()->global_context()->object_function()); 301 isolate()->global_context()->object_function());
290 Handle<JSObject> json_object = 302 Handle<JSObject> json_object =
291 isolate()->factory()->NewJSObject(object_constructor); 303 isolate()->factory()->NewJSObject(object_constructor);
292 ASSERT_EQ(c0_, '{'); 304 ASSERT_EQ('{', c0_);
293 305
294 AdvanceSkipWhitespace(); 306 AdvanceSkipWhitespace();
295 if (c0_ != '}') { 307 if (c0_ != '}') {
296 do { 308 do {
297 if (c0_ != '"') return ReportUnexpectedCharacter(); 309 if (c0_ != '"') return ReportUnexpectedCharacter();
298 Handle<String> key = ParseJsonSymbol(); 310 Handle<String> key = ParseJsonSymbol();
299 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); 311 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter();
300 AdvanceSkipWhitespace(); 312 AdvanceSkipWhitespace();
301 Handle<Object> value = ParseJsonValue(); 313 Handle<Object> value = ParseJsonValue();
302 if (value.is_null()) return ReportUnexpectedCharacter(); 314 if (value.is_null()) return ReportUnexpectedCharacter();
303 315
304 uint32_t index; 316 uint32_t index;
305 if (key->AsArrayIndex(&index)) { 317 if (key->AsArrayIndex(&index)) {
306 SetOwnElement(json_object, index, value, kNonStrictMode); 318 SetOwnElement(json_object, index, value, kNonStrictMode);
307 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { 319 } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
308 SetPrototype(json_object, value); 320 SetPrototype(json_object, value);
309 } else { 321 } else {
310 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); 322 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
311 } 323 }
312 } while (MatchSkipWhiteSpace(',')); 324 } while (MatchSkipWhiteSpace(','));
313 if (c0_ != '}') { 325 if (c0_ != '}') {
314 return ReportUnexpectedCharacter(); 326 return ReportUnexpectedCharacter();
315 } 327 }
316 } 328 }
317 AdvanceSkipWhitespace(); 329 AdvanceSkipWhitespace();
318 return json_object; 330 return json_object;
319 } 331 }
320 332
321 // Parse a JSON array. Position must be right at '['. 333 // Parse a JSON array. Position must be right at '['.
322 template <bool seq_ascii> 334 template <typename StringType>
323 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() { 335 Handle<Object> JsonParser<StringType>::ParseJsonArray() {
324 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT); 336 ZoneScope zone_scope(isolate(), DELETE_ON_EXIT);
325 ZoneList<Handle<Object> > elements(4); 337 ZoneList<Handle<Object> > elements(4);
326 ASSERT_EQ(c0_, '['); 338 ASSERT_EQ(c0_, '[');
327 339
328 AdvanceSkipWhitespace(); 340 AdvanceSkipWhitespace();
329 if (c0_ != ']') { 341 if (c0_ != ']') {
330 do { 342 do {
331 Handle<Object> element = ParseJsonValue(); 343 Handle<Object> element = ParseJsonValue();
332 if (element.is_null()) return ReportUnexpectedCharacter(); 344 if (element.is_null()) return ReportUnexpectedCharacter();
333 elements.Add(element); 345 elements.Add(element);
334 } while (MatchSkipWhiteSpace(',')); 346 } while (MatchSkipWhiteSpace(','));
335 if (c0_ != ']') { 347 if (c0_ != ']') {
336 return ReportUnexpectedCharacter(); 348 return ReportUnexpectedCharacter();
337 } 349 }
338 } 350 }
339 AdvanceSkipWhitespace(); 351 AdvanceSkipWhitespace();
340 // Allocate a fixed array with all the elements. 352 // Allocate a fixed array with all the elements.
341 Handle<FixedArray> fast_elements = 353 Handle<FixedArray> fast_elements =
342 isolate()->factory()->NewFixedArray(elements.length()); 354 isolate()->factory()->NewFixedArray(elements.length());
343 for (int i = 0, n = elements.length(); i < n; i++) { 355 for (int i = 0, n = elements.length(); i < n; i++) {
344 fast_elements->set(i, *elements[i]); 356 fast_elements->set(i, *elements[i]);
345 } 357 }
346 return isolate()->factory()->NewJSArrayWithElements(fast_elements); 358 return isolate()->factory()->NewJSArrayWithElements(fast_elements);
347 } 359 }
348 360
349 361
350 template <bool seq_ascii> 362 template <typename StringType>
351 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { 363 Handle<Object> JsonParser<StringType>::ParseJsonNumber() {
352 bool negative = false; 364 bool negative = false;
353 int beg_pos = position_; 365 int beg_pos = position_;
354 if (c0_ == '-') { 366 if (c0_ == '-') {
355 Advance(); 367 Advance();
356 negative = true; 368 negative = true;
357 } 369 }
358 if (c0_ == '0') { 370 if (c0_ == '0') {
359 Advance(); 371 Advance();
360 // Prefix zero is only allowed if it's the only digit before 372 // Prefix zero is only allowed if it's the only digit before
361 // a decimal point or exponent. 373 // a decimal point or exponent.
(...skipping 22 matching lines...) Expand all
384 if (AsciiAlphaToLower(c0_) == 'e') { 396 if (AsciiAlphaToLower(c0_) == 'e') {
385 Advance(); 397 Advance();
386 if (c0_ == '-' || c0_ == '+') Advance(); 398 if (c0_ == '-' || c0_ == '+') Advance();
387 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter(); 399 if (c0_ < '0' || c0_ > '9') return ReportUnexpectedCharacter();
388 do { 400 do {
389 Advance(); 401 Advance();
390 } while (c0_ >= '0' && c0_ <= '9'); 402 } while (c0_ >= '0' && c0_ <= '9');
391 } 403 }
392 int length = position_ - beg_pos; 404 int length = position_ - beg_pos;
393 double number; 405 double number;
394 if (seq_ascii) { 406
395 Vector<const char> chars(seq_source_->GetChars() + beg_pos, length); 407 Vector<const SourceChar> chars(GetChars() + beg_pos, length);
396 number = StringToDouble(isolate()->unicode_cache(), 408 number = StringToDouble(isolate()->unicode_cache(),
397 chars, 409 chars,
398 NO_FLAGS, // Hex, octal or trailing junk. 410 NO_FLAGS, // Hex, octal or trailing junk.
399 OS::nan_value()); 411 OS::nan_value());
400 } else {
401 Vector<char> buffer = Vector<char>::New(length);
402 String::WriteToFlat(*source_, buffer.start(), beg_pos, position_);
403 Vector<const char> result =
404 Vector<const char>(reinterpret_cast<const char*>(buffer.start()),
405 length);
406 number = StringToDouble(isolate()->unicode_cache(),
407 result,
408 NO_FLAGS, // Hex, octal or trailing junk.
409 0.0);
410 buffer.Dispose();
411 }
412 SkipWhitespace(); 412 SkipWhitespace();
413 return isolate()->factory()->NewNumber(number); 413 return isolate()->factory()->NewNumber(number);
414 } 414 }
415 415
416 416
417 template <typename StringType> 417 template <typename StringType>
418 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); 418 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c);
419 419
420 template <> 420 template <>
421 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { 421 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) {
(...skipping 15 matching lines...) Expand all
437 437
438 template <> 438 template <>
439 inline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) { 439 inline Handle<SeqAsciiString> NewRawString(Factory* factory, int length) {
440 return factory->NewRawAsciiString(length, NOT_TENURED); 440 return factory->NewRawAsciiString(length, NOT_TENURED);
441 } 441 }
442 442
443 443
444 // Scans the rest of a JSON string starting from position_ and writes 444 // Scans the rest of a JSON string starting from position_ and writes
445 // prefix[start..end] along with the scanned characters into a 445 // prefix[start..end] along with the scanned characters into a
446 // sequential string of type StringType. 446 // sequential string of type StringType.
447 template <bool seq_ascii> 447 template <typename StringType>
448 template <typename StringType, typename SinkChar> 448 template <typename SinkStringType>
449 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( 449 Handle<String> JsonParser<StringType>::SlowScanJsonString(
450 Handle<String> prefix, int start, int end) { 450 Handle<String> prefix, int start, int end) {
451 typedef typename SinkStringType::CharType SinkChar;
451 int count = end - start; 452 int count = end - start;
452 int max_length = count + source_length_ - position_; 453 int max_length = count + source_length_ - position_;
453 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); 454 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count));
454 Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(), 455 Handle<SinkStringType> seq_str =
455 length); 456 NewRawString<SinkStringType>(isolate()->factory(),
457 length);
456 // Copy prefix into seq_str. 458 // Copy prefix into seq_str.
457 SinkChar* dest = seq_str->GetChars(); 459 SinkChar* dest = seq_str->GetChars();
458 String::WriteToFlat(*prefix, dest, start, end); 460 String::WriteToFlat(*prefix, dest, start, end);
459 461
460 while (c0_ != '"') { 462 while (c0_ != '"') {
461 // Check for control character (0x00-0x1f) or unterminated string (<0). 463 // Check for control character (0x00-0x1f) or unterminated string (<0).
462 if (c0_ < 0x20) return Handle<String>::null(); 464 if (c0_ < 0x20) return Handle<String>::null();
463 if (count >= length) { 465 if (count >= length) {
464 // We need to create a longer sequential string for the result. 466 // We need to create a longer sequential string for the result.
465 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); 467 return SlowScanJsonString<SinkStringType>(seq_str, 0, count);
466 } 468 }
467 if (c0_ != '\\') { 469 if (c0_ != '\\') {
468 // If the sink can contain UC16 characters, or source_ contains only 470 // If the sink can contain UC16 characters, or source_ contains only
469 // ASCII characters, there's no need to test whether we can store the 471 // ASCII characters, there's no need to test whether we can store the
470 // character. Otherwise check whether the UC16 source character can fit 472 // character. Otherwise check whether the UC16 source character can fit
471 // in the ASCII sink. 473 // in the ASCII sink.
472 if (sizeof(SinkChar) == kUC16Size || 474 if (sizeof(SinkChar) == kUC16Size ||
473 seq_ascii || 475 sizeof(SourceChar) == kCharSize ||
474 c0_ <= kMaxAsciiCharCode) { 476 c0_ <= kMaxAsciiCharCode) {
475 SeqStringSet(seq_str, count++, c0_); 477 SeqStringSet(seq_str, count++, c0_);
476 Advance(); 478 Advance();
477 } else { 479 } else {
478 // StringType is SeqAsciiString and we just read a non-ASCII char. 480 // SinkStringType is SeqAsciiString and we just read a non-ASCII char.
479 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count); 481 return SlowScanJsonString<SeqTwoByteString>(seq_str, 0, count);
480 } 482 }
481 } else { 483 } else {
482 Advance(); // Advance past the \. 484 Advance(); // Advance past the '\'.
483 switch (c0_) { 485 switch (c0_) {
484 case '"': 486 case '"':
485 case '\\': 487 case '\\':
486 case '/': 488 case '/':
487 SeqStringSet(seq_str, count++, c0_); 489 SeqStringSet(seq_str, count++, c0_);
488 break; 490 break;
489 case 'b': 491 case 'b':
490 SeqStringSet(seq_str, count++, '\x08'); 492 SeqStringSet(seq_str, count++, '\x08');
491 break; 493 break;
492 case 'f': 494 case 'f':
(...skipping 18 matching lines...) Expand all
511 } 513 }
512 value = value * 16 + digit; 514 value = value * 16 + digit;
513 } 515 }
514 if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) { 516 if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) {
515 SeqStringSet(seq_str, count++, value); 517 SeqStringSet(seq_str, count++, value);
516 break; 518 break;
517 } else { 519 } else {
518 // StringType is SeqAsciiString and we just read a non-ASCII char. 520 // StringType is SeqAsciiString and we just read a non-ASCII char.
519 position_ -= 6; // Rewind position_ to \ in \uxxxx. 521 position_ -= 6; // Rewind position_ to \ in \uxxxx.
520 Advance(); 522 Advance();
521 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 523 return SlowScanJsonString<SeqTwoByteString>(seq_str,
522 0, 524 0,
523 count); 525 count);
524 } 526 }
525 } 527 }
526 default: 528 default:
527 return Handle<String>::null(); 529 return Handle<String>::null();
528 } 530 }
529 Advance(); 531 Advance();
530 } 532 }
531 } 533 }
532 // Shrink seq_string length to count. 534 // Shrink seq_string length to count.
533 if (isolate()->heap()->InNewSpace(*seq_str)) { 535 if (isolate()->heap()->InNewSpace(*seq_str)) {
534 isolate()->heap()->new_space()-> 536 isolate()->heap()->new_space()->
535 template ShrinkStringAtAllocationBoundary<StringType>( 537 template ShrinkStringAtAllocationBoundary<SinkStringType>(
536 *seq_str, count); 538 *seq_str, count);
537 } else { 539 } else {
538 int string_size = StringType::SizeFor(count); 540 int string_size = SinkStringType::SizeFor(count);
539 int allocated_string_size = StringType::SizeFor(length); 541 int allocated_string_size = SinkStringType::SizeFor(length);
540 int delta = allocated_string_size - string_size; 542 int delta = allocated_string_size - string_size;
541 Address start_filler_object = seq_str->address() + string_size; 543 Address start_filler_object = seq_str->address() + string_size;
542 seq_str->set_length(count); 544 seq_str->set_length(count);
543 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta); 545 isolate()->heap()->CreateFillerObjectAt(start_filler_object, delta);
544 } 546 }
545 ASSERT_EQ('"', c0_); 547 ASSERT_EQ('"', c0_);
546 // Advance past the last '"'. 548 // Advance past the last '"'.
547 AdvanceSkipWhitespace(); 549 AdvanceSkipWhitespace();
548 return seq_str; 550 return seq_str;
549 } 551 }
550 552
551 553
552 template <bool seq_ascii> 554 template <typename StringType>
553 template <bool is_symbol> 555 template <bool is_symbol>
554 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { 556 Handle<String> JsonParser<StringType>::ScanJsonString() {
555 ASSERT_EQ('"', c0_); 557 ASSERT_EQ('"', c0_);
556 Advance(); 558 Advance();
557 if (c0_ == '"') { 559 if (c0_ == '"') {
558 AdvanceSkipWhitespace(); 560 AdvanceSkipWhitespace();
559 return Handle<String>(isolate()->heap()->empty_string()); 561 return Handle<String>(isolate()->heap()->empty_string());
560 } 562 }
561 int beg_pos = position_; 563 int beg_pos = position_;
562 // Fast case for ASCII only without escape characters. 564 // Fast case for ASCII only without escape characters.
563 do { 565 do {
564 // Check for control character (0x00-0x1f) or unterminated string (<0). 566 // Check for control character (0x00-0x1f) or unterminated string (<0).
565 if (c0_ < 0x20) return Handle<String>::null(); 567 if (c0_ < 0x20) return Handle<String>::null();
566 if (c0_ != '\\') { 568 if (c0_ != '\\') {
567 if (seq_ascii || c0_ <= kMaxAsciiCharCode) { 569 if (c0_ <= kMaxAsciiCharCode) {
568 Advance(); 570 Advance();
569 } else { 571 } else {
570 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, 572 return SlowScanJsonString<SeqTwoByteString>(source_,
571 beg_pos, 573 beg_pos,
572 position_); 574 position_);
573 } 575 }
574 } else { 576 } else {
575 return SlowScanJsonString<SeqAsciiString, char>(source_, 577 return SlowScanJsonString<SeqAsciiString>(source_,
576 beg_pos, 578 beg_pos,
577 position_); 579 position_);
578 } 580 }
579 } while (c0_ != '"'); 581 } while (c0_ != '"');
580 int length = position_ - beg_pos; 582 int length = position_ - beg_pos;
581 Handle<String> result; 583 Handle<String> result;
582 if (seq_ascii && is_symbol) { 584 if (is_symbol && source_->IsSeqAsciiString()) {
583 result = isolate()->factory()->LookupAsciiSymbol(seq_source_, 585 result = isolate()->factory()->LookupAsciiSymbol(
584 beg_pos, 586 Handle<SeqAsciiString>::cast(source_), beg_pos, length);
585 length);
586 } else { 587 } else {
587 result = isolate()->factory()->NewRawAsciiString(length); 588 result = isolate()->factory()->NewRawAsciiString(length);
588 char* dest = SeqAsciiString::cast(*result)->GetChars(); 589 char* dest = SeqAsciiString::cast(*result)->GetChars();
589 String::WriteToFlat(*source_, dest, beg_pos, position_); 590 String::WriteToFlat(*source_, dest, beg_pos, position_);
590 } 591 }
591 ASSERT_EQ('"', c0_); 592 ASSERT_EQ('"', c0_);
592 // Advance past the last '"'. 593 // Advance past the last '"'.
593 AdvanceSkipWhitespace(); 594 AdvanceSkipWhitespace();
594 return result; 595 return result;
595 } 596 }
596 597
598
599 template <typename StringType>
600 void JsonParser<StringType>::InitializeSource() { }
601
602
603 template <>
604 void JsonParser<ExternalAsciiString>::InitializeSource() {
605 characters_ = source_->resource()->data();
606 }
607
608
609 template <>
610 void JsonParser<ExternalTwoByteString>::InitializeSource() {
611 characters_ = source_->resource()->data();
612 }
613
614
615 template <>
616 uc32 JsonParser<SeqAsciiString>::GetChar(int pos) {
617 return static_cast<uc32>(source_->SeqAsciiStringGet(pos));
618 }
619
620
621 template <>
622 uc32 JsonParser<SeqTwoByteString>::GetChar(int pos) {
623 return static_cast<uc32>(source_->SeqTwoByteStringGet(pos));
624 }
625
626
627 template <>
628 uc32 JsonParser<ExternalAsciiString>::GetChar(int pos) {
629 ASSERT(pos >= 0);
630 ASSERT(pos < source_length_);
631 return static_cast<uc32>(characters_[pos]);
632 }
633
634
635 template <>
636 uc32 JsonParser<ExternalTwoByteString>::GetChar(int pos) {
637 ASSERT(pos >= 0);
638 ASSERT(pos < source_length_);
639 return static_cast<uc32>(characters_[pos]);
640 }
641
642
643 template <>
644 const char* JsonParser<SeqAsciiString>::GetChars() {
645 return source_->GetChars();
646 }
647
648
649 template <>
650 const uc16* JsonParser<SeqTwoByteString>::GetChars() {
651 return source_->GetChars();
652 }
653
654
655 template <>
656 const char* JsonParser<ExternalAsciiString>::GetChars() {
657 return characters_;
658 }
659
660
661 template <>
662 const uc16* JsonParser<ExternalTwoByteString>::GetChars() {
663 return characters_;
664 }
665
597 } } // namespace v8::internal 666 } } // namespace v8::internal
598 667
599 #endif // V8_JSON_PARSER_H_ 668 #endif // V8_JSON_PARSER_H_
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698