MIPS: Classes: implement 'new super'.
authorakos.palfi@imgtec.com <akos.palfi@imgtec.com>
Thu, 23 Oct 2014 12:05:46 +0000 (12:05 +0000)
committerakos.palfi@imgtec.com <akos.palfi@imgtec.com>
Thu, 23 Oct 2014 12:05:46 +0000 (12:05 +0000)
Port r24825 (b26f0181)

BUG=
R=dslomov@chromium.org, dusan.milosavljevic@imgtec.com

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24841 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

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

index c710dcf..deafb7c 100644 (file)
@@ -2939,6 +2939,14 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(a0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3054,10 +3062,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     }
   } else if (call_type == Call::SUPER_CALL) {
     SuperReference* super_ref = callee->AsSuperReference();
-    DCHECK(super_ref != NULL);
-    __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    __ Push(a0);
-    __ CallRuntime(Runtime::kGetPrototype, 1);
+    EmitLoadSuperConstructor(super_ref);
     __ Push(result_register());
     VisitForStackValue(super_ref->this_var());
     EmitCall(expr, CallICState::METHOD);
@@ -3089,7 +3094,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
index b57dbb1..959edc0 100644 (file)
@@ -2938,6 +2938,14 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(a0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3053,10 +3061,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     }
   } else if (call_type == Call::SUPER_CALL) {
     SuperReference* super_ref = callee->AsSuperReference();
-    DCHECK(super_ref != NULL);
-    __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    __ Push(a0);
-    __ CallRuntime(Runtime::kGetPrototype, 1);
+    EmitLoadSuperConstructor(super_ref);
     __ Push(result_register());
     VisitForStackValue(super_ref->this_var());
     EmitCall(expr, CallICState::METHOD);
@@ -3088,7 +3093,12 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();