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