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 |