[es6] Don't use the %GetPrototype runtime entry for super calls.
The %GetPrototype runtime function does a lot more than the GetSuperConstructor specified in ES6 12.3.5.2. So this introduces a proper %_GetSuperConstructor instead with support in TurboFan. R=jarin@chromium.org, rossberg@chromium.org Review URL: https://codereview.chromium.org/1522503002 Cr-Commit-Position: refs/heads/master@{#32804}
This commit is contained in:
parent
56673804e0
commit
c77c1ca80b
@ -111,6 +111,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||||
return ReduceCall(node);
|
||||
case Runtime::kInlineTailCall:
|
||||
return ReduceTailCall(node);
|
||||
case Runtime::kInlineGetSuperConstructor:
|
||||
return ReduceGetSuperConstructor(node);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -614,6 +616,18 @@ Reduction JSIntrinsicLowering::ReduceTailCall(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceGetSuperConstructor(Node* node) {
|
||||
Node* active_function = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
Node* active_function_map = effect =
|
||||
graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
|
||||
active_function, effect, control);
|
||||
return Change(node, simplified()->LoadField(AccessBuilder::ForMapPrototype()),
|
||||
active_function_map, effect, control);
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
|
||||
Node* b) {
|
||||
RelaxControls(node);
|
||||
|
@ -72,6 +72,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
|
||||
Reduction ReduceToString(Node* node);
|
||||
Reduction ReduceCall(Node* node);
|
||||
Reduction ReduceTailCall(Node* node);
|
||||
Reduction ReduceGetSuperConstructor(Node* node);
|
||||
|
||||
Reduction Change(Node* node, const Operator* op);
|
||||
Reduction Change(Node* node, const Operator* op, Node* a, Node* b);
|
||||
|
@ -361,7 +361,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
|
||||
body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
|
||||
if (call_super) {
|
||||
// %_DefaultConstructorCallSuper(new.target, %GetPrototype(<this-fun>))
|
||||
// let super_constructor = %_GetSuperConstructor(<this-function>)
|
||||
// %_DefaultConstructorCallSuper(new.target, super_constructor)
|
||||
ZoneList<Expression*>* args =
|
||||
new (zone()) ZoneList<Expression*>(2, zone());
|
||||
VariableProxy* new_target_proxy = scope_->NewUnresolved(
|
||||
@ -374,9 +375,9 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
|
||||
ZoneList<Expression*>* tmp =
|
||||
new (zone()) ZoneList<Expression*>(1, zone());
|
||||
tmp->Add(this_function_proxy, zone());
|
||||
Expression* get_prototype =
|
||||
factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
|
||||
args->Add(get_prototype, zone());
|
||||
Expression* super_constructor = factory()->NewCallRuntime(
|
||||
Runtime::kInlineGetSuperConstructor, tmp, pos);
|
||||
args->Add(super_constructor, zone());
|
||||
CallRuntime* call = factory()->NewCallRuntime(
|
||||
Runtime::kInlineDefaultConstructorCallSuper, args, pos);
|
||||
body->Add(factory()->NewReturnStatement(call, pos), zone());
|
||||
@ -6433,12 +6434,13 @@ Expression* Parser::SpreadCall(Expression* function,
|
||||
int pos) {
|
||||
if (function->IsSuperCallReference()) {
|
||||
// Super calls
|
||||
// %reflect_construct(%GetPrototype(<this-function>), args, new.target))
|
||||
// let super_constructor = %_GetSuperConstructor(<this-function>)
|
||||
// %reflect_construct(super_constructor, args, new.target)
|
||||
ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
|
||||
tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
|
||||
Expression* get_prototype =
|
||||
factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos);
|
||||
args->InsertAt(0, get_prototype, zone());
|
||||
Expression* super_constructor = factory()->NewCallRuntime(
|
||||
Runtime::kInlineGetSuperConstructor, tmp, pos);
|
||||
args->InsertAt(0, super_constructor, zone());
|
||||
args->Add(function->AsSuperCallReference()->new_target_var(), zone());
|
||||
return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
|
||||
pos);
|
||||
|
@ -509,5 +509,13 @@ RUNTIME_FUNCTION(Runtime_DefaultConstructorCallSuper) {
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetSuperConstructor) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_CHECKED(JSFunction, active_function, 0);
|
||||
return active_function->map()->prototype();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -91,7 +91,8 @@ namespace internal {
|
||||
F(StoreToSuper_Sloppy, 4, 1) \
|
||||
F(StoreKeyedToSuper_Strict, 4, 1) \
|
||||
F(StoreKeyedToSuper_Sloppy, 4, 1) \
|
||||
F(DefaultConstructorCallSuper, 2, 1)
|
||||
F(DefaultConstructorCallSuper, 2, 1) \
|
||||
F(GetSuperConstructor, 1, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_COLLECTIONS(F) \
|
||||
|
Loading…
Reference in New Issue
Block a user