| 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 |