| 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 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 } | 507 } |
| 508 | 508 |
| 509 // ES#sec-regexp.prototype.exec | 509 // ES#sec-regexp.prototype.exec |
| 510 // RegExp.prototype.exec ( string ) | 510 // RegExp.prototype.exec ( string ) |
| 511 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { | 511 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { |
| 512 Node* const maybe_receiver = Parameter(0); | 512 Node* const maybe_receiver = Parameter(0); |
| 513 Node* const maybe_string = Parameter(1); | 513 Node* const maybe_string = Parameter(1); |
| 514 Node* const context = Parameter(4); | 514 Node* const context = Parameter(4); |
| 515 | 515 |
| 516 // Ensure {maybe_receiver} is a JSRegExp. | 516 // Ensure {maybe_receiver} is a JSRegExp. |
| 517 Node* const regexp_map = ThrowIfNotInstanceType( | 517 ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, |
| 518 context, maybe_receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec"); | 518 "RegExp.prototype.exec"); |
| 519 Node* const receiver = maybe_receiver; | 519 Node* const receiver = maybe_receiver; |
| 520 | 520 |
| 521 // Convert {maybe_string} to a String. | 521 // Convert {maybe_string} to a String. |
| 522 Node* const string = ToString(context, maybe_string); | 522 Node* const string = ToString(context, maybe_string); |
| 523 | 523 |
| 524 Label if_isfastpath(this), if_isslowpath(this); | 524 Label if_isfastpath(this), if_isslowpath(this); |
| 525 Branch(IsInitialRegExpMap(context, receiver, regexp_map), &if_isfastpath, | 525 Branch(IsInitialRegExpMap(context, receiver, LoadMap(receiver)), |
| 526 &if_isslowpath); | 526 &if_isfastpath, &if_isslowpath); |
| 527 | 527 |
| 528 Bind(&if_isfastpath); | 528 Bind(&if_isfastpath); |
| 529 { | 529 { |
| 530 Node* const result = | 530 Node* const result = |
| 531 RegExpPrototypeExecBody(context, receiver, string, true); | 531 RegExpPrototypeExecBody(context, receiver, string, true); |
| 532 Return(result); | 532 Return(result); |
| 533 } | 533 } |
| 534 | 534 |
| 535 Bind(&if_isslowpath); | 535 Bind(&if_isslowpath); |
| 536 { | 536 { |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 } | 1308 } |
| 1309 | 1309 |
| 1310 // ES#sec-regexp.prototype.test | 1310 // ES#sec-regexp.prototype.test |
| 1311 // RegExp.prototype.test ( S ) | 1311 // RegExp.prototype.test ( S ) |
| 1312 TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) { | 1312 TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) { |
| 1313 Node* const maybe_receiver = Parameter(0); | 1313 Node* const maybe_receiver = Parameter(0); |
| 1314 Node* const maybe_string = Parameter(1); | 1314 Node* const maybe_string = Parameter(1); |
| 1315 Node* const context = Parameter(4); | 1315 Node* const context = Parameter(4); |
| 1316 | 1316 |
| 1317 // Ensure {maybe_receiver} is a JSReceiver. | 1317 // Ensure {maybe_receiver} is a JSReceiver. |
| 1318 Node* const map = ThrowIfNotJSReceiver( | 1318 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 1319 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, | 1319 MessageTemplate::kIncompatibleMethodReceiver, |
| 1320 "RegExp.prototype.test"); | 1320 "RegExp.prototype.test"); |
| 1321 Node* const receiver = maybe_receiver; | 1321 Node* const receiver = maybe_receiver; |
| 1322 | 1322 |
| 1323 // Convert {maybe_string} to a String. | 1323 // Convert {maybe_string} to a String. |
| 1324 Node* const string = ToString(context, maybe_string); | 1324 Node* const string = ToString(context, maybe_string); |
| 1325 | 1325 |
| 1326 Label fast_path(this), slow_path(this); | 1326 Label fast_path(this), slow_path(this); |
| 1327 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); | 1327 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path, |
| 1328 &slow_path); |
| 1328 | 1329 |
| 1329 Bind(&fast_path); | 1330 Bind(&fast_path); |
| 1330 { | 1331 { |
| 1331 Label if_didnotmatch(this); | 1332 Label if_didnotmatch(this); |
| 1332 RegExpPrototypeExecBodyWithoutResult(context, receiver, string, | 1333 RegExpPrototypeExecBodyWithoutResult(context, receiver, string, |
| 1333 &if_didnotmatch, true); | 1334 &if_didnotmatch, true); |
| 1334 Return(TrueConstant()); | 1335 Return(TrueConstant()); |
| 1335 | 1336 |
| 1336 Bind(&if_didnotmatch); | 1337 Bind(&if_didnotmatch); |
| 1337 Return(FalseConstant()); | 1338 Return(FalseConstant()); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 } | 1718 } |
| 1718 | 1719 |
| 1719 // ES#sec-regexp.prototype-@@match | 1720 // ES#sec-regexp.prototype-@@match |
| 1720 // RegExp.prototype [ @@match ] ( string ) | 1721 // RegExp.prototype [ @@match ] ( string ) |
| 1721 TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) { | 1722 TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) { |
| 1722 Node* const maybe_receiver = Parameter(0); | 1723 Node* const maybe_receiver = Parameter(0); |
| 1723 Node* const maybe_string = Parameter(1); | 1724 Node* const maybe_string = Parameter(1); |
| 1724 Node* const context = Parameter(4); | 1725 Node* const context = Parameter(4); |
| 1725 | 1726 |
| 1726 // Ensure {maybe_receiver} is a JSReceiver. | 1727 // Ensure {maybe_receiver} is a JSReceiver. |
| 1727 Node* const map = ThrowIfNotJSReceiver( | 1728 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 1728 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, | 1729 MessageTemplate::kIncompatibleMethodReceiver, |
| 1729 "RegExp.prototype.@@match"); | 1730 "RegExp.prototype.@@match"); |
| 1730 Node* const receiver = maybe_receiver; | 1731 Node* const receiver = maybe_receiver; |
| 1731 | 1732 |
| 1732 // Convert {maybe_string} to a String. | 1733 // Convert {maybe_string} to a String. |
| 1733 Node* const string = ToString(context, maybe_string); | 1734 Node* const string = ToString(context, maybe_string); |
| 1734 | 1735 |
| 1735 Label fast_path(this), slow_path(this); | 1736 Label fast_path(this), slow_path(this); |
| 1736 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); | 1737 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path, |
| 1738 &slow_path); |
| 1737 | 1739 |
| 1738 Bind(&fast_path); | 1740 Bind(&fast_path); |
| 1739 RegExpPrototypeMatchBody(context, receiver, string, true); | 1741 RegExpPrototypeMatchBody(context, receiver, string, true); |
| 1740 | 1742 |
| 1741 Bind(&slow_path); | 1743 Bind(&slow_path); |
| 1742 RegExpPrototypeMatchBody(context, receiver, string, false); | 1744 RegExpPrototypeMatchBody(context, receiver, string, false); |
| 1743 } | 1745 } |
| 1744 | 1746 |
| 1745 void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( | 1747 void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( |
| 1746 Node* const context, Node* const regexp, Node* const string) { | 1748 Node* const context, Node* const regexp, Node* const string) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 } | 1844 } |
| 1843 | 1845 |
| 1844 // ES#sec-regexp.prototype-@@search | 1846 // ES#sec-regexp.prototype-@@search |
| 1845 // RegExp.prototype [ @@search ] ( string ) | 1847 // RegExp.prototype [ @@search ] ( string ) |
| 1846 TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) { | 1848 TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) { |
| 1847 Node* const maybe_receiver = Parameter(0); | 1849 Node* const maybe_receiver = Parameter(0); |
| 1848 Node* const maybe_string = Parameter(1); | 1850 Node* const maybe_string = Parameter(1); |
| 1849 Node* const context = Parameter(4); | 1851 Node* const context = Parameter(4); |
| 1850 | 1852 |
| 1851 // Ensure {maybe_receiver} is a JSReceiver. | 1853 // Ensure {maybe_receiver} is a JSReceiver. |
| 1852 Node* const map = ThrowIfNotJSReceiver( | 1854 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 1853 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, | 1855 MessageTemplate::kIncompatibleMethodReceiver, |
| 1854 "RegExp.prototype.@@search"); | 1856 "RegExp.prototype.@@search"); |
| 1855 Node* const receiver = maybe_receiver; | 1857 Node* const receiver = maybe_receiver; |
| 1856 | 1858 |
| 1857 // Convert {maybe_string} to a String. | 1859 // Convert {maybe_string} to a String. |
| 1858 Node* const string = ToString(context, maybe_string); | 1860 Node* const string = ToString(context, maybe_string); |
| 1859 | 1861 |
| 1860 Label fast_path(this), slow_path(this); | 1862 Label fast_path(this), slow_path(this); |
| 1861 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); | 1863 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path, |
| 1864 &slow_path); |
| 1862 | 1865 |
| 1863 Bind(&fast_path); | 1866 Bind(&fast_path); |
| 1864 RegExpPrototypeSearchBodyFast(context, receiver, string); | 1867 RegExpPrototypeSearchBodyFast(context, receiver, string); |
| 1865 | 1868 |
| 1866 Bind(&slow_path); | 1869 Bind(&slow_path); |
| 1867 RegExpPrototypeSearchBodySlow(context, receiver, string); | 1870 RegExpPrototypeSearchBodySlow(context, receiver, string); |
| 1868 } | 1871 } |
| 1869 | 1872 |
| 1870 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp, | 1873 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp, |
| 1871 // {string} is a String, and {limit} is a Smi. | 1874 // {string} is a String, and {limit} is a Smi. |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2178 | 2181 |
| 2179 // ES#sec-regexp.prototype-@@split | 2182 // ES#sec-regexp.prototype-@@split |
| 2180 // RegExp.prototype [ @@split ] ( string, limit ) | 2183 // RegExp.prototype [ @@split ] ( string, limit ) |
| 2181 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { | 2184 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { |
| 2182 Node* const maybe_receiver = Parameter(0); | 2185 Node* const maybe_receiver = Parameter(0); |
| 2183 Node* const maybe_string = Parameter(1); | 2186 Node* const maybe_string = Parameter(1); |
| 2184 Node* const maybe_limit = Parameter(2); | 2187 Node* const maybe_limit = Parameter(2); |
| 2185 Node* const context = Parameter(5); | 2188 Node* const context = Parameter(5); |
| 2186 | 2189 |
| 2187 // Ensure {maybe_receiver} is a JSReceiver. | 2190 // Ensure {maybe_receiver} is a JSReceiver. |
| 2188 Node* const map = ThrowIfNotJSReceiver( | 2191 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 2189 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, | 2192 MessageTemplate::kIncompatibleMethodReceiver, |
| 2190 "RegExp.prototype.@@split"); | 2193 "RegExp.prototype.@@split"); |
| 2191 Node* const receiver = maybe_receiver; | 2194 Node* const receiver = maybe_receiver; |
| 2192 | 2195 |
| 2193 // Convert {maybe_string} to a String. | 2196 // Convert {maybe_string} to a String. |
| 2194 Node* const string = ToString(context, maybe_string); | 2197 Node* const string = ToString(context, maybe_string); |
| 2195 | 2198 |
| 2196 Label stub(this), runtime(this, Label::kDeferred); | 2199 Label stub(this), runtime(this, Label::kDeferred); |
| 2197 BranchIfFastRegExp(context, receiver, map, &stub, &runtime); | 2200 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &stub, &runtime); |
| 2198 | 2201 |
| 2199 Bind(&stub); | 2202 Bind(&stub); |
| 2200 Callable split_callable = CodeFactory::RegExpSplit(isolate()); | 2203 Callable split_callable = CodeFactory::RegExpSplit(isolate()); |
| 2201 Return(CallStub(split_callable, context, receiver, string, maybe_limit)); | 2204 Return(CallStub(split_callable, context, receiver, string, maybe_limit)); |
| 2202 | 2205 |
| 2203 Bind(&runtime); | 2206 Bind(&runtime); |
| 2204 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, | 2207 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, |
| 2205 maybe_limit)); | 2208 maybe_limit)); |
| 2206 } | 2209 } |
| 2207 | 2210 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 // } | 2605 // } |
| 2603 // } else { | 2606 // } else { |
| 2604 // if (replace.contains("$")) { | 2607 // if (replace.contains("$")) { |
| 2605 // CallRuntime(RegExpReplace) | 2608 // CallRuntime(RegExpReplace) |
| 2606 // } else { | 2609 // } else { |
| 2607 // ReplaceSimpleStringFastPath() // Bails to runtime for global regexps. | 2610 // ReplaceSimpleStringFastPath() // Bails to runtime for global regexps. |
| 2608 // } | 2611 // } |
| 2609 // } | 2612 // } |
| 2610 | 2613 |
| 2611 // Ensure {maybe_receiver} is a JSReceiver. | 2614 // Ensure {maybe_receiver} is a JSReceiver. |
| 2612 Node* const map = ThrowIfNotJSReceiver( | 2615 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 2613 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, | 2616 MessageTemplate::kIncompatibleMethodReceiver, |
| 2614 "RegExp.prototype.@@replace"); | 2617 "RegExp.prototype.@@replace"); |
| 2615 Node* const receiver = maybe_receiver; | 2618 Node* const receiver = maybe_receiver; |
| 2616 | 2619 |
| 2617 // Convert {maybe_string} to a String. | 2620 // Convert {maybe_string} to a String. |
| 2618 Callable tostring_callable = CodeFactory::ToString(isolate()); | 2621 Callable tostring_callable = CodeFactory::ToString(isolate()); |
| 2619 Node* const string = CallStub(tostring_callable, context, maybe_string); | 2622 Node* const string = CallStub(tostring_callable, context, maybe_string); |
| 2620 | 2623 |
| 2621 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? | 2624 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? |
| 2622 Label stub(this), runtime(this, Label::kDeferred); | 2625 Label stub(this), runtime(this, Label::kDeferred); |
| 2623 BranchIfFastRegExp(context, receiver, map, &stub, &runtime); | 2626 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &stub, &runtime); |
| 2624 | 2627 |
| 2625 Bind(&stub); | 2628 Bind(&stub); |
| 2626 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); | 2629 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); |
| 2627 Return(CallStub(replace_callable, context, receiver, string, replace_value)); | 2630 Return(CallStub(replace_callable, context, receiver, string, replace_value)); |
| 2628 | 2631 |
| 2629 Bind(&runtime); | 2632 Bind(&runtime); |
| 2630 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, | 2633 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, |
| 2631 replace_value)); | 2634 replace_value)); |
| 2632 } | 2635 } |
| 2633 | 2636 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2658 Bind(&if_matched); | 2661 Bind(&if_matched); |
| 2659 { | 2662 { |
| 2660 Node* result = | 2663 Node* result = |
| 2661 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2664 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
| 2662 Return(result); | 2665 Return(result); |
| 2663 } | 2666 } |
| 2664 } | 2667 } |
| 2665 | 2668 |
| 2666 } // namespace internal | 2669 } // namespace internal |
| 2667 } // namespace v8 | 2670 } // namespace v8 |
| OLD | NEW |