• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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