| Index: src/arm/full-codegen-arm.cc
 | 
| diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
 | 
| index 6ee8eb1cd68540b417adbabed51221313e3f1f93..40ada3902a4bb370171c5fc5de5c9c199852bc69 100644
 | 
| --- a/src/arm/full-codegen-arm.cc
 | 
| +++ b/src/arm/full-codegen-arm.cc
 | 
| @@ -3118,6 +3118,22 @@ void FullCodeGenerator::EmitLoadSuperConstructor() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void FullCodeGenerator::EmitInitializeThisAfterSuper(
 | 
| +    SuperReference* super_ref) {
 | 
| +  Variable* this_var = super_ref->this_var()->var();
 | 
| +  GetVar(r1, this_var);
 | 
| +  __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
 | 
| +  Label uninitialized_this;
 | 
| +  __ b(eq, &uninitialized_this);
 | 
| +  __ mov(r0, Operand(this_var->name()));
 | 
| +  __ Push(r0);
 | 
| +  __ CallRuntime(Runtime::kThrowReferenceError, 1);
 | 
| +  __ bind(&uninitialized_this);
 | 
| +
 | 
| +  EmitVariableAssignment(this_var, Token::INIT_CONST);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void FullCodeGenerator::VisitCall(Call* expr) {
 | 
|  #ifdef DEBUG
 | 
|    // We want to verify that RecordJSReturnSite gets called on all paths
 | 
| @@ -3341,18 +3357,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
 | 
|  
 | 
|    RecordJSReturnSite(expr);
 | 
|  
 | 
| -  SuperReference* super_ref = expr->expression()->AsSuperReference();
 | 
| -  Variable* this_var = super_ref->this_var()->var();
 | 
| -  GetVar(r1, this_var);
 | 
| -  __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
 | 
| -  Label uninitialized_this;
 | 
| -  __ b(eq, &uninitialized_this);
 | 
| -  __ mov(r0, Operand(this_var->name()));
 | 
| -  __ Push(r0);
 | 
| -  __ CallRuntime(Runtime::kThrowReferenceError, 1);
 | 
| -  __ bind(&uninitialized_this);
 | 
| -
 | 
| -  EmitVariableAssignment(this_var, Token::INIT_CONST);
 | 
| +  EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference());
 | 
|    context()->Plug(r0);
 | 
|  }
 | 
|  
 | 
| @@ -4608,27 +4613,81 @@ void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void FullCodeGenerator::EmitCallSuperWithSpread(CallRuntime* expr) {
 | 
| +  // Assert: expr === CallRuntime("ReflectConstruct")
 | 
| +  CallRuntime* call = expr->arguments()->at(0)->AsCallRuntime();
 | 
| +  ZoneList<Expression*>* args = call->arguments();
 | 
| +  DCHECK_EQ(3, args->length());
 | 
| +
 | 
| +  SuperReference* super_reference = args->at(0)->AsSuperReference();
 | 
| +
 | 
| +  // Load ReflectConstruct function
 | 
| +  EmitLoadJSRuntimeFunction(call);
 | 
| +
 | 
| +  // Push the target function under the receiver.
 | 
| +  __ ldr(ip, MemOperand(sp, 0));
 | 
| +  __ push(ip);
 | 
| +  __ str(r0, MemOperand(sp, kPointerSize));
 | 
| +
 | 
| +  // Push super
 | 
| +  EmitLoadSuperConstructor();
 | 
| +  __ Push(result_register());
 | 
| +
 | 
| +  // Push arguments array
 | 
| +  VisitForStackValue(args->at(1));
 | 
| +
 | 
| +  // Push NewTarget
 | 
| +  DCHECK(args->at(2)->IsVariableProxy());
 | 
| +  VisitForStackValue(args->at(2));
 | 
| +
 | 
| +  EmitCallJSRuntimeFunction(call);
 | 
| +
 | 
| +  // Restore context register.
 | 
| +  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
 | 
| +  context()->DropAndPlug(1, r0);
 | 
| +
 | 
| +  EmitInitializeThisAfterSuper(super_reference);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
 | 
| +  // Push the builtins object as the receiver.
 | 
| +  Register receiver = LoadDescriptor::ReceiverRegister();
 | 
| +  __ ldr(receiver, GlobalObjectOperand());
 | 
| +  __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
 | 
| +  __ push(receiver);
 | 
| +
 | 
| +  // Load the function from the receiver.
 | 
| +  __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
 | 
| +  if (FLAG_vector_ics) {
 | 
| +    __ mov(VectorLoadICDescriptor::SlotRegister(),
 | 
| +           Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
 | 
| +    CallLoadIC(NOT_CONTEXTUAL);
 | 
| +  } else {
 | 
| +    CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
 | 
| +  ZoneList<Expression*>* args = expr->arguments();
 | 
| +  int arg_count = args->length();
 | 
| +
 | 
| +  // Record source position of the IC call.
 | 
| +  SetSourcePosition(expr->position());
 | 
| +  CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
 | 
| +  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
 | 
| +  __ CallStub(&stub);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
 | 
|    ZoneList<Expression*>* args = expr->arguments();
 | 
|    int arg_count = args->length();
 | 
|  
 | 
|    if (expr->is_jsruntime()) {
 | 
|      Comment cmnt(masm_, "[ CallRuntime");
 | 
| -    // Push the builtins object as the receiver.
 | 
| -    Register receiver = LoadDescriptor::ReceiverRegister();
 | 
| -    __ ldr(receiver, GlobalObjectOperand());
 | 
| -    __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
 | 
| -    __ push(receiver);
 | 
| -
 | 
| -    // Load the function from the receiver.
 | 
| -    __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
 | 
| -    if (FLAG_vector_ics) {
 | 
| -      __ mov(VectorLoadICDescriptor::SlotRegister(),
 | 
| -             Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
 | 
| -      CallLoadIC(NOT_CONTEXTUAL);
 | 
| -    } else {
 | 
| -      CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
 | 
| -    }
 | 
| +    EmitLoadJSRuntimeFunction(expr);
 | 
|  
 | 
|      // Push the target function under the receiver.
 | 
|      __ ldr(ip, MemOperand(sp, 0));
 | 
| @@ -4640,11 +4699,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
 | 
|        VisitForStackValue(args->at(i));
 | 
|      }
 | 
|  
 | 
| -    // Record source position of the IC call.
 | 
| -    SetSourcePosition(expr->position());
 | 
| -    CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
 | 
| -    __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
 | 
| -    __ CallStub(&stub);
 | 
| +    EmitCallJSRuntimeFunction(expr);
 | 
|  
 | 
|      // Restore context register.
 | 
|      __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
 | 
| 
 |