| 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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 inline Factory* factory() { return factory_; } | 175 inline Factory* factory() { return factory_; } |
| 176 inline Handle<JSFunction> object_constructor() { return object_constructor_; } | 176 inline Handle<JSFunction> object_constructor() { return object_constructor_; } |
| 177 | 177 |
| 178 static const int kInitialSpecialStringLength = 1024; | 178 static const int kInitialSpecialStringLength = 1024; |
| 179 static const int kPretenureTreshold = 100 * 1024; | 179 static const int kPretenureTreshold = 100 * 1024; |
| 180 | 180 |
| 181 | 181 |
| 182 private: | 182 private: |
| 183 Zone* zone() { return &zone_; } | 183 Zone* zone() { return &zone_; } |
| 184 | 184 |
| 185 void CommitStateToJsonObject(Handle<JSObject> json_object, Handle<Map> map, |
| 186 ZoneList<Handle<Object> >* properties); |
| 187 |
| 185 Handle<String> source_; | 188 Handle<String> source_; |
| 186 int source_length_; | 189 int source_length_; |
| 187 Handle<SeqOneByteString> seq_source_; | 190 Handle<SeqOneByteString> seq_source_; |
| 188 | 191 |
| 189 PretenureFlag pretenure_; | 192 PretenureFlag pretenure_; |
| 190 Isolate* isolate_; | 193 Isolate* isolate_; |
| 191 Factory* factory_; | 194 Factory* factory_; |
| 192 Zone zone_; | 195 Zone zone_; |
| 193 Handle<JSFunction> object_constructor_; | 196 Handle<JSFunction> object_constructor_; |
| 194 uc32 c0_; | 197 uc32 c0_; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 descriptor)->NowContains(value)); | 406 descriptor)->NowContains(value)); |
| 404 properties.Add(value, zone()); | 407 properties.Add(value, zone()); |
| 405 map = target; | 408 map = target; |
| 406 continue; | 409 continue; |
| 407 } else { | 410 } else { |
| 408 transitioning = false; | 411 transitioning = false; |
| 409 } | 412 } |
| 410 } | 413 } |
| 411 | 414 |
| 412 // Commit the intermediate state to the object and stop transitioning. | 415 // Commit the intermediate state to the object and stop transitioning. |
| 413 JSObject::AllocateStorageForMap(json_object, map); | 416 CommitStateToJsonObject(json_object, map, &properties); |
| 414 int length = properties.length(); | |
| 415 for (int i = 0; i < length; i++) { | |
| 416 Handle<Object> value = properties[i]; | |
| 417 FieldIndex index = FieldIndex::ForPropertyIndex(*map, i); | |
| 418 json_object->FastPropertyAtPut(index, *value); | |
| 419 } | |
| 420 } else { | 417 } else { |
| 421 key = ParseJsonInternalizedString(); | 418 key = ParseJsonInternalizedString(); |
| 422 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); | 419 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); |
| 423 | 420 |
| 424 AdvanceSkipWhitespace(); | 421 AdvanceSkipWhitespace(); |
| 425 value = ParseJsonValue(); | 422 value = ParseJsonValue(); |
| 426 if (value.is_null()) return ReportUnexpectedCharacter(); | 423 if (value.is_null()) return ReportUnexpectedCharacter(); |
| 427 } | 424 } |
| 428 | 425 |
| 429 Runtime::DefineObjectProperty(json_object, key, value, NONE).Check(); | 426 Runtime::DefineObjectProperty(json_object, key, value, NONE).Check(); |
| 430 } while (MatchSkipWhiteSpace(',')); | 427 } while (MatchSkipWhiteSpace(',')); |
| 431 if (c0_ != '}') { | 428 if (c0_ != '}') { |
| 432 return ReportUnexpectedCharacter(); | 429 return ReportUnexpectedCharacter(); |
| 433 } | 430 } |
| 434 | 431 |
| 435 // If we transitioned until the very end, transition the map now. | 432 // If we transitioned until the very end, transition the map now. |
| 436 if (transitioning) { | 433 if (transitioning) { |
| 437 JSObject::AllocateStorageForMap(json_object, map); | 434 CommitStateToJsonObject(json_object, map, &properties); |
| 438 int length = properties.length(); | |
| 439 for (int i = 0; i < length; i++) { | |
| 440 Handle<Object> value = properties[i]; | |
| 441 FieldIndex index = FieldIndex::ForPropertyIndex(*map, i); | |
| 442 json_object->FastPropertyAtPut(index, *value); | |
| 443 } | |
| 444 } | 435 } |
| 445 } | 436 } |
| 446 AdvanceSkipWhitespace(); | 437 AdvanceSkipWhitespace(); |
| 447 return scope.CloseAndEscape(json_object); | 438 return scope.CloseAndEscape(json_object); |
| 448 } | 439 } |
| 449 | 440 |
| 441 |
| 442 template <bool seq_one_byte> |
| 443 void JsonParser<seq_one_byte>::CommitStateToJsonObject( |
| 444 Handle<JSObject> json_object, Handle<Map> map, |
| 445 ZoneList<Handle<Object> >* properties) { |
| 446 JSObject::AllocateStorageForMap(json_object, map); |
| 447 DCHECK(!json_object->map()->is_dictionary_map()); |
| 448 |
| 449 DisallowHeapAllocation no_gc; |
| 450 Factory* factory = isolate()->factory(); |
| 451 // If the |json_object|'s map is exactly the same as |map| then the |
| 452 // |properties| values correspond to the |map| and nothing more has to be |
| 453 // done. But if the |json_object|'s map is different then we have to |
| 454 // iterate descriptors to ensure that properties still correspond to the |
| 455 // map. |
| 456 bool slow_case = json_object->map() != *map; |
| 457 DescriptorArray* descriptors = NULL; |
| 458 |
| 459 int length = properties->length(); |
| 460 if (slow_case) { |
| 461 descriptors = json_object->map()->instance_descriptors(); |
| 462 DCHECK(json_object->map()->NumberOfOwnDescriptors() == length); |
| 463 } |
| 464 for (int i = 0; i < length; i++) { |
| 465 Handle<Object> value = (*properties)[i]; |
| 466 if (slow_case && value->IsMutableHeapNumber() && |
| 467 !descriptors->GetDetails(i).representation().IsDouble()) { |
| 468 // Turn mutable heap numbers into immutable if the field representation |
| 469 // is not double. |
| 470 HeapNumber::cast(*value)->set_map(*factory->heap_number_map()); |
| 471 } |
| 472 FieldIndex index = FieldIndex::ForPropertyIndex(*map, i); |
| 473 json_object->FastPropertyAtPut(index, *value); |
| 474 } |
| 475 } |
| 476 |
| 477 |
| 450 // Parse a JSON array. Position must be right at '['. | 478 // Parse a JSON array. Position must be right at '['. |
| 451 template <bool seq_one_byte> | 479 template <bool seq_one_byte> |
| 452 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { | 480 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { |
| 453 HandleScope scope(isolate()); | 481 HandleScope scope(isolate()); |
| 454 ZoneList<Handle<Object> > elements(4, zone()); | 482 ZoneList<Handle<Object> > elements(4, zone()); |
| 455 DCHECK_EQ(c0_, '['); | 483 DCHECK_EQ(c0_, '['); |
| 456 | 484 |
| 457 AdvanceSkipWhitespace(); | 485 AdvanceSkipWhitespace(); |
| 458 if (c0_ != ']') { | 486 if (c0_ != ']') { |
| 459 do { | 487 do { |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 | 811 |
| 784 DCHECK_EQ('"', c0_); | 812 DCHECK_EQ('"', c0_); |
| 785 // Advance past the last '"'. | 813 // Advance past the last '"'. |
| 786 AdvanceSkipWhitespace(); | 814 AdvanceSkipWhitespace(); |
| 787 return result; | 815 return result; |
| 788 } | 816 } |
| 789 | 817 |
| 790 } } // namespace v8::internal | 818 } } // namespace v8::internal |
| 791 | 819 |
| 792 #endif // V8_JSON_PARSER_H_ | 820 #endif // V8_JSON_PARSER_H_ |
| OLD | NEW |