Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-regexp-gen.h" | 5 #include "src/builtins/builtins-regexp-gen.h" |
| 6 #include "src/builtins/builtins-utils-gen.h" | 6 #include "src/builtins/builtins-utils-gen.h" |
| 7 #include "src/builtins/builtins.h" | 7 #include "src/builtins/builtins.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 Int32Constant(kShortExternalStringTag))); | 52 Int32Constant(kShortExternalStringTag))); |
| 53 var_data.Bind(LoadObjectField(string, ExternalString::kResourceDataOffset, | 53 var_data.Bind(LoadObjectField(string, ExternalString::kResourceDataOffset, |
| 54 MachineType::Pointer())); | 54 MachineType::Pointer())); |
| 55 Goto(&if_join); | 55 Goto(&if_join); |
| 56 } | 56 } |
| 57 | 57 |
| 58 BIND(&if_join); | 58 BIND(&if_join); |
| 59 return var_data.value(); | 59 return var_data.value(); |
| 60 } | 60 } |
| 61 | 61 |
| 62 Node* LoadOneByteChar(Node* string, Node* index) { | 62 void DispatchOnStringEncodings(Node* const lhs_instance_type, |
| 63 return Load(MachineType::Uint8(), string, OneByteCharOffset(index)); | 63 Node* const rhs_instance_type, |
| 64 Label* if_one_one, Label* if_one_two, | |
| 65 Label* if_two_one, Label* if_two_two) { | |
| 66 STATIC_ASSERT(kStringEncodingMask == 0x8); | |
| 67 STATIC_ASSERT(kTwoByteStringTag == 0x0); | |
| 68 STATIC_ASSERT(kOneByteStringTag == 0x8); | |
| 69 | |
| 70 // First combine the encodings. | |
| 71 | |
| 72 Node* const encoding_mask = Int32Constant(kStringEncodingMask); | |
| 73 Node* const lhs_encoding = Word32And(lhs_instance_type, encoding_mask); | |
| 74 Node* const rhs_encoding = Word32And(rhs_instance_type, encoding_mask); | |
| 75 | |
| 76 Node* const combined_encodings = | |
| 77 Word32Or(lhs_encoding, Word32Shr(rhs_encoding, 1)); | |
| 78 | |
| 79 // Then dispatch on the combined encoding. | |
| 80 | |
| 81 Label unreachable(this, Label::kDeferred); | |
| 82 | |
| 83 int32_t values[] = { | |
| 84 kOneByteStringTag | (kOneByteStringTag >> 1), | |
| 85 kOneByteStringTag | (kTwoByteStringTag >> 1), | |
| 86 kTwoByteStringTag | (kOneByteStringTag >> 1), | |
| 87 kTwoByteStringTag | (kTwoByteStringTag >> 1), | |
| 88 }; | |
| 89 Label* labels[] = { | |
| 90 if_one_one, if_one_two, if_two_one, if_two_two, | |
| 91 }; | |
| 92 | |
| 93 STATIC_ASSERT(arraysize(values) == arraysize(labels)); | |
| 94 Switch(combined_encodings, &unreachable, values, labels, arraysize(values)); | |
| 95 | |
| 96 BIND(&unreachable); | |
| 97 Unreachable(); | |
| 64 } | 98 } |
| 65 | 99 |
| 66 Node* OneByteCharAddress(Node* string, Node* index) { | 100 template <typename SubjectChar, typename PatternChar> |
| 67 Node* offset = OneByteCharOffset(index); | 101 Node* CallSearchStringRaw(Node* const subject_ptr, Node* const subject_length, |
| 68 return IntPtrAdd(string, offset); | 102 Node* const search_ptr, Node* const search_length, |
| 103 Node* const start_position) { | |
| 104 Node* const function_addr = ExternalConstant( | |
| 105 ExternalReference::search_string_raw<SubjectChar, PatternChar>( | |
| 106 isolate())); | |
| 107 Node* const isolate_ptr = | |
| 108 ExternalConstant(ExternalReference::isolate_address(isolate())); | |
|
Camillo Bruni
2017/04/18 14:12:36
I presume this is faster than just doing it in C++
jgruber
2017/04/19 06:59:05
I'm not sure how we would fetch the current isolat
| |
| 109 | |
| 110 MachineType type_ptr = MachineType::Pointer(); | |
| 111 MachineType type_intptr = MachineType::IntPtr(); | |
| 112 | |
| 113 Node* const result = CallCFunction6( | |
| 114 type_intptr, type_ptr, type_ptr, type_intptr, type_ptr, type_intptr, | |
| 115 type_intptr, function_addr, isolate_ptr, subject_ptr, subject_length, | |
| 116 search_ptr, search_length, start_position); | |
| 117 | |
| 118 return result; | |
| 69 } | 119 } |
| 70 | 120 |
| 71 Node* OneByteCharOffset(Node* index) { | 121 Node* PointerToStringDataAtIndex(Node* const string_data, Node* const index, |
| 72 return CharOffset(String::ONE_BYTE_ENCODING, index); | 122 String::Encoding encoding) { |
| 73 } | 123 const ElementsKind kind = (encoding == String::ONE_BYTE_ENCODING) |
| 124 ? UINT8_ELEMENTS | |
| 125 : UINT16_ELEMENTS; | |
| 74 | 126 |
| 75 Node* CharOffset(String::Encoding encoding, Node* index) { | 127 Node* const offset_in_bytes = |
| 76 const int header = SeqOneByteString::kHeaderSize - kHeapObjectTag; | 128 ElementOffsetFromIndex(index, kind, INTPTR_PARAMETERS); |
| 77 Node* offset = index; | 129 return IntPtrAdd(string_data, offset_in_bytes); |
| 78 if (encoding == String::TWO_BYTE_ENCODING) { | |
| 79 offset = IntPtrAdd(offset, offset); | |
| 80 } | |
| 81 offset = IntPtrAdd(offset, IntPtrConstant(header)); | |
| 82 return offset; | |
| 83 } | |
| 84 | |
| 85 void DispatchOnStringInstanceType(Node* const instance_type, | |
| 86 Label* if_onebyte_sequential, | |
| 87 Label* if_onebyte_external, | |
| 88 Label* if_otherwise) { | |
| 89 const int kMask = kStringRepresentationMask | kStringEncodingMask; | |
| 90 Node* const encoding_and_representation = | |
| 91 Word32And(instance_type, Int32Constant(kMask)); | |
| 92 | |
| 93 int32_t values[] = { | |
| 94 kOneByteStringTag | kSeqStringTag, | |
| 95 kOneByteStringTag | kExternalStringTag, | |
| 96 }; | |
| 97 Label* labels[] = { | |
| 98 if_onebyte_sequential, if_onebyte_external, | |
| 99 }; | |
| 100 STATIC_ASSERT(arraysize(values) == arraysize(labels)); | |
| 101 | |
| 102 Switch(encoding_and_representation, if_otherwise, values, labels, | |
| 103 arraysize(values)); | |
| 104 } | 130 } |
| 105 | 131 |
| 106 void GenerateStringEqual(Node* context, Node* left, Node* right); | 132 void GenerateStringEqual(Node* context, Node* left, Node* right); |
| 107 void GenerateStringRelationalComparison(Node* context, Node* left, | 133 void GenerateStringRelationalComparison(Node* context, Node* left, |
| 108 Node* right, | 134 Node* right, |
| 109 RelationalComparisonMode mode); | 135 RelationalComparisonMode mode); |
| 110 | 136 |
| 111 Node* ToSmiBetweenZeroAnd(Node* context, Node* value, Node* limit); | 137 Node* ToSmiBetweenZeroAnd(Node* context, Node* value, Node* limit); |
| 112 | 138 |
| 113 Node* LoadSurrogatePairAt(Node* string, Node* length, Node* index, | 139 Node* LoadSurrogatePairAt(Node* string, Node* length, Node* index, |
| 114 UnicodeEncoding encoding); | 140 UnicodeEncoding encoding); |
| 115 | 141 |
| 116 void StringIndexOf(Node* receiver, Node* instance_type, Node* search_string, | 142 void StringIndexOf(Node* const subject_string, |
| 117 Node* search_string_instance_type, Node* position, | 143 Node* const subject_instance_type, |
| 144 Node* const search_string, | |
| 145 Node* const search_instance_type, Node* const position, | |
| 118 std::function<void(Node*)> f_return); | 146 std::function<void(Node*)> f_return); |
| 119 | 147 |
| 120 Node* IndexOfDollarChar(Node* const context, Node* const string); | 148 Node* IndexOfDollarChar(Node* const context, Node* const string); |
| 121 | 149 |
| 122 Node* IsNullOrUndefined(Node* const value); | 150 Node* IsNullOrUndefined(Node* const value); |
| 123 void RequireObjectCoercible(Node* const context, Node* const value, | 151 void RequireObjectCoercible(Node* const context, Node* const value, |
| 124 const char* method_name); | 152 const char* method_name); |
| 125 | 153 |
| 126 Node* SmiIsNegative(Node* const value) { | 154 Node* SmiIsNegative(Node* const value) { |
| 127 return SmiLessThan(value, SmiConstant(0)); | 155 return SmiLessThan(value, SmiConstant(0)); |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 CodeStubAssembler::VariableList({&var_result}, zone()), | 733 CodeStubAssembler::VariableList({&var_result}, zone()), |
| 706 [this, context, &var_result](Node* arg) { | 734 [this, context, &var_result](Node* arg) { |
| 707 arg = CallStub(CodeFactory::ToString(isolate()), context, arg); | 735 arg = CallStub(CodeFactory::ToString(isolate()), context, arg); |
| 708 var_result.Bind(CallStub(CodeFactory::StringAdd(isolate()), context, | 736 var_result.Bind(CallStub(CodeFactory::StringAdd(isolate()), context, |
| 709 var_result.value(), arg)); | 737 var_result.value(), arg)); |
| 710 }); | 738 }); |
| 711 arguments.PopAndReturn(var_result.value()); | 739 arguments.PopAndReturn(var_result.value()); |
| 712 } | 740 } |
| 713 | 741 |
| 714 void StringBuiltinsAssembler::StringIndexOf( | 742 void StringBuiltinsAssembler::StringIndexOf( |
| 715 Node* receiver, Node* instance_type, Node* search_string, | 743 Node* const subject_string, Node* const subject_instance_type, |
| 716 Node* search_string_instance_type, Node* position, | 744 Node* const search_string, Node* const search_instance_type, |
| 717 std::function<void(Node*)> f_return) { | 745 Node* const position, std::function<void(Node*)> f_return) { |
| 718 CSA_ASSERT(this, IsString(receiver)); | 746 CSA_ASSERT(this, IsString(subject_string)); |
| 719 CSA_ASSERT(this, IsString(search_string)); | 747 CSA_ASSERT(this, IsString(search_string)); |
| 720 CSA_ASSERT(this, TaggedIsSmi(position)); | 748 CSA_ASSERT(this, TaggedIsSmi(position)); |
| 721 | 749 |
| 722 Label zero_length_needle(this), | 750 Node* const int_zero = IntPtrConstant(0); |
| 723 call_runtime_unchecked(this, Label::kDeferred), return_minus_1(this), | |
| 724 check_search_string(this), continue_fast_path(this); | |
| 725 | 751 |
| 726 Node* const int_zero = IntPtrConstant(0); | |
| 727 VARIABLE(var_needle_byte, MachineType::PointerRepresentation(), int_zero); | 752 VARIABLE(var_needle_byte, MachineType::PointerRepresentation(), int_zero); |
| 728 VARIABLE(var_string_addr, MachineType::PointerRepresentation(), int_zero); | 753 VARIABLE(var_string_addr, MachineType::PointerRepresentation(), int_zero); |
| 729 | 754 |
| 730 Node* needle_length = SmiUntag(LoadStringLength(search_string)); | 755 Node* const search_length = SmiUntag(LoadStringLength(search_string)); |
| 731 // Use faster/complex runtime fallback for long search strings. | 756 Node* const subject_length = SmiUntag(LoadStringLength(subject_string)); |
| 732 GotoIf(IntPtrLessThan(IntPtrConstant(1), needle_length), | 757 Node* const start_position = IntPtrMax(SmiUntag(position), int_zero); |
| 733 &call_runtime_unchecked); | |
| 734 Node* string_length = SmiUntag(LoadStringLength(receiver)); | |
| 735 Node* start_position = IntPtrMax(SmiUntag(position), int_zero); | |
| 736 | 758 |
| 737 GotoIf(IntPtrEqual(int_zero, needle_length), &zero_length_needle); | 759 Label zero_length_needle(this), return_minus_1(this); |
| 738 // Check that the needle fits in the start position. | 760 { |
| 739 GotoIfNot(IntPtrLessThanOrEqual(needle_length, | 761 GotoIf(IntPtrEqual(int_zero, search_length), &zero_length_needle); |
| 740 IntPtrSub(string_length, start_position)), | |
| 741 &return_minus_1); | |
| 742 | 762 |
| 743 // Load the string address. | 763 // Check that the needle fits in the start position. |
| 764 GotoIfNot(IntPtrLessThanOrEqual(search_length, | |
| 765 IntPtrSub(subject_length, start_position)), | |
| 766 &return_minus_1); | |
| 767 } | |
| 768 | |
| 769 // Try to unpack subject and search strings. Bail to runtime if either needs | |
| 770 // to be flattened. | |
| 771 ToDirectStringAssembler subject_to_direct(state(), subject_string); | |
| 772 ToDirectStringAssembler search_to_direct(state(), search_string); | |
| 773 | |
| 774 Label call_runtime_unchecked(this, Label::kDeferred); | |
| 775 | |
| 776 subject_to_direct.TryToDirect(&call_runtime_unchecked); | |
| 777 search_to_direct.TryToDirect(&call_runtime_unchecked); | |
| 778 | |
| 779 // Load pointers to string data. | |
| 780 Node* const subject_ptr = | |
| 781 subject_to_direct.PointerToData(&call_runtime_unchecked); | |
| 782 Node* const search_ptr = | |
| 783 search_to_direct.PointerToData(&call_runtime_unchecked); | |
| 784 | |
| 785 Node* const subject_offset = subject_to_direct.offset(); | |
| 786 Node* const search_offset = search_to_direct.offset(); | |
| 787 | |
| 788 // Like String::IndexOf, the actual matching is done by the optimized | |
| 789 // SearchString method in string-search.h. Dispatch based on string instance | |
| 790 // types, then call straight into C++ for matching. | |
| 791 | |
| 792 CSA_ASSERT(this, IntPtrGreaterThan(search_length, int_zero)); | |
| 793 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(start_position, int_zero)); | |
| 794 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(subject_length, start_position)); | |
| 795 CSA_ASSERT(this, | |
| 796 IntPtrLessThanOrEqual(search_length, | |
| 797 IntPtrSub(subject_length, start_position))); | |
| 798 | |
| 799 Label one_one(this), one_two(this), two_one(this), two_two(this); | |
| 800 DispatchOnStringEncodings(subject_to_direct.instance_type(), | |
| 801 search_to_direct.instance_type(), &one_one, | |
| 802 &one_two, &two_one, &two_two); | |
| 803 | |
| 804 typedef const uint8_t onebyte_t; | |
| 805 typedef const uc16 twobyte_t; | |
| 806 | |
| 807 Bind(&one_one); | |
|
Camillo Bruni
2017/04/18 14:12:36
BIND(&one_one);
jgruber
2017/04/19 06:59:05
Done.
| |
| 744 { | 808 { |
| 745 Label if_onebyte_sequential(this); | 809 Node* const adjusted_subject_ptr = PointerToStringDataAtIndex( |
| 746 Label if_onebyte_external(this, Label::kDeferred); | 810 subject_ptr, subject_offset, String::ONE_BYTE_ENCODING); |
| 811 Node* const adjusted_search_ptr = PointerToStringDataAtIndex( | |
| 812 search_ptr, search_offset, String::ONE_BYTE_ENCODING); | |
| 747 | 813 |
| 748 // Only support one-byte strings on the fast path. | 814 Label direct_memchr_call(this), generic_fast_path(this); |
| 749 DispatchOnStringInstanceType(instance_type, &if_onebyte_sequential, | 815 Branch(IntPtrEqual(search_length, IntPtrConstant(1)), &direct_memchr_call, |
| 750 &if_onebyte_external, &call_runtime_unchecked); | 816 &generic_fast_path); |
| 751 | 817 |
| 752 BIND(&if_onebyte_sequential); | 818 // An additional fast path that calls directly into memchr for 1-length |
| 819 // search strings. | |
| 820 BIND(&direct_memchr_call); | |
| 753 { | 821 { |
| 754 var_string_addr.Bind( | 822 Node* const string_addr = IntPtrAdd(adjusted_subject_ptr, start_position); |
| 755 OneByteCharAddress(BitcastTaggedToWord(receiver), start_position)); | 823 Node* const search_length = IntPtrSub(subject_length, start_position); |
| 756 Goto(&check_search_string); | 824 Node* const search_byte = |
| 825 ChangeInt32ToIntPtr(Load(MachineType::Uint8(), adjusted_search_ptr)); | |
| 826 | |
| 827 Node* const memchr = | |
| 828 ExternalConstant(ExternalReference::libc_memchr_function(isolate())); | |
| 829 Node* const result_address = | |
| 830 CallCFunction3(MachineType::Pointer(), MachineType::Pointer(), | |
| 831 MachineType::IntPtr(), MachineType::UintPtr(), memchr, | |
| 832 string_addr, search_byte, search_length); | |
| 833 GotoIf(WordEqual(result_address, int_zero), &return_minus_1); | |
| 834 Node* const result_index = | |
| 835 IntPtrAdd(IntPtrSub(result_address, string_addr), start_position); | |
| 836 f_return(SmiTag(result_index)); | |
| 757 } | 837 } |
| 758 | 838 |
| 759 BIND(&if_onebyte_external); | 839 BIND(&generic_fast_path); |
| 760 { | 840 { |
| 761 Node* const unpacked = TryDerefExternalString(receiver, instance_type, | 841 Node* const result = CallSearchStringRaw<onebyte_t, onebyte_t>( |
| 762 &call_runtime_unchecked); | 842 adjusted_subject_ptr, subject_length, adjusted_search_ptr, |
| 763 var_string_addr.Bind(OneByteCharAddress(unpacked, start_position)); | 843 search_length, start_position); |
| 764 Goto(&check_search_string); | 844 f_return(SmiTag(result)); |
| 765 } | 845 } |
| 766 } | 846 } |
| 767 | 847 |
| 768 // Load the needle character. | 848 Bind(&one_two); |
|
Camillo Bruni
2017/04/18 14:12:36
BIND(...);
jgruber
2017/04/19 06:59:04
Done.
| |
| 769 BIND(&check_search_string); | |
| 770 { | 849 { |
| 771 Label if_onebyte_sequential(this); | 850 Node* const adjusted_subject_ptr = PointerToStringDataAtIndex( |
| 772 Label if_onebyte_external(this, Label::kDeferred); | 851 subject_ptr, subject_offset, String::ONE_BYTE_ENCODING); |
| 852 Node* const adjusted_search_ptr = PointerToStringDataAtIndex( | |
| 853 search_ptr, search_offset, String::TWO_BYTE_ENCODING); | |
| 773 | 854 |
| 774 DispatchOnStringInstanceType(search_string_instance_type, | 855 Node* const result = CallSearchStringRaw<onebyte_t, twobyte_t>( |
| 775 &if_onebyte_sequential, &if_onebyte_external, | 856 adjusted_subject_ptr, subject_length, adjusted_search_ptr, |
| 776 &call_runtime_unchecked); | 857 search_length, start_position); |
| 777 | 858 f_return(SmiTag(result)); |
| 778 BIND(&if_onebyte_sequential); | |
| 779 { | |
| 780 var_needle_byte.Bind( | |
| 781 ChangeInt32ToIntPtr(LoadOneByteChar(search_string, int_zero))); | |
| 782 Goto(&continue_fast_path); | |
| 783 } | |
| 784 | |
| 785 BIND(&if_onebyte_external); | |
| 786 { | |
| 787 Node* const unpacked = TryDerefExternalString( | |
| 788 search_string, search_string_instance_type, &call_runtime_unchecked); | |
| 789 var_needle_byte.Bind( | |
| 790 ChangeInt32ToIntPtr(LoadOneByteChar(unpacked, int_zero))); | |
| 791 Goto(&continue_fast_path); | |
| 792 } | |
| 793 } | 859 } |
| 794 | 860 |
| 795 BIND(&continue_fast_path); | 861 Bind(&two_one); |
|
Camillo Bruni
2017/04/18 14:12:36
BIND(...);
jgruber
2017/04/19 06:59:05
Done.
| |
| 796 { | 862 { |
| 797 Node* needle_byte = var_needle_byte.value(); | 863 Node* const adjusted_subject_ptr = PointerToStringDataAtIndex( |
| 798 Node* string_addr = var_string_addr.value(); | 864 subject_ptr, subject_offset, String::TWO_BYTE_ENCODING); |
| 799 Node* search_length = IntPtrSub(string_length, start_position); | 865 Node* const adjusted_search_ptr = PointerToStringDataAtIndex( |
| 800 // Call out to the highly optimized memchr to perform the actual byte | 866 search_ptr, search_offset, String::ONE_BYTE_ENCODING); |
| 801 // search. | 867 |
| 802 Node* memchr = | 868 Node* const result = CallSearchStringRaw<twobyte_t, onebyte_t>( |
| 803 ExternalConstant(ExternalReference::libc_memchr_function(isolate())); | 869 adjusted_subject_ptr, subject_length, adjusted_search_ptr, |
| 804 Node* result_address = | 870 search_length, start_position); |
| 805 CallCFunction3(MachineType::Pointer(), MachineType::Pointer(), | 871 f_return(SmiTag(result)); |
| 806 MachineType::IntPtr(), MachineType::UintPtr(), memchr, | 872 } |
| 807 string_addr, needle_byte, search_length); | 873 |
| 808 GotoIf(WordEqual(result_address, int_zero), &return_minus_1); | 874 Bind(&two_two); |
|
Camillo Bruni
2017/04/18 14:12:36
BIND(...);
jgruber
2017/04/19 06:59:04
Done.
| |
| 809 Node* result_index = | 875 { |
| 810 IntPtrAdd(IntPtrSub(result_address, string_addr), start_position); | 876 Node* const adjusted_subject_ptr = PointerToStringDataAtIndex( |
| 811 f_return(SmiTag(result_index)); | 877 subject_ptr, subject_offset, String::TWO_BYTE_ENCODING); |
| 878 Node* const adjusted_search_ptr = PointerToStringDataAtIndex( | |
| 879 search_ptr, search_offset, String::TWO_BYTE_ENCODING); | |
| 880 | |
| 881 Node* const result = CallSearchStringRaw<twobyte_t, twobyte_t>( | |
| 882 adjusted_subject_ptr, subject_length, adjusted_search_ptr, | |
| 883 search_length, start_position); | |
| 884 f_return(SmiTag(result)); | |
| 812 } | 885 } |
| 813 | 886 |
| 814 BIND(&return_minus_1); | 887 BIND(&return_minus_1); |
| 815 f_return(SmiConstant(-1)); | 888 f_return(SmiConstant(-1)); |
| 816 | 889 |
| 817 BIND(&zero_length_needle); | 890 BIND(&zero_length_needle); |
| 818 { | 891 { |
| 819 Comment("0-length search_string"); | 892 Comment("0-length search_string"); |
| 820 f_return(SmiTag(IntPtrMin(string_length, start_position))); | 893 f_return(SmiTag(IntPtrMin(subject_length, start_position))); |
| 821 } | 894 } |
| 822 | 895 |
| 823 BIND(&call_runtime_unchecked); | 896 BIND(&call_runtime_unchecked); |
| 824 { | 897 { |
| 825 // Simplified version of the runtime call where the types of the arguments | 898 // Simplified version of the runtime call where the types of the arguments |
| 826 // are already known due to type checks in this stub. | 899 // are already known due to type checks in this stub. |
| 827 Comment("Call Runtime Unchecked"); | 900 Comment("Call Runtime Unchecked"); |
| 828 Node* result = CallRuntime(Runtime::kStringIndexOfUnchecked, SmiConstant(0), | 901 Node* result = CallRuntime(Runtime::kStringIndexOfUnchecked, SmiConstant(0), |
| 829 receiver, search_string, position); | 902 subject_string, search_string, position); |
| 830 f_return(result); | 903 f_return(result); |
| 831 } | 904 } |
| 832 } | 905 } |
| 833 | 906 |
| 834 // ES6 String.prototype.indexOf(searchString [, position]) | 907 // ES6 String.prototype.indexOf(searchString [, position]) |
| 835 // #sec-string.prototype.indexof | 908 // #sec-string.prototype.indexof |
| 836 // Unchecked helper for builtins lowering. | 909 // Unchecked helper for builtins lowering. |
| 837 TF_BUILTIN(StringIndexOf, StringBuiltinsAssembler) { | 910 TF_BUILTIN(StringIndexOf, StringBuiltinsAssembler) { |
| 838 Node* receiver = Parameter(Descriptor::kReceiver); | 911 Node* receiver = Parameter(Descriptor::kReceiver); |
| 839 Node* search_string = Parameter(Descriptor::kSearchString); | 912 Node* search_string = Parameter(Descriptor::kSearchString); |
| (...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1706 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, | 1779 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, |
| 1707 HeapConstant(factory()->NewStringFromAsciiChecked( | 1780 HeapConstant(factory()->NewStringFromAsciiChecked( |
| 1708 "String Iterator.prototype.next", TENURED)), | 1781 "String Iterator.prototype.next", TENURED)), |
| 1709 iterator); | 1782 iterator); |
| 1710 Unreachable(); | 1783 Unreachable(); |
| 1711 } | 1784 } |
| 1712 } | 1785 } |
| 1713 | 1786 |
| 1714 } // namespace internal | 1787 } // namespace internal |
| 1715 } // namespace v8 | 1788 } // namespace v8 |
| OLD | NEW |