[builtins] Port RegExpExec function to Torque

Bug: v8:8976
Change-Id: I992b5527fc1d8f58b2fdb5a212651a933c25f856
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1860998
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64303}
This commit is contained in:
Z Nguyen-Huu 2019-10-15 17:21:44 -07:00 committed by Commit Bot
parent 9a9fc1c112
commit 958616da50
6 changed files with 31 additions and 58 deletions

View File

@ -1494,55 +1494,6 @@ TNode<BoolT> RegExpBuiltinsAssembler::FlagGetter(TNode<Context> context,
: SlowFlagGetter(context, regexp, flag);
}
// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
TNode<Object> RegExpBuiltinsAssembler::RegExpExec(
TNode<Context> context, TNode<JSReceiver> maybe_regexp,
TNode<String> string) {
TVARIABLE(Object, var_result);
Label out(this);
// Take the slow path of fetching the exec property, calling it, and
// verifying its return value.
// Get the exec property.
TNode<Object> const exec =
GetProperty(context, maybe_regexp, isolate()->factory()->exec_string());
// Is {exec} callable?
Label if_iscallable(this), if_isnotcallable(this);
GotoIf(TaggedIsSmi(exec), &if_isnotcallable);
TNode<Map> const exec_map = LoadMap(CAST(exec));
Branch(IsCallableMap(exec_map), &if_iscallable, &if_isnotcallable);
BIND(&if_iscallable);
{
Callable call_callable = CodeFactory::Call(isolate());
var_result = CallJS(call_callable, context, exec, maybe_regexp, string);
GotoIf(IsNull(var_result.value()), &out);
ThrowIfNotJSReceiver(context, var_result.value(),
MessageTemplate::kInvalidRegExpExecResult, "");
Goto(&out);
}
BIND(&if_isnotcallable);
{
ThrowIfNotInstanceType(context, maybe_regexp, JS_REG_EXP_TYPE,
"RegExp.prototype.exec");
var_result = CallBuiltin(Builtins::kRegExpPrototypeExecSlow, context,
maybe_regexp, string);
Goto(&out);
}
BIND(&out);
return var_result.value();
}
TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex(
SloppyTNode<String> string, SloppyTNode<Number> index,
SloppyTNode<BoolT> is_unicode, bool is_fastpath) {

View File

@ -170,10 +170,6 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
const TNode<Object> maybe_pattern,
const TNode<Object> maybe_flags);
TNode<Object> RegExpExec(TNode<Context> context,
TNode<JSReceiver> maybe_regexp,
TNode<String> string);
TNode<Number> AdvanceStringIndex(SloppyTNode<String> string,
SloppyTNode<Number> index,
SloppyTNode<BoolT> is_unicode,

View File

@ -178,7 +178,7 @@ namespace regexp {
iteratingRegExp, matchIndices, iteratingString);
isFastRegExp = true;
} else {
match = RegExpExec(context, iteratingRegExp, iteratingString);
match = RegExpExec(iteratingRegExp, iteratingString);
if (match == Null) {
goto IfNoMatch;
}

View File

@ -59,7 +59,7 @@ namespace regexp {
}
// Call exec.
const execResult = RegExpExec(context, regexp, string);
const execResult = RegExpExec(regexp, string);
// Reset last index if necessary.
const currentLastIndex = SlowLoadLastIndex(regexp);

View File

@ -20,7 +20,7 @@ namespace regexp {
otherwise return False;
return True;
}
const matchIndices = RegExpExec(context, receiver, str);
const matchIndices = RegExpExec(receiver, str);
return SelectBooleanConstant(matchIndices != Null);
}

View File

@ -22,8 +22,34 @@ namespace regexp {
BranchIfFastRegExp_Permissive(o) otherwise return true, return false;
}
extern macro RegExpBuiltinsAssembler::RegExpExec(Context, JSReceiver, String):
JSAny;
const kInvalidRegExpExecResult: constexpr MessageTemplate
generates 'MessageTemplate::kInvalidRegExpExecResult';
// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S )
@export
transitioning macro RegExpExec(implicit context: Context)(
receiver: JSReceiver, string: String): JSAny {
// Take the slow path of fetching the exec property, calling it, and
// verifying its return value.
const exec = GetProperty(receiver, 'exec');
// Is {exec} callable?
typeswitch (exec) {
case (execCallable: Callable): {
const result = Call(context, execCallable, receiver, string);
if (result != Null) {
ThrowIfNotJSReceiver(result, kInvalidRegExpExecResult, '');
}
return result;
}
case (Object): {
const regexp = Cast<JSRegExp>(receiver) otherwise ThrowTypeError(
kIncompatibleMethodReceiver, 'RegExp.prototype.exec', receiver);
return RegExpPrototypeExecSlow(regexp, string);
}
}
}
extern macro
RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast(