| 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/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 typedef compiler::Node Node; | 509 typedef compiler::Node Node; |
| 510 | 510 |
| 511 Node* receiver = assembler->Parameter(0); | 511 Node* receiver = assembler->Parameter(0); |
| 512 Node* context = assembler->Parameter(3); | 512 Node* context = assembler->Parameter(3); |
| 513 | 513 |
| 514 Node* result = assembler->ToThisValue( | 514 Node* result = assembler->ToThisValue( |
| 515 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); | 515 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); |
| 516 assembler->Return(result); | 516 assembler->Return(result); |
| 517 } | 517 } |
| 518 | 518 |
| 519 void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) { | 519 BUILTIN(StringPrototypeIterator) { |
| 520 typedef CodeStubAssembler::Label Label; | 520 HandleScope scope(isolate); |
| 521 typedef compiler::Node Node; | 521 TO_THIS_STRING(object, "String.prototype[Symbol.iterator]"); |
| 522 typedef CodeStubAssembler::Variable Variable; | |
| 523 | 522 |
| 524 Variable var_string(assembler, MachineRepresentation::kTagged); | 523 Handle<String> string; |
| 525 Variable var_index(assembler, MachineRepresentation::kTagged); | 524 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, |
| 525 Object::ToString(isolate, object)); |
| 526 | 526 |
| 527 Variable* loop_inputs[] = {&var_string, &var_index}; | 527 return *isolate->factory()->NewJSStringIterator(string); |
| 528 Label loop(assembler, 2, loop_inputs); | |
| 529 Label allocate_iterator(assembler); | |
| 530 | |
| 531 Node* receiver = assembler->Parameter(0); | |
| 532 Node* context = assembler->Parameter(3); | |
| 533 | |
| 534 Node* string = assembler->ToThisString(context, receiver, | |
| 535 "String.prototype[Symbol.iterator]"); | |
| 536 var_string.Bind(string); | |
| 537 var_index.Bind(assembler->SmiConstant(Smi::FromInt(0))); | |
| 538 | |
| 539 assembler->Goto(&loop); | |
| 540 assembler->Bind(&loop); | |
| 541 { | |
| 542 // Load the instance type of the {string}. | |
| 543 Node* string_instance_type = assembler->LoadInstanceType(string); | |
| 544 | |
| 545 // Check if the {string} is a SeqString. | |
| 546 Label if_stringisnotsequential(assembler); | |
| 547 assembler->Branch(assembler->Word32Equal( | |
| 548 assembler->Word32And(string_instance_type, | |
| 549 assembler->Int32Constant( | |
| 550 kStringRepresentationMask)), | |
| 551 assembler->Int32Constant(kSeqStringTag)), | |
| 552 &allocate_iterator, &if_stringisnotsequential); | |
| 553 | |
| 554 assembler->Bind(&if_stringisnotsequential); | |
| 555 { | |
| 556 // Check if the {string} is a ConsString. | |
| 557 Label if_stringiscons(assembler), if_stringisnotcons(assembler); | |
| 558 assembler->Branch( | |
| 559 assembler->Word32Equal( | |
| 560 assembler->Word32And( | |
| 561 string_instance_type, | |
| 562 assembler->Int32Constant(kStringRepresentationMask)), | |
| 563 assembler->Int32Constant(kConsStringTag)), | |
| 564 &if_stringiscons, &if_stringisnotcons); | |
| 565 | |
| 566 assembler->Bind(&if_stringiscons); | |
| 567 { | |
| 568 // Flatten cons-string and finish. | |
| 569 var_string.Bind(assembler->CallRuntime( | |
| 570 Runtime::kFlattenString, assembler->NoContextConstant(), string)); | |
| 571 assembler->Goto(&allocate_iterator); | |
| 572 } | |
| 573 | |
| 574 assembler->Bind(&if_stringisnotcons); | |
| 575 { | |
| 576 // Check if the {string} is an ExternalString. | |
| 577 Label if_stringisnotexternal(assembler); | |
| 578 assembler->Branch( | |
| 579 assembler->Word32Equal( | |
| 580 assembler->Word32And( | |
| 581 string_instance_type, | |
| 582 assembler->Int32Constant(kStringRepresentationMask)), | |
| 583 assembler->Int32Constant(kExternalStringTag)), | |
| 584 &allocate_iterator, &if_stringisnotexternal); | |
| 585 | |
| 586 assembler->Bind(&if_stringisnotexternal); | |
| 587 { | |
| 588 // The {string} is a SlicedString, continue with its parent. | |
| 589 Node* index = var_index.value(); | |
| 590 Node* string_offset = | |
| 591 assembler->LoadObjectField(string, SlicedString::kOffsetOffset); | |
| 592 Node* string_parent = | |
| 593 assembler->LoadObjectField(string, SlicedString::kParentOffset); | |
| 594 var_index.Bind(assembler->SmiAdd(index, string_offset)); | |
| 595 var_string.Bind(string_parent); | |
| 596 assembler->Goto(&loop); | |
| 597 } | |
| 598 } | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 assembler->Bind(&allocate_iterator); | |
| 603 { | |
| 604 Node* native_context = assembler->LoadNativeContext(context); | |
| 605 Node* map = assembler->LoadFixedArrayElement( | |
| 606 native_context, | |
| 607 assembler->IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0, | |
| 608 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 609 Node* iterator = assembler->Allocate(JSStringIterator::kSize); | |
| 610 assembler->StoreMapNoWriteBarrier(iterator, map); | |
| 611 assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset, | |
| 612 Heap::kEmptyFixedArrayRootIndex); | |
| 613 assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset, | |
| 614 Heap::kEmptyFixedArrayRootIndex); | |
| 615 assembler->StoreObjectFieldNoWriteBarrier( | |
| 616 iterator, JSStringIterator::kStringOffset, var_string.value()); | |
| 617 | |
| 618 assembler->StoreObjectFieldNoWriteBarrier( | |
| 619 iterator, JSStringIterator::kNextIndexOffset, var_index.value()); | |
| 620 assembler->Return(iterator); | |
| 621 } | |
| 622 } | 528 } |
| 623 | 529 |
| 624 namespace { | 530 BUILTIN(StringIteratorPrototypeNext) { |
| 531 HandleScope scope(isolate); |
| 625 | 532 |
| 626 // Return the |word32| codepoint at {index}. Supports SeqStrings and | 533 if (!args.receiver()->IsJSStringIterator()) { |
| 627 // ExternalStrings. | 534 Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked( |
| 628 compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler, | 535 "String Iterator.prototype.next"); |
| 629 compiler::Node* string, | 536 THROW_NEW_ERROR_RETURN_FAILURE( |
| 630 compiler::Node* length, | 537 isolate, |
| 631 compiler::Node* index, | 538 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason)); |
| 632 UnicodeEncoding encoding) { | 539 } |
| 633 typedef CodeStubAssembler::Label Label; | 540 Handle<JSStringIterator> iterator = |
| 634 typedef compiler::Node Node; | 541 Handle<JSStringIterator>::cast(args.receiver()); |
| 635 typedef CodeStubAssembler::Variable Variable; | 542 Handle<String> string(iterator->string()); |
| 636 Label handle_surrogate_pair(assembler), return_result(assembler); | |
| 637 Variable var_result(assembler, MachineRepresentation::kWord32); | |
| 638 Variable var_trail(assembler, MachineRepresentation::kWord16); | |
| 639 var_result.Bind(assembler->Int32Constant(0)); | |
| 640 var_trail.Bind(assembler->Int32Constant(0)); | |
| 641 | 543 |
| 642 Node* string_instance_type = assembler->LoadInstanceType(string); | 544 int position = iterator->index(); |
| 545 int length = string->length(); |
| 643 | 546 |
| 644 Label if_stringissequential(assembler), if_stringisexternal(assembler); | 547 if (position < length) { |
| 645 assembler->Branch(assembler->Word32Equal( | 548 uint16_t lead = string->Get(position); |
| 646 assembler->Word32And(string_instance_type, | 549 if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) { |
| 647 assembler->Int32Constant( | 550 uint16_t trail = string->Get(position + 1); |
| 648 kStringRepresentationMask)), | 551 if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) { |
| 649 assembler->Int32Constant(kSeqStringTag)), | 552 // Return surrogate pair code units |
| 650 &if_stringissequential, &if_stringisexternal); | 553 iterator->set_index(position + 2); |
| 651 | 554 Handle<String> value = |
| 652 assembler->Bind(&if_stringissequential); | 555 isolate->factory()->NewSurrogatePairString(lead, trail); |
| 653 { | 556 return *isolate->factory()->NewJSIteratorResult(value, false); |
| 654 Label if_stringisonebyte(assembler), if_stringistwobyte(assembler); | |
| 655 assembler->Branch( | |
| 656 assembler->Word32Equal( | |
| 657 assembler->Word32And(string_instance_type, | |
| 658 assembler->Int32Constant(kStringEncodingMask)), | |
| 659 assembler->Int32Constant(kOneByteStringTag)), | |
| 660 &if_stringisonebyte, &if_stringistwobyte); | |
| 661 | |
| 662 assembler->Bind(&if_stringisonebyte); | |
| 663 { | |
| 664 var_result.Bind(assembler->Load( | |
| 665 MachineType::Uint8(), string, | |
| 666 assembler->IntPtrAdd( | |
| 667 index, assembler->IntPtrConstant(SeqOneByteString::kHeaderSize - | |
| 668 kHeapObjectTag)))); | |
| 669 assembler->Goto(&return_result); | |
| 670 } | |
| 671 | |
| 672 assembler->Bind(&if_stringistwobyte); | |
| 673 { | |
| 674 Node* lead = assembler->Load( | |
| 675 MachineType::Uint16(), string, | |
| 676 assembler->IntPtrAdd( | |
| 677 assembler->WordShl(index, assembler->IntPtrConstant(1)), | |
| 678 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - | |
| 679 kHeapObjectTag))); | |
| 680 var_result.Bind(lead); | |
| 681 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); | |
| 682 | |
| 683 Label if_isdoublecodeunit(assembler); | |
| 684 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), | |
| 685 &return_result); | |
| 686 assembler->GotoIf( | |
| 687 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), | |
| 688 &return_result); | |
| 689 assembler->Branch( | |
| 690 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), | |
| 691 &if_isdoublecodeunit, &return_result); | |
| 692 | |
| 693 assembler->Bind(&if_isdoublecodeunit); | |
| 694 { | |
| 695 Node* trail = assembler->Load( | |
| 696 MachineType::Uint16(), string, | |
| 697 assembler->IntPtrAdd( | |
| 698 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), | |
| 699 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - | |
| 700 kHeapObjectTag))); | |
| 701 assembler->GotoIf( | |
| 702 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), | |
| 703 &return_result); | |
| 704 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( | |
| 705 trail, assembler->Int32Constant(0xE000)), | |
| 706 &return_result); | |
| 707 | |
| 708 var_trail.Bind(trail); | |
| 709 assembler->Goto(&handle_surrogate_pair); | |
| 710 } | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 assembler->Bind(&if_stringisexternal); | |
| 715 { | |
| 716 assembler->Assert(assembler->Word32Equal( | |
| 717 assembler->Word32And( | |
| 718 string_instance_type, | |
| 719 assembler->Int32Constant(kStringRepresentationMask)), | |
| 720 assembler->Int32Constant(kExternalStringTag))); | |
| 721 Label if_stringisshort(assembler), if_stringisnotshort(assembler); | |
| 722 | |
| 723 assembler->Branch(assembler->Word32Equal( | |
| 724 assembler->Word32And(string_instance_type, | |
| 725 assembler->Int32Constant( | |
| 726 kShortExternalStringMask)), | |
| 727 assembler->Int32Constant(0)), | |
| 728 &if_stringisshort, &if_stringisnotshort); | |
| 729 | |
| 730 assembler->Bind(&if_stringisshort); | |
| 731 { | |
| 732 // Load the actual resource data from the {string}. | |
| 733 Node* string_resource_data = assembler->LoadObjectField( | |
| 734 string, ExternalString::kResourceDataOffset, MachineType::Pointer()); | |
| 735 | |
| 736 Label if_stringistwobyte(assembler), if_stringisonebyte(assembler); | |
| 737 assembler->Branch(assembler->Word32Equal( | |
| 738 assembler->Word32And( | |
| 739 string_instance_type, | |
| 740 assembler->Int32Constant(kStringEncodingMask)), | |
| 741 assembler->Int32Constant(kTwoByteStringTag)), | |
| 742 &if_stringistwobyte, &if_stringisonebyte); | |
| 743 | |
| 744 assembler->Bind(&if_stringisonebyte); | |
| 745 { | |
| 746 var_result.Bind( | |
| 747 assembler->Load(MachineType::Uint8(), string_resource_data, index)); | |
| 748 assembler->Goto(&return_result); | |
| 749 } | |
| 750 | |
| 751 assembler->Bind(&if_stringistwobyte); | |
| 752 { | |
| 753 Label if_isdoublecodeunit(assembler); | |
| 754 Node* lead = assembler->Load( | |
| 755 MachineType::Uint16(), string_resource_data, | |
| 756 assembler->WordShl(index, assembler->IntPtrConstant(1))); | |
| 757 var_result.Bind(lead); | |
| 758 Node* next_pos = | |
| 759 assembler->Int32Add(index, assembler->Int32Constant(1)); | |
| 760 | |
| 761 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), | |
| 762 &return_result); | |
| 763 assembler->GotoIf( | |
| 764 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), | |
| 765 &return_result); | |
| 766 assembler->Branch( | |
| 767 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), | |
| 768 &if_isdoublecodeunit, &return_result); | |
| 769 | |
| 770 assembler->Bind(&if_isdoublecodeunit); | |
| 771 { | |
| 772 Node* trail = assembler->Load( | |
| 773 MachineType::Uint16(), string, | |
| 774 assembler->IntPtrAdd( | |
| 775 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), | |
| 776 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - | |
| 777 kHeapObjectTag))); | |
| 778 assembler->GotoIf(assembler->Uint32LessThan( | |
| 779 trail, assembler->Int32Constant(0xDC00)), | |
| 780 &return_result); | |
| 781 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( | |
| 782 trail, assembler->Int32Constant(0xE000)), | |
| 783 &return_result); | |
| 784 | |
| 785 var_trail.Bind(trail); | |
| 786 assembler->Goto(&handle_surrogate_pair); | |
| 787 } | |
| 788 } | 557 } |
| 789 } | 558 } |
| 790 | 559 |
| 791 assembler->Bind(&if_stringisnotshort); | 560 // Return single code unit |
| 792 { | 561 iterator->set_index(position + 1); |
| 793 Label if_isdoublecodeunit(assembler); | 562 Handle<String> value = |
| 794 Node* lead = assembler->SmiToWord32(assembler->CallRuntime( | 563 isolate->factory()->LookupSingleCharacterStringFromCode(lead); |
| 795 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), | 564 return *isolate->factory()->NewJSIteratorResult(value, false); |
| 796 string, assembler->SmiTag(index))); | |
| 797 var_result.Bind(lead); | |
| 798 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); | |
| 799 | |
| 800 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), | |
| 801 &return_result); | |
| 802 assembler->GotoIf( | |
| 803 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), | |
| 804 &return_result); | |
| 805 assembler->Branch(assembler->Uint32GreaterThanOrEqual( | |
| 806 lead, assembler->Int32Constant(0xDC00)), | |
| 807 &return_result, &if_isdoublecodeunit); | |
| 808 | |
| 809 assembler->Bind(&if_isdoublecodeunit); | |
| 810 { | |
| 811 Node* trail = assembler->SmiToWord32(assembler->CallRuntime( | |
| 812 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), | |
| 813 string, assembler->SmiTag(next_pos))); | |
| 814 assembler->GotoIf( | |
| 815 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), | |
| 816 &return_result); | |
| 817 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( | |
| 818 trail, assembler->Int32Constant(0xE000)), | |
| 819 &return_result); | |
| 820 var_trail.Bind(trail); | |
| 821 assembler->Goto(&handle_surrogate_pair); | |
| 822 } | |
| 823 } | |
| 824 } | 565 } |
| 825 | 566 |
| 826 assembler->Bind(&handle_surrogate_pair); | 567 iterator->set_string(isolate->heap()->empty_string()); |
| 827 { | |
| 828 Node* lead = var_result.value(); | |
| 829 Node* trail = var_trail.value(); | |
| 830 #ifdef ENABLE_SLOW_DCHECKS | |
| 831 // Check that this path is only taken if a surrogate pair is found | |
| 832 assembler->Assert(assembler->Uint32GreaterThanOrEqual( | |
| 833 lead, assembler->Int32Constant(0xD800))); | |
| 834 assembler->Assert( | |
| 835 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00))); | |
| 836 assembler->Assert(assembler->Uint32GreaterThanOrEqual( | |
| 837 trail, assembler->Int32Constant(0xDC00))); | |
| 838 assembler->Assert( | |
| 839 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xE000))); | |
| 840 #endif | |
| 841 | 568 |
| 842 switch (encoding) { | 569 return *isolate->factory()->NewJSIteratorResult( |
| 843 case UnicodeEncoding::UTF16: | 570 isolate->factory()->undefined_value(), true); |
| 844 var_result.Bind(assembler->WordOr( | |
| 845 assembler->WordShl(trail, assembler->Int32Constant(16)), lead)); | |
| 846 break; | |
| 847 | |
| 848 case UnicodeEncoding::UTF32: { | |
| 849 // Convert UTF16 surrogate pair into |word32| code point, encoded as | |
| 850 // UTF32. | |
| 851 Node* surrogate_offset = | |
| 852 assembler->Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00); | |
| 853 | |
| 854 // (lead << 10) + trail + SURROGATE_OFFSET | |
| 855 var_result.Bind(assembler->Int32Add( | |
| 856 assembler->WordShl(lead, assembler->Int32Constant(10)), | |
| 857 assembler->Int32Add(trail, surrogate_offset))); | |
| 858 break; | |
| 859 } | |
| 860 } | |
| 861 assembler->Goto(&return_result); | |
| 862 } | |
| 863 | |
| 864 assembler->Bind(&return_result); | |
| 865 return var_result.value(); | |
| 866 } | |
| 867 | |
| 868 compiler::Node* LoadSurrogatePairAt(CodeStubAssembler* assembler, | |
| 869 compiler::Node* string, | |
| 870 compiler::Node* length, | |
| 871 compiler::Node* index) { | |
| 872 return LoadSurrogatePairInternal(assembler, string, length, index, | |
| 873 UnicodeEncoding::UTF16); | |
| 874 } | |
| 875 | |
| 876 } // namespace | |
| 877 | |
| 878 void Builtins::Generate_StringIteratorPrototypeNext( | |
| 879 CodeStubAssembler* assembler) { | |
| 880 typedef CodeStubAssembler::Label Label; | |
| 881 typedef compiler::Node Node; | |
| 882 typedef CodeStubAssembler::Variable Variable; | |
| 883 | |
| 884 Variable var_value(assembler, MachineRepresentation::kTagged); | |
| 885 Variable var_done(assembler, MachineRepresentation::kTagged); | |
| 886 | |
| 887 var_value.Bind(assembler->UndefinedConstant()); | |
| 888 var_done.Bind(assembler->BooleanConstant(true)); | |
| 889 | |
| 890 Label throw_bad_receiver(assembler), next_codepoint(assembler), | |
| 891 return_result(assembler); | |
| 892 | |
| 893 Node* iterator = assembler->Parameter(0); | |
| 894 Node* context = assembler->Parameter(3); | |
| 895 | |
| 896 assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver); | |
| 897 assembler->GotoUnless( | |
| 898 assembler->WordEqual(assembler->LoadInstanceType(iterator), | |
| 899 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), | |
| 900 &throw_bad_receiver); | |
| 901 | |
| 902 Node* string = | |
| 903 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); | |
| 904 Node* position = | |
| 905 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); | |
| 906 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); | |
| 907 | |
| 908 assembler->Branch(assembler->SmiLessThan(position, length), &next_codepoint, | |
| 909 &return_result); | |
| 910 | |
| 911 assembler->Bind(&next_codepoint); | |
| 912 { | |
| 913 Node* ch = | |
| 914 LoadSurrogatePairAt(assembler, string, assembler->SmiUntag(length), | |
| 915 assembler->SmiUntag(position)); | |
| 916 Node* value = assembler->StringFromCodePoint(ch, UnicodeEncoding::UTF16); | |
| 917 var_value.Bind(value); | |
| 918 Node* length = assembler->LoadObjectField(value, String::kLengthOffset); | |
| 919 assembler->StoreObjectFieldNoWriteBarrier( | |
| 920 iterator, JSStringIterator::kNextIndexOffset, | |
| 921 assembler->SmiAdd(position, length)); | |
| 922 var_done.Bind(assembler->BooleanConstant(false)); | |
| 923 assembler->Goto(&return_result); | |
| 924 } | |
| 925 | |
| 926 assembler->Bind(&return_result); | |
| 927 { | |
| 928 Node* native_context = assembler->LoadNativeContext(context); | |
| 929 Node* map = assembler->LoadFixedArrayElement( | |
| 930 native_context, | |
| 931 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, | |
| 932 CodeStubAssembler::INTPTR_PARAMETERS); | |
| 933 Node* result = assembler->Allocate(JSIteratorResult::kSize); | |
| 934 assembler->StoreMapNoWriteBarrier(result, map); | |
| 935 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | |
| 936 Heap::kEmptyFixedArrayRootIndex); | |
| 937 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | |
| 938 Heap::kEmptyFixedArrayRootIndex); | |
| 939 assembler->StoreObjectFieldNoWriteBarrier( | |
| 940 result, JSIteratorResult::kValueOffset, var_value.value()); | |
| 941 assembler->StoreObjectFieldNoWriteBarrier( | |
| 942 result, JSIteratorResult::kDoneOffset, var_done.value()); | |
| 943 assembler->Return(result); | |
| 944 } | |
| 945 | |
| 946 assembler->Bind(&throw_bad_receiver); | |
| 947 { | |
| 948 // The {receiver} is not a valid JSGeneratorObject. | |
| 949 Node* result = assembler->CallRuntime( | |
| 950 Runtime::kThrowIncompatibleMethodReceiver, context, | |
| 951 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | |
| 952 "String Iterator.prototype.next", TENURED)), | |
| 953 iterator); | |
| 954 assembler->Return(result); // Never reached. | |
| 955 } | |
| 956 } | 571 } |
| 957 | 572 |
| 958 } // namespace internal | 573 } // namespace internal |
| 959 } // namespace v8 | 574 } // namespace v8 |
| OLD | NEW |