Commit c77c1ca8 authored by bmeurer's avatar bmeurer Committed by Commit bot

[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}
parent 56673804
...@@ -111,6 +111,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -111,6 +111,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceCall(node); return ReduceCall(node);
case Runtime::kInlineTailCall: case Runtime::kInlineTailCall:
return ReduceTailCall(node); return ReduceTailCall(node);
case Runtime::kInlineGetSuperConstructor:
return ReduceGetSuperConstructor(node);
default: default:
break; break;
} }
...@@ -614,6 +616,18 @@ Reduction JSIntrinsicLowering::ReduceTailCall(Node* node) { ...@@ -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, Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
Node* b) { Node* b) {
RelaxControls(node); RelaxControls(node);
......
...@@ -72,6 +72,7 @@ class JSIntrinsicLowering final : public AdvancedReducer { ...@@ -72,6 +72,7 @@ class JSIntrinsicLowering final : public AdvancedReducer {
Reduction ReduceToString(Node* node); Reduction ReduceToString(Node* node);
Reduction ReduceCall(Node* node); Reduction ReduceCall(Node* node);
Reduction ReduceTailCall(Node* node); Reduction ReduceTailCall(Node* node);
Reduction ReduceGetSuperConstructor(Node* node);
Reduction Change(Node* node, const Operator* op); Reduction Change(Node* node, const Operator* op);
Reduction Change(Node* node, const Operator* op, Node* a, Node* b); Reduction Change(Node* node, const Operator* op, Node* a, Node* b);
......
...@@ -361,7 +361,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, ...@@ -361,7 +361,8 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone()); body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
if (call_super) { if (call_super) {
// %_DefaultConstructorCallSuper(new.target, %GetPrototype(<this-fun>)) // let super_constructor = %_GetSuperConstructor(<this-function>)
// %_DefaultConstructorCallSuper(new.target, super_constructor)
ZoneList<Expression*>* args = ZoneList<Expression*>* args =
new (zone()) ZoneList<Expression*>(2, zone()); new (zone()) ZoneList<Expression*>(2, zone());
VariableProxy* new_target_proxy = scope_->NewUnresolved( VariableProxy* new_target_proxy = scope_->NewUnresolved(
...@@ -374,9 +375,9 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, ...@@ -374,9 +375,9 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
ZoneList<Expression*>* tmp = ZoneList<Expression*>* tmp =
new (zone()) ZoneList<Expression*>(1, zone()); new (zone()) ZoneList<Expression*>(1, zone());
tmp->Add(this_function_proxy, zone()); tmp->Add(this_function_proxy, zone());
Expression* get_prototype = Expression* super_constructor = factory()->NewCallRuntime(
factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos); Runtime::kInlineGetSuperConstructor, tmp, pos);
args->Add(get_prototype, zone()); args->Add(super_constructor, zone());
CallRuntime* call = factory()->NewCallRuntime( CallRuntime* call = factory()->NewCallRuntime(
Runtime::kInlineDefaultConstructorCallSuper, args, pos); Runtime::kInlineDefaultConstructorCallSuper, args, pos);
body->Add(factory()->NewReturnStatement(call, pos), zone()); body->Add(factory()->NewReturnStatement(call, pos), zone());
...@@ -6433,12 +6434,13 @@ Expression* Parser::SpreadCall(Expression* function, ...@@ -6433,12 +6434,13 @@ Expression* Parser::SpreadCall(Expression* function,
int pos) { int pos) {
if (function->IsSuperCallReference()) { if (function->IsSuperCallReference()) {
// Super calls // 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()); ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
Expression* get_prototype = Expression* super_constructor = factory()->NewCallRuntime(
factory()->NewCallRuntime(Runtime::kGetPrototype, tmp, pos); Runtime::kInlineGetSuperConstructor, tmp, pos);
args->InsertAt(0, get_prototype, zone()); args->InsertAt(0, super_constructor, zone());
args->Add(function->AsSuperCallReference()->new_target_var(), zone()); args->Add(function->AsSuperCallReference()->new_target_var(), zone());
return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
pos); pos);
......
...@@ -509,5 +509,13 @@ RUNTIME_FUNCTION(Runtime_DefaultConstructorCallSuper) { ...@@ -509,5 +509,13 @@ RUNTIME_FUNCTION(Runtime_DefaultConstructorCallSuper) {
return *result; 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 internal
} // namespace v8 } // namespace v8
...@@ -91,7 +91,8 @@ namespace internal { ...@@ -91,7 +91,8 @@ namespace internal {
F(StoreToSuper_Sloppy, 4, 1) \ F(StoreToSuper_Sloppy, 4, 1) \
F(StoreKeyedToSuper_Strict, 4, 1) \ F(StoreKeyedToSuper_Strict, 4, 1) \
F(StoreKeyedToSuper_Sloppy, 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) \ #define FOR_EACH_INTRINSIC_COLLECTIONS(F) \
......
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