| 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 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); | 333 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); |
| 334 | 334 |
| 335 StoreLastIndex(context, regexp, new_lastindex, is_fastpath); | 335 StoreLastIndex(context, regexp, new_lastindex, is_fastpath); |
| 336 Goto(&out); | 336 Goto(&out); |
| 337 } | 337 } |
| 338 | 338 |
| 339 Bind(&out); | 339 Bind(&out); |
| 340 return var_result.value(); | 340 return var_result.value(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 // Wrapper around RegExpPrototypeExecBody to reduce code duplication. | |
| 344 TF_BUILTIN(RegExpExecInternalFast, RegExpBuiltinsAssembler) { | |
| 345 typedef RegExpExecInternalDescriptor Descriptor; | |
| 346 | |
| 347 Node* const regexp = Parameter(Descriptor::kReceiver); | |
| 348 Node* const string = Parameter(Descriptor::kString); | |
| 349 Node* const context = Parameter(Descriptor::kContext); | |
| 350 | |
| 351 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); | |
| 352 CSA_ASSERT(this, IsString(string)); | |
| 353 | |
| 354 Return(RegExpPrototypeExecBody(context, regexp, string, true)); | |
| 355 } | |
| 356 | |
| 357 // Wrapper around RegExpPrototypeExecBody to reduce code duplication. | |
| 358 TF_BUILTIN(RegExpExecInternalSlow, RegExpBuiltinsAssembler) { | |
| 359 typedef RegExpExecInternalDescriptor Descriptor; | |
| 360 | |
| 361 Node* const regexp = Parameter(Descriptor::kReceiver); | |
| 362 Node* const string = Parameter(Descriptor::kString); | |
| 363 Node* const context = Parameter(Descriptor::kContext); | |
| 364 | |
| 365 CSA_ASSERT(this, IsString(string)); | |
| 366 | |
| 367 Return(RegExpPrototypeExecBody(context, regexp, string, false)); | |
| 368 } | |
| 369 | |
| 370 // ES#sec-regexp.prototype.exec | 343 // ES#sec-regexp.prototype.exec |
| 371 // RegExp.prototype.exec ( string ) | 344 // RegExp.prototype.exec ( string ) |
| 372 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBody(Node* const context, | 345 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBody(Node* const context, |
| 373 Node* const regexp, | 346 Node* const regexp, |
| 374 Node* const string, | 347 Node* const string, |
| 375 const bool is_fastpath) { | 348 const bool is_fastpath) { |
| 376 Node* const null = NullConstant(); | 349 Node* const null = NullConstant(); |
| 377 | 350 |
| 378 Variable var_result(this, MachineRepresentation::kTagged); | 351 Variable var_result(this, MachineRepresentation::kTagged); |
| 379 | 352 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 | 491 |
| 519 // Convert {maybe_string} to a String. | 492 // Convert {maybe_string} to a String. |
| 520 Node* const string = ToString(context, maybe_string); | 493 Node* const string = ToString(context, maybe_string); |
| 521 | 494 |
| 522 Label if_isfastpath(this), if_isslowpath(this); | 495 Label if_isfastpath(this), if_isslowpath(this); |
| 523 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath, | 496 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath, |
| 524 &if_isslowpath); | 497 &if_isslowpath); |
| 525 | 498 |
| 526 Bind(&if_isfastpath); | 499 Bind(&if_isfastpath); |
| 527 { | 500 { |
| 528 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate(), true); | 501 Node* const result = |
| 529 Return(CallStub(exec_callable, context, receiver, string)); | 502 RegExpPrototypeExecBody(context, receiver, string, true); |
| 503 Return(result); |
| 530 } | 504 } |
| 531 | 505 |
| 532 Bind(&if_isslowpath); | 506 Bind(&if_isslowpath); |
| 533 { | 507 { |
| 534 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate(), false); | 508 Node* const result = |
| 535 Return(CallStub(exec_callable, context, receiver, string)); | 509 RegExpPrototypeExecBody(context, receiver, string, false); |
| 510 Return(result); |
| 536 } | 511 } |
| 537 } | 512 } |
| 538 | 513 |
| 539 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, | 514 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, |
| 540 Node* const regexp, | 515 Node* const regexp, |
| 541 bool is_fastpath) { | 516 bool is_fastpath) { |
| 542 Isolate* isolate = this->isolate(); | 517 Isolate* isolate = this->isolate(); |
| 543 | 518 |
| 544 Node* const int_zero = IntPtrConstant(0); | 519 Node* const int_zero = IntPtrConstant(0); |
| 545 Node* const int_one = IntPtrConstant(1); | 520 Node* const int_one = IntPtrConstant(1); |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 Node* const null = NullConstant(); | 1217 Node* const null = NullConstant(); |
| 1243 | 1218 |
| 1244 Variable var_result(this, MachineRepresentation::kTagged); | 1219 Variable var_result(this, MachineRepresentation::kTagged); |
| 1245 Label out(this), if_isfastpath(this), if_isslowpath(this); | 1220 Label out(this), if_isfastpath(this), if_isslowpath(this); |
| 1246 | 1221 |
| 1247 Node* const map = LoadMap(regexp); | 1222 Node* const map = LoadMap(regexp); |
| 1248 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath); | 1223 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath); |
| 1249 | 1224 |
| 1250 Bind(&if_isfastpath); | 1225 Bind(&if_isfastpath); |
| 1251 { | 1226 { |
| 1252 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, true); | 1227 Node* const result = RegExpPrototypeExecBody(context, regexp, string, true); |
| 1253 Node* const result = CallStub(exec_callable, context, regexp, string); | |
| 1254 var_result.Bind(result); | 1228 var_result.Bind(result); |
| 1255 Goto(&out); | 1229 Goto(&out); |
| 1256 } | 1230 } |
| 1257 | 1231 |
| 1258 Bind(&if_isslowpath); | 1232 Bind(&if_isslowpath); |
| 1259 { | 1233 { |
| 1260 // Take the slow path of fetching the exec property, calling it, and | 1234 // Take the slow path of fetching the exec property, calling it, and |
| 1261 // verifying its return value. | 1235 // verifying its return value. |
| 1262 | 1236 |
| 1263 // Get the exec property. | 1237 // Get the exec property. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1285 MessageTemplate::kInvalidRegExpExecResult, "unused"); | 1259 MessageTemplate::kInvalidRegExpExecResult, "unused"); |
| 1286 | 1260 |
| 1287 Goto(&out); | 1261 Goto(&out); |
| 1288 } | 1262 } |
| 1289 | 1263 |
| 1290 Bind(&if_isnotcallable); | 1264 Bind(&if_isnotcallable); |
| 1291 { | 1265 { |
| 1292 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, | 1266 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, |
| 1293 "RegExp.prototype.exec"); | 1267 "RegExp.prototype.exec"); |
| 1294 | 1268 |
| 1295 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, false); | 1269 Node* const result = |
| 1296 Node* const result = CallStub(exec_callable, context, regexp, string); | 1270 RegExpPrototypeExecBody(context, regexp, string, false); |
| 1297 var_result.Bind(result); | 1271 var_result.Bind(result); |
| 1298 Goto(&out); | 1272 Goto(&out); |
| 1299 } | 1273 } |
| 1300 } | 1274 } |
| 1301 | 1275 |
| 1302 Bind(&out); | 1276 Bind(&out); |
| 1303 return var_result.value(); | 1277 return var_result.value(); |
| 1304 } | 1278 } |
| 1305 | 1279 |
| 1306 // ES#sec-regexp.prototype.test | 1280 // ES#sec-regexp.prototype.test |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 Node* const smi_zero = SmiConstant(Smi::kZero); | 1517 Node* const smi_zero = SmiConstant(Smi::kZero); |
| 1544 | 1518 |
| 1545 Node* const is_global = | 1519 Node* const is_global = |
| 1546 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); | 1520 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); |
| 1547 | 1521 |
| 1548 Label if_isglobal(this), if_isnotglobal(this); | 1522 Label if_isglobal(this), if_isnotglobal(this); |
| 1549 Branch(is_global, &if_isglobal, &if_isnotglobal); | 1523 Branch(is_global, &if_isglobal, &if_isnotglobal); |
| 1550 | 1524 |
| 1551 Bind(&if_isnotglobal); | 1525 Bind(&if_isnotglobal); |
| 1552 { | 1526 { |
| 1553 if (is_fastpath) { | 1527 Node* const result = |
| 1554 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, true); | 1528 is_fastpath ? RegExpPrototypeExecBody(context, regexp, string, true) |
| 1555 Return(CallStub(exec_callable, context, regexp, string)); | 1529 : RegExpExec(context, regexp, string); |
| 1556 } else { | 1530 Return(result); |
| 1557 Return(RegExpExec(context, regexp, string)); | |
| 1558 } | |
| 1559 } | 1531 } |
| 1560 | 1532 |
| 1561 Bind(&if_isglobal); | 1533 Bind(&if_isglobal); |
| 1562 { | 1534 { |
| 1563 Node* const is_unicode = | 1535 Node* const is_unicode = |
| 1564 FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath); | 1536 FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath); |
| 1565 | 1537 |
| 1566 StoreLastIndex(context, regexp, smi_zero, is_fastpath); | 1538 StoreLastIndex(context, regexp, smi_zero, is_fastpath); |
| 1567 | 1539 |
| 1568 // Allocate an array to store the resulting match strings. | 1540 // Allocate an array to store the resulting match strings. |
| (...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2584 Bind(&if_matched); | 2556 Bind(&if_matched); |
| 2585 { | 2557 { |
| 2586 Node* result = | 2558 Node* result = |
| 2587 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2559 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
| 2588 Return(result); | 2560 Return(result); |
| 2589 } | 2561 } |
| 2590 } | 2562 } |
| 2591 | 2563 |
| 2592 } // namespace internal | 2564 } // namespace internal |
| 2593 } // namespace v8 | 2565 } // namespace v8 |
| OLD | NEW |