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 |