| OLD | NEW |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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-gen.h" | 5 #include "src/builtins/builtins-regexp-gen.h" |
| 6 | 6 |
| 7 #include "src/builtins/builtins-constructor-gen.h" | 7 #include "src/builtins/builtins-constructor-gen.h" |
| 8 #include "src/builtins/builtins-utils-gen.h" | 8 #include "src/builtins/builtins-utils-gen.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 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 if (is_fastpath) { | 570 if (is_fastpath) { |
| 571 // ToLength on a positive smi is a nop and can be skipped. | 571 // ToLength on a positive smi is a nop and can be skipped. |
| 572 CSA_ASSERT(this, TaggedIsPositiveSmi(regexp_lastindex)); | 572 CSA_ASSERT(this, TaggedIsPositiveSmi(regexp_lastindex)); |
| 573 } else { | 573 } else { |
| 574 // Omit ToLength if lastindex is a non-negative smi. | 574 // Omit ToLength if lastindex is a non-negative smi. |
| 575 Label call_tolength(this, Label::kDeferred), next(this); | 575 Label call_tolength(this, Label::kDeferred), next(this); |
| 576 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); | 576 Branch(TaggedIsPositiveSmi(regexp_lastindex), &next, &call_tolength); |
| 577 | 577 |
| 578 BIND(&call_tolength); | 578 BIND(&call_tolength); |
| 579 { | 579 { |
| 580 var_lastindex.Bind( | 580 var_lastindex.Bind(ToLength_Inline(context, regexp_lastindex)); |
| 581 CallBuiltin(Builtins::kToLength, context, regexp_lastindex)); | |
| 582 Goto(&next); | 581 Goto(&next); |
| 583 } | 582 } |
| 584 | 583 |
| 585 BIND(&next); | 584 BIND(&next); |
| 586 } | 585 } |
| 587 } | 586 } |
| 588 | 587 |
| 589 // Check whether the regexp is global or sticky, which determines whether we | 588 // Check whether the regexp is global or sticky, which determines whether we |
| 590 // update last index later on. | 589 // update last index later on. |
| 591 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); | 590 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); |
| (...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 | 1933 |
| 1935 // Advance last index if the match is the empty string. | 1934 // Advance last index if the match is the empty string. |
| 1936 | 1935 |
| 1937 Node* const match_length = LoadStringLength(match); | 1936 Node* const match_length = LoadStringLength(match); |
| 1938 GotoIfNot(SmiEqual(match_length, smi_zero), &loop); | 1937 GotoIfNot(SmiEqual(match_length, smi_zero), &loop); |
| 1939 | 1938 |
| 1940 Node* last_index = LoadLastIndex(context, regexp, is_fastpath); | 1939 Node* last_index = LoadLastIndex(context, regexp, is_fastpath); |
| 1941 if (is_fastpath) { | 1940 if (is_fastpath) { |
| 1942 CSA_ASSERT(this, TaggedIsPositiveSmi(last_index)); | 1941 CSA_ASSERT(this, TaggedIsPositiveSmi(last_index)); |
| 1943 } else { | 1942 } else { |
| 1944 last_index = CallBuiltin(Builtins::kToLength, context, last_index); | 1943 last_index = ToLength_Inline(context, last_index); |
| 1945 } | 1944 } |
| 1946 | 1945 |
| 1947 Node* const new_last_index = | 1946 Node* const new_last_index = |
| 1948 AdvanceStringIndex(string, last_index, is_unicode, is_fastpath); | 1947 AdvanceStringIndex(string, last_index, is_unicode, is_fastpath); |
| 1949 | 1948 |
| 1950 if (is_fastpath) { | 1949 if (is_fastpath) { |
| 1951 // On the fast path, we can be certain that lastIndex can never be | 1950 // On the fast path, we can be certain that lastIndex can never be |
| 1952 // incremented to overflow the Smi range since the maximal string | 1951 // incremented to overflow the Smi range since the maximal string |
| 1953 // length is less than the maximal Smi value. | 1952 // length is less than the maximal Smi value. |
| 1954 STATIC_ASSERT(String::kMaxLength < Smi::kMaxValue); | 1953 STATIC_ASSERT(String::kMaxLength < Smi::kMaxValue); |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2802 runtime(this, Label::kDeferred); | 2801 runtime(this, Label::kDeferred); |
| 2803 | 2802 |
| 2804 // 2. Is {replace_value} callable? | 2803 // 2. Is {replace_value} callable? |
| 2805 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); | 2804 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); |
| 2806 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, | 2805 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, |
| 2807 &checkreplacestring); | 2806 &checkreplacestring); |
| 2808 | 2807 |
| 2809 // 3. Does ToString({replace_value}) contain '$'? | 2808 // 3. Does ToString({replace_value}) contain '$'? |
| 2810 BIND(&checkreplacestring); | 2809 BIND(&checkreplacestring); |
| 2811 { | 2810 { |
| 2812 Node* const replace_string = | 2811 Node* const replace_string = ToString_Inline(context, replace_value); |
| 2813 CallBuiltin(Builtins::kToString, context, replace_value); | |
| 2814 | 2812 |
| 2815 // ToString(replaceValue) could potentially change the shape of the RegExp | 2813 // ToString(replaceValue) could potentially change the shape of the RegExp |
| 2816 // object. Recheck that we are still on the fast path and bail to runtime | 2814 // object. Recheck that we are still on the fast path and bail to runtime |
| 2817 // otherwise. | 2815 // otherwise. |
| 2818 { | 2816 { |
| 2819 Label next(this); | 2817 Label next(this); |
| 2820 BranchIfFastRegExp(context, regexp, &next, &runtime); | 2818 BranchIfFastRegExp(context, regexp, &next, &runtime); |
| 2821 BIND(&next); | 2819 BIND(&next); |
| 2822 } | 2820 } |
| 2823 | 2821 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2891 // } | 2889 // } |
| 2892 // } | 2890 // } |
| 2893 | 2891 |
| 2894 // Ensure {maybe_receiver} is a JSReceiver. | 2892 // Ensure {maybe_receiver} is a JSReceiver. |
| 2895 ThrowIfNotJSReceiver(context, maybe_receiver, | 2893 ThrowIfNotJSReceiver(context, maybe_receiver, |
| 2896 MessageTemplate::kIncompatibleMethodReceiver, | 2894 MessageTemplate::kIncompatibleMethodReceiver, |
| 2897 "RegExp.prototype.@@replace"); | 2895 "RegExp.prototype.@@replace"); |
| 2898 Node* const receiver = maybe_receiver; | 2896 Node* const receiver = maybe_receiver; |
| 2899 | 2897 |
| 2900 // Convert {maybe_string} to a String. | 2898 // Convert {maybe_string} to a String. |
| 2901 Node* const string = CallBuiltin(Builtins::kToString, context, maybe_string); | 2899 Node* const string = ToString_Inline(context, maybe_string); |
| 2902 | 2900 |
| 2903 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? | 2901 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? |
| 2904 Label stub(this), runtime(this, Label::kDeferred); | 2902 Label stub(this), runtime(this, Label::kDeferred); |
| 2905 BranchIfFastRegExp(context, receiver, &stub, &runtime); | 2903 BranchIfFastRegExp(context, receiver, &stub, &runtime); |
| 2906 | 2904 |
| 2907 BIND(&stub); | 2905 BIND(&stub); |
| 2908 args.PopAndReturn(CallBuiltin(Builtins::kRegExpReplace, context, receiver, | 2906 args.PopAndReturn(CallBuiltin(Builtins::kRegExpReplace, context, receiver, |
| 2909 string, replace_value)); | 2907 string, replace_value)); |
| 2910 | 2908 |
| 2911 BIND(&runtime); | 2909 BIND(&runtime); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2942 BIND(&if_matched); | 2940 BIND(&if_matched); |
| 2943 { | 2941 { |
| 2944 Node* result = | 2942 Node* result = |
| 2945 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2943 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
| 2946 Return(result); | 2944 Return(result); |
| 2947 } | 2945 } |
| 2948 } | 2946 } |
| 2949 | 2947 |
| 2950 } // namespace internal | 2948 } // namespace internal |
| 2951 } // namespace v8 | 2949 } // namespace v8 |
| OLD | NEW |