[builtins] Port RegExp FlagsGetter to Torque
Bug: v8:8976 Change-Id: Id6449c0e2a473db7b1d3a1c143324d8810000374 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1773558 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@{#63464}
This commit is contained in:
parent
e36eb3e947
commit
e3debe47cc
@ -1665,6 +1665,9 @@ extern macro ThrowTypeError(implicit context: Context)(
|
|||||||
extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)(
|
extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)(
|
||||||
Smi, Object, Object): void;
|
Smi, Object, Object): void;
|
||||||
|
|
||||||
|
extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)(
|
||||||
|
JSAny, constexpr MessageTemplate, constexpr string): void;
|
||||||
|
|
||||||
extern macro ArraySpeciesCreate(Context, JSAny, Number): JSReceiver;
|
extern macro ArraySpeciesCreate(Context, JSAny, Number): JSReceiver;
|
||||||
extern macro ArrayCreate(implicit context: Context)(Number): JSArray;
|
extern macro ArrayCreate(implicit context: Context)(Number): JSArray;
|
||||||
extern macro BuildAppendJSArray(
|
extern macro BuildAppendJSArray(
|
||||||
|
@ -847,8 +847,6 @@ namespace internal {
|
|||||||
TFJ(RegExpPrototypeCompile, 2, kReceiver, kPattern, kFlags) \
|
TFJ(RegExpPrototypeCompile, 2, kReceiver, kPattern, kFlags) \
|
||||||
/* ES #sec-regexp.prototype.exec */ \
|
/* ES #sec-regexp.prototype.exec */ \
|
||||||
TFJ(RegExpPrototypeExec, 1, kReceiver, kString) \
|
TFJ(RegExpPrototypeExec, 1, kReceiver, kString) \
|
||||||
/* ES #sec-get-regexp.prototype.flags */ \
|
|
||||||
TFJ(RegExpPrototypeFlagsGetter, 0, kReceiver) \
|
|
||||||
/* ES #sec-regexp.prototype-@@match */ \
|
/* ES #sec-regexp.prototype-@@match */ \
|
||||||
TFJ(RegExpPrototypeMatch, 1, kReceiver, kString) \
|
TFJ(RegExpPrototypeMatch, 1, kReceiver, kString) \
|
||||||
/* https://tc39.github.io/proposal-string-matchall/ */ \
|
/* https://tc39.github.io/proposal-string-matchall/ */ \
|
||||||
|
@ -1459,11 +1459,11 @@ TF_BUILTIN(PromiseResolveTrampoline, PromiseBuiltinsAssembler) {
|
|||||||
// 1. Let C be the this value.
|
// 1. Let C be the this value.
|
||||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||||
Node* value = Parameter(Descriptor::kValue);
|
Node* value = Parameter(Descriptor::kValue);
|
||||||
Node* context = Parameter(Descriptor::kContext);
|
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||||
|
|
||||||
// 2. If Type(C) is not Object, throw a TypeError exception.
|
// 2. If Type(C) is not Object, throw a TypeError exception.
|
||||||
ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
|
ThrowIfNotJSReceiver(context, CAST(receiver),
|
||||||
"PromiseResolve");
|
MessageTemplate::kCalledOnNonObject, "PromiseResolve");
|
||||||
|
|
||||||
// 3. Return ? PromiseResolve(C, x).
|
// 3. Return ? PromiseResolve(C, x).
|
||||||
Return(CallBuiltin(Builtins::kPromiseResolve, context, receiver, value));
|
Return(CallBuiltin(Builtins::kPromiseResolve, context, receiver, value));
|
||||||
@ -1767,10 +1767,11 @@ TF_BUILTIN(PromisePrototypeFinally, PromiseBuiltinsAssembler) {
|
|||||||
// 1. Let promise be the this value.
|
// 1. Let promise be the this value.
|
||||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||||
Node* const on_finally = Parameter(Descriptor::kOnFinally);
|
Node* const on_finally = Parameter(Descriptor::kOnFinally);
|
||||||
Node* const context = Parameter(Descriptor::kContext);
|
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||||
|
|
||||||
// 2. If Type(promise) is not Object, throw a TypeError exception.
|
// 2. If Type(promise) is not Object, throw a TypeError exception.
|
||||||
ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
|
ThrowIfNotJSReceiver(context, CAST(receiver),
|
||||||
|
MessageTemplate::kCalledOnNonObject,
|
||||||
"Promise.prototype.finally");
|
"Promise.prototype.finally");
|
||||||
|
|
||||||
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
|
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
|
||||||
@ -2570,8 +2571,8 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
|
|||||||
|
|
||||||
Node* const receiver = Parameter(Descriptor::kReceiver);
|
Node* const receiver = Parameter(Descriptor::kReceiver);
|
||||||
TNode<Context> const context = CAST(Parameter(Descriptor::kContext));
|
TNode<Context> const context = CAST(Parameter(Descriptor::kContext));
|
||||||
ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
|
ThrowIfNotJSReceiver(context, CAST(receiver),
|
||||||
"Promise.race");
|
MessageTemplate::kCalledOnNonObject, "Promise.race");
|
||||||
|
|
||||||
// Let promiseCapability be ? NewPromiseCapability(C).
|
// Let promiseCapability be ? NewPromiseCapability(C).
|
||||||
// Don't fire debugEvent so that forwarding the rejection through all does not
|
// Don't fire debugEvent so that forwarding the rejection through all does not
|
||||||
|
@ -13,10 +13,10 @@ namespace internal {
|
|||||||
TF_BUILTIN(ReflectHas, CodeStubAssembler) {
|
TF_BUILTIN(ReflectHas, CodeStubAssembler) {
|
||||||
Node* target = Parameter(Descriptor::kTarget);
|
Node* target = Parameter(Descriptor::kTarget);
|
||||||
Node* key = Parameter(Descriptor::kKey);
|
Node* key = Parameter(Descriptor::kKey);
|
||||||
Node* context = Parameter(Descriptor::kContext);
|
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||||
|
|
||||||
ThrowIfNotJSReceiver(context, target, MessageTemplate::kCalledOnNonObject,
|
ThrowIfNotJSReceiver(context, CAST(target),
|
||||||
"Reflect.has");
|
MessageTemplate::kCalledOnNonObject, "Reflect.has");
|
||||||
|
|
||||||
Return(CallBuiltin(Builtins::kHasProperty, context, target, key));
|
Return(CallBuiltin(Builtins::kHasProperty, context, target, key));
|
||||||
}
|
}
|
||||||
|
@ -893,34 +893,6 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpPrototypeExecBody(
|
|||||||
return var_result.value();
|
return var_result.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver(
|
|
||||||
Node* context, Node* maybe_receiver, MessageTemplate msg_template,
|
|
||||||
char const* method_name) {
|
|
||||||
Label out(this), throw_exception(this, Label::kDeferred);
|
|
||||||
VARIABLE(var_value_map, MachineRepresentation::kTagged);
|
|
||||||
|
|
||||||
GotoIf(TaggedIsSmi(maybe_receiver), &throw_exception);
|
|
||||||
|
|
||||||
// Load the instance type of the {value}.
|
|
||||||
var_value_map.Bind(LoadMap(maybe_receiver));
|
|
||||||
TNode<Uint16T> const value_instance_type =
|
|
||||||
LoadMapInstanceType(var_value_map.value());
|
|
||||||
|
|
||||||
Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception);
|
|
||||||
|
|
||||||
// The {value} is not a compatible receiver for this method.
|
|
||||||
BIND(&throw_exception);
|
|
||||||
{
|
|
||||||
TNode<Object> const value_str =
|
|
||||||
CallBuiltin(Builtins::kToString, context, maybe_receiver);
|
|
||||||
ThrowTypeError(context, msg_template, StringConstant(method_name),
|
|
||||||
value_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
BIND(&out);
|
|
||||||
return var_value_map.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
TNode<BoolT> RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype(
|
TNode<BoolT> RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype(
|
||||||
SloppyTNode<Context> context, SloppyTNode<Object> receiver) {
|
SloppyTNode<Context> context, SloppyTNode<Object> receiver) {
|
||||||
TNode<Context> native_context = LoadNativeContext(context);
|
TNode<Context> native_context = LoadNativeContext(context);
|
||||||
@ -1211,8 +1183,8 @@ TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) {
|
|||||||
string));
|
string));
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<String> RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
|
TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context,
|
||||||
Node* const regexp,
|
TNode<Object> regexp,
|
||||||
bool is_fastpath) {
|
bool is_fastpath) {
|
||||||
Isolate* isolate = this->isolate();
|
Isolate* isolate = this->isolate();
|
||||||
|
|
||||||
@ -1225,9 +1197,9 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
|
|||||||
|
|
||||||
if (is_fastpath) {
|
if (is_fastpath) {
|
||||||
// Refer to JSRegExp's flag property on the fast-path.
|
// Refer to JSRegExp's flag property on the fast-path.
|
||||||
CSA_ASSERT(this, IsJSRegExp(regexp));
|
CSA_ASSERT(this, IsJSRegExp(CAST(regexp)));
|
||||||
TNode<Smi> const flags_smi =
|
TNode<Smi> const flags_smi =
|
||||||
CAST(LoadObjectField(regexp, JSRegExp::kFlagsOffset));
|
CAST(LoadObjectField(CAST(regexp), JSRegExp::kFlagsOffset));
|
||||||
var_flags = SmiUntag(flags_smi);
|
var_flags = SmiUntag(flags_smi);
|
||||||
|
|
||||||
#define CASE_FOR_FLAG(FLAG) \
|
#define CASE_FOR_FLAG(FLAG) \
|
||||||
@ -1382,29 +1354,6 @@ Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context,
|
|||||||
pattern, flags);
|
pattern, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES #sec-get-regexp.prototype.flags
|
|
||||||
TF_BUILTIN(RegExpPrototypeFlagsGetter, RegExpBuiltinsAssembler) {
|
|
||||||
TNode<Object> maybe_receiver = CAST(Parameter(Descriptor::kReceiver));
|
|
||||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
|
||||||
|
|
||||||
ThrowIfNotJSReceiver(context, maybe_receiver,
|
|
||||||
MessageTemplate::kRegExpNonObject,
|
|
||||||
"RegExp.prototype.flags");
|
|
||||||
TNode<JSReceiver> receiver = CAST(maybe_receiver);
|
|
||||||
|
|
||||||
// The check is strict because the following code relies on individual flag
|
|
||||||
// getters on the regexp prototype (e.g.: global, sticky, ...). We don't
|
|
||||||
// bother to check these individually.
|
|
||||||
Label if_isfastpath(this), if_isslowpath(this, Label::kDeferred);
|
|
||||||
BranchIfFastRegExp_Strict(context, receiver, &if_isfastpath, &if_isslowpath);
|
|
||||||
|
|
||||||
BIND(&if_isfastpath);
|
|
||||||
Return(FlagsGetter(context, receiver, true));
|
|
||||||
|
|
||||||
BIND(&if_isslowpath);
|
|
||||||
Return(FlagsGetter(context, receiver, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ES#sec-regexp-pattern-flags
|
// ES#sec-regexp-pattern-flags
|
||||||
// RegExp ( pattern, flags )
|
// RegExp ( pattern, flags )
|
||||||
TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) {
|
TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) {
|
||||||
@ -1562,7 +1511,7 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) {
|
|||||||
BIND(&next);
|
BIND(&next);
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<String> const new_flags = FlagsGetter(context, pattern, true);
|
TNode<String> const new_flags = FlagsGetter(context, CAST(pattern), true);
|
||||||
TNode<Object> const new_pattern =
|
TNode<Object> const new_pattern =
|
||||||
LoadObjectField(pattern, JSRegExp::kSourceOffset);
|
LoadObjectField(pattern, JSRegExp::kSourceOffset);
|
||||||
|
|
||||||
@ -1645,8 +1594,8 @@ 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(Node* context, Node* regexp,
|
TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context,
|
||||||
Node* string) {
|
Node* regexp, Node* string) {
|
||||||
TVARIABLE(Object, var_result);
|
TVARIABLE(Object, var_result);
|
||||||
Label out(this);
|
Label out(this);
|
||||||
|
|
||||||
@ -2157,7 +2106,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow(
|
void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow(
|
||||||
Node* const context, Node* const regexp, Node* const string) {
|
TNode<Context> context, Node* const regexp, Node* const string) {
|
||||||
CSA_ASSERT(this, IsJSReceiver(regexp));
|
CSA_ASSERT(this, IsJSReceiver(regexp));
|
||||||
CSA_ASSERT(this, IsString(string));
|
CSA_ASSERT(this, IsString(string));
|
||||||
|
|
||||||
@ -2167,7 +2116,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow(
|
|||||||
|
|
||||||
// Grab the initial value of last index.
|
// Grab the initial value of last index.
|
||||||
TNode<Object> const previous_last_index =
|
TNode<Object> const previous_last_index =
|
||||||
SlowLoadLastIndex(CAST(context), CAST(regexp));
|
SlowLoadLastIndex(context, CAST(regexp));
|
||||||
|
|
||||||
// Ensure last index is 0.
|
// Ensure last index is 0.
|
||||||
{
|
{
|
||||||
@ -2187,7 +2136,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow(
|
|||||||
{
|
{
|
||||||
Label next(this), slow(this, Label::kDeferred);
|
Label next(this), slow(this, Label::kDeferred);
|
||||||
TNode<Object> const current_last_index =
|
TNode<Object> const current_last_index =
|
||||||
SlowLoadLastIndex(CAST(context), CAST(regexp));
|
SlowLoadLastIndex(context, CAST(regexp));
|
||||||
|
|
||||||
BranchIfSameValue(current_last_index, previous_last_index, &next, &slow);
|
BranchIfSameValue(current_last_index, previous_last_index, &next, &slow);
|
||||||
|
|
||||||
|
@ -84,10 +84,6 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
TNode<String> string,
|
TNode<String> string,
|
||||||
const bool is_fastpath);
|
const bool is_fastpath);
|
||||||
|
|
||||||
Node* ThrowIfNotJSReceiver(Node* context, Node* maybe_receiver,
|
|
||||||
MessageTemplate msg_template,
|
|
||||||
char const* method_name);
|
|
||||||
|
|
||||||
TNode<BoolT> IsReceiverInitialRegExpPrototype(SloppyTNode<Context> context,
|
TNode<BoolT> IsReceiverInitialRegExpPrototype(SloppyTNode<Context> context,
|
||||||
SloppyTNode<Object> receiver);
|
SloppyTNode<Object> receiver);
|
||||||
|
|
||||||
@ -153,8 +149,8 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
void BranchIfFastRegExpResult(Node* const context, Node* const object,
|
void BranchIfFastRegExpResult(Node* const context, Node* const object,
|
||||||
Label* if_isunmodified, Label* if_ismodified);
|
Label* if_isunmodified, Label* if_ismodified);
|
||||||
|
|
||||||
TNode<String> FlagsGetter(Node* const context, Node* const regexp,
|
TNode<String> FlagsGetter(TNode<Context> context, TNode<Object> regexp,
|
||||||
bool is_fastpath);
|
const bool is_fastpath);
|
||||||
|
|
||||||
TNode<BoolT> FastFlagGetter(TNode<JSRegExp> regexp, JSRegExp::Flag flag);
|
TNode<BoolT> FastFlagGetter(TNode<JSRegExp> regexp, JSRegExp::Flag flag);
|
||||||
TNode<BoolT> FastFlagGetterGlobal(TNode<JSRegExp> regexp) {
|
TNode<BoolT> FastFlagGetterGlobal(TNode<JSRegExp> regexp) {
|
||||||
@ -171,7 +167,7 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
Node* RegExpInitialize(Node* const context, Node* const regexp,
|
Node* RegExpInitialize(Node* const context, Node* const regexp,
|
||||||
Node* const maybe_pattern, Node* const maybe_flags);
|
Node* const maybe_pattern, Node* const maybe_flags);
|
||||||
|
|
||||||
TNode<Object> RegExpExec(Node* context, Node* regexp, Node* string);
|
TNode<Object> RegExpExec(TNode<Context> context, Node* regexp, Node* string);
|
||||||
|
|
||||||
TNode<Number> AdvanceStringIndex(SloppyTNode<String> string,
|
TNode<Number> AdvanceStringIndex(SloppyTNode<String> string,
|
||||||
SloppyTNode<Number> index,
|
SloppyTNode<Number> index,
|
||||||
@ -190,7 +186,7 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
|||||||
void RegExpPrototypeSearchBodyFast(TNode<Context> context,
|
void RegExpPrototypeSearchBodyFast(TNode<Context> context,
|
||||||
TNode<JSRegExp> regexp,
|
TNode<JSRegExp> regexp,
|
||||||
TNode<String> string);
|
TNode<String> string);
|
||||||
void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp,
|
void RegExpPrototypeSearchBodySlow(TNode<Context> context, Node* const regexp,
|
||||||
Node* const string);
|
Node* const string);
|
||||||
|
|
||||||
void RegExpPrototypeSplitBody(TNode<Context> context, TNode<JSRegExp> regexp,
|
void RegExpPrototypeSplitBody(TNode<Context> context, TNode<JSRegExp> regexp,
|
||||||
|
@ -130,4 +130,35 @@ namespace regexp {
|
|||||||
receiver, kUnicode, kRegExpPrototypeUnicodeGetter,
|
receiver, kUnicode, kRegExpPrototypeUnicodeGetter,
|
||||||
'RegExp.prototype.unicode');
|
'RegExp.prototype.unicode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern transitioning macro
|
||||||
|
RegExpBuiltinsAssembler::FlagsGetter(implicit context: Context)(
|
||||||
|
Object, constexpr bool): String;
|
||||||
|
|
||||||
|
transitioning macro
|
||||||
|
FastFlagsGetter(implicit context: Context)(receiver: FastJSRegExp): String {
|
||||||
|
return FlagsGetter(receiver, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitioning macro SlowFlagsGetter(implicit context:
|
||||||
|
Context)(receiver: JSAny): String {
|
||||||
|
return FlagsGetter(receiver, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const kRegExpNonObject: constexpr MessageTemplate
|
||||||
|
generates 'MessageTemplate::kRegExpNonObject';
|
||||||
|
|
||||||
|
// ES #sec-get-regexp.prototype.flags
|
||||||
|
// TFJ(RegExpPrototypeFlagsGetter, 0, kReceiver) \
|
||||||
|
transitioning javascript builtin RegExpPrototypeFlagsGetter(
|
||||||
|
js-implicit context: Context, receiver: JSAny)(): String {
|
||||||
|
ThrowIfNotJSReceiver(receiver, kRegExpNonObject, 'RegExp.prototype.flags');
|
||||||
|
|
||||||
|
// The check is strict because the following code relies on individual flag
|
||||||
|
// getters on the regexp prototype (e.g.: global, sticky, ...). We don't
|
||||||
|
// bother to check these individually.
|
||||||
|
const fastRegexp = Cast<FastJSRegExp>(receiver)
|
||||||
|
otherwise return SlowFlagsGetter(receiver);
|
||||||
|
return FastFlagsGetter(fastRegexp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6052,27 +6052,26 @@ Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
|
|||||||
return var_value_map.value();
|
return var_value_map.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* CodeStubAssembler::ThrowIfNotJSReceiver(Node* context, Node* value,
|
void CodeStubAssembler::ThrowIfNotJSReceiver(TNode<Context> context,
|
||||||
MessageTemplate msg_template,
|
TNode<Object> value,
|
||||||
const char* method_name) {
|
MessageTemplate msg_template,
|
||||||
Label out(this), throw_exception(this, Label::kDeferred);
|
const char* method_name) {
|
||||||
VARIABLE(var_value_map, MachineRepresentation::kTagged);
|
Label done(this), throw_exception(this, Label::kDeferred);
|
||||||
|
|
||||||
GotoIf(TaggedIsSmi(value), &throw_exception);
|
GotoIf(TaggedIsSmi(value), &throw_exception);
|
||||||
|
|
||||||
// Load the instance type of the {value}.
|
// Load the instance type of the {value}.
|
||||||
var_value_map.Bind(LoadMap(value));
|
TNode<Map> value_map = LoadMap(CAST(value));
|
||||||
TNode<Uint16T> const value_instance_type =
|
TNode<Uint16T> const value_instance_type = LoadMapInstanceType(value_map);
|
||||||
LoadMapInstanceType(var_value_map.value());
|
|
||||||
|
|
||||||
Branch(IsJSReceiverInstanceType(value_instance_type), &out, &throw_exception);
|
Branch(IsJSReceiverInstanceType(value_instance_type), &done,
|
||||||
|
&throw_exception);
|
||||||
|
|
||||||
// The {value} is not a compatible receiver for this method.
|
// The {value} is not a compatible receiver for this method.
|
||||||
BIND(&throw_exception);
|
BIND(&throw_exception);
|
||||||
ThrowTypeError(context, msg_template, method_name);
|
ThrowTypeError(context, msg_template, StringConstant(method_name), value);
|
||||||
|
|
||||||
BIND(&out);
|
BIND(&done);
|
||||||
return var_value_map.value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStubAssembler::ThrowIfNotCallable(TNode<Context> context,
|
void CodeStubAssembler::ThrowIfNotCallable(TNode<Context> context,
|
||||||
@ -13008,7 +13007,7 @@ TNode<JSReceiver> CodeStubAssembler::SpeciesConstructor(
|
|||||||
|
|
||||||
// 4. If Type(C) is not Object, throw a TypeError exception.
|
// 4. If Type(C) is not Object, throw a TypeError exception.
|
||||||
ThrowIfNotJSReceiver(context, constructor,
|
ThrowIfNotJSReceiver(context, constructor,
|
||||||
MessageTemplate::kConstructorNotReceiver);
|
MessageTemplate::kConstructorNotReceiver, "");
|
||||||
|
|
||||||
// 5. Let S be ? Get(C, @@species).
|
// 5. Let S be ? Get(C, @@species).
|
||||||
TNode<Object> species =
|
TNode<Object> species =
|
||||||
|
@ -2321,10 +2321,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
InstanceType instance_type,
|
InstanceType instance_type,
|
||||||
char const* method_name);
|
char const* method_name);
|
||||||
// Throws a TypeError for {method_name} if {value} is not a JSReceiver.
|
// Throws a TypeError for {method_name} if {value} is not a JSReceiver.
|
||||||
// Returns the {value}'s map.
|
void ThrowIfNotJSReceiver(TNode<Context> context, TNode<Object> value,
|
||||||
Node* ThrowIfNotJSReceiver(Node* context, Node* value,
|
MessageTemplate msg_template,
|
||||||
MessageTemplate msg_template,
|
const char* method_name);
|
||||||
const char* method_name = nullptr);
|
|
||||||
void ThrowIfNotCallable(TNode<Context> context, TNode<Object> value,
|
void ThrowIfNotCallable(TNode<Context> context, TNode<Object> value,
|
||||||
const char* method_name);
|
const char* method_name);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user