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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 | 374 |
375 Handle<String> key; | 375 Handle<String> key; |
376 Handle<Object> value; | 376 Handle<Object> value; |
377 | 377 |
378 // Try to follow existing transitions as long as possible. Once we stop | 378 // Try to follow existing transitions as long as possible. Once we stop |
379 // transitioning, no transition can be found anymore. | 379 // transitioning, no transition can be found anymore. |
380 if (transitioning) { | 380 if (transitioning) { |
381 // First check whether there is a single expected transition. If so, try | 381 // First check whether there is a single expected transition. If so, try |
382 // to parse it first. | 382 // to parse it first. |
383 bool follow_expected = false; | 383 bool follow_expected = false; |
384 Handle<Map> target; | |
384 if (seq_ascii) { | 385 if (seq_ascii) { |
385 key = JSObject::ExpectedTransitionKey(map); | 386 key = JSObject::ExpectedTransitionKey(map); |
386 follow_expected = !key.is_null() && ParseJsonString(key); | 387 follow_expected = !key.is_null() && ParseJsonString(key); |
387 } | 388 } |
388 // If the expected transition hits, follow it. | 389 // If the expected transition hits, follow it. |
389 if (follow_expected) { | 390 if (follow_expected) { |
390 map = JSObject::ExpectedTransitionTarget(map); | 391 target = JSObject::ExpectedTransitionTarget(map); |
391 } else { | 392 } else { |
392 // If the expected transition failed, parse an internalized string and | 393 // If the expected transition failed, parse an internalized string and |
393 // try to find a matching transition. | 394 // try to find a matching transition. |
394 key = ParseJsonInternalizedString(); | 395 key = ParseJsonInternalizedString(); |
395 if (key.is_null()) return ReportUnexpectedCharacter(); | 396 if (key.is_null()) return ReportUnexpectedCharacter(); |
396 | 397 |
397 Handle<Map> target = JSObject::FindTransitionToField(map, key); | 398 target = JSObject::FindTransitionToField(map, key); |
398 // If a transition was found, follow it and continue. | 399 // If a transition was found, follow it and continue. |
399 if (!target.is_null()) { | 400 transitioning = !target.is_null(); |
400 map = target; | |
401 } else { | |
402 // If no transition was found, commit the intermediate state to the | |
403 // object and stop transitioning. | |
404 JSObject::TransitionToMap(json_object, map); | |
405 int length = properties.length(); | |
406 for (int i = 0; i < length; i++) { | |
407 Handle<Object> value = properties[i]; | |
408 Representation representation = | |
409 map->instance_descriptors()->GetDetails(i).representation(); | |
410 if (representation.IsDouble() && value->IsSmi()) { | |
411 // TODO(verwaest): Allocate heap number. | |
412 } | |
413 json_object->FastPropertyAtPut(i, *value); | |
414 } | |
415 transitioning = false; | |
416 } | |
417 } | 401 } |
418 if (c0_ != ':') return ReportUnexpectedCharacter(); | 402 if (c0_ != ':') return ReportUnexpectedCharacter(); |
419 | 403 |
420 AdvanceSkipWhitespace(); | 404 AdvanceSkipWhitespace(); |
421 value = ParseJsonValue(); | 405 value = ParseJsonValue(); |
422 if (value.is_null()) return ReportUnexpectedCharacter(); | 406 if (value.is_null()) return ReportUnexpectedCharacter(); |
423 | 407 |
424 properties.Add(value, zone()); | |
425 if (transitioning) { | 408 if (transitioning) { |
426 int field = properties.length() - 1; | 409 int descriptor = map->NumberOfOwnDescriptors(); |
427 Representation expected_representation = | 410 PropertyDetails details = |
428 map->instance_descriptors()->GetDetails(field).representation(); | 411 target->instance_descriptors()->GetDetails(descriptor); |
429 if (!value->FitsRepresentation(expected_representation)) { | 412 Representation expected_representation = details.representation(); |
430 map = Map::GeneralizeRepresentation( | 413 |
431 map, field, value->OptimalRepresentation()); | 414 if (value->FitsRepresentation(expected_representation)) { |
415 // If the target representation is double and the value is already | |
416 // double, use the existing box. | |
417 if (FLAG_track_double_fields && | |
418 value->IsSmi() && | |
419 expected_representation.IsDouble()) { | |
420 value = factory()->NewHeapNumber( | |
421 Handle<Smi>::cast(value)->value()); | |
422 } | |
423 properties.Add(value, zone()); | |
424 map = target; | |
425 continue; | |
426 } else { | |
427 transitioning = false; | |
432 } | 428 } |
433 continue; | 429 } |
430 | |
431 // Commit the intermediate state to the object and stop transitioning. | |
432 JSObject::TransitionToMap(json_object, map); | |
danno
2013/05/07 13:04:47
AllocateStorageForMap... better name?
Toon Verwaest
2013/05/07 15:08:52
Done.
| |
433 int length = properties.length(); | |
434 for (int i = 0; i < length; i++) { | |
435 Handle<Object> value = properties[i]; | |
436 json_object->FastPropertyAtPut(i, *value); | |
434 } | 437 } |
435 } else { | 438 } else { |
436 key = ParseJsonInternalizedString(); | 439 key = ParseJsonInternalizedString(); |
437 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); | 440 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); |
438 | 441 |
439 AdvanceSkipWhitespace(); | 442 AdvanceSkipWhitespace(); |
440 value = ParseJsonValue(); | 443 value = ParseJsonValue(); |
441 if (value.is_null()) return ReportUnexpectedCharacter(); | 444 if (value.is_null()) return ReportUnexpectedCharacter(); |
442 } | 445 } |
443 | 446 |
444 JSObject::SetLocalPropertyIgnoreAttributes( | 447 JSObject::SetLocalPropertyIgnoreAttributes( |
445 json_object, key, value, NONE); | 448 json_object, key, value, NONE); |
446 } while (MatchSkipWhiteSpace(',')); | 449 } while (MatchSkipWhiteSpace(',')); |
447 if (c0_ != '}') { | 450 if (c0_ != '}') { |
448 return ReportUnexpectedCharacter(); | 451 return ReportUnexpectedCharacter(); |
449 } | 452 } |
450 | 453 |
451 // If we transitioned until the very end, transition the map now. | 454 // If we transitioned until the very end, transition the map now. |
452 if (transitioning) { | 455 if (transitioning) { |
453 JSObject::TransitionToMap(json_object, map); | 456 JSObject::TransitionToMap(json_object, map); |
454 int length = properties.length(); | 457 int length = properties.length(); |
455 for (int i = 0; i < length; i++) { | 458 for (int i = 0; i < length; i++) { |
456 Handle<Object> value = properties[i]; | 459 Handle<Object> value = properties[i]; |
457 Representation representation = | 460 // If the target representation is double and the value is already |
458 map->instance_descriptors()->GetDetails(i).representation(); | 461 // double, use the existing box. |
459 if (representation.IsDouble() && value->IsSmi()) { | 462 if (FLAG_track_double_fields && value->IsSmi()) { |
460 // TODO(verwaest): Allocate heap number. | 463 Representation representation = |
464 map->instance_descriptors()->GetDetails(i).representation(); | |
465 if (representation.IsDouble()) { | |
466 value = factory()->NewHeapNumber( | |
467 Handle<Smi>::cast(value)->value()); | |
468 } | |
461 } | 469 } |
462 json_object->FastPropertyAtPut(i, *value); | 470 json_object->FastPropertyAtPut(i, *value); |
463 } | 471 } |
464 } | 472 } |
465 } | 473 } |
466 AdvanceSkipWhitespace(); | 474 AdvanceSkipWhitespace(); |
467 return scope.CloseAndEscape(json_object); | 475 return scope.CloseAndEscape(json_object); |
468 } | 476 } |
469 | 477 |
470 // Parse a JSON array. Position must be right at '['. | 478 // Parse a JSON array. Position must be right at '['. |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 | 811 |
804 ASSERT_EQ('"', c0_); | 812 ASSERT_EQ('"', c0_); |
805 // Advance past the last '"'. | 813 // Advance past the last '"'. |
806 AdvanceSkipWhitespace(); | 814 AdvanceSkipWhitespace(); |
807 return result; | 815 return result; |
808 } | 816 } |
809 | 817 |
810 } } // namespace v8::internal | 818 } } // namespace v8::internal |
811 | 819 |
812 #endif // V8_JSON_PARSER_H_ | 820 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |