[builtins] Port RegExp SourceGetter to Torque

Bug: v8:8976
Change-Id: I5eb7871a5d5daa15faff73666d400bb87627bbe0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1762711
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63323}
This commit is contained in:
Z Nguyen-Huu 2019-08-21 10:39:14 -07:00 committed by Commit Bot
parent 141138f84a
commit aa41caa576
6 changed files with 52 additions and 58 deletions

View File

@ -995,6 +995,7 @@ torque_files = [
"src/builtins/proxy.tq",
"src/builtins/reflect.tq",
"src/builtins/regexp-replace.tq",
"src/builtins/regexp-source.tq",
"src/builtins/regexp-test.tq",
"src/builtins/regexp.tq",
"src/builtins/string.tq",

View File

@ -863,8 +863,6 @@ namespace internal {
TFJ(RegExpPrototypeMultilineGetter, 0, kReceiver) \
/* ES #sec-regexp.prototype-@@search */ \
TFJ(RegExpPrototypeSearch, 1, kReceiver, kString) \
/* ES #sec-get-regexp.prototype.source */ \
TFJ(RegExpPrototypeSourceGetter, 0, kReceiver) \
/* ES #sec-get-regexp.prototype.sticky */ \
TFJ(RegExpPrototypeStickyGetter, 0, kReceiver) \
CPP(RegExpPrototypeToString) \

View File

@ -919,6 +919,17 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver(
return var_value_map.value();
}
TNode<BoolT> RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype(
SloppyTNode<Context> context, SloppyTNode<Object> receiver) {
TNode<Context> native_context = LoadNativeContext(context);
Node* const regexp_fun =
LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
TNode<Object> const initial_prototype = LoadMapPrototype(initial_map);
return WordEqual(receiver, initial_prototype);
}
Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype(Node* const context,
Node* const object,
Node* const map) {
@ -1568,54 +1579,6 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) {
Return(result);
}
// ES6 21.2.5.10.
// ES #sec-get-regexp.prototype.source
TF_BUILTIN(RegExpPrototypeSourceGetter, RegExpBuiltinsAssembler) {
TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
// Check whether we have an unmodified regexp instance.
Label if_isjsregexp(this), if_isnotjsregexp(this, Label::kDeferred);
GotoIf(TaggedIsSmi(receiver), &if_isnotjsregexp);
Branch(IsJSRegExp(CAST(receiver)), &if_isjsregexp, &if_isnotjsregexp);
BIND(&if_isjsregexp);
Return(LoadObjectField(CAST(receiver), JSRegExp::kSourceOffset));
BIND(&if_isnotjsregexp);
{
Isolate* isolate = this->isolate();
Node* const native_context = LoadNativeContext(context);
Node* const regexp_fun =
LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const initial_prototype = LoadMapPrototype(initial_map);
Label if_isprototype(this), if_isnotprototype(this);
Branch(WordEqual(receiver, initial_prototype), &if_isprototype,
&if_isnotprototype);
BIND(&if_isprototype);
{
const int counter = v8::Isolate::kRegExpPrototypeSourceGetter;
Node* const counter_smi = SmiConstant(counter);
CallRuntime(Runtime::kIncrementUseCounter, context, counter_smi);
Node* const result =
HeapConstant(isolate->factory()->NewStringFromAsciiChecked("(?:)"));
Return(result);
}
BIND(&if_isnotprototype);
{
ThrowTypeError(context, MessageTemplate::kRegExpNonRegExp,
"RegExp.prototype.source");
}
}
}
// Fast-path implementation for flag checks on an unmodified JSRegExp instance.
TNode<Int32T> RegExpBuiltinsAssembler::FastFlagGetter(TNode<JSRegExp> regexp,
JSRegExp::Flag flag) {
@ -1701,15 +1664,8 @@ void RegExpBuiltinsAssembler::FlagGetter(Node* context, Node* receiver,
BIND(&if_isnotunmodifiedjsregexp);
{
Node* const native_context = LoadNativeContext(context);
Node* const regexp_fun =
LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const initial_prototype = LoadMapPrototype(initial_map);
Label if_isprototype(this), if_isnotprototype(this);
Branch(WordEqual(receiver, initial_prototype), &if_isprototype,
Branch(IsReceiverInitialRegExpPrototype(context, receiver), &if_isprototype,
&if_isnotprototype);
BIND(&if_isprototype);

View File

@ -87,6 +87,9 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
MessageTemplate msg_template,
char const* method_name);
TNode<BoolT> IsReceiverInitialRegExpPrototype(SloppyTNode<Context> context,
SloppyTNode<Object> receiver);
// Fast path check logic.
//
// Are you afraid? If not, you should be.

View File

@ -0,0 +1,33 @@
// 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 {
const kRegExpNonRegExp: constexpr MessageTemplate
generates 'MessageTemplate::kRegExpNonRegExp';
extern runtime IncrementUseCounter(Context, Smi): void;
const kRegExpPrototypeSourceGetter: constexpr int31
generates 'v8::Isolate::kRegExpPrototypeSourceGetter';
// ES6 21.2.5.10.
// ES #sec-get-regexp.prototype.source
transitioning javascript builtin RegExpPrototypeSourceGetter(
js-implicit context: Context)(receiver: Object): Object {
typeswitch (receiver) {
case (receiver: JSRegExp): {
return receiver.source;
}
case (Object): {
}
}
if (!IsReceiverInitialRegExpPrototype(receiver)) {
const methodName: constexpr string = 'RegExp.prototype.source';
ThrowTypeError(kRegExpNonRegExp, methodName);
}
IncrementUseCounter(context, SmiConstant(kRegExpPrototypeSourceGetter));
return '(?:)';
}
}

View File

@ -29,4 +29,7 @@ namespace regexp {
RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast(
implicit context: Context)(JSRegExp, String):
RegExpMatchInfo labels IfDidNotMatch;
extern macro RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype(
implicit context: Context)(Object): bool;
}