[CSA][cleanup] TNodify builtins regexp gen

Bug: v8:6949, v8:9396
Change-Id: I035a00f61077e49377c9cd39ae1b216a80c98e6b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1803615
Reviewed-by: Dan Elphick <delphick@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63848}
This commit is contained in:
Santiago Aboy Solanes 2019-09-16 16:07:50 +01:00 committed by Commit Bot
parent c3d7f5f188
commit 7fcbde16e7
3 changed files with 87 additions and 95 deletions

View File

@ -237,8 +237,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2)); IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2));
TVARIABLE(IntPtrT, var_to_cursor, IntPtrConstant(1)); TVARIABLE(IntPtrT, var_to_cursor, IntPtrConstant(1));
Variable* vars[] = {&var_from_cursor, &var_to_cursor}; Label loop(this, {&var_from_cursor, &var_to_cursor});
Label loop(this, 2, vars);
Goto(&loop); Goto(&loop);
BIND(&loop); BIND(&loop);
@ -317,9 +316,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
TVARIABLE(IntPtrT, var_i, IntPtrZero()); TVARIABLE(IntPtrT, var_i, IntPtrZero());
Variable* vars[] = {&var_i}; Label loop(this, &var_i);
const int vars_count = sizeof(vars) / sizeof(vars[0]);
Label loop(this, vars_count, vars);
Goto(&loop); Goto(&loop);
BIND(&loop); BIND(&loop);
@ -908,14 +905,13 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype(
return TaggedEqual(receiver, initial_prototype); return TaggedEqual(receiver, initial_prototype);
} }
Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(
SloppyTNode<Context> context, SloppyTNode<Object> object, TNode<Context> context, TNode<Object> object, TNode<Map> map) {
SloppyTNode<Map> map) {
Label out(this); Label out(this);
VARIABLE(var_result, MachineRepresentation::kWord32); TVARIABLE(BoolT, var_result);
#ifdef V8_ENABLE_FORCE_SLOW_PATH #ifdef V8_ENABLE_FORCE_SLOW_PATH
var_result.Bind(Int32Constant(0)); var_result = Int32FalseConstant();
GotoIfForceSlowPath(&out); GotoIfForceSlowPath(&out);
#endif #endif
@ -926,13 +922,13 @@ Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(
LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset); LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
TNode<BoolT> const has_initialmap = TaggedEqual(map, initial_map); TNode<BoolT> const has_initialmap = TaggedEqual(map, initial_map);
var_result.Bind(has_initialmap); var_result = has_initialmap;
GotoIfNot(has_initialmap, &out); GotoIfNot(has_initialmap, &out);
// The smi check is required to omit ToLength(lastIndex) calls with possible // The smi check is required to omit ToLength(lastIndex) calls with possible
// user-code execution on the fast path. // user-code execution on the fast path.
TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object)); TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object));
var_result.Bind(TaggedIsPositiveSmi(last_index)); var_result = TaggedIsPositiveSmi(last_index);
Goto(&out); Goto(&out);
BIND(&out); BIND(&out);
@ -984,8 +980,8 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec(
return var_result.value(); return var_result.value();
} }
Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(
SloppyTNode<Context> context, SloppyTNode<Object> object) { TNode<Context> context, TNode<Object> object) {
CSA_ASSERT(this, TaggedIsNotSmi(object)); CSA_ASSERT(this, TaggedIsNotSmi(object));
return IsFastRegExpNoPrototype(context, object, LoadMap(CAST(object))); return IsFastRegExpNoPrototype(context, object, LoadMap(CAST(object)));
} }
@ -1060,10 +1056,9 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp_Permissive(
if_isunmodified, if_ismodified); if_isunmodified, if_ismodified);
} }
void RegExpBuiltinsAssembler::BranchIfFastRegExpResult(Node* const context, void RegExpBuiltinsAssembler::BranchIfFastRegExpResult(
Node* const object, const TNode<Context> context, const TNode<Object> object,
Label* if_isunmodified, Label* if_isunmodified, Label* if_ismodified) {
Label* if_ismodified) {
// Could be a Smi. // Could be a Smi.
TNode<Map> const map = LoadReceiverMap(object); TNode<Map> const map = LoadReceiverMap(object);
@ -1260,7 +1255,7 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context,
{ {
TNode<String> const result = AllocateSeqOneByteString(var_length.value()); TNode<String> const result = AllocateSeqOneByteString(var_length.value());
VARIABLE(var_offset, MachineType::PointerRepresentation(), TVARIABLE(IntPtrT, var_offset,
IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
#define CASE_FOR_FLAG(FLAG, CHAR) \ #define CASE_FOR_FLAG(FLAG, CHAR) \
@ -1270,7 +1265,7 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context,
TNode<Int32T> const value = Int32Constant(CHAR); \ TNode<Int32T> const value = Int32Constant(CHAR); \
StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
var_offset.value(), value); \ var_offset.value(), value); \
var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \ var_offset = IntPtrAdd(var_offset.value(), int_one); \
Goto(&next); \ Goto(&next); \
BIND(&next); \ BIND(&next); \
} while (false) } while (false)
@ -1339,12 +1334,9 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsRegExp(TNode<Context> context,
// ES#sec-regexpinitialize // ES#sec-regexpinitialize
// Runtime Semantics: RegExpInitialize ( obj, pattern, flags ) // Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context, TNode<Object> RegExpBuiltinsAssembler::RegExpInitialize(
Node* const regexp, const TNode<Context> context, const TNode<JSRegExp> regexp,
Node* const maybe_pattern, const TNode<Object> maybe_pattern, const TNode<Object> maybe_flags) {
Node* const maybe_flags) {
CSA_ASSERT(this, IsJSRegExp(regexp));
// Normalize pattern. // Normalize pattern.
TNode<Object> const pattern = Select<Object>( TNode<Object> const pattern = Select<Object>(
IsUndefined(maybe_pattern), [=] { return EmptyStringConstant(); }, IsUndefined(maybe_pattern), [=] { return EmptyStringConstant(); },
@ -1451,7 +1443,7 @@ TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) {
// Allocate. // Allocate.
VARIABLE(var_regexp, MachineRepresentation::kTagged); TVARIABLE(JSRegExp, var_regexp);
{ {
Label allocate_jsregexp(this), allocate_generic(this, Label::kDeferred), Label allocate_jsregexp(this), allocate_generic(this, Label::kDeferred),
next(this); next(this);
@ -1462,25 +1454,23 @@ TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) {
{ {
TNode<Map> const initial_map = CAST(LoadObjectField( TNode<Map> const initial_map = CAST(LoadObjectField(
regexp_function, JSFunction::kPrototypeOrInitialMapOffset)); regexp_function, JSFunction::kPrototypeOrInitialMapOffset));
TNode<JSObject> const regexp = AllocateJSObjectFromMap(initial_map); var_regexp = CAST(AllocateJSObjectFromMap(initial_map));
var_regexp.Bind(regexp);
Goto(&next); Goto(&next);
} }
BIND(&allocate_generic); BIND(&allocate_generic);
{ {
ConstructorBuiltinsAssembler constructor_assembler(this->state()); ConstructorBuiltinsAssembler constructor_assembler(this->state());
TNode<JSObject> const regexp = constructor_assembler.EmitFastNewObject( var_regexp = CAST(constructor_assembler.EmitFastNewObject(
context, regexp_function, CAST(var_new_target.value())); context, regexp_function, CAST(var_new_target.value())));
var_regexp.Bind(regexp);
Goto(&next); Goto(&next);
} }
BIND(&next); BIND(&next);
} }
Node* const result = RegExpInitialize(context, var_regexp.value(), const TNode<Object> result = RegExpInitialize(
var_pattern.value(), var_flags.value()); context, var_regexp.value(), var_pattern.value(), var_flags.value());
Return(result); Return(result);
} }
@ -1494,10 +1484,10 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) {
ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE,
"RegExp.prototype.compile"); "RegExp.prototype.compile");
Node* const receiver = maybe_receiver; const TNode<JSRegExp> receiver = CAST(maybe_receiver);
VARIABLE(var_flags, MachineRepresentation::kTagged, maybe_flags); TVARIABLE(Object, var_flags, maybe_flags);
VARIABLE(var_pattern, MachineRepresentation::kTagged, maybe_pattern); TVARIABLE(Object, var_pattern, maybe_pattern);
// Handle a JSRegExp pattern. // Handle a JSRegExp pattern.
{ {
@ -1506,8 +1496,6 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) {
GotoIf(TaggedIsSmi(maybe_pattern), &next); GotoIf(TaggedIsSmi(maybe_pattern), &next);
GotoIfNot(IsJSRegExp(CAST(maybe_pattern)), &next); GotoIfNot(IsJSRegExp(CAST(maybe_pattern)), &next);
Node* const pattern = maybe_pattern;
// {maybe_flags} must be undefined in this case, otherwise throw. // {maybe_flags} must be undefined in this case, otherwise throw.
{ {
Label next(this); Label next(this);
@ -1518,19 +1506,20 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) {
BIND(&next); BIND(&next);
} }
TNode<String> const new_flags = FlagsGetter(context, CAST(pattern), true); const TNode<JSRegExp> pattern = CAST(maybe_pattern);
TNode<String> const new_flags = FlagsGetter(context, pattern, true);
TNode<Object> const new_pattern = TNode<Object> const new_pattern =
LoadObjectField(pattern, JSRegExp::kSourceOffset); LoadObjectField(pattern, JSRegExp::kSourceOffset);
var_flags.Bind(new_flags); var_flags = new_flags;
var_pattern.Bind(new_pattern); var_pattern = new_pattern;
Goto(&next); Goto(&next);
BIND(&next); BIND(&next);
} }
Node* const result = RegExpInitialize(context, receiver, var_pattern.value(), const TNode<Object> result = RegExpInitialize(
var_flags.value()); context, receiver, var_pattern.value(), var_flags.value());
Return(result); Return(result);
} }
@ -1601,8 +1590,9 @@ TNode<BoolT> RegExpBuiltinsAssembler::FlagGetter(TNode<Context> context,
} }
// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context, TNode<Object> RegExpBuiltinsAssembler::RegExpExec(
Node* regexp, Node* string) { TNode<Context> context, TNode<JSReceiver> maybe_regexp,
TNode<String> string) {
TVARIABLE(Object, var_result); TVARIABLE(Object, var_result);
Label out(this); Label out(this);
@ -1611,7 +1601,7 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context,
// Get the exec property. // Get the exec property.
TNode<Object> const exec = TNode<Object> const exec =
GetProperty(context, regexp, isolate()->factory()->exec_string()); GetProperty(context, maybe_regexp, isolate()->factory()->exec_string());
// Is {exec} callable? // Is {exec} callable?
Label if_iscallable(this), if_isnotcallable(this); Label if_iscallable(this), if_isnotcallable(this);
@ -1624,7 +1614,8 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context,
BIND(&if_iscallable); BIND(&if_iscallable);
{ {
Callable call_callable = CodeFactory::Call(isolate()); Callable call_callable = CodeFactory::Call(isolate());
var_result = CAST(CallJS(call_callable, context, exec, regexp, string)); var_result =
CAST(CallJS(call_callable, context, exec, maybe_regexp, string));
GotoIf(IsNull(var_result.value()), &out); GotoIf(IsNull(var_result.value()), &out);
@ -1636,11 +1627,11 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context,
BIND(&if_isnotcallable); BIND(&if_isnotcallable);
{ {
ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, ThrowIfNotInstanceType(context, maybe_regexp, JS_REGEXP_TYPE,
"RegExp.prototype.exec"); "RegExp.prototype.exec");
var_result = CallBuiltin(Builtins::kRegExpPrototypeExecSlow, context, var_result = CallBuiltin(Builtins::kRegExpPrototypeExecSlow, context,
regexp, string); maybe_regexp, string);
Goto(&out); Goto(&out);
} }
@ -1731,7 +1722,7 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
{ {
var_result = is_fastpath ? RegExpPrototypeExecBody(context, CAST(regexp), var_result = is_fastpath ? RegExpPrototypeExecBody(context, CAST(regexp),
string, true) string, true)
: RegExpExec(context, regexp, string); : RegExpExec(context, CAST(regexp), string);
Goto(&done); Goto(&done);
} }
@ -1749,9 +1740,9 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
// Loop preparations. Within the loop, collect results from RegExpExec // Loop preparations. Within the loop, collect results from RegExpExec
// and store match strings in the array. // and store match strings in the array.
Variable* vars[] = {array.var_array(), array.var_length(), Label loop(this,
array.var_capacity()}; {array.var_array(), array.var_length(), array.var_capacity()}),
Label loop(this, 3, vars), out(this); out(this);
// Check if the regexp is an ATOM type. If then, keep the literal string to // Check if the regexp is an ATOM type. If then, keep the literal string to
// search for so that we can avoid calling substring in the loop below. // search for so that we can avoid calling substring in the loop below.
@ -1772,7 +1763,7 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
BIND(&loop); BIND(&loop);
{ {
VARIABLE(var_match, MachineRepresentation::kTagged); TVARIABLE(String, var_match);
Label if_didmatch(this), if_didnotmatch(this); Label if_didmatch(this), if_didnotmatch(this);
if (is_fastpath) { if (is_fastpath) {
@ -1790,24 +1781,24 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
match_indices, RegExpMatchInfo::kFirstCaptureIndex); match_indices, RegExpMatchInfo::kFirstCaptureIndex);
TNode<Object> const match_to = UnsafeLoadFixedArrayElement( TNode<Object> const match_to = UnsafeLoadFixedArrayElement(
match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
var_match.Bind(CallBuiltin(Builtins::kSubString, context, string, var_match = CAST(CallBuiltin(Builtins::kSubString, context, string,
match_from, match_to)); match_from, match_to));
Goto(&if_didmatch); Goto(&if_didmatch);
} }
BIND(&donotsubstring); BIND(&donotsubstring);
var_match.Bind(var_search_string.value()); var_match = var_search_string.value();
Goto(&if_didmatch); Goto(&if_didmatch);
} else { } else {
DCHECK(!is_fastpath); DCHECK(!is_fastpath);
TNode<Object> const result = RegExpExec(context, regexp, string); TNode<Object> const result = RegExpExec(context, CAST(regexp), string);
Label load_match(this); Label load_match(this);
Branch(IsNull(result), &if_didnotmatch, &load_match); Branch(IsNull(result), &if_didnotmatch, &load_match);
BIND(&load_match); BIND(&load_match);
var_match.Bind( var_match =
ToString_Inline(context, GetProperty(context, result, SmiZero()))); ToString_Inline(context, GetProperty(context, result, SmiZero()));
Goto(&if_didmatch); Goto(&if_didmatch);
} }
@ -1821,11 +1812,11 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
BIND(&if_didmatch); BIND(&if_didmatch);
{ {
Node* match = var_match.value(); TNode<String> match = var_match.value();
// Store the match, growing the fixed array if needed. // Store the match, growing the fixed array if needed.
array.Push(CAST(match)); array.Push(match);
// Advance last index if the match is the empty string. // Advance last index if the match is the empty string.
@ -2113,11 +2104,9 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
TVARIABLE(Smi, var_last_matched_until, SmiZero()); TVARIABLE(Smi, var_last_matched_until, SmiZero());
TVARIABLE(Smi, var_next_search_from, SmiZero()); TVARIABLE(Smi, var_next_search_from, SmiZero());
Variable* vars[] = {array.var_array(), array.var_length(), Label loop(this, {array.var_array(), array.var_length(), array.var_capacity(),
array.var_capacity(), &var_last_matched_until, &var_last_matched_until, &var_next_search_from}),
&var_next_search_from}; push_suffix_and_out(this), out(this);
const int vars_count = sizeof(vars) / sizeof(vars[0]);
Label loop(this, vars_count, vars), push_suffix_and_out(this), out(this);
Goto(&loop); Goto(&loop);
BIND(&loop); BIND(&loop);
@ -2194,19 +2183,18 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
match_indices, RegExpMatchInfo::kNumberOfCapturesIndex)); match_indices, RegExpMatchInfo::kNumberOfCapturesIndex));
TNode<IntPtrT> const int_num_registers = SmiUntag(num_registers); TNode<IntPtrT> const int_num_registers = SmiUntag(num_registers);
VARIABLE(var_reg, MachineType::PointerRepresentation()); TVARIABLE(IntPtrT, var_reg, IntPtrConstant(2));
var_reg.Bind(IntPtrConstant(2));
Variable* vars[] = {array.var_array(), array.var_length(), VariableList vars({array.var_array(), array.var_length(),
array.var_capacity(), &var_reg}; array.var_capacity(), &var_reg},
const int vars_count = sizeof(vars) / sizeof(vars[0]); zone());
Label nested_loop(this, vars_count, vars), nested_loop_out(this); Label nested_loop(this, vars), nested_loop_out(this);
Branch(IntPtrLessThan(var_reg.value(), int_num_registers), &nested_loop, Branch(IntPtrLessThan(var_reg.value(), int_num_registers), &nested_loop,
&nested_loop_out); &nested_loop_out);
BIND(&nested_loop); BIND(&nested_loop);
{ {
Node* const reg = var_reg.value(); const TNode<IntPtrT> reg = var_reg.value();
TNode<Object> const from = LoadFixedArrayElement( TNode<Object> const from = LoadFixedArrayElement(
match_indices, reg, match_indices, reg,
RegExpMatchInfo::kFirstCaptureIndex * kTaggedSize, mode); RegExpMatchInfo::kFirstCaptureIndex * kTaggedSize, mode);
@ -2215,30 +2203,30 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
(RegExpMatchInfo::kFirstCaptureIndex + 1) * kTaggedSize, mode)); (RegExpMatchInfo::kFirstCaptureIndex + 1) * kTaggedSize, mode));
Label select_capture(this), select_undefined(this), store_value(this); Label select_capture(this), select_undefined(this), store_value(this);
VARIABLE(var_value, MachineRepresentation::kTagged); TVARIABLE(Object, var_value);
Branch(SmiEqual(to, SmiConstant(-1)), &select_undefined, Branch(SmiEqual(to, SmiConstant(-1)), &select_undefined,
&select_capture); &select_capture);
BIND(&select_capture); BIND(&select_capture);
{ {
var_value.Bind( var_value =
CallBuiltin(Builtins::kSubString, context, string, from, to)); CallBuiltin(Builtins::kSubString, context, string, from, to);
Goto(&store_value); Goto(&store_value);
} }
BIND(&select_undefined); BIND(&select_undefined);
{ {
var_value.Bind(UndefinedConstant()); var_value = UndefinedConstant();
Goto(&store_value); Goto(&store_value);
} }
BIND(&store_value); BIND(&store_value);
{ {
array.Push(CAST(var_value.value())); array.Push(var_value.value());
GotoIf(WordEqual(array.length(), int_limit), &out); GotoIf(WordEqual(array.length(), int_limit), &out);
TNode<WordT> const new_reg = IntPtrAdd(reg, IntPtrConstant(2)); const TNode<IntPtrT> new_reg = IntPtrAdd(reg, IntPtrConstant(2));
var_reg.Bind(new_reg); var_reg = new_reg;
Branch(IntPtrLessThan(new_reg, int_num_registers), &nested_loop, Branch(IntPtrLessThan(new_reg, int_num_registers), &nested_loop,
&nested_loop_out); &nested_loop_out);
@ -2255,8 +2243,8 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
BIND(&push_suffix_and_out); BIND(&push_suffix_and_out);
{ {
TNode<Smi> const from = var_last_matched_until.value(); const TNode<Smi> from = var_last_matched_until.value();
Node* const to = string_length; const TNode<Smi> to = string_length;
array.Push(CallBuiltin(Builtins::kSubString, context, string, from, to)); array.Push(CallBuiltin(Builtins::kSubString, context, string, from, to));
Goto(&out); Goto(&out);
} }

View File

@ -139,17 +139,17 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
// Performs fast path checks on the given object itself, but omits prototype // Performs fast path checks on the given object itself, but omits prototype
// checks. // checks.
Node* IsFastRegExpNoPrototype(SloppyTNode<Context> context, TNode<BoolT> IsFastRegExpNoPrototype(TNode<Context> context,
SloppyTNode<Object> object); TNode<Object> object);
Node* IsFastRegExpNoPrototype(SloppyTNode<Context> context, TNode<BoolT> IsFastRegExpNoPrototype(TNode<Context> context,
SloppyTNode<Object> object, TNode<Object> object, TNode<Map> map);
SloppyTNode<Map> map);
// For debugging only. Uses a slow GetProperty call to fetch object.exec. // For debugging only. Uses a slow GetProperty call to fetch object.exec.
TNode<BoolT> IsFastRegExpWithOriginalExec(TNode<Context> context, TNode<BoolT> IsFastRegExpWithOriginalExec(TNode<Context> context,
TNode<JSRegExp> object); TNode<JSRegExp> object);
void BranchIfFastRegExpResult(Node* const context, Node* const object, void BranchIfFastRegExpResult(const TNode<Context> context,
const TNode<Object> object,
Label* if_isunmodified, Label* if_ismodified); Label* if_isunmodified, Label* if_ismodified);
TNode<String> FlagsGetter(TNode<Context> context, TNode<Object> regexp, TNode<String> FlagsGetter(TNode<Context> context, TNode<Object> regexp,
@ -167,10 +167,14 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
TNode<BoolT> FlagGetter(TNode<Context> context, TNode<Object> regexp, TNode<BoolT> FlagGetter(TNode<Context> context, TNode<Object> regexp,
JSRegExp::Flag flag, bool is_fastpath); JSRegExp::Flag flag, bool is_fastpath);
Node* RegExpInitialize(Node* const context, Node* const regexp, TNode<Object> RegExpInitialize(const TNode<Context> context,
Node* const maybe_pattern, Node* const maybe_flags); const TNode<JSRegExp> regexp,
const TNode<Object> maybe_pattern,
const TNode<Object> maybe_flags);
TNode<Object> RegExpExec(TNode<Context> context, Node* regexp, Node* string); TNode<Object> RegExpExec(TNode<Context> context,
TNode<JSReceiver> maybe_regexp,
TNode<String> string);
TNode<Number> AdvanceStringIndex(SloppyTNode<String> string, TNode<Number> AdvanceStringIndex(SloppyTNode<String> string,
SloppyTNode<Number> index, SloppyTNode<Number> index,

View File

@ -22,7 +22,7 @@ namespace regexp {
BranchIfFastRegExp_Permissive(o) otherwise return true, return false; BranchIfFastRegExp_Permissive(o) otherwise return true, return false;
} }
extern macro RegExpBuiltinsAssembler::RegExpExec(Context, JSAny, JSAny): extern macro RegExpBuiltinsAssembler::RegExpExec(Context, JSReceiver, String):
JSAny; JSAny;
extern macro extern macro