OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins-regexp.h" | 5 #include "src/builtins/builtins-regexp.h" |
6 | 6 |
7 #include "src/builtins/builtins-constructor.h" | 7 #include "src/builtins/builtins-constructor.h" |
8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
9 #include "src/builtins/builtins.h" | 9 #include "src/builtins/builtins.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 234 |
235 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string))); | 235 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(string))); |
236 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); | 236 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); |
237 | 237 |
238 Variable var_result(this, MachineRepresentation::kTagged); | 238 Variable var_result(this, MachineRepresentation::kTagged); |
239 Label out(this); | 239 Label out(this); |
240 | 240 |
241 Node* const native_context = LoadNativeContext(context); | 241 Node* const native_context = LoadNativeContext(context); |
242 Node* const string_length = LoadStringLength(string); | 242 Node* const string_length = LoadStringLength(string); |
243 | 243 |
| 244 // Load lastIndex. |
| 245 Variable var_lastindex(this, MachineRepresentation::kTagged); |
| 246 { |
| 247 Node* const regexp_lastindex = LoadLastIndex(context, regexp, is_fastpath); |
| 248 var_lastindex.Bind(regexp_lastindex); |
| 249 |
| 250 // Omit ToLength if lastindex is a non-negative smi. |
| 251 Label call_tolength(this, Label::kDeferred), next(this); |
| 252 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); |
| 253 |
| 254 Bind(&call_tolength); |
| 255 { |
| 256 Callable tolength_callable = CodeFactory::ToLength(isolate); |
| 257 var_lastindex.Bind( |
| 258 CallStub(tolength_callable, context, regexp_lastindex)); |
| 259 Goto(&next); |
| 260 } |
| 261 |
| 262 Bind(&next); |
| 263 } |
| 264 |
244 // Check whether the regexp is global or sticky, which determines whether we | 265 // Check whether the regexp is global or sticky, which determines whether we |
245 // update last index later on. | 266 // update last index later on. |
246 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); | 267 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); |
247 Node* const is_global_or_sticky = WordAnd( | 268 Node* const is_global_or_sticky = WordAnd( |
248 SmiUntag(flags), IntPtrConstant(JSRegExp::kGlobal | JSRegExp::kSticky)); | 269 SmiUntag(flags), IntPtrConstant(JSRegExp::kGlobal | JSRegExp::kSticky)); |
249 Node* const should_update_last_index = | 270 Node* const should_update_last_index = |
250 WordNotEqual(is_global_or_sticky, int_zero); | 271 WordNotEqual(is_global_or_sticky, int_zero); |
251 | 272 |
252 // Grab and possibly update last index. | 273 // Grab and possibly update last index. |
253 Label run_exec(this); | 274 Label run_exec(this); |
254 Variable var_lastindex(this, MachineRepresentation::kTagged); | |
255 { | 275 { |
256 Label if_doupdate(this), if_dontupdate(this); | 276 Label if_doupdate(this), if_dontupdate(this); |
257 Branch(should_update_last_index, &if_doupdate, &if_dontupdate); | 277 Branch(should_update_last_index, &if_doupdate, &if_dontupdate); |
258 | 278 |
259 Bind(&if_doupdate); | 279 Bind(&if_doupdate); |
260 { | 280 { |
261 Node* const regexp_lastindex = | |
262 LoadLastIndex(context, regexp, is_fastpath); | |
263 var_lastindex.Bind(regexp_lastindex); | |
264 | |
265 // Omit ToLength if lastindex is a non-negative smi. | |
266 { | |
267 Label call_tolength(this, Label::kDeferred), next(this); | |
268 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); | |
269 | |
270 Bind(&call_tolength); | |
271 { | |
272 Callable tolength_callable = CodeFactory::ToLength(isolate); | |
273 var_lastindex.Bind( | |
274 CallStub(tolength_callable, context, regexp_lastindex)); | |
275 Goto(&next); | |
276 } | |
277 | |
278 Bind(&next); | |
279 } | |
280 | |
281 Node* const lastindex = var_lastindex.value(); | 281 Node* const lastindex = var_lastindex.value(); |
282 | 282 |
283 Label if_isoob(this, Label::kDeferred); | 283 Label if_isoob(this, Label::kDeferred); |
284 GotoUnless(TaggedIsSmi(lastindex), &if_isoob); | 284 GotoUnless(TaggedIsSmi(lastindex), &if_isoob); |
285 GotoUnless(SmiLessThanOrEqual(lastindex, string_length), &if_isoob); | 285 GotoUnless(SmiLessThanOrEqual(lastindex, string_length), &if_isoob); |
286 Goto(&run_exec); | 286 Goto(&run_exec); |
287 | 287 |
288 Bind(&if_isoob); | 288 Bind(&if_isoob); |
289 { | 289 { |
290 StoreLastIndex(context, regexp, smi_zero, is_fastpath); | 290 StoreLastIndex(context, regexp, smi_zero, is_fastpath); |
(...skipping 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 Bind(&if_matched); | 2556 Bind(&if_matched); |
2557 { | 2557 { |
2558 Node* result = | 2558 Node* result = |
2559 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2559 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
2560 Return(result); | 2560 Return(result); |
2561 } | 2561 } |
2562 } | 2562 } |
2563 | 2563 |
2564 } // namespace internal | 2564 } // namespace internal |
2565 } // namespace v8 | 2565 } // namespace v8 |
OLD | NEW |