Index: src/compiler/ast-graph-builder.cc |
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
index fd1b6960d094b5b7ec47a20f1996d828737bf949..2d3d8279b12aabe9a67967a6e8d95714e8ddd207 100644 |
--- a/src/compiler/ast-graph-builder.cc |
+++ b/src/compiler/ast-graph-builder.cc |
@@ -2415,11 +2415,7 @@ void AstGraphBuilder::VisitCall(Call* expr) { |
break; |
} |
case Call::SUPER_CALL: |
- // TODO(dslomov): Implement super calls. |
- callee_value = jsgraph()->UndefinedConstant(); |
- receiver_value = jsgraph()->UndefinedConstant(); |
- SetStackOverflow(); |
- break; |
+ return VisitCallSuper(expr); |
case Call::POSSIBLY_EVAL_CALL: |
possibly_eval = true; |
if (callee->AsVariableProxy()->var()->IsLookupSlot()) { |
@@ -2486,6 +2482,45 @@ void AstGraphBuilder::VisitCall(Call* expr) { |
} |
+void AstGraphBuilder::VisitCallSuper(Call* expr) { |
+ SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
+ DCHECK_NOT_NULL(super); |
+ |
+ // Prepare the callee to the super call. The super constructor is stored as |
+ // the prototype of the constructor we are currently executing. |
+ VisitForValue(super->this_function_var()); |
+ Node* this_function = environment()->Pop(); |
+ const Operator* op = javascript()->CallRuntime(Runtime::kGetPrototype, 1); |
+ Node* super_function = NewNode(op, this_function); |
+ // TODO(mstarzinger): This probably needs a proper bailout id. |
+ PrepareFrameState(super_function, BailoutId::None()); |
+ environment()->Push(super_function); |
+ |
+ // Evaluate all arguments to the super call. |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ VisitForValues(args); |
+ |
+ // Original receiver is loaded from the {new.target} variable. |
+ VisitForValue(super->new_target_var()); |
+ |
+ // Create node to perform the super call. |
+ const Operator* call = javascript()->CallConstruct(args->length() + 2); |
+ Node* value = ProcessArguments(call, args->length() + 2); |
+ PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
+ |
+ // TODO(mstarzinger): It sure would be nice if this were desugared. Also we |
+ // are still missing the hole-check in the assignment below, fix that. |
+ FrameStateBeforeAndAfter states(this, BailoutId::None()); |
+ BuildVariableAssignment(super->this_var()->var(), value, Token::INIT_CONST, |
+ VectorSlotPair(), BailoutId::None(), states); |
+ |
+ // TODO(mstarzinger): Remove bailout once lowering is correct. |
+ SetStackOverflow(); |
+ |
+ ast_context()->ProduceValue(value); |
+} |
+ |
+ |
void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
VisitForValue(expr->expression()); |
@@ -2493,9 +2528,12 @@ void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
ZoneList<Expression*>* args = expr->arguments(); |
VisitForValues(args); |
+ // Original receiver is the same as the callee. |
+ environment()->Push(environment()->Peek(args->length())); |
+ |
// Create node to perform the construct call. |
- const Operator* call = javascript()->CallConstruct(args->length() + 1); |
- Node* value = ProcessArguments(call, args->length() + 1); |
+ const Operator* call = javascript()->CallConstruct(args->length() + 2); |
+ Node* value = ProcessArguments(call, args->length() + 2); |
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
ast_context()->ProduceValue(value); |
} |