OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_JSON_PARSER_H_ | 5 #ifndef V8_JSON_PARSER_H_ |
6 #define V8_JSON_PARSER_H_ | 6 #define V8_JSON_PARSER_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/char-predicates-inl.h" | 10 #include "src/char-predicates-inl.h" |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 } | 293 } |
294 | 294 |
295 | 295 |
296 // Parse a JSON object. Position must be right at '{'. | 296 // Parse a JSON object. Position must be right at '{'. |
297 template <bool seq_one_byte> | 297 template <bool seq_one_byte> |
298 Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() { | 298 Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() { |
299 HandleScope scope(isolate()); | 299 HandleScope scope(isolate()); |
300 Handle<JSObject> json_object = | 300 Handle<JSObject> json_object = |
301 factory()->NewJSObject(object_constructor(), pretenure_); | 301 factory()->NewJSObject(object_constructor(), pretenure_); |
302 Handle<Map> map(json_object->map()); | 302 Handle<Map> map(json_object->map()); |
| 303 int descriptor = 0; |
303 ZoneList<Handle<Object> > properties(8, zone()); | 304 ZoneList<Handle<Object> > properties(8, zone()); |
304 DCHECK_EQ(c0_, '{'); | 305 DCHECK_EQ(c0_, '{'); |
305 | 306 |
306 bool transitioning = true; | 307 bool transitioning = true; |
307 | 308 |
308 AdvanceSkipWhitespace(); | 309 AdvanceSkipWhitespace(); |
309 if (c0_ != '}') { | 310 if (c0_ != '}') { |
310 do { | 311 do { |
311 if (c0_ != '"') return ReportUnexpectedCharacter(); | 312 if (c0_ != '"') return ReportUnexpectedCharacter(); |
312 | 313 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 // If a transition was found, follow it and continue. | 376 // If a transition was found, follow it and continue. |
376 transitioning = !target.is_null(); | 377 transitioning = !target.is_null(); |
377 } | 378 } |
378 if (c0_ != ':') return ReportUnexpectedCharacter(); | 379 if (c0_ != ':') return ReportUnexpectedCharacter(); |
379 | 380 |
380 AdvanceSkipWhitespace(); | 381 AdvanceSkipWhitespace(); |
381 value = ParseJsonValue(); | 382 value = ParseJsonValue(); |
382 if (value.is_null()) return ReportUnexpectedCharacter(); | 383 if (value.is_null()) return ReportUnexpectedCharacter(); |
383 | 384 |
384 if (transitioning) { | 385 if (transitioning) { |
385 int descriptor = map->NumberOfOwnDescriptors(); | |
386 PropertyDetails details = | 386 PropertyDetails details = |
387 target->instance_descriptors()->GetDetails(descriptor); | 387 target->instance_descriptors()->GetDetails(descriptor); |
388 Representation expected_representation = details.representation(); | 388 Representation expected_representation = details.representation(); |
389 | 389 |
390 if (value->FitsRepresentation(expected_representation)) { | 390 if (value->FitsRepresentation(expected_representation)) { |
391 if (expected_representation.IsDouble()) { | 391 if (expected_representation.IsHeapObject() && |
392 value = Object::NewStorageFor(isolate(), value, | 392 !target->instance_descriptors() |
393 expected_representation); | 393 ->GetFieldType(descriptor) |
394 } else if (expected_representation.IsHeapObject() && | 394 ->NowContains(value)) { |
395 !target->instance_descriptors()->GetFieldType( | |
396 descriptor)->NowContains(value)) { | |
397 Handle<HeapType> value_type(value->OptimalType( | 395 Handle<HeapType> value_type(value->OptimalType( |
398 isolate(), expected_representation)); | 396 isolate(), expected_representation)); |
399 Map::GeneralizeFieldType(target, descriptor, | 397 Map::GeneralizeFieldType(target, descriptor, |
400 expected_representation, value_type); | 398 expected_representation, value_type); |
401 } | 399 } |
402 DCHECK(target->instance_descriptors()->GetFieldType( | 400 DCHECK(target->instance_descriptors()->GetFieldType( |
403 descriptor)->NowContains(value)); | 401 descriptor)->NowContains(value)); |
404 properties.Add(value, zone()); | 402 properties.Add(value, zone()); |
405 map = target; | 403 map = target; |
| 404 descriptor++; |
406 continue; | 405 continue; |
407 } else { | 406 } else { |
408 transitioning = false; | 407 transitioning = false; |
409 } | 408 } |
410 } | 409 } |
411 | 410 |
412 // Commit the intermediate state to the object and stop transitioning. | 411 // Commit the intermediate state to the object and stop transitioning. |
413 CommitStateToJsonObject(json_object, map, &properties); | 412 CommitStateToJsonObject(json_object, map, &properties); |
414 } else { | 413 } else { |
415 key = ParseJsonInternalizedString(); | 414 key = ParseJsonInternalizedString(); |
(...skipping 21 matching lines...) Expand all Loading... |
437 | 436 |
438 | 437 |
439 template <bool seq_one_byte> | 438 template <bool seq_one_byte> |
440 void JsonParser<seq_one_byte>::CommitStateToJsonObject( | 439 void JsonParser<seq_one_byte>::CommitStateToJsonObject( |
441 Handle<JSObject> json_object, Handle<Map> map, | 440 Handle<JSObject> json_object, Handle<Map> map, |
442 ZoneList<Handle<Object> >* properties) { | 441 ZoneList<Handle<Object> >* properties) { |
443 JSObject::AllocateStorageForMap(json_object, map); | 442 JSObject::AllocateStorageForMap(json_object, map); |
444 DCHECK(!json_object->map()->is_dictionary_map()); | 443 DCHECK(!json_object->map()->is_dictionary_map()); |
445 | 444 |
446 DisallowHeapAllocation no_gc; | 445 DisallowHeapAllocation no_gc; |
447 Factory* factory = isolate()->factory(); | |
448 // If the |json_object|'s map is exactly the same as |map| then the | |
449 // |properties| values correspond to the |map| and nothing more has to be | |
450 // done. But if the |json_object|'s map is different then we have to | |
451 // iterate descriptors to ensure that properties still correspond to the | |
452 // map. | |
453 bool slow_case = json_object->map() != *map; | |
454 DescriptorArray* descriptors = NULL; | |
455 | 446 |
456 int length = properties->length(); | 447 int length = properties->length(); |
457 if (slow_case) { | |
458 descriptors = json_object->map()->instance_descriptors(); | |
459 DCHECK(json_object->map()->NumberOfOwnDescriptors() == length); | |
460 } | |
461 for (int i = 0; i < length; i++) { | 448 for (int i = 0; i < length; i++) { |
462 Handle<Object> value = (*properties)[i]; | 449 Handle<Object> value = (*properties)[i]; |
463 if (slow_case && value->IsMutableHeapNumber() && | 450 json_object->WriteToField(i, *value); |
464 !descriptors->GetDetails(i).representation().IsDouble()) { | |
465 // Turn mutable heap numbers into immutable if the field representation | |
466 // is not double. | |
467 HeapNumber::cast(*value)->set_map(*factory->heap_number_map()); | |
468 } | |
469 FieldIndex index = FieldIndex::ForPropertyIndex(*map, i); | |
470 json_object->FastPropertyAtPut(index, *value); | |
471 } | 451 } |
472 } | 452 } |
473 | 453 |
474 | 454 |
475 // Parse a JSON array. Position must be right at '['. | 455 // Parse a JSON array. Position must be right at '['. |
476 template <bool seq_one_byte> | 456 template <bool seq_one_byte> |
477 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { | 457 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { |
478 HandleScope scope(isolate()); | 458 HandleScope scope(isolate()); |
479 ZoneList<Handle<Object> > elements(4, zone()); | 459 ZoneList<Handle<Object> > elements(4, zone()); |
480 DCHECK_EQ(c0_, '['); | 460 DCHECK_EQ(c0_, '['); |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 | 787 |
808 DCHECK_EQ('"', c0_); | 788 DCHECK_EQ('"', c0_); |
809 // Advance past the last '"'. | 789 // Advance past the last '"'. |
810 AdvanceSkipWhitespace(); | 790 AdvanceSkipWhitespace(); |
811 return result; | 791 return result; |
812 } | 792 } |
813 | 793 |
814 } } // namespace v8::internal | 794 } } // namespace v8::internal |
815 | 795 |
816 #endif // V8_JSON_PARSER_H_ | 796 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |