MIPS: new classes: implement default constructors.
authorakos.palfi <akos.palfi@imgtec.com>
Wed, 11 Feb 2015 20:41:53 +0000 (12:41 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 11 Feb 2015 20:42:04 +0000 (20:42 +0000)
Port 9b158fa79a510bd1fee2f663163d9116879cb33a

BUG=

Review URL: https://codereview.chromium.org/914303003

Cr-Commit-Position: refs/heads/master@{#26598}

src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc

index f99085adfea614bc21039ccfa15c6fd44c7dc7e3..7b493283c27e54c306506b33acb33fb0ab1bb7a2 100644 (file)
@@ -3041,8 +3041,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
 }
 
 
-void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
-  DCHECK(super_ref != NULL);
+void FullCodeGenerator::EmitLoadSuperConstructor() {
   __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ Push(a0);
   __ CallRuntime(Runtime::kGetPrototype, 1);
@@ -3166,9 +3165,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     if (FLAG_experimental_classes) {
       EmitSuperConstructorCall(expr);
     } else {
-      SuperReference* super_ref = callee->AsSuperReference();
-      EmitLoadSuperConstructor(super_ref);
+      EmitLoadSuperConstructor();
       __ Push(result_register());
+      SuperReference* super_ref = callee->AsSuperReference();
       VisitForStackValue(super_ref->this_var());
       EmitCall(expr, CallICState::METHOD);
     }
@@ -3241,10 +3240,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   GetVar(result_register(), new_target_var);
   __ Push(result_register());
 
-  SuperReference* super_ref = expr->expression()->AsSuperReference();
-  EmitLoadSuperConstructor(super_ref);
+  EmitLoadSuperConstructor();
   __ push(result_register());
 
+  SuperReference* super_ref = expr->expression()->AsSuperReference();
   Variable* this_var = super_ref->this_var()->var();
 
   GetVar(a0, this_var);
@@ -4175,6 +4174,63 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
 }
 
 
+void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
+  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
+  GetVar(result_register(), new_target_var);
+  __ Push(result_register());
+
+  EmitLoadSuperConstructor();
+  __ Push(result_register());
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label adaptor_frame, args_set_up, runtime;
+  __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
+  __ Branch(&adaptor_frame, eq, a3,
+            Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  // default constructor has no arguments, so no adaptor frame means no args.
+  __ mov(a0, zero_reg);
+  __ Branch(&args_set_up);
+
+  // Copy arguments from adaptor frame.
+  {
+    __ bind(&adaptor_frame);
+    __ lw(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
+    __ SmiUntag(a1, a1);
+
+    // Subtract 1 from arguments count, for new.target.
+    __ Addu(a1, a1, Operand(-1));
+    __ mov(a0, a1);
+
+    // Get arguments pointer in a2.
+    __ sll(at, a1, kPointerSizeLog2);
+    __ addu(a2, a2, at);
+    __ Addu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset));
+    Label loop;
+    __ bind(&loop);
+    // Pre-decrement a2 with kPointerSize on each iteration.
+    // Pre-decrement in order to skip receiver.
+    __ Addu(a2, a2, Operand(-kPointerSize));
+    __ lw(a3, MemOperand(a2));
+    __ Push(a3);
+    __ Addu(a1, a1, Operand(-1));
+    __ Branch(&loop, ne, a1, Operand(zero_reg));
+  }
+
+  __ bind(&args_set_up);
+  __ sll(at, a0, kPointerSizeLog2);
+  __ Addu(at, at, Operand(sp));
+  __ lw(a1, MemOperand(at, 0));
+
+  CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL);
+  __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
+
+  __ Drop(1);
+
+  context()->Plug(result_register());
+}
+
+
 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
   RegExpConstructResultStub stub(isolate());
   ZoneList<Expression*>* args = expr->arguments();
index f724da958467d14c233c4f9e8e2e4dd9b483f1f6..18c102796de98dde7f0470e4912f01f092d3c4ea 100644 (file)
@@ -3040,8 +3040,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
 }
 
 
-void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
-  DCHECK(super_ref != NULL);
+void FullCodeGenerator::EmitLoadSuperConstructor() {
   __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
   __ Push(a0);
   __ CallRuntime(Runtime::kGetPrototype, 1);
@@ -3165,9 +3164,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     if (FLAG_experimental_classes) {
       EmitSuperConstructorCall(expr);
     } else {
-      SuperReference* super_ref = callee->AsSuperReference();
-      EmitLoadSuperConstructor(super_ref);
+      EmitLoadSuperConstructor();
       __ Push(result_register());
+      SuperReference* super_ref = callee->AsSuperReference();
       VisitForStackValue(super_ref->this_var());
       EmitCall(expr, CallICState::METHOD);
     }
@@ -3240,10 +3239,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   GetVar(result_register(), new_target_var);
   __ Push(result_register());
 
-  SuperReference* super_ref = expr->expression()->AsSuperReference();
-  EmitLoadSuperConstructor(super_ref);
+  EmitLoadSuperConstructor();
   __ push(result_register());
 
+  SuperReference* super_ref = expr->expression()->AsSuperReference();
   Variable* this_var = super_ref->this_var()->var();
 
   GetVar(a0, this_var);
@@ -4176,6 +4175,63 @@ void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
 }
 
 
+void FullCodeGenerator::EmitDefaultConstructorCallSuper(CallRuntime* expr) {
+  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
+  GetVar(result_register(), new_target_var);
+  __ Push(result_register());
+
+  EmitLoadSuperConstructor();
+  __ Push(result_register());
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label adaptor_frame, args_set_up, runtime;
+  __ ld(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ ld(a3, MemOperand(a2, StandardFrameConstants::kContextOffset));
+  __ Branch(&adaptor_frame, eq, a3,
+            Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
+  // default constructor has no arguments, so no adaptor frame means no args.
+  __ mov(a0, zero_reg);
+  __ Branch(&args_set_up);
+
+  // Copy arguments from adaptor frame.
+  {
+    __ bind(&adaptor_frame);
+    __ ld(a1, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
+    __ SmiUntag(a1, a1);
+
+    // Subtract 1 from arguments count, for new.target.
+    __ Daddu(a1, a1, Operand(-1));
+    __ mov(a0, a1);
+
+    // Get arguments pointer in a2.
+    __ dsll(at, a1, kPointerSizeLog2);
+    __ Daddu(a2, a2, Operand(at));
+    __ Daddu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset));
+    Label loop;
+    __ bind(&loop);
+    // Pre-decrement a2 with kPointerSize on each iteration.
+    // Pre-decrement in order to skip receiver.
+    __ Daddu(a2, a2, Operand(-kPointerSize));
+    __ ld(a3, MemOperand(a2));
+    __ Push(a3);
+    __ Daddu(a1, a1, Operand(-1));
+    __ Branch(&loop, ne, a1, Operand(zero_reg));
+  }
+
+  __ bind(&args_set_up);
+  __ dsll(at, a0, kPointerSizeLog2);
+  __ Daddu(at, at, Operand(sp));
+  __ ld(a1, MemOperand(at, 0));
+
+  CallConstructStub stub(isolate(), SUPER_CONSTRUCTOR_CALL);
+  __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
+
+  __ Drop(1);
+
+  context()->Plug(result_register());
+}
+
+
 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
   RegExpConstructResultStub stub(isolate());
   ZoneList<Expression*>* args = expr->arguments();