[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:
parent
141138f84a
commit
aa41caa576
1
BUILD.gn
1
BUILD.gn
@ -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",
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
33
src/builtins/regexp-source.tq
Normal file
33
src/builtins/regexp-source.tq
Normal 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 '(?:)';
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user