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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 Handle<Object> ParseJsonArray(); | 142 Handle<Object> ParseJsonArray(); |
143 | 143 |
144 | 144 |
145 // Mark that a parsing error has happened at the current token, and | 145 // Mark that a parsing error has happened at the current token, and |
146 // return a null handle. Primarily for readability. | 146 // return a null handle. Primarily for readability. |
147 inline Handle<Object> ReportUnexpectedCharacter() { | 147 inline Handle<Object> ReportUnexpectedCharacter() { |
148 return Handle<Object>::null(); | 148 return Handle<Object>::null(); |
149 } | 149 } |
150 | 150 |
151 inline Isolate* isolate() { return isolate_; } | 151 inline Isolate* isolate() { return isolate_; } |
| 152 inline Factory* factory() { return factory_; } |
| 153 inline Handle<JSFunction> object_constructor() { return object_constructor_; } |
152 inline Zone* zone() const { return zone_; } | 154 inline Zone* zone() const { return zone_; } |
153 | 155 |
154 static const int kInitialSpecialStringLength = 1024; | 156 static const int kInitialSpecialStringLength = 1024; |
155 | 157 |
156 | 158 |
157 private: | 159 private: |
158 Handle<String> source_; | 160 Handle<String> source_; |
159 int source_length_; | 161 int source_length_; |
160 Handle<SeqAsciiString> seq_source_; | 162 Handle<SeqAsciiString> seq_source_; |
161 | 163 |
162 Isolate* isolate_; | 164 Isolate* isolate_; |
| 165 Factory* factory_; |
| 166 Handle<JSFunction> object_constructor_; |
163 uc32 c0_; | 167 uc32 c0_; |
164 int position_; | 168 int position_; |
165 Zone* zone_; | 169 Zone* zone_; |
166 }; | 170 }; |
167 | 171 |
168 template <bool seq_ascii> | 172 template <bool seq_ascii> |
169 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, | 173 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, |
170 Zone* zone) { | 174 Zone* zone) { |
171 isolate_ = source->map()->GetHeap()->isolate(); | 175 isolate_ = source->map()->GetHeap()->isolate(); |
| 176 factory_ = isolate_->factory(); |
| 177 object_constructor_ = |
| 178 Handle<JSFunction>(isolate()->native_context()->object_function()); |
172 zone_ = zone; | 179 zone_ = zone; |
173 FlattenString(source); | 180 FlattenString(source); |
174 source_ = source; | 181 source_ = source; |
175 source_length_ = source_->length(); | 182 source_length_ = source_->length(); |
176 | 183 |
177 // Optimized fast case where we only have ASCII characters. | 184 // Optimized fast case where we only have ASCII characters. |
178 if (seq_ascii) { | 185 if (seq_ascii) { |
179 seq_source_ = Handle<SeqAsciiString>::cast(source_); | 186 seq_source_ = Handle<SeqAsciiString>::cast(source_); |
180 } | 187 } |
181 | 188 |
182 // Set initial position right before the string. | 189 // Set initial position right before the string. |
183 position_ = -1; | 190 position_ = -1; |
184 // Advance to the first character (possibly EOS) | 191 // Advance to the first character (possibly EOS) |
185 AdvanceSkipWhitespace(); | 192 AdvanceSkipWhitespace(); |
186 Handle<Object> result = ParseJsonValue(); | 193 Handle<Object> result = ParseJsonValue(); |
187 if (result.is_null() || c0_ != kEndOfString) { | 194 if (result.is_null() || c0_ != kEndOfString) { |
188 // Parse failed. Current character is the unexpected token. | 195 // Parse failed. Current character is the unexpected token. |
189 | 196 |
190 const char* message; | 197 const char* message; |
191 Factory* factory = isolate()->factory(); | 198 Factory* factory = this->factory(); |
192 Handle<JSArray> array; | 199 Handle<JSArray> array; |
193 | 200 |
194 switch (c0_) { | 201 switch (c0_) { |
195 case kEndOfString: | 202 case kEndOfString: |
196 message = "unexpected_eos"; | 203 message = "unexpected_eos"; |
197 array = factory->NewJSArray(0); | 204 array = factory->NewJSArray(0); |
198 break; | 205 break; |
199 case '-': | 206 case '-': |
200 case '0': | 207 case '0': |
201 case '1': | 208 case '1': |
(...skipping 28 matching lines...) Expand all Loading... |
230 isolate()->Throw(*result, &location); | 237 isolate()->Throw(*result, &location); |
231 return Handle<Object>::null(); | 238 return Handle<Object>::null(); |
232 } | 239 } |
233 return result; | 240 return result; |
234 } | 241 } |
235 | 242 |
236 | 243 |
237 // Parse any JSON value. | 244 // Parse any JSON value. |
238 template <bool seq_ascii> | 245 template <bool seq_ascii> |
239 Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() { | 246 Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() { |
240 switch (c0_) { | 247 if (c0_ == '"') return ParseJsonString(); |
241 case '"': | 248 if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(); |
242 return ParseJsonString(); | 249 if (c0_ == '{') return ParseJsonObject(); |
243 case '-': | 250 if (c0_ == '[') return ParseJsonArray(); |
244 case '0': | 251 if (c0_ == 'f') { |
245 case '1': | 252 if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && |
246 case '2': | 253 AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { |
247 case '3': | 254 AdvanceSkipWhitespace(); |
248 case '4': | 255 return factory()->false_value(); |
249 case '5': | 256 } |
250 case '6': | 257 return ReportUnexpectedCharacter(); |
251 case '7': | |
252 case '8': | |
253 case '9': | |
254 return ParseJsonNumber(); | |
255 case 'f': | |
256 if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && | |
257 AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { | |
258 AdvanceSkipWhitespace(); | |
259 return isolate()->factory()->false_value(); | |
260 } else { | |
261 return ReportUnexpectedCharacter(); | |
262 } | |
263 case 't': | |
264 if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && | |
265 AdvanceGetChar() == 'e') { | |
266 AdvanceSkipWhitespace(); | |
267 return isolate()->factory()->true_value(); | |
268 } else { | |
269 return ReportUnexpectedCharacter(); | |
270 } | |
271 case 'n': | |
272 if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && | |
273 AdvanceGetChar() == 'l') { | |
274 AdvanceSkipWhitespace(); | |
275 return isolate()->factory()->null_value(); | |
276 } else { | |
277 return ReportUnexpectedCharacter(); | |
278 } | |
279 case '{': | |
280 return ParseJsonObject(); | |
281 case '[': | |
282 return ParseJsonArray(); | |
283 default: | |
284 return ReportUnexpectedCharacter(); | |
285 } | 258 } |
| 259 if (c0_ == 't') { |
| 260 if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && |
| 261 AdvanceGetChar() == 'e') { |
| 262 AdvanceSkipWhitespace(); |
| 263 return factory()->true_value(); |
| 264 } |
| 265 return ReportUnexpectedCharacter(); |
| 266 } |
| 267 if (c0_ == 'n') { |
| 268 if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && |
| 269 AdvanceGetChar() == 'l') { |
| 270 AdvanceSkipWhitespace(); |
| 271 return factory()->null_value(); |
| 272 } |
| 273 return ReportUnexpectedCharacter(); |
| 274 } |
| 275 return ReportUnexpectedCharacter(); |
286 } | 276 } |
287 | 277 |
288 | 278 |
289 // Parse a JSON object. Position must be right at '{'. | 279 // Parse a JSON object. Position must be right at '{'. |
290 template <bool seq_ascii> | 280 template <bool seq_ascii> |
291 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { | 281 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { |
292 Handle<Object> prototype; | 282 Handle<Object> prototype; |
293 Handle<JSFunction> object_constructor( | |
294 isolate()->native_context()->object_function()); | |
295 Handle<JSObject> json_object = | 283 Handle<JSObject> json_object = |
296 isolate()->factory()->NewJSObject(object_constructor); | 284 factory()->NewJSObject(object_constructor()); |
297 ASSERT_EQ(c0_, '{'); | 285 ASSERT_EQ(c0_, '{'); |
298 | 286 |
299 AdvanceSkipWhitespace(); | 287 AdvanceSkipWhitespace(); |
300 if (c0_ != '}') { | 288 if (c0_ != '}') { |
301 do { | 289 do { |
302 if (c0_ != '"') return ReportUnexpectedCharacter(); | 290 if (c0_ != '"') return ReportUnexpectedCharacter(); |
303 | 291 |
304 int start_position = position_; | 292 int start_position = position_; |
305 Advance(); | 293 Advance(); |
306 | 294 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 if (element.is_null()) return ReportUnexpectedCharacter(); | 358 if (element.is_null()) return ReportUnexpectedCharacter(); |
371 elements.Add(element, zone()); | 359 elements.Add(element, zone()); |
372 } while (MatchSkipWhiteSpace(',')); | 360 } while (MatchSkipWhiteSpace(',')); |
373 if (c0_ != ']') { | 361 if (c0_ != ']') { |
374 return ReportUnexpectedCharacter(); | 362 return ReportUnexpectedCharacter(); |
375 } | 363 } |
376 } | 364 } |
377 AdvanceSkipWhitespace(); | 365 AdvanceSkipWhitespace(); |
378 // Allocate a fixed array with all the elements. | 366 // Allocate a fixed array with all the elements. |
379 Handle<FixedArray> fast_elements = | 367 Handle<FixedArray> fast_elements = |
380 isolate()->factory()->NewFixedArray(elements.length()); | 368 factory()->NewFixedArray(elements.length()); |
381 for (int i = 0, n = elements.length(); i < n; i++) { | 369 for (int i = 0, n = elements.length(); i < n; i++) { |
382 fast_elements->set(i, *elements[i]); | 370 fast_elements->set(i, *elements[i]); |
383 } | 371 } |
384 return isolate()->factory()->NewJSArrayWithElements(fast_elements); | 372 return factory()->NewJSArrayWithElements(fast_elements); |
385 } | 373 } |
386 | 374 |
387 | 375 |
388 template <bool seq_ascii> | 376 template <bool seq_ascii> |
389 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { | 377 Handle<Object> JsonParser<seq_ascii>::ParseJsonNumber() { |
390 bool negative = false; | 378 bool negative = false; |
391 int beg_pos = position_; | 379 int beg_pos = position_; |
392 if (c0_ == '-') { | 380 if (c0_ == '-') { |
393 Advance(); | 381 Advance(); |
394 negative = true; | 382 negative = true; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 Vector<const char> result = | 429 Vector<const char> result = |
442 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), | 430 Vector<const char>(reinterpret_cast<const char*>(buffer.start()), |
443 length); | 431 length); |
444 number = StringToDouble(isolate()->unicode_cache(), | 432 number = StringToDouble(isolate()->unicode_cache(), |
445 result, | 433 result, |
446 NO_FLAGS, // Hex, octal or trailing junk. | 434 NO_FLAGS, // Hex, octal or trailing junk. |
447 0.0); | 435 0.0); |
448 buffer.Dispose(); | 436 buffer.Dispose(); |
449 } | 437 } |
450 SkipWhitespace(); | 438 SkipWhitespace(); |
451 return isolate()->factory()->NewNumber(number); | 439 return factory()->NewNumber(number); |
452 } | 440 } |
453 | 441 |
454 | 442 |
455 template <typename StringType> | 443 template <typename StringType> |
456 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); | 444 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); |
457 | 445 |
458 template <> | 446 template <> |
459 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { | 447 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { |
460 seq_str->SeqTwoByteStringSet(i, c); | 448 seq_str->SeqTwoByteStringSet(i, c); |
461 } | 449 } |
(...skipping 20 matching lines...) Expand all Loading... |
482 // Scans the rest of a JSON string starting from position_ and writes | 470 // Scans the rest of a JSON string starting from position_ and writes |
483 // prefix[start..end] along with the scanned characters into a | 471 // prefix[start..end] along with the scanned characters into a |
484 // sequential string of type StringType. | 472 // sequential string of type StringType. |
485 template <bool seq_ascii> | 473 template <bool seq_ascii> |
486 template <typename StringType, typename SinkChar> | 474 template <typename StringType, typename SinkChar> |
487 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( | 475 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( |
488 Handle<String> prefix, int start, int end) { | 476 Handle<String> prefix, int start, int end) { |
489 int count = end - start; | 477 int count = end - start; |
490 int max_length = count + source_length_ - position_; | 478 int max_length = count + source_length_ - position_; |
491 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); | 479 int length = Min(max_length, Max(kInitialSpecialStringLength, 2 * count)); |
492 Handle<StringType> seq_str = NewRawString<StringType>(isolate()->factory(), | 480 Handle<StringType> seq_str = NewRawString<StringType>(factory(), length); |
493 length); | |
494 // Copy prefix into seq_str. | 481 // Copy prefix into seq_str. |
495 SinkChar* dest = seq_str->GetChars(); | 482 SinkChar* dest = seq_str->GetChars(); |
496 String::WriteToFlat(*prefix, dest, start, end); | 483 String::WriteToFlat(*prefix, dest, start, end); |
497 | 484 |
498 while (c0_ != '"') { | 485 while (c0_ != '"') { |
499 // Check for control character (0x00-0x1f) or unterminated string (<0). | 486 // Check for control character (0x00-0x1f) or unterminated string (<0). |
500 if (c0_ < 0x20) return Handle<String>::null(); | 487 if (c0_ < 0x20) return Handle<String>::null(); |
501 if (count >= length) { | 488 if (count >= length) { |
502 // We need to create a longer sequential string for the result. | 489 // We need to create a longer sequential string for the result. |
503 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); | 490 return SlowScanJsonString<StringType, SinkChar>(seq_str, 0, count); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 } | 648 } |
662 } else { | 649 } else { |
663 return SlowScanJsonString<SeqAsciiString, char>(source_, | 650 return SlowScanJsonString<SeqAsciiString, char>(source_, |
664 beg_pos, | 651 beg_pos, |
665 position_); | 652 position_); |
666 } | 653 } |
667 } while (c0_ != '"'); | 654 } while (c0_ != '"'); |
668 int length = position_ - beg_pos; | 655 int length = position_ - beg_pos; |
669 Handle<String> result; | 656 Handle<String> result; |
670 if (seq_ascii && is_symbol) { | 657 if (seq_ascii && is_symbol) { |
671 result = isolate()->factory()->LookupAsciiSymbol(seq_source_, | 658 result = factory()->LookupAsciiSymbol(seq_source_, |
672 beg_pos, | 659 beg_pos, |
673 length); | 660 length); |
674 } else { | 661 } else { |
675 result = isolate()->factory()->NewRawAsciiString(length); | 662 result = factory()->NewRawAsciiString(length); |
676 char* dest = SeqAsciiString::cast(*result)->GetChars(); | 663 char* dest = SeqAsciiString::cast(*result)->GetChars(); |
677 String::WriteToFlat(*source_, dest, beg_pos, position_); | 664 String::WriteToFlat(*source_, dest, beg_pos, position_); |
678 } | 665 } |
679 ASSERT_EQ('"', c0_); | 666 ASSERT_EQ('"', c0_); |
680 // Advance past the last '"'. | 667 // Advance past the last '"'. |
681 AdvanceSkipWhitespace(); | 668 AdvanceSkipWhitespace(); |
682 return result; | 669 return result; |
683 } | 670 } |
684 | 671 |
685 } } // namespace v8::internal | 672 } } // namespace v8::internal |
686 | 673 |
687 #endif // V8_JSON_PARSER_H_ | 674 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |