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_REGEXP_GEN_H_
6 #define V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
7 
8 #include "src/code-stub-assembler.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 class RegExpBuiltinsAssembler : public CodeStubAssembler {
14  public:
RegExpBuiltinsAssembler(compiler::CodeAssemblerState * state)15   explicit RegExpBuiltinsAssembler(compiler::CodeAssemblerState* state)
16       : CodeStubAssembler(state) {}
17 
18   void BranchIfFastRegExp(Node* const context, Node* const object,
19                           Node* const map, Label* const if_isunmodified,
20                           Label* const if_ismodified);
21 
22   // Create and initialize a RegExp object.
23   TNode<Object> RegExpCreate(TNode<Context> context,
24                              TNode<Context> native_context,
25                              TNode<Object> regexp_string, TNode<String> flags);
26 
27   TNode<Object> RegExpCreate(TNode<Context> context, TNode<Map> initial_map,
28                              TNode<Object> regexp_string, TNode<String> flags);
29 
30   TNode<Object> MatchAllIterator(TNode<Context> context,
31                                  TNode<Context> native_context,
32                                  TNode<Object> regexp, TNode<String> string,
33                                  TNode<BoolT> is_fast_regexp,
34                                  char const* method_name);
35 
36  protected:
37   // Allocate a RegExpResult with the given length (the number of captures,
38   // including the match itself), index (the index where the match starts),
39   // and input string. |length| and |index| are expected to be tagged, and
40   // |input| must be a string.
41   Node* AllocateRegExpResult(Node* context, Node* length, Node* index,
42                              Node* input);
43 
44   Node* FastLoadLastIndex(Node* regexp);
45   Node* SlowLoadLastIndex(Node* context, Node* regexp);
46   Node* LoadLastIndex(Node* context, Node* regexp, bool is_fastpath);
47 
48   void FastStoreLastIndex(Node* regexp, Node* value);
49   void SlowStoreLastIndex(Node* context, Node* regexp, Node* value);
50   void StoreLastIndex(Node* context, Node* regexp, Node* value,
51                       bool is_fastpath);
52 
53   // Loads {var_string_start} and {var_string_end} with the corresponding
54   // offsets into the given {string_data}.
55   void GetStringPointers(Node* const string_data, Node* const offset,
56                          Node* const last_index, Node* const string_length,
57                          String::Encoding encoding, Variable* var_string_start,
58                          Variable* var_string_end);
59 
60   // Low level logic around the actual call into pattern matching code.
61   Node* RegExpExecInternal(Node* const context, Node* const regexp,
62                            Node* const string, Node* const last_index,
63                            Node* const match_info);
64 
65   Node* ConstructNewResultFromMatchInfo(Node* const context, Node* const regexp,
66                                         Node* const match_info,
67                                         TNode<String> const string);
68 
69   Node* RegExpPrototypeExecBodyWithoutResult(Node* const context,
70                                              Node* const regexp,
71                                              Node* const string,
72                                              Label* if_didnotmatch,
73                                              const bool is_fastpath);
74   Node* RegExpPrototypeExecBody(Node* const context, Node* const regexp,
75                                 TNode<String> string, const bool is_fastpath);
76 
77   Node* ThrowIfNotJSReceiver(Node* context, Node* maybe_receiver,
78                              MessageTemplate::Template msg_template,
79                              char const* method_name);
80 
81   // Analogous to BranchIfFastRegExp, for use in asserts.
82   TNode<BoolT> IsFastRegExp(SloppyTNode<Context> context,
83                             SloppyTNode<Object> object);
84 
85   void BranchIfFastRegExp(Node* const context, Node* const object,
86                           Label* const if_isunmodified,
87                           Label* const if_ismodified);
88 
89   // Performs fast path checks on the given object itself, but omits prototype
90   // checks.
91   Node* IsFastRegExpNoPrototype(Node* const context, Node* const object);
92   Node* IsFastRegExpNoPrototype(Node* const context, Node* const object,
93                                 Node* const map);
94 
95   void BranchIfFastRegExpResult(Node* const context, Node* const object,
96                                 Label* if_isunmodified, Label* if_ismodified);
97 
98   Node* FlagsGetter(Node* const context, Node* const regexp, bool is_fastpath);
99 
100   Node* FastFlagGetter(Node* const regexp, JSRegExp::Flag flag);
101   Node* SlowFlagGetter(Node* const context, Node* const regexp,
102                        JSRegExp::Flag flag);
103   Node* FlagGetter(Node* const context, Node* const regexp, JSRegExp::Flag flag,
104                    bool is_fastpath);
105   void FlagGetter(Node* context, Node* receiver, JSRegExp::Flag flag,
106                   int counter, const char* method_name);
107 
108   Node* IsRegExp(Node* const context, Node* const maybe_receiver);
109 
110   Node* RegExpInitialize(Node* const context, Node* const regexp,
111                          Node* const maybe_pattern, Node* const maybe_flags);
112 
113   Node* RegExpExec(Node* context, Node* regexp, Node* string);
114 
115   Node* AdvanceStringIndex(Node* const string, Node* const index,
116                            Node* const is_unicode, bool is_fastpath);
117 
118   void RegExpPrototypeMatchBody(Node* const context, Node* const regexp,
119                                 TNode<String> const string,
120                                 const bool is_fastpath);
121 
122   void RegExpPrototypeSearchBodyFast(Node* const context, Node* const regexp,
123                                      Node* const string);
124   void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp,
125                                      Node* const string);
126 
127   void RegExpPrototypeSplitBody(Node* const context, Node* const regexp,
128                                 TNode<String> const string,
129                                 TNode<Smi> const limit);
130 
131   Node* ReplaceGlobalCallableFastPath(Node* context, Node* regexp, Node* string,
132                                       Node* replace_callable);
133   Node* ReplaceSimpleStringFastPath(Node* context, Node* regexp,
134                                     TNode<String> string,
135                                     TNode<String> replace_string);
136 };
137 
138 }  // namespace internal
139 }  // namespace v8
140 
141 #endif  // V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
142