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