• 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  protected:
65   void StringEqual_Loop(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
66                         MachineType lhs_type, TNode<String> rhs,
67                         TNode<Word32T> rhs_instance_type, MachineType rhs_type,
68                         TNode<IntPtrT> length, Label* if_equal,
69                         Label* if_not_equal);
70   TNode<RawPtrT> DirectStringData(TNode<String> string,
71                                   TNode<Word32T> string_instance_type);
72 
73   void DispatchOnStringEncodings(const TNode<Word32T> lhs_instance_type,
74                                  const TNode<Word32T> rhs_instance_type,
75                                  Label* if_one_one, Label* if_one_two,
76                                  Label* if_two_one, Label* if_two_two);
77 
78   template <typename SubjectChar, typename PatternChar>
79   TNode<IntPtrT> CallSearchStringRaw(const TNode<RawPtrT> subject_ptr,
80                                      const TNode<IntPtrT> subject_length,
81                                      const TNode<RawPtrT> search_ptr,
82                                      const TNode<IntPtrT> search_length,
83                                      const TNode<IntPtrT> start_position);
84 
85   TNode<RawPtrT> PointerToStringDataAtIndex(TNode<RawPtrT> string_data,
86                                             TNode<IntPtrT> index,
87                                             String::Encoding encoding);
88 
89   void GenerateStringEqual(TNode<String> left, TNode<String> right);
90   void GenerateStringRelationalComparison(TNode<String> left,
91                                           TNode<String> right, Operation op);
92 
93   using StringAtAccessor = std::function<TNode<Object>(
94       TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)>;
95 
96   void StringIndexOf(const TNode<String> subject_string,
97                      const TNode<String> search_string,
98                      const TNode<Smi> position,
99                      const std::function<void(TNode<Smi>)>& f_return);
100 
101   const TNode<Smi> IndexOfDollarChar(const TNode<Context> context,
102                                      const TNode<String> string);
103 
104   TNode<JSArray> StringToArray(TNode<NativeContext> context,
105                                TNode<String> subject_string,
106                                TNode<Smi> subject_length,
107                                TNode<Number> limit_number);
108 
SmiIsNegative(TNode<Smi> value)109   TNode<BoolT> SmiIsNegative(TNode<Smi> value) {
110     return SmiLessThan(value, SmiConstant(0));
111   }
112 
113   TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left,
114                                    TNode<String> right);
115 
116   TNode<String> StringAdd(TNode<ContextOrEmptyContext> context,
117                           TNode<String> left, TNode<String> right);
118 
119   // Check if |string| is an indirect (thin or flat cons) string type that can
120   // be dereferenced by DerefIndirectString.
121   void BranchIfCanDerefIndirectString(TNode<String> string,
122                                       TNode<Int32T> instance_type,
123                                       Label* can_deref, Label* cannot_deref);
124   // Allocate an appropriate one- or two-byte ConsString with the first and
125   // second parts specified by |left| and |right|.
126   // Unpack an indirect (thin or flat cons) string type.
127   void DerefIndirectString(TVariable<String>* var_string,
128                            TNode<Int32T> instance_type);
129   // Check if |var_string| has an indirect (thin or flat cons) string type, and
130   // unpack it if so.
131   void MaybeDerefIndirectString(TVariable<String>* var_string,
132                                 TNode<Int32T> instance_type, Label* did_deref,
133                                 Label* cannot_deref);
134   // Check if |var_left| or |var_right| has an indirect (thin or flat cons)
135   // string type, and unpack it/them if so. Fall through if nothing was done.
136   void MaybeDerefIndirectStrings(TVariable<String>* var_left,
137                                  TNode<Int32T> left_instance_type,
138                                  TVariable<String>* var_right,
139                                  TNode<Int32T> right_instance_type,
140                                  Label* did_something);
141   TNode<String> DerefIndirectString(TNode<String> string,
142                                     TNode<Int32T> instance_type,
143                                     Label* cannot_deref);
144 
145   // Implements boilerplate logic for {match, split, replace, search} of the
146   // form:
147   //
148   //  if (!IS_NULL_OR_UNDEFINED(object)) {
149   //    var maybe_function = object[symbol];
150   //    if (!IS_UNDEFINED(maybe_function)) {
151   //      return %_Call(maybe_function, ...);
152   //    }
153   //  }
154   //
155   // Contains fast paths for Smi and RegExp objects.
156   // Important: {regexp_call} may not contain any code that can call into JS.
157   using NodeFunction0 = std::function<void()>;
158   using NodeFunction1 = std::function<void(TNode<Object> fn)>;
159   using DescriptorIndexNameValue =
160       PrototypeCheckAssembler::DescriptorIndexNameValue;
161   void MaybeCallFunctionAtSymbol(
162       const TNode<Context> context, const TNode<Object> object,
163       const TNode<Object> maybe_string, Handle<Symbol> symbol,
164       DescriptorIndexNameValue additional_property_to_check,
165       const NodeFunction0& regexp_call, const NodeFunction1& generic_call);
166 
167  private:
168   template <typename T>
169   TNode<String> AllocAndCopyStringCharacters(TNode<T> from,
170                                              TNode<Int32T> from_instance_type,
171                                              TNode<IntPtrT> from_index,
172                                              TNode<IntPtrT> character_count);
173 };
174 
175 class StringIncludesIndexOfAssembler : public StringBuiltinsAssembler {
176  public:
StringIncludesIndexOfAssembler(compiler::CodeAssemblerState * state)177   explicit StringIncludesIndexOfAssembler(compiler::CodeAssemblerState* state)
178       : StringBuiltinsAssembler(state) {}
179 
180  protected:
181   enum SearchVariant { kIncludes, kIndexOf };
182 
183   void Generate(SearchVariant variant, TNode<IntPtrT> argc,
184                 TNode<Context> context);
185 };
186 
187 }  // namespace internal
188 }  // namespace v8
189 
190 #endif  // V8_BUILTINS_BUILTINS_STRING_GEN_H_
191