Line data Source code
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/base/optional.h"
9 : #include "src/code-stub-assembler.h"
10 : #include "src/message-template.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 2576 : class RegExpBuiltinsAssembler : public CodeStubAssembler {
16 : public:
17 : explicit RegExpBuiltinsAssembler(compiler::CodeAssemblerState* state)
18 2576 : : CodeStubAssembler(state) {}
19 :
20 : void BranchIfFastRegExp(
21 : Node* const context, Node* const object, Node* const map,
22 : base::Optional<DescriptorIndexAndName> additional_property_to_check,
23 : Label* const if_isunmodified, Label* const if_ismodified);
24 :
25 : // Create and initialize a RegExp object.
26 : TNode<Object> RegExpCreate(TNode<Context> context,
27 : TNode<Context> native_context,
28 : TNode<Object> regexp_string, TNode<String> flags);
29 :
30 : TNode<Object> RegExpCreate(TNode<Context> context, TNode<Map> initial_map,
31 : TNode<Object> regexp_string, TNode<String> flags);
32 :
33 : TNode<BoolT> IsRegExp(TNode<Context> context, TNode<Object> maybe_receiver);
34 :
35 : TNode<Smi> SmiZero();
36 : TNode<IntPtrT> IntPtrZero();
37 :
38 : // Allocate a RegExpResult with the given length (the number of captures,
39 : // including the match itself), index (the index where the match starts),
40 : // and input string.
41 : TNode<JSRegExpResult> AllocateRegExpResult(TNode<Context> context,
42 : TNode<Smi> length,
43 : TNode<Smi> index,
44 : TNode<String> input);
45 :
46 : TNode<Object> FastLoadLastIndex(TNode<JSRegExp> regexp);
47 : TNode<Object> SlowLoadLastIndex(TNode<Context> context, TNode<Object> regexp);
48 : TNode<Object> LoadLastIndex(TNode<Context> context, TNode<Object> regexp,
49 : bool is_fastpath);
50 :
51 : void FastStoreLastIndex(Node* regexp, Node* value);
52 : void SlowStoreLastIndex(Node* context, Node* regexp, Node* value);
53 : void StoreLastIndex(Node* context, Node* regexp, Node* value,
54 : bool is_fastpath);
55 :
56 : // Loads {var_string_start} and {var_string_end} with the corresponding
57 : // offsets into the given {string_data}.
58 : void GetStringPointers(Node* const string_data, Node* const offset,
59 : Node* const last_index, Node* const string_length,
60 : String::Encoding encoding, Variable* var_string_start,
61 : Variable* var_string_end);
62 :
63 : // Low level logic around the actual call into pattern matching code.
64 : TNode<HeapObject> RegExpExecInternal(TNode<Context> context,
65 : TNode<JSRegExp> regexp,
66 : TNode<String> string,
67 : TNode<Number> last_index,
68 : TNode<RegExpMatchInfo> match_info);
69 :
70 : TNode<JSRegExpResult> ConstructNewResultFromMatchInfo(
71 : TNode<Context> context, TNode<JSReceiver> maybe_regexp,
72 : TNode<RegExpMatchInfo> match_info, TNode<String> string);
73 :
74 : TNode<RegExpMatchInfo> RegExpPrototypeExecBodyWithoutResult(
75 : TNode<Context> context, TNode<JSReceiver> maybe_regexp,
76 : TNode<String> string, Label* if_didnotmatch, const bool is_fastpath);
77 : TNode<RegExpMatchInfo> RegExpPrototypeExecBodyWithoutResultFast(
78 : TNode<Context> context, TNode<JSReceiver> maybe_regexp,
79 : TNode<String> string, Label* if_didnotmatch);
80 :
81 : TNode<HeapObject> RegExpPrototypeExecBody(TNode<Context> context,
82 : TNode<JSReceiver> maybe_regexp,
83 : TNode<String> string,
84 : const bool is_fastpath);
85 :
86 : Node* ThrowIfNotJSReceiver(Node* context, Node* maybe_receiver,
87 : MessageTemplate msg_template,
88 : char const* method_name);
89 :
90 : // Analogous to BranchIfFastRegExp, for use in asserts.
91 : TNode<BoolT> IsFastRegExp(SloppyTNode<Context> context,
92 : SloppyTNode<Object> object);
93 :
94 : void BranchIfFastRegExp(Node* const context, Node* const object,
95 : Label* const if_isunmodified,
96 : Label* const if_ismodified);
97 :
98 : // Performs fast path checks on the given object itself, but omits prototype
99 : // checks.
100 : Node* IsFastRegExpNoPrototype(Node* const context, Node* const object);
101 : TNode<BoolT> IsFastRegExpWithOriginalExec(TNode<Context> context,
102 : TNode<JSRegExp> object);
103 : Node* IsFastRegExpNoPrototype(Node* const context, Node* const object,
104 : Node* const map);
105 :
106 : void BranchIfFastRegExpResult(Node* const context, Node* const object,
107 : Label* if_isunmodified, Label* if_ismodified);
108 :
109 : Node* FlagsGetter(Node* const context, Node* const regexp, bool is_fastpath);
110 :
111 : TNode<Int32T> FastFlagGetter(TNode<JSRegExp> regexp, JSRegExp::Flag flag);
112 : TNode<BoolT> FastFlagGetterGlobal(TNode<JSRegExp> regexp) {
113 224 : return ReinterpretCast<BoolT>(FastFlagGetter(regexp, JSRegExp::kGlobal));
114 : }
115 : TNode<BoolT> FastFlagGetterUnicode(TNode<JSRegExp> regexp) {
116 112 : return ReinterpretCast<BoolT>(FastFlagGetter(regexp, JSRegExp::kUnicode));
117 : }
118 : TNode<Int32T> SlowFlagGetter(TNode<Context> context, TNode<Object> regexp,
119 : JSRegExp::Flag flag);
120 : TNode<Int32T> FlagGetter(TNode<Context> context, TNode<Object> regexp,
121 : JSRegExp::Flag flag, bool is_fastpath);
122 :
123 : void FlagGetter(Node* context, Node* receiver, JSRegExp::Flag flag,
124 : int counter, const char* method_name);
125 :
126 : Node* RegExpInitialize(Node* const context, Node* const regexp,
127 : Node* const maybe_pattern, Node* const maybe_flags);
128 :
129 : Node* RegExpExec(Node* context, Node* regexp, Node* string);
130 :
131 : Node* AdvanceStringIndex(Node* const string, Node* const index,
132 : Node* const is_unicode, bool is_fastpath);
133 :
134 : Node* AdvanceStringIndexFast(Node* const string, Node* const index,
135 : Node* const is_unicode) {
136 56 : return AdvanceStringIndex(string, index, is_unicode, true);
137 : }
138 :
139 : void RegExpPrototypeMatchBody(Node* const context, Node* const regexp,
140 : TNode<String> const string,
141 : const bool is_fastpath);
142 :
143 : void RegExpPrototypeSearchBodyFast(Node* const context, Node* const regexp,
144 : Node* const string);
145 : void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp,
146 : Node* const string);
147 :
148 : void RegExpPrototypeSplitBody(Node* const context, Node* const regexp,
149 : TNode<String> const string,
150 : TNode<Smi> const limit);
151 :
152 : Node* ReplaceGlobalCallableFastPath(Node* context, Node* regexp, Node* string,
153 : Node* replace_callable);
154 : };
155 :
156 168 : class RegExpMatchAllAssembler : public RegExpBuiltinsAssembler {
157 : public:
158 : explicit RegExpMatchAllAssembler(compiler::CodeAssemblerState* state)
159 : : RegExpBuiltinsAssembler(state) {}
160 :
161 : TNode<Object> CreateRegExpStringIterator(TNode<Context> native_context,
162 : TNode<Object> regexp,
163 : TNode<String> string,
164 : TNode<Int32T> global,
165 : TNode<Int32T> full_unicode);
166 : void Generate(TNode<Context> context, TNode<Context> native_context,
167 : TNode<Object> receiver, TNode<Object> maybe_string);
168 : };
169 :
170 : } // namespace internal
171 : } // namespace v8
172 :
173 : #endif // V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
|