[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:
bmeurer 2015-12-11 07:48:48 -08:00 committed by Commit bot
parent 56673804e0
commit c77c1ca80b
5 changed files with 35 additions and 9 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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) \