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/code-stub-assembler.h" 9 10 namespace v8 { 11 namespace internal { 12 13 class StringBuiltinsAssembler : public CodeStubAssembler { 14 public: 15 explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state) 16 : CodeStubAssembler(state) {} 17 18 // ES#sec-getsubstitution 19 Node* GetSubstitution(Node* context, Node* subject_string, 20 Node* match_start_index, Node* match_end_index, 21 Node* replace_string); 22 void StringEqual_Core(Node* context, Node* lhs, Node* lhs_instance_type, 23 Node* rhs, Node* rhs_instance_type, 24 TNode<IntPtrT> length, Label* if_equal, 25 Label* if_not_equal, Label* if_indirect); 26 27 protected: 28 void StringEqual_Loop(Node* lhs, Node* lhs_instance_type, 29 MachineType lhs_type, Node* rhs, 30 Node* rhs_instance_type, MachineType rhs_type, 31 TNode<IntPtrT> length, Label* if_equal, 32 Label* if_not_equal); 33 Node* DirectStringData(Node* string, Node* string_instance_type); 34 35 void DispatchOnStringEncodings(Node* const lhs_instance_type, 36 Node* const rhs_instance_type, 37 Label* if_one_one, Label* if_one_two, 38 Label* if_two_one, Label* if_two_two); 39 40 template <typename SubjectChar, typename PatternChar> 41 Node* CallSearchStringRaw(Node* const subject_ptr, Node* const subject_length, 42 Node* const search_ptr, Node* const search_length, 43 Node* const start_position); 44 45 Node* PointerToStringDataAtIndex(Node* const string_data, Node* const index, 46 String::Encoding encoding); 47 48 // substr and slice have a common way of handling the {start} argument. 49 void ConvertAndBoundsCheckStartArgument(Node* context, Variable* var_start, 50 Node* start, Node* string_length); 51 52 void GenerateStringEqual(Node* context, Node* left, Node* right); 53 void GenerateStringRelationalComparison(Node* context, Node* left, 54 Node* right, Operation op); 55 56 TNode<Smi> ToSmiBetweenZeroAnd(SloppyTNode<Context> context, 57 SloppyTNode<Object> value, 58 SloppyTNode<Smi> limit); 59 60 typedef std::function<TNode<Object>( 61 TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)> 62 StringAtAccessor; 63 64 void GenerateStringAt(const char* method_name, TNode<Context> context, 65 Node* receiver, TNode<Object> maybe_position, 66 TNode<Object> default_return, 67 StringAtAccessor accessor); 68 69 TNode<Int32T> LoadSurrogatePairAt(SloppyTNode<String> string, 70 SloppyTNode<IntPtrT> length, 71 SloppyTNode<IntPtrT> index, 72 UnicodeEncoding encoding); 73 74 void StringIndexOf(Node* const subject_string, Node* const search_string, 75 Node* const position, std::function<void(Node*)> f_return); 76 77 TNode<Smi> IndexOfDollarChar(Node* const context, Node* const string); 78 79 TNode<JSArray> StringToArray(TNode<Context> context, 80 TNode<String> subject_string, 81 TNode<Smi> subject_length, 82 TNode<Number> limit_number); 83 84 void RequireObjectCoercible(Node* const context, Node* const value, 85 const char* method_name); 86 87 TNode<BoolT> SmiIsNegative(TNode<Smi> value) { 88 return SmiLessThan(value, SmiConstant(0)); 89 } 90 91 // Implements boilerplate logic for {match, split, replace, search} of the 92 // form: 93 // 94 // if (!IS_NULL_OR_UNDEFINED(object)) { 95 // var maybe_function = object[symbol]; 96 // if (!IS_UNDEFINED(maybe_function)) { 97 // return %_Call(maybe_function, ...); 98 // } 99 // } 100 // 101 // Contains fast paths for Smi and RegExp objects. 102 // Important: {regexp_call} may not contain any code that can call into JS. 103 typedef std::function<void()> NodeFunction0; 104 typedef std::function<void(Node* fn)> NodeFunction1; 105 void MaybeCallFunctionAtSymbol(Node* const context, Node* const object, 106 Node* const maybe_string, 107 Handle<Symbol> symbol, 108 const NodeFunction0& regexp_call, 109 const NodeFunction1& generic_call); 110 111 void Generate_StringAdd(StringAddFlags flags, PretenureFlag pretenure_flag, 112 Node* context, Node* left, Node* right); 113 }; 114 115 class StringIncludesIndexOfAssembler : public StringBuiltinsAssembler { 116 public: 117 explicit StringIncludesIndexOfAssembler(compiler::CodeAssemblerState* state) 118 : StringBuiltinsAssembler(state) {} 119 120 protected: 121 enum SearchVariant { kIncludes, kIndexOf }; 122 123 void Generate(SearchVariant variant, TNode<IntPtrT> argc, 124 TNode<Context> context); 125 }; 126 127 class StringTrimAssembler : public StringBuiltinsAssembler { 128 public: 129 explicit StringTrimAssembler(compiler::CodeAssemblerState* state) 130 : StringBuiltinsAssembler(state) {} 131 132 void GotoIfNotWhiteSpaceOrLineTerminator(Node* const char_code, 133 Label* const if_not_whitespace); 134 135 protected: 136 void Generate(String::TrimMode mode, const char* method, TNode<IntPtrT> argc, 137 TNode<Context> context); 138 139 void ScanForNonWhiteSpaceOrLineTerminator(Node* const string_data, 140 Node* const string_data_offset, 141 Node* const is_stringonebyte, 142 Variable* const var_index, 143 Node* const end, int increment, 144 Label* const if_none_found); 145 146 void BuildLoop(Variable* const var_index, Node* const end, int increment, 147 Label* const if_none_found, Label* const out, 148 std::function<Node*(Node*)> get_character); 149 }; 150 151 } // namespace internal 152 } // namespace v8 153 154 #endif // V8_BUILTINS_BUILTINS_STRING_GEN_H_ 155