| 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 |