| Index: src/ia32/full-codegen-ia32.cc
 | 
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
 | 
| index 1e578b41412e00625fe300bbdb781b2ae8fb57c8..4e7126ba3ffa91c962fa6704bb5d76d6959442a3 100644
 | 
| --- a/src/ia32/full-codegen-ia32.cc
 | 
| +++ b/src/ia32/full-codegen-ia32.cc
 | 
| @@ -3005,6 +3005,21 @@ void FullCodeGenerator::EmitLoadSuperConstructor() {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void FullCodeGenerator::EmitInitializeThisAfterSuper(
 | 
| +    SuperReference* super_ref) {
 | 
| +  Variable* this_var = super_ref->this_var()->var();
 | 
| +  GetVar(ecx, this_var);
 | 
| +  __ cmp(ecx, isolate()->factory()->the_hole_value());
 | 
| +  Label uninitialized_this;
 | 
| +  __ j(equal, &uninitialized_this);
 | 
| +  __ push(Immediate(this_var->name()));
 | 
| +  __ 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
 | 
| @@ -3219,17 +3234,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
 | 
|  
 | 
|    RecordJSReturnSite(expr);
 | 
|  
 | 
| -  SuperReference* super_ref = expr->expression()->AsSuperReference();
 | 
| -  Variable* this_var = super_ref->this_var()->var();
 | 
| -  GetVar(ecx, this_var);
 | 
| -  __ cmp(ecx, isolate()->factory()->the_hole_value());
 | 
| -  Label uninitialized_this;
 | 
| -  __ j(equal, &uninitialized_this);
 | 
| -  __ push(Immediate(this_var->name()));
 | 
| -  __ CallRuntime(Runtime::kThrowReferenceError, 1);
 | 
| -  __ bind(&uninitialized_this);
 | 
| -
 | 
| -  EmitVariableAssignment(this_var, Token::INIT_CONST);
 | 
| +  EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference());
 | 
|    context()->Plug(eax);
 | 
|  }
 | 
|  
 | 
| @@ -4531,26 +4536,79 @@ 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
 | 
| +  __ push(Operand(esp, 0));
 | 
| +  __ mov(Operand(esp, kPointerSize), eax);
 | 
| +
 | 
| +  // 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.
 | 
| +  __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
 | 
| +  context()->DropAndPlug(1, eax);
 | 
| +
 | 
| +  EmitInitializeThisAfterSuper(super_reference);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
 | 
| +  // Push the builtins object as receiver.
 | 
| +  __ mov(eax, GlobalObjectOperand());
 | 
| +  __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
 | 
| +
 | 
| +  // Load the function from the receiver.
 | 
| +  __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
 | 
| +  __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
 | 
| +  if (FLAG_vector_ics) {
 | 
| +    __ mov(VectorLoadICDescriptor::SlotRegister(),
 | 
| +           Immediate(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);
 | 
| +  __ mov(edi, Operand(esp, (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 receiver.
 | 
| -    __ mov(eax, GlobalObjectOperand());
 | 
| -    __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
 | 
| -
 | 
| -    // Load the function from the receiver.
 | 
| -    __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
 | 
| -    __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
 | 
| -    if (FLAG_vector_ics) {
 | 
| -      __ mov(VectorLoadICDescriptor::SlotRegister(),
 | 
| -             Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
 | 
| -      CallLoadIC(NOT_CONTEXTUAL);
 | 
| -    } else {
 | 
| -      CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
 | 
| -    }
 | 
| +    EmitLoadJSRuntimeFunction(expr);
 | 
|  
 | 
|      // Push the target function under the receiver.
 | 
|      __ push(Operand(esp, 0));
 | 
| @@ -4561,11 +4619,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);
 | 
| -    __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
 | 
| -    __ CallStub(&stub);
 | 
| +    EmitCallJSRuntimeFunction(expr);
 | 
|  
 | 
|      // Restore context register.
 | 
|      __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
 | 
| 
 |