Commit c6196ad7 authored by Z Nguyen-Huu's avatar Z Nguyen-Huu Committed by Commit Bot

[builtins] Port RegExp.p.match to Torque

Bug: v8:8976
Change-Id: I6ed0a8d4b64a15b071d9b59121e08db9f6679694
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1779331
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63533}
parent 85e2dbb3
......@@ -993,6 +993,7 @@ torque_files = [
"src/builtins/proxy-set-prototype-of.tq",
"src/builtins/proxy.tq",
"src/builtins/reflect.tq",
"src/builtins/regexp-match.tq",
"src/builtins/regexp-replace.tq",
"src/builtins/regexp-source.tq",
"src/builtins/regexp-test.tq",
......
......@@ -850,8 +850,6 @@ namespace internal {
TFJ(RegExpPrototypeCompile, 2, kReceiver, kPattern, kFlags) \
/* ES #sec-regexp.prototype.exec */ \
TFJ(RegExpPrototypeExec, 1, kReceiver, kString) \
/* ES #sec-regexp.prototype-@@match */ \
TFJ(RegExpPrototypeMatch, 1, kReceiver, kString) \
/* https://tc39.github.io/proposal-string-matchall/ */ \
TFJ(RegExpPrototypeMatchAll, 1, kReceiver, kString) \
/* ES #sec-regexp.prototype-@@search */ \
......@@ -865,7 +863,6 @@ namespace internal {
TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \
TFS(RegExpExecInternal, kRegExp, kString, kLastIndex, kMatchInfo) \
ASM(RegExpInterpreterTrampoline, CCall) \
TFS(RegExpMatchFast, kReceiver, kPattern) \
TFS(RegExpPrototypeExecSlow, kReceiver, kString) \
TFS(RegExpSearchFast, kReceiver, kPattern) \
TFS(RegExpSplit, kRegExp, kString, kLimit) \
......
......@@ -1709,29 +1709,29 @@ TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex(
return var_result.value();
}
void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context,
TNode<Object> regexp,
TNode<String> string,
const bool is_fastpath) {
TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
TNode<Context> context, TNode<Object> regexp, TNode<String> string,
const bool is_fastpath) {
if (is_fastpath) {
CSA_ASSERT_BRANCH(this, [&](Label* ok, Label* not_ok) {
BranchIfFastRegExp_Strict(context, CAST(regexp), ok, not_ok);
});
}
TVARIABLE(Object, var_result);
TNode<BoolT> const is_global =
FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath);
Label if_isglobal(this), if_isnotglobal(this);
Label if_isglobal(this), if_isnotglobal(this), done(this);
Branch(is_global, &if_isglobal, &if_isnotglobal);
BIND(&if_isnotglobal);
{
TNode<Object> const result =
is_fastpath
? RegExpPrototypeExecBody(context, CAST(regexp), string, true)
: RegExpExec(context, regexp, string);
Return(result);
var_result = is_fastpath ? RegExpPrototypeExecBody(context, CAST(regexp),
string, true)
: RegExpExec(context, regexp, string);
Goto(&done);
}
BIND(&if_isglobal);
......@@ -1814,7 +1814,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context,
{
// Return null if there were no matches, otherwise just exit the loop.
GotoIfNot(IntPtrEqual(array.length(), IntPtrZero()), &out);
Return(NullConstant());
var_result = NullConstant();
Goto(&done);
}
BIND(&if_didmatch);
......@@ -1858,41 +1859,13 @@ void RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(TNode<Context> context,
{
// Wrap the match in a JSArray.
TNode<JSArray> const result = array.ToJSArray(context);
Return(result);
var_result = array.ToJSArray(context);
Goto(&done);
}
}
}
// ES#sec-regexp.prototype-@@match
// RegExp.prototype [ @@match ] ( string )
TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) {
TNode<Object> maybe_receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Object> maybe_string = CAST(Parameter(Descriptor::kString));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// Ensure {maybe_receiver} is a JSReceiver.
ThrowIfNotJSReceiver(context, maybe_receiver,
MessageTemplate::kIncompatibleMethodReceiver,
"RegExp.prototype.@@match");
TNode<JSReceiver> receiver = CAST(maybe_receiver);
// Convert {maybe_string} to a String.
TNode<String> const string = ToString_Inline(context, maybe_string);
// Strict: Reads global and unicode properties.
// TODO(jgruber): Handle slow flag accesses on the fast path and make this
// permissive.
Label fast_path(this), slow_path(this);
BranchIfFastRegExp_Strict(context, receiver, &fast_path, &slow_path);
BIND(&fast_path);
// TODO(pwong): Could be optimized to remove the overhead of calling the
// builtin (at the cost of a larger builtin).
Return(CallBuiltin(Builtins::kRegExpMatchFast, context, receiver, string));
BIND(&slow_path);
RegExpPrototypeMatchBody(context, receiver, string, false);
BIND(&done);
return var_result.value();
}
void RegExpMatchAllAssembler::Generate(TNode<Context> context,
......@@ -2066,17 +2039,6 @@ TF_BUILTIN(RegExpPrototypeMatchAll, RegExpMatchAllAssembler) {
Generate(context, native_context, receiver, maybe_string);
}
// Helper that skips a few initial checks. and assumes...
// 1) receiver is a "fast" RegExp
// 2) pattern is a string
TF_BUILTIN(RegExpMatchFast, RegExpBuiltinsAssembler) {
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<String> string = CAST(Parameter(Descriptor::kPattern));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
RegExpPrototypeMatchBody(context, receiver, string, true);
}
void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string) {
CSA_ASSERT(this, IsFastRegExpPermissive(context, regexp));
......
......@@ -179,9 +179,10 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
return CAST(AdvanceStringIndex(string, index, is_unicode, true));
}
void RegExpPrototypeMatchBody(TNode<Context> context, TNode<Object> regexp,
TNode<String> const string,
const bool is_fastpath);
TNode<Object> RegExpPrototypeMatchBody(TNode<Context> context,
TNode<Object> regexp,
TNode<String> const string,
const bool is_fastpath);
void RegExpPrototypeSearchBodyFast(TNode<Context> context,
TNode<JSRegExp> regexp,
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include 'src/builtins/builtins-regexp-gen.h'
namespace regexp {
extern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeMatchBody(
implicit context: Context)(Object, String, constexpr bool): JSAny;
transitioning macro FastRegExpPrototypeMatchBody(implicit context: Context)(
receiver: FastJSRegExp, string: String): JSAny {
return RegExpPrototypeMatchBody(receiver, string, true);
}
transitioning macro SlowRegExpPrototypeMatchBody(implicit context: Context)(
receiver: Object, string: String): JSAny {
return RegExpPrototypeMatchBody(receiver, string, false);
}
// Helper that skips a few initial checks. and assumes...
// 1) receiver is a "fast" RegExp
// 2) pattern is a string
transitioning builtin RegExpMatchFast(implicit context: Context)(
receiver: FastJSRegExp, string: String): JSAny {
return FastRegExpPrototypeMatchBody(receiver, string);
}
// ES#sec-regexp.prototype-@@match
// RegExp.prototype [ @@match ] ( string )
transitioning javascript builtin RegExpPrototypeMatch(
js-implicit context: Context, receiver: JSAny)(string: JSAny): JSAny {
ThrowIfNotJSReceiver(
receiver, kIncompatibleMethodReceiver, 'RegExp.prototype.@@match');
const receiver = UnsafeCast<JSReceiver>(receiver);
const string: String = ToString_Inline(context, string);
// Strict: Reads global and unicode properties.
// TODO(jgruber): Handle slow flag accesses on the fast path and make this
// permissive.
const fastRegExp = Cast<FastJSRegExp>(receiver)
otherwise return SlowRegExpPrototypeMatchBody(receiver, string);
// TODO(pwong): Could be optimized to remove the overhead of calling the
// builtin (at the cost of a larger builtin).
return RegExpMatchFast(fastRegExp, string);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment