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 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 typedef compiler::Node Node; | 609 typedef compiler::Node Node; |
610 | 610 |
611 Node* receiver = assembler->Parameter(0); | 611 Node* receiver = assembler->Parameter(0); |
612 Node* context = assembler->Parameter(3); | 612 Node* context = assembler->Parameter(3); |
613 | 613 |
614 Node* result = assembler->ToThisValue( | 614 Node* result = assembler->ToThisValue( |
615 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); | 615 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); |
616 assembler->Return(result); | 616 assembler->Return(result); |
617 } | 617 } |
618 | 618 |
619 BUILTIN(StringPrototypeIterator) { | 619 void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) { |
620 HandleScope scope(isolate); | 620 typedef CodeStubAssembler::Label Label; |
621 TO_THIS_STRING(object, "String.prototype[Symbol.iterator]"); | 621 typedef compiler::Node Node; |
622 | 622 typedef CodeStubAssembler::Variable Variable; |
623 Handle<String> string; | 623 |
624 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, | 624 Variable var_string(assembler, MachineRepresentation::kTagged); |
625 Object::ToString(isolate, object)); | 625 Variable var_index(assembler, MachineRepresentation::kTagged); |
626 | 626 |
627 return *isolate->factory()->NewJSStringIterator(string); | 627 Variable* loop_inputs[] = {&var_string, &var_index}; |
| 628 Label loop(assembler, 2, loop_inputs); |
| 629 Label allocate_iterator(assembler); |
| 630 |
| 631 Node* receiver = assembler->Parameter(0); |
| 632 Node* context = assembler->Parameter(3); |
| 633 |
| 634 Node* string = assembler->ToThisString(context, receiver, |
| 635 "String.prototype[Symbol.iterator]"); |
| 636 var_string.Bind(string); |
| 637 var_index.Bind(assembler->SmiConstant(Smi::FromInt(0))); |
| 638 |
| 639 assembler->Goto(&loop); |
| 640 assembler->Bind(&loop); |
| 641 { |
| 642 // Load the instance type of the {string}. |
| 643 Node* string_instance_type = assembler->LoadInstanceType(string); |
| 644 |
| 645 // Check if the {string} is a SeqString. |
| 646 Label if_stringisnotsequential(assembler); |
| 647 assembler->Branch(assembler->Word32Equal( |
| 648 assembler->Word32And(string_instance_type, |
| 649 assembler->Int32Constant( |
| 650 kStringRepresentationMask)), |
| 651 assembler->Int32Constant(kSeqStringTag)), |
| 652 &allocate_iterator, &if_stringisnotsequential); |
| 653 |
| 654 assembler->Bind(&if_stringisnotsequential); |
| 655 { |
| 656 // Check if the {string} is a ConsString. |
| 657 Label if_stringiscons(assembler), if_stringisnotcons(assembler); |
| 658 assembler->Branch( |
| 659 assembler->Word32Equal( |
| 660 assembler->Word32And( |
| 661 string_instance_type, |
| 662 assembler->Int32Constant(kStringRepresentationMask)), |
| 663 assembler->Int32Constant(kConsStringTag)), |
| 664 &if_stringiscons, &if_stringisnotcons); |
| 665 |
| 666 assembler->Bind(&if_stringiscons); |
| 667 { |
| 668 // Flatten cons-string and finish. |
| 669 var_string.Bind(assembler->CallRuntime( |
| 670 Runtime::kFlattenString, assembler->NoContextConstant(), string)); |
| 671 assembler->Goto(&allocate_iterator); |
| 672 } |
| 673 |
| 674 assembler->Bind(&if_stringisnotcons); |
| 675 { |
| 676 // Check if the {string} is an ExternalString. |
| 677 Label if_stringisnotexternal(assembler); |
| 678 assembler->Branch( |
| 679 assembler->Word32Equal( |
| 680 assembler->Word32And( |
| 681 string_instance_type, |
| 682 assembler->Int32Constant(kStringRepresentationMask)), |
| 683 assembler->Int32Constant(kExternalStringTag)), |
| 684 &allocate_iterator, &if_stringisnotexternal); |
| 685 |
| 686 assembler->Bind(&if_stringisnotexternal); |
| 687 { |
| 688 // The {string} is a SlicedString, continue with its parent. |
| 689 Node* index = var_index.value(); |
| 690 Node* string_offset = |
| 691 assembler->LoadObjectField(string, SlicedString::kOffsetOffset); |
| 692 Node* string_parent = |
| 693 assembler->LoadObjectField(string, SlicedString::kParentOffset); |
| 694 var_index.Bind(assembler->SmiAdd(index, string_offset)); |
| 695 var_string.Bind(string_parent); |
| 696 assembler->Goto(&loop); |
| 697 } |
| 698 } |
| 699 } |
| 700 } |
| 701 |
| 702 assembler->Bind(&allocate_iterator); |
| 703 { |
| 704 Node* native_context = assembler->LoadNativeContext(context); |
| 705 Node* map = assembler->LoadFixedArrayElement( |
| 706 native_context, |
| 707 assembler->IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0, |
| 708 CodeStubAssembler::INTPTR_PARAMETERS); |
| 709 Node* iterator = assembler->Allocate(JSStringIterator::kSize); |
| 710 assembler->StoreMapNoWriteBarrier(iterator, map); |
| 711 assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset, |
| 712 Heap::kEmptyFixedArrayRootIndex); |
| 713 assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset, |
| 714 Heap::kEmptyFixedArrayRootIndex); |
| 715 assembler->StoreObjectFieldNoWriteBarrier( |
| 716 iterator, JSStringIterator::kStringOffset, var_string.value()); |
| 717 |
| 718 assembler->StoreObjectFieldNoWriteBarrier( |
| 719 iterator, JSStringIterator::kNextIndexOffset, var_index.value()); |
| 720 assembler->Return(iterator); |
| 721 } |
628 } | 722 } |
629 | 723 |
630 BUILTIN(StringIteratorPrototypeNext) { | 724 namespace { |
631 HandleScope scope(isolate); | 725 |
632 | 726 // Return the |word32| codepoint at {index}. Supports SeqStrings and |
633 if (!args.receiver()->IsJSStringIterator()) { | 727 // ExternalStrings. |
634 Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked( | 728 compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler, |
635 "String Iterator.prototype.next"); | 729 compiler::Node* string, |
636 THROW_NEW_ERROR_RETURN_FAILURE( | 730 compiler::Node* length, |
637 isolate, | 731 compiler::Node* index, |
638 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason)); | 732 UnicodeEncoding encoding) { |
639 } | 733 typedef CodeStubAssembler::Label Label; |
640 Handle<JSStringIterator> iterator = | 734 typedef compiler::Node Node; |
641 Handle<JSStringIterator>::cast(args.receiver()); | 735 typedef CodeStubAssembler::Variable Variable; |
642 Handle<String> string(iterator->string()); | 736 Label handle_surrogate_pair(assembler), return_result(assembler); |
643 | 737 Variable var_result(assembler, MachineRepresentation::kWord32); |
644 int position = iterator->index(); | 738 Variable var_trail(assembler, MachineRepresentation::kWord16); |
645 int length = string->length(); | 739 var_result.Bind(assembler->Int32Constant(0)); |
646 | 740 var_trail.Bind(assembler->Int32Constant(0)); |
647 if (position < length) { | 741 |
648 uint16_t lead = string->Get(position); | 742 Node* string_instance_type = assembler->LoadInstanceType(string); |
649 if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) { | 743 |
650 uint16_t trail = string->Get(position + 1); | 744 Label if_stringissequential(assembler), if_stringisexternal(assembler); |
651 if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) { | 745 assembler->Branch(assembler->Word32Equal( |
652 // Return surrogate pair code units | 746 assembler->Word32And(string_instance_type, |
653 iterator->set_index(position + 2); | 747 assembler->Int32Constant( |
654 Handle<String> value = | 748 kStringRepresentationMask)), |
655 isolate->factory()->NewSurrogatePairString(lead, trail); | 749 assembler->Int32Constant(kSeqStringTag)), |
656 return *isolate->factory()->NewJSIteratorResult(value, false); | 750 &if_stringissequential, &if_stringisexternal); |
657 } | 751 |
658 } | 752 assembler->Bind(&if_stringissequential); |
659 | 753 { |
660 // Return single code unit | 754 Label if_stringisonebyte(assembler), if_stringistwobyte(assembler); |
661 iterator->set_index(position + 1); | 755 assembler->Branch( |
662 Handle<String> value = | 756 assembler->Word32Equal( |
663 isolate->factory()->LookupSingleCharacterStringFromCode(lead); | 757 assembler->Word32And(string_instance_type, |
664 return *isolate->factory()->NewJSIteratorResult(value, false); | 758 assembler->Int32Constant(kStringEncodingMask)), |
665 } | 759 assembler->Int32Constant(kOneByteStringTag)), |
666 | 760 &if_stringisonebyte, &if_stringistwobyte); |
667 iterator->set_string(isolate->heap()->empty_string()); | 761 |
668 | 762 assembler->Bind(&if_stringisonebyte); |
669 return *isolate->factory()->NewJSIteratorResult( | 763 { |
670 isolate->factory()->undefined_value(), true); | 764 var_result.Bind(assembler->Load( |
| 765 MachineType::Uint8(), string, |
| 766 assembler->IntPtrAdd( |
| 767 index, assembler->IntPtrConstant(SeqOneByteString::kHeaderSize - |
| 768 kHeapObjectTag)))); |
| 769 assembler->Goto(&return_result); |
| 770 } |
| 771 |
| 772 assembler->Bind(&if_stringistwobyte); |
| 773 { |
| 774 Node* lead = assembler->Load( |
| 775 MachineType::Uint16(), string, |
| 776 assembler->IntPtrAdd( |
| 777 assembler->WordShl(index, assembler->IntPtrConstant(1)), |
| 778 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 779 kHeapObjectTag))); |
| 780 var_result.Bind(lead); |
| 781 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 782 |
| 783 Label if_isdoublecodeunit(assembler); |
| 784 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 785 &return_result); |
| 786 assembler->GotoIf( |
| 787 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 788 &return_result); |
| 789 assembler->Branch( |
| 790 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), |
| 791 &if_isdoublecodeunit, &return_result); |
| 792 |
| 793 assembler->Bind(&if_isdoublecodeunit); |
| 794 { |
| 795 Node* trail = assembler->Load( |
| 796 MachineType::Uint16(), string, |
| 797 assembler->IntPtrAdd( |
| 798 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), |
| 799 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 800 kHeapObjectTag))); |
| 801 assembler->GotoIf( |
| 802 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), |
| 803 &return_result); |
| 804 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 805 trail, assembler->Int32Constant(0xE000)), |
| 806 &return_result); |
| 807 |
| 808 var_trail.Bind(trail); |
| 809 assembler->Goto(&handle_surrogate_pair); |
| 810 } |
| 811 } |
| 812 } |
| 813 |
| 814 assembler->Bind(&if_stringisexternal); |
| 815 { |
| 816 assembler->Assert(assembler->Word32Equal( |
| 817 assembler->Word32And( |
| 818 string_instance_type, |
| 819 assembler->Int32Constant(kStringRepresentationMask)), |
| 820 assembler->Int32Constant(kExternalStringTag))); |
| 821 Label if_stringisshort(assembler), if_stringisnotshort(assembler); |
| 822 |
| 823 assembler->Branch(assembler->Word32Equal( |
| 824 assembler->Word32And(string_instance_type, |
| 825 assembler->Int32Constant( |
| 826 kShortExternalStringMask)), |
| 827 assembler->Int32Constant(0)), |
| 828 &if_stringisshort, &if_stringisnotshort); |
| 829 |
| 830 assembler->Bind(&if_stringisshort); |
| 831 { |
| 832 // Load the actual resource data from the {string}. |
| 833 Node* string_resource_data = assembler->LoadObjectField( |
| 834 string, ExternalString::kResourceDataOffset, MachineType::Pointer()); |
| 835 |
| 836 Label if_stringistwobyte(assembler), if_stringisonebyte(assembler); |
| 837 assembler->Branch(assembler->Word32Equal( |
| 838 assembler->Word32And( |
| 839 string_instance_type, |
| 840 assembler->Int32Constant(kStringEncodingMask)), |
| 841 assembler->Int32Constant(kTwoByteStringTag)), |
| 842 &if_stringistwobyte, &if_stringisonebyte); |
| 843 |
| 844 assembler->Bind(&if_stringisonebyte); |
| 845 { |
| 846 var_result.Bind( |
| 847 assembler->Load(MachineType::Uint8(), string_resource_data, index)); |
| 848 assembler->Goto(&return_result); |
| 849 } |
| 850 |
| 851 assembler->Bind(&if_stringistwobyte); |
| 852 { |
| 853 Label if_isdoublecodeunit(assembler); |
| 854 Node* lead = assembler->Load( |
| 855 MachineType::Uint16(), string_resource_data, |
| 856 assembler->WordShl(index, assembler->IntPtrConstant(1))); |
| 857 var_result.Bind(lead); |
| 858 Node* next_pos = |
| 859 assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 860 |
| 861 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 862 &return_result); |
| 863 assembler->GotoIf( |
| 864 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 865 &return_result); |
| 866 assembler->Branch( |
| 867 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), |
| 868 &if_isdoublecodeunit, &return_result); |
| 869 |
| 870 assembler->Bind(&if_isdoublecodeunit); |
| 871 { |
| 872 Node* trail = assembler->Load( |
| 873 MachineType::Uint16(), string, |
| 874 assembler->IntPtrAdd( |
| 875 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), |
| 876 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 877 kHeapObjectTag))); |
| 878 assembler->GotoIf(assembler->Uint32LessThan( |
| 879 trail, assembler->Int32Constant(0xDC00)), |
| 880 &return_result); |
| 881 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 882 trail, assembler->Int32Constant(0xE000)), |
| 883 &return_result); |
| 884 |
| 885 var_trail.Bind(trail); |
| 886 assembler->Goto(&handle_surrogate_pair); |
| 887 } |
| 888 } |
| 889 } |
| 890 |
| 891 assembler->Bind(&if_stringisnotshort); |
| 892 { |
| 893 Label if_isdoublecodeunit(assembler); |
| 894 Node* lead = assembler->SmiToWord32(assembler->CallRuntime( |
| 895 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), |
| 896 string, assembler->SmiTag(index))); |
| 897 var_result.Bind(lead); |
| 898 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 899 |
| 900 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 901 &return_result); |
| 902 assembler->GotoIf( |
| 903 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 904 &return_result); |
| 905 assembler->Branch(assembler->Uint32GreaterThanOrEqual( |
| 906 lead, assembler->Int32Constant(0xDC00)), |
| 907 &return_result, &if_isdoublecodeunit); |
| 908 |
| 909 assembler->Bind(&if_isdoublecodeunit); |
| 910 { |
| 911 Node* trail = assembler->SmiToWord32(assembler->CallRuntime( |
| 912 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), |
| 913 string, assembler->SmiTag(next_pos))); |
| 914 assembler->GotoIf( |
| 915 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), |
| 916 &return_result); |
| 917 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 918 trail, assembler->Int32Constant(0xE000)), |
| 919 &return_result); |
| 920 var_trail.Bind(trail); |
| 921 assembler->Goto(&handle_surrogate_pair); |
| 922 } |
| 923 } |
| 924 } |
| 925 |
| 926 assembler->Bind(&handle_surrogate_pair); |
| 927 { |
| 928 Node* lead = var_result.value(); |
| 929 Node* trail = var_trail.value(); |
| 930 #ifdef ENABLE_SLOW_DCHECKS |
| 931 // Check that this path is only taken if a surrogate pair is found |
| 932 assembler->Assert(assembler->Uint32GreaterThanOrEqual( |
| 933 lead, assembler->Int32Constant(0xD800))); |
| 934 assembler->Assert( |
| 935 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00))); |
| 936 assembler->Assert(assembler->Uint32GreaterThanOrEqual( |
| 937 trail, assembler->Int32Constant(0xDC00))); |
| 938 assembler->Assert( |
| 939 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xE000))); |
| 940 #endif |
| 941 |
| 942 switch (encoding) { |
| 943 case UnicodeEncoding::UTF16: |
| 944 var_result.Bind(assembler->WordOr( |
| 945 assembler->WordShl(trail, assembler->Int32Constant(16)), lead)); |
| 946 break; |
| 947 |
| 948 case UnicodeEncoding::UTF32: { |
| 949 // Convert UTF16 surrogate pair into |word32| code point, encoded as |
| 950 // UTF32. |
| 951 Node* surrogate_offset = |
| 952 assembler->Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00); |
| 953 |
| 954 // (lead << 10) + trail + SURROGATE_OFFSET |
| 955 var_result.Bind(assembler->Int32Add( |
| 956 assembler->WordShl(lead, assembler->Int32Constant(10)), |
| 957 assembler->Int32Add(trail, surrogate_offset))); |
| 958 break; |
| 959 } |
| 960 } |
| 961 assembler->Goto(&return_result); |
| 962 } |
| 963 |
| 964 assembler->Bind(&return_result); |
| 965 return var_result.value(); |
671 } | 966 } |
672 | 967 |
| 968 compiler::Node* LoadSurrogatePairAt(CodeStubAssembler* assembler, |
| 969 compiler::Node* string, |
| 970 compiler::Node* length, |
| 971 compiler::Node* index) { |
| 972 return LoadSurrogatePairInternal(assembler, string, length, index, |
| 973 UnicodeEncoding::UTF16); |
| 974 } |
| 975 |
| 976 } // namespace |
| 977 |
| 978 void Builtins::Generate_StringIteratorPrototypeNext( |
| 979 CodeStubAssembler* assembler) { |
| 980 typedef CodeStubAssembler::Label Label; |
| 981 typedef compiler::Node Node; |
| 982 typedef CodeStubAssembler::Variable Variable; |
| 983 |
| 984 Variable var_value(assembler, MachineRepresentation::kTagged); |
| 985 Variable var_done(assembler, MachineRepresentation::kTagged); |
| 986 |
| 987 var_value.Bind(assembler->UndefinedConstant()); |
| 988 var_done.Bind(assembler->BooleanConstant(true)); |
| 989 |
| 990 Label throw_bad_receiver(assembler), next_codepoint(assembler), |
| 991 return_result(assembler); |
| 992 |
| 993 Node* iterator = assembler->Parameter(0); |
| 994 Node* context = assembler->Parameter(3); |
| 995 |
| 996 assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver); |
| 997 assembler->GotoUnless( |
| 998 assembler->WordEqual(assembler->LoadInstanceType(iterator), |
| 999 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), |
| 1000 &throw_bad_receiver); |
| 1001 |
| 1002 Node* string = |
| 1003 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); |
| 1004 Node* position = |
| 1005 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); |
| 1006 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); |
| 1007 |
| 1008 assembler->Branch(assembler->SmiLessThan(position, length), &next_codepoint, |
| 1009 &return_result); |
| 1010 |
| 1011 assembler->Bind(&next_codepoint); |
| 1012 { |
| 1013 Node* ch = |
| 1014 LoadSurrogatePairAt(assembler, string, assembler->SmiUntag(length), |
| 1015 assembler->SmiUntag(position)); |
| 1016 Node* value = assembler->StringFromCodePoint(ch, UnicodeEncoding::UTF16); |
| 1017 var_value.Bind(value); |
| 1018 Node* length = assembler->LoadObjectField(value, String::kLengthOffset); |
| 1019 assembler->StoreObjectFieldNoWriteBarrier( |
| 1020 iterator, JSStringIterator::kNextIndexOffset, |
| 1021 assembler->SmiAdd(position, length)); |
| 1022 var_done.Bind(assembler->BooleanConstant(false)); |
| 1023 assembler->Goto(&return_result); |
| 1024 } |
| 1025 |
| 1026 assembler->Bind(&return_result); |
| 1027 { |
| 1028 Node* native_context = assembler->LoadNativeContext(context); |
| 1029 Node* map = assembler->LoadFixedArrayElement( |
| 1030 native_context, |
| 1031 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, |
| 1032 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1033 Node* result = assembler->Allocate(JSIteratorResult::kSize); |
| 1034 assembler->StoreMapNoWriteBarrier(result, map); |
| 1035 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, |
| 1036 Heap::kEmptyFixedArrayRootIndex); |
| 1037 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, |
| 1038 Heap::kEmptyFixedArrayRootIndex); |
| 1039 assembler->StoreObjectFieldNoWriteBarrier( |
| 1040 result, JSIteratorResult::kValueOffset, var_value.value()); |
| 1041 assembler->StoreObjectFieldNoWriteBarrier( |
| 1042 result, JSIteratorResult::kDoneOffset, var_done.value()); |
| 1043 assembler->Return(result); |
| 1044 } |
| 1045 |
| 1046 assembler->Bind(&throw_bad_receiver); |
| 1047 { |
| 1048 // The {receiver} is not a valid JSGeneratorObject. |
| 1049 Node* result = assembler->CallRuntime( |
| 1050 Runtime::kThrowIncompatibleMethodReceiver, context, |
| 1051 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
| 1052 "String Iterator.prototype.next", TENURED)), |
| 1053 iterator); |
| 1054 assembler->Return(result); // Never reached. |
| 1055 } |
| 1056 } |
| 1057 |
673 } // namespace internal | 1058 } // namespace internal |
674 } // namespace v8 | 1059 } // namespace v8 |
OLD | NEW |