Chromium Code Reviews| 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 2285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2296 | 2296 |
| 2297 CSA_ASSERT(this, IsFastRegExp(context, regexp)); | 2297 CSA_ASSERT(this, IsFastRegExp(context, regexp)); |
| 2298 CSA_ASSERT(this, IsString(string)); | 2298 CSA_ASSERT(this, IsString(string)); |
| 2299 | 2299 |
| 2300 // TODO(jgruber): Even if map checks send us to the fast path, we still need | 2300 // TODO(jgruber): Even if map checks send us to the fast path, we still need |
| 2301 // to verify the constructor property and jump to the slow path if it has | 2301 // to verify the constructor property and jump to the slow path if it has |
| 2302 // been changed. | 2302 // been changed. |
| 2303 | 2303 |
| 2304 // Convert {maybe_limit} to a uint32, capping at the maximal smi value. | 2304 // Convert {maybe_limit} to a uint32, capping at the maximal smi value. |
| 2305 Variable var_limit(this, MachineRepresentation::kTagged); | 2305 Variable var_limit(this, MachineRepresentation::kTagged); |
| 2306 Label if_limitissmimax(this), limit_done(this); | 2306 Label if_limitissmimax(this), limit_done(this), runtime(this); |
| 2307 | 2307 |
| 2308 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); | 2308 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); |
| 2309 | 2309 |
| 2310 Node* const limit = ToUint32(context, maybe_limit); | |
|
Camillo Bruni
2017/04/06 14:54:15
future-nit: something like ToUint32(..., &was_fast
jgruber
2017/04/06 15:21:12
Sounds reasonable. I want to keep this CL small an
| |
| 2310 { | 2311 { |
| 2311 Node* const limit = ToUint32(context, maybe_limit); | 2312 // ToUint32(limit) could potentially change the shape of the RegExp |
| 2313 // object. Recheck that we are still on the fast path and bail to runtime | |
| 2314 // otherwise. | |
| 2315 { | |
| 2316 Label next(this); | |
| 2317 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime); | |
|
Camillo Bruni
2017/04/06 14:54:15
site-note: You'd probably be better off with a Got
jgruber
2017/04/06 15:21:12
Acknowledged.
| |
| 2318 Bind(&next); | |
| 2319 } | |
| 2320 | |
| 2312 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax); | 2321 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax); |
| 2313 | 2322 |
| 2314 var_limit.Bind(limit); | 2323 var_limit.Bind(limit); |
| 2315 Goto(&limit_done); | 2324 Goto(&limit_done); |
| 2316 } | 2325 } |
| 2317 | 2326 |
| 2318 Bind(&if_limitissmimax); | 2327 Bind(&if_limitissmimax); |
| 2319 { | 2328 { |
| 2320 // TODO(jgruber): In this case, we can probably avoid generation of limit | 2329 // TODO(jgruber): In this case, we can probably avoid generation of limit |
| 2321 // checks in Generate_RegExpPrototypeSplitBody. | 2330 // checks in Generate_RegExpPrototypeSplitBody. |
| 2322 var_limit.Bind(SmiConstant(Smi::kMaxValue)); | 2331 var_limit.Bind(SmiConstant(Smi::kMaxValue)); |
| 2323 Goto(&limit_done); | 2332 Goto(&limit_done); |
| 2324 } | 2333 } |
| 2325 | 2334 |
| 2326 Bind(&limit_done); | 2335 Bind(&limit_done); |
| 2327 { | 2336 { |
| 2328 Node* const limit = var_limit.value(); | 2337 Node* const limit = var_limit.value(); |
| 2329 RegExpPrototypeSplitBody(context, regexp, string, limit); | 2338 RegExpPrototypeSplitBody(context, regexp, string, limit); |
| 2330 } | 2339 } |
| 2340 | |
| 2341 Bind(&runtime); | |
| 2342 { | |
| 2343 // The runtime call passes in limit to ensure the second ToUint32(limit) | |
| 2344 // call is not observable. | |
| 2345 CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(limit))); | |
|
Camillo Bruni
2017/04/06 14:54:15
nit: CSA_ASSERT(this, IsNumber(limit));
jgruber
2017/04/06 15:21:12
Can do in a follow-up (don't want to touch c-s-a.{
| |
| 2346 Return(CallRuntime(Runtime::kRegExpSplit, context, regexp, string, limit)); | |
| 2347 } | |
| 2331 } | 2348 } |
| 2332 | 2349 |
| 2333 // ES#sec-regexp.prototype-@@split | 2350 // ES#sec-regexp.prototype-@@split |
| 2334 // RegExp.prototype [ @@split ] ( string, limit ) | 2351 // RegExp.prototype [ @@split ] ( string, limit ) |
| 2335 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { | 2352 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { |
| 2336 Node* const maybe_receiver = Parameter(Descriptor::kReceiver); | 2353 Node* const maybe_receiver = Parameter(Descriptor::kReceiver); |
| 2337 Node* const maybe_string = Parameter(Descriptor::kString); | 2354 Node* const maybe_string = Parameter(Descriptor::kString); |
| 2338 Node* const maybe_limit = Parameter(Descriptor::kLimit); | 2355 Node* const maybe_limit = Parameter(Descriptor::kLimit); |
| 2339 Node* const context = Parameter(Descriptor::kContext); | 2356 Node* const context = Parameter(Descriptor::kContext); |
| 2340 | 2357 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2692 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); | 2709 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); |
| 2693 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, | 2710 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, |
| 2694 &checkreplacestring); | 2711 &checkreplacestring); |
| 2695 | 2712 |
| 2696 // 3. Does ToString({replace_value}) contain '$'? | 2713 // 3. Does ToString({replace_value}) contain '$'? |
| 2697 Bind(&checkreplacestring); | 2714 Bind(&checkreplacestring); |
| 2698 { | 2715 { |
| 2699 Node* const replace_string = | 2716 Node* const replace_string = |
| 2700 CallBuiltin(Builtins::kToString, context, replace_value); | 2717 CallBuiltin(Builtins::kToString, context, replace_value); |
| 2701 | 2718 |
| 2719 // ToString(replaceValue) could potentially change the shape of the RegExp | |
| 2720 // object. Recheck that we are still on the fast path and bail to runtime | |
| 2721 // otherwise. | |
| 2722 { | |
| 2723 Label next(this); | |
| 2724 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime); | |
| 2725 Bind(&next); | |
| 2726 } | |
| 2727 | |
| 2702 Node* const dollar_string = HeapConstant( | 2728 Node* const dollar_string = HeapConstant( |
| 2703 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); | 2729 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); |
| 2704 Node* const dollar_ix = | 2730 Node* const dollar_ix = |
| 2705 CallBuiltin(Builtins::kStringIndexOf, context, replace_string, | 2731 CallBuiltin(Builtins::kStringIndexOf, context, replace_string, |
| 2706 dollar_string, SmiConstant(0)); | 2732 dollar_string, SmiConstant(0)); |
| 2707 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); | 2733 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); |
| 2708 | 2734 |
| 2709 Return( | 2735 Return( |
| 2710 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); | 2736 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); |
| 2711 } | 2737 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2811 Bind(&if_matched); | 2837 Bind(&if_matched); |
| 2812 { | 2838 { |
| 2813 Node* result = | 2839 Node* result = |
| 2814 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2840 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
| 2815 Return(result); | 2841 Return(result); |
| 2816 } | 2842 } |
| 2817 } | 2843 } |
| 2818 | 2844 |
| 2819 } // namespace internal | 2845 } // namespace internal |
| 2820 } // namespace v8 | 2846 } // namespace v8 |
| OLD | NEW |