| 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::AllocateStorageForMap(json_object, map); |
| 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::AllocateStorageForMap(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 |