| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/json-parser.h" | 5 #include "src/json-parser.h" |
| 6 | 6 |
| 7 #include "src/char-predicates-inl.h" | 7 #include "src/char-predicates-inl.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 DisallowHeapAllocation no_gc; | 481 DisallowHeapAllocation no_gc; |
| 482 DescriptorArray* descriptors = json_object->map()->instance_descriptors(); | 482 DescriptorArray* descriptors = json_object->map()->instance_descriptors(); |
| 483 int length = properties->length(); | 483 int length = properties->length(); |
| 484 for (int i = 0; i < length; i++) { | 484 for (int i = 0; i < length; i++) { |
| 485 Handle<Object> value = (*properties)[i]; | 485 Handle<Object> value = (*properties)[i]; |
| 486 // Initializing store. | 486 // Initializing store. |
| 487 json_object->WriteToField(i, descriptors->GetDetails(i), *value); | 487 json_object->WriteToField(i, descriptors->GetDetails(i), *value); |
| 488 } | 488 } |
| 489 } | 489 } |
| 490 | 490 |
| 491 class ElementKindLattice { |
| 492 private: |
| 493 enum { |
| 494 SMI_ELEMENTS, |
| 495 NUMBER_ELEMENTS, |
| 496 OBJECT_ELEMENTS, |
| 497 }; |
| 498 |
| 499 public: |
| 500 ElementKindLattice() : value_(SMI_ELEMENTS) {} |
| 501 |
| 502 void Update(Handle<Object> o) { |
| 503 if (o->IsSmi()) { |
| 504 return; |
| 505 } else if (o->IsHeapNumber()) { |
| 506 if (value_ < NUMBER_ELEMENTS) value_ = NUMBER_ELEMENTS; |
| 507 } else { |
| 508 DCHECK(!o->IsNumber()); |
| 509 value_ = OBJECT_ELEMENTS; |
| 510 } |
| 511 } |
| 512 |
| 513 ElementsKind GetElementsKind() const { |
| 514 switch (value_) { |
| 515 case SMI_ELEMENTS: |
| 516 return FAST_SMI_ELEMENTS; |
| 517 case NUMBER_ELEMENTS: |
| 518 return FAST_DOUBLE_ELEMENTS; |
| 519 case OBJECT_ELEMENTS: |
| 520 return FAST_ELEMENTS; |
| 521 default: |
| 522 UNREACHABLE(); |
| 523 return FAST_ELEMENTS; |
| 524 } |
| 525 } |
| 526 |
| 527 private: |
| 528 int value_; |
| 529 }; |
| 530 |
| 491 // Parse a JSON array. Position must be right at '['. | 531 // Parse a JSON array. Position must be right at '['. |
| 492 template <bool seq_one_byte> | 532 template <bool seq_one_byte> |
| 493 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { | 533 Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() { |
| 494 HandleScope scope(isolate()); | 534 HandleScope scope(isolate()); |
| 495 ZoneList<Handle<Object> > elements(4, zone()); | 535 ZoneList<Handle<Object> > elements(4, zone()); |
| 496 DCHECK_EQ(c0_, '['); | 536 DCHECK_EQ(c0_, '['); |
| 497 | 537 |
| 538 ElementKindLattice lattice; |
| 539 |
| 498 AdvanceSkipWhitespace(); | 540 AdvanceSkipWhitespace(); |
| 499 if (c0_ != ']') { | 541 if (c0_ != ']') { |
| 500 do { | 542 do { |
| 501 Handle<Object> element = ParseJsonValue(); | 543 Handle<Object> element = ParseJsonValue(); |
| 502 if (element.is_null()) return ReportUnexpectedCharacter(); | 544 if (element.is_null()) return ReportUnexpectedCharacter(); |
| 503 elements.Add(element, zone()); | 545 elements.Add(element, zone()); |
| 546 lattice.Update(element); |
| 504 } while (MatchSkipWhiteSpace(',')); | 547 } while (MatchSkipWhiteSpace(',')); |
| 505 if (c0_ != ']') { | 548 if (c0_ != ']') { |
| 506 return ReportUnexpectedCharacter(); | 549 return ReportUnexpectedCharacter(); |
| 507 } | 550 } |
| 508 } | 551 } |
| 509 AdvanceSkipWhitespace(); | 552 AdvanceSkipWhitespace(); |
| 553 |
| 510 // Allocate a fixed array with all the elements. | 554 // Allocate a fixed array with all the elements. |
| 511 Handle<FixedArray> fast_elements = | 555 |
| 512 factory()->NewFixedArray(elements.length(), pretenure_); | 556 Handle<Object> json_array; |
| 513 for (int i = 0, n = elements.length(); i < n; i++) { | 557 const ElementsKind kind = lattice.GetElementsKind(); |
| 514 fast_elements->set(i, *elements[i]); | 558 |
| 559 switch (kind) { |
| 560 case FAST_ELEMENTS: |
| 561 case FAST_SMI_ELEMENTS: { |
| 562 Handle<FixedArray> elems = |
| 563 factory()->NewFixedArray(elements.length(), pretenure_); |
| 564 for (int i = 0; i < elements.length(); i++) elems->set(i, *elements[i]); |
| 565 json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_); |
| 566 break; |
| 567 } |
| 568 case FAST_DOUBLE_ELEMENTS: { |
| 569 Handle<FixedDoubleArray> elems = Handle<FixedDoubleArray>::cast( |
| 570 factory()->NewFixedDoubleArray(elements.length(), pretenure_)); |
| 571 for (int i = 0; i < elements.length(); i++) { |
| 572 elems->set(i, elements[i]->Number()); |
| 573 } |
| 574 json_array = factory()->NewJSArrayWithElements(elems, kind, pretenure_); |
| 575 break; |
| 576 } |
| 577 default: |
| 578 UNREACHABLE(); |
| 515 } | 579 } |
| 516 Handle<Object> json_array = factory()->NewJSArrayWithElements( | 580 |
| 517 fast_elements, FAST_ELEMENTS, pretenure_); | |
| 518 return scope.CloseAndEscape(json_array); | 581 return scope.CloseAndEscape(json_array); |
| 519 } | 582 } |
| 520 | 583 |
| 521 template <bool seq_one_byte> | 584 template <bool seq_one_byte> |
| 522 Handle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() { | 585 Handle<Object> JsonParser<seq_one_byte>::ParseJsonNumber() { |
| 523 bool negative = false; | 586 bool negative = false; |
| 524 int beg_pos = position_; | 587 int beg_pos = position_; |
| 525 if (c0_ == '-') { | 588 if (c0_ == '-') { |
| 526 Advance(); | 589 Advance(); |
| 527 negative = true; | 590 negative = true; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 AdvanceSkipWhitespace(); | 880 AdvanceSkipWhitespace(); |
| 818 return result; | 881 return result; |
| 819 } | 882 } |
| 820 | 883 |
| 821 // Explicit instantiation. | 884 // Explicit instantiation. |
| 822 template class JsonParser<true>; | 885 template class JsonParser<true>; |
| 823 template class JsonParser<false>; | 886 template class JsonParser<false>; |
| 824 | 887 |
| 825 } // namespace internal | 888 } // namespace internal |
| 826 } // namespace v8 | 889 } // namespace v8 |
| OLD | NEW |