Chromium Code Reviews| Index: src/builtins/builtins-regexp-gen.cc |
| diff --git a/src/builtins/builtins-regexp-gen.cc b/src/builtins/builtins-regexp-gen.cc |
| index 86772ecd398e0d66c9deddd94c8c156ad349758a..f9851bf42e0c07b8314d9bc7d3e93701dfcebe8e 100644 |
| --- a/src/builtins/builtins-regexp-gen.cc |
| +++ b/src/builtins/builtins-regexp-gen.cc |
| @@ -2303,12 +2303,21 @@ TF_BUILTIN(RegExpSplit, RegExpBuiltinsAssembler) { |
| // Convert {maybe_limit} to a uint32, capping at the maximal smi value. |
| Variable var_limit(this, MachineRepresentation::kTagged); |
| - Label if_limitissmimax(this), limit_done(this); |
| + Label if_limitissmimax(this), limit_done(this), runtime(this); |
| GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); |
| + 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
|
| { |
| - Node* const limit = ToUint32(context, maybe_limit); |
| + // ToUint32(limit) could potentially change the shape of the RegExp |
| + // object. Recheck that we are still on the fast path and bail to runtime |
| + // otherwise. |
| + { |
| + Label next(this); |
| + 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.
|
| + Bind(&next); |
| + } |
| + |
| GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax); |
| var_limit.Bind(limit); |
| @@ -2328,6 +2337,14 @@ TF_BUILTIN(RegExpSplit, RegExpBuiltinsAssembler) { |
| Node* const limit = var_limit.value(); |
| RegExpPrototypeSplitBody(context, regexp, string, limit); |
| } |
| + |
| + Bind(&runtime); |
| + { |
| + // The runtime call passes in limit to ensure the second ToUint32(limit) |
| + // call is not observable. |
| + 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.{
|
| + Return(CallRuntime(Runtime::kRegExpSplit, context, regexp, string, limit)); |
| + } |
| } |
| // ES#sec-regexp.prototype-@@split |
| @@ -2699,6 +2716,15 @@ TF_BUILTIN(RegExpReplace, RegExpBuiltinsAssembler) { |
| Node* const replace_string = |
| CallBuiltin(Builtins::kToString, context, replace_value); |
| + // ToString(replaceValue) could potentially change the shape of the RegExp |
| + // object. Recheck that we are still on the fast path and bail to runtime |
| + // otherwise. |
| + { |
| + Label next(this); |
| + BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime); |
| + Bind(&next); |
| + } |
| + |
| Node* const dollar_string = HeapConstant( |
| isolate()->factory()->LookupSingleCharacterStringFromCode('$')); |
| Node* const dollar_ix = |