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 3 // found in the LICENSE file. 4 5 #ifndef V8_BUILTINS_BUILTINS_STRING_GEN_H_ 6 #define V8_BUILTINS_BUILTINS_STRING_GEN_H_ 7 8 #include "src/codegen/code-stub-assembler.h" 9 10 namespace v8 { 11 namespace internal { 12 13 class StringBuiltinsAssembler : public CodeStubAssembler { 14 public: StringBuiltinsAssembler(compiler::CodeAssemblerState * state)15 explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state) 16 : CodeStubAssembler(state) {} 17 18 // ES#sec-getsubstitution 19 TNode<String> GetSubstitution(TNode<Context> context, 20 TNode<String> subject_string, 21 TNode<Smi> match_start_index, 22 TNode<Smi> match_end_index, 23 TNode<String> replace_string); 24 void StringEqual_Core(TNode<String> lhs, TNode<Word32T> lhs_instance_type, 25 TNode<String> rhs, TNode<Word32T> rhs_instance_type, 26 TNode<IntPtrT> length, Label* if_equal, 27 Label* if_not_equal, Label* if_indirect); 28 void BranchIfStringPrimitiveWithNoCustomIteration(TNode<Object> object, 29 TNode<Context> context, 30 Label* if_true, 31 Label* if_false); 32 33 TNode<Int32T> LoadSurrogatePairAt(TNode<String> string, TNode<IntPtrT> length, 34 TNode<IntPtrT> index, 35 UnicodeEncoding encoding); 36 37 TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint); 38 39 // Return a new string object which holds a substring containing the range 40 // [from,to[ of string. 41 // TODO(v8:9880): Fix implementation to use UintPtrT arguments and drop 42 // IntPtrT version once all callers use UintPtrT version. 43 TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from, 44 TNode<IntPtrT> to); SubString(TNode<String> string,TNode<UintPtrT> from,TNode<UintPtrT> to)45 TNode<String> SubString(TNode<String> string, TNode<UintPtrT> from, 46 TNode<UintPtrT> to) { 47 return SubString(string, Signed(from), Signed(to)); 48 } 49 50 // Copies |character_count| elements from |from_string| to |to_string| 51 // starting at the |from_index|'th character. |from_string| and |to_string| 52 // can either be one-byte strings or two-byte strings, although if 53 // |from_string| is two-byte, then |to_string| must be two-byte. 54 // |from_index|, |to_index| and |character_count| must be intptr_ts s.t. 0 <= 55 // |from_index| <= |from_index| + |character_count| <= from_string.length and 56 // 0 <= |to_index| <= |to_index| + |character_count| <= to_string.length. 57 template <typename T> 58 void CopyStringCharacters(TNode<T> from_string, TNode<String> to_string, 59 TNode<IntPtrT> from_index, TNode<IntPtrT> to_index, 60 TNode<IntPtrT> character_count, 61 String::Encoding from_encoding, 62 String::Encoding to_encoding); 63 64 // Torque wrapper methods for CallSearchStringRaw for each combination of 65 // search and subject character widths (char8/char16). This is a workaround 66 // for Torque's current lack of support for extern macros with generics. 67 TNode<IntPtrT> SearchOneByteStringInTwoByteString( 68 const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length, 69 const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length, 70 const TNode<IntPtrT> start_position); 71 TNode<IntPtrT> SearchOneByteStringInOneByteString( 72 const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length, 73 const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length, 74 const TNode<IntPtrT> start_position); 75 TNode<IntPtrT> SearchTwoByteStringInTwoByteString( 76 const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length, 77 const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length, 78 const TNode<IntPtrT> start_position); 79 TNode<IntPtrT> SearchTwoByteStringInOneByteString( 80 const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length, 81 const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length, 82 const TNode<IntPtrT> start_position); 83 TNode<IntPtrT> SearchOneByteInOneByteString( 84 const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length, 85 const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> start_position); 86 87 protected: 88 void StringEqual_Loop(TNode<String> lhs, TNode<Word32T> lhs_instance_type, 89 MachineType lhs_type, TNode<String> rhs, 90 TNode<Word32T> rhs_instance_type, MachineType rhs_type, 91 TNode<IntPtrT> length, Label* if_equal, 92 Label* if_not_equal); 93 TNode<RawPtrT> DirectStringData(TNode<String> string, 94 TNode<Word32T> string_instance_type); 95 96 template <typename SubjectChar, typename PatternChar> 97 TNode<IntPtrT> CallSearchStringRaw(const TNode<RawPtrT> subject_ptr, 98 const TNode<IntPtrT> subject_length, 99 const TNode<RawPtrT> search_ptr, 100 const TNode<IntPtrT> search_length, 101 const TNode<IntPtrT> start_position); 102 103 void GenerateStringEqual(TNode<String> left, TNode<String> right); 104 void GenerateStringRelationalComparison(TNode<String> left, 105 TNode<String> right, Operation op); 106 107 using StringAtAccessor = std::function<TNode<Object>( 108 TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)>; 109 110 const TNode<Smi> IndexOfDollarChar(const TNode<Context> context, 111 const TNode<String> string); 112 113 TNode<JSArray> StringToArray(TNode<NativeContext> context, 114 TNode<String> subject_string, 115 TNode<Smi> subject_length, 116 TNode<Number> limit_number); 117 SmiIsNegative(TNode<Smi> value)118 TNode<BoolT> SmiIsNegative(TNode<Smi> value) { 119 return SmiLessThan(value, SmiConstant(0)); 120 } 121 122 TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left, 123 TNode<String> right); 124 125 TNode<String> StringAdd(TNode<ContextOrEmptyContext> context, 126 TNode<String> left, TNode<String> right); 127 128 // Check if |string| is an indirect (thin or flat cons) string type that can 129 // be dereferenced by DerefIndirectString. 130 void BranchIfCanDerefIndirectString(TNode<String> string, 131 TNode<Int32T> instance_type, 132 Label* can_deref, Label* cannot_deref); 133 // Allocate an appropriate one- or two-byte ConsString with the first and 134 // second parts specified by |left| and |right|. 135 // Unpack an indirect (thin or flat cons) string type. 136 void DerefIndirectString(TVariable<String>* var_string, 137 TNode<Int32T> instance_type); 138 // Check if |var_string| has an indirect (thin or flat cons) string type, and 139 // unpack it if so. 140 void MaybeDerefIndirectString(TVariable<String>* var_string, 141 TNode<Int32T> instance_type, Label* did_deref, 142 Label* cannot_deref); 143 // Check if |var_left| or |var_right| has an indirect (thin or flat cons) 144 // string type, and unpack it/them if so. Fall through if nothing was done. 145 void MaybeDerefIndirectStrings(TVariable<String>* var_left, 146 TNode<Int32T> left_instance_type, 147 TVariable<String>* var_right, 148 TNode<Int32T> right_instance_type, 149 Label* did_something); 150 TNode<String> DerefIndirectString(TNode<String> string, 151 TNode<Int32T> instance_type, 152 Label* cannot_deref); 153 154 // Implements boilerplate logic for {match, split, replace, search} of the 155 // form: 156 // 157 // if (!IS_NULL_OR_UNDEFINED(object)) { 158 // var maybe_function = object[symbol]; 159 // if (!IS_UNDEFINED(maybe_function)) { 160 // return %_Call(maybe_function, ...); 161 // } 162 // } 163 // 164 // Contains fast paths for Smi and RegExp objects. 165 // Important: {regexp_call} may not contain any code that can call into JS. 166 using NodeFunction0 = std::function<void()>; 167 using NodeFunction1 = std::function<void(TNode<Object> fn)>; 168 using DescriptorIndexNameValue = 169 PrototypeCheckAssembler::DescriptorIndexNameValue; 170 void MaybeCallFunctionAtSymbol( 171 const TNode<Context> context, const TNode<Object> object, 172 const TNode<Object> maybe_string, Handle<Symbol> symbol, 173 DescriptorIndexNameValue additional_property_to_check, 174 const NodeFunction0& regexp_call, const NodeFunction1& generic_call); 175 176 private: 177 template <typename T> 178 TNode<String> AllocAndCopyStringCharacters(TNode<T> from, 179 TNode<Int32T> from_instance_type, 180 TNode<IntPtrT> from_index, 181 TNode<IntPtrT> character_count); 182 }; 183 184 } // namespace internal 185 } // namespace v8 186 187 #endif // V8_BUILTINS_BUILTINS_STRING_GEN_H_ 188