Revision: 3148
Author: [email protected]
Date: Tue Oct 27 07:52:55 2009
Log: Add VisitCallNew to fast compiler.
Review URL: http://codereview.chromium.org/334041
http://code.google.com/p/v8/source/detail?r=3148

Modified:
  /branches/bleeding_edge/src/arm/fast-codegen-arm.cc
  /branches/bleeding_edge/src/compiler.cc
  /branches/bleeding_edge/src/fast-codegen.cc
  /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc
  /branches/bleeding_edge/src/x64/fast-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Tue Oct 27 06:38:57  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Tue Oct 27 07:52:55  
2009
@@ -534,6 +534,52 @@
        break;
    }
  }
+
+
+void FastCodeGenerator::VisitCallNew(CallNew* node) {
+  Comment cmnt(masm_, "[ CallNew");
+  // According to ECMA-262, section 11.2.2, page 44, the function
+  // expression in new calls must be evaluated before the
+  // arguments.
+  // Push function on the stack.
+  Visit(node->expression());
+  ASSERT(node->expression()->location().is_temporary());
+
+  // Push global object (receiver).
+  __ ldr(r0, CodeGenerator::GlobalObject());
+  __ push(r0);
+  // Push the arguments ("left-to-right") on the stack.
+  ZoneList<Expression*>* args = node->arguments();
+  int arg_count = args->length();
+  for (int i = 0; i < arg_count; i++) {
+    Visit(args->at(i));
+    ASSERT(args->at(i)->location().is_temporary());
+    // If location is temporary, it is already on the stack,
+    // so nothing to do here.
+  }
+
+  // Call the construct call builtin that handles allocation and
+  // constructor invocation.
+  SetSourcePosition(node->position());
+
+  // Load function, arg_count into r1 and r0.
+  __ mov(r0, Operand(arg_count));
+  // Function is in esp[arg_count + 1].
+  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
+
+  Handle<Code>  
construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
+  __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
+
+  // Replace function on TOS with result in r0, or pop it.
+  switch (node->location().type()) {
+    case Location::TEMP:
+      __ str(r0, MemOperand(sp, 0));
+      break;
+    case Location::NOWHERE:
+      __ pop();
+      break;
+  }
+}


  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Tue Oct 27 01:48:01 2009
+++ /branches/bleeding_edge/src/compiler.cc     Tue Oct 27 07:52:55 2009
@@ -725,7 +725,14 @@


  void CodeGenSelector::VisitCallNew(CallNew* expr) {
-  BAILOUT("CallNew");
+  Visit(expr->expression());
+  CHECK_BAILOUT;
+  ZoneList<Expression*>* args = expr->arguments();
+  // Check all arguments to the call
+  for (int i = 0; i < args->length(); i++) {
+    Visit(args->at(i));
+    CHECK_BAILOUT;
+  }
  }


=======================================
--- /branches/bleeding_edge/src/fast-codegen.cc Tue Oct 27 06:38:57 2009
+++ /branches/bleeding_edge/src/fast-codegen.cc Tue Oct 27 07:52:55 2009
@@ -354,11 +354,6 @@
  void FastCodeGenerator::VisitProperty(Property* expr) {
    UNREACHABLE();
  }
-
-
-void FastCodeGenerator::VisitCallNew(CallNew* expr) {
-  UNREACHABLE();
-}


  void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Tue Oct 27  
06:38:57 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Tue Oct 27  
07:52:55 2009
@@ -525,6 +525,52 @@
        break;
    }
  }
+
+
+void FastCodeGenerator::VisitCallNew(CallNew* node) {
+  Comment cmnt(masm_, "[ CallNew");
+  // According to ECMA-262, section 11.2.2, page 44, the function
+  // expression in new calls must be evaluated before the
+  // arguments.
+  // Push function on the stack.
+  Visit(node->expression());
+  ASSERT(node->expression()->location().is_temporary());
+
+  // Push global object (receiver).
+  __ push(CodeGenerator::GlobalObject());
+
+  // Push the arguments ("left-to-right") on the stack.
+  ZoneList<Expression*>* args = node->arguments();
+  int arg_count = args->length();
+  for (int i = 0; i < arg_count; i++) {
+    Visit(args->at(i));
+    ASSERT(args->at(i)->location().is_temporary());
+    // If location is temporary, it is already on the stack,
+    // so nothing to do here.
+  }
+
+  // Call the construct call builtin that handles allocation and
+  // constructor invocation.
+  SetSourcePosition(node->position());
+
+  // Load function, arg_count into edi and eax.
+  __ Set(eax, Immediate(arg_count));
+  // Function is in esp[arg_count + 1].
+  __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
+
+  Handle<Code>  
construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
+  __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
+
+  // Replace function on TOS with result in eax, or pop it.
+  switch (node->location().type()) {
+    case Location::TEMP:
+      __ mov(Operand(esp, 0), eax);
+      break;
+    case Location::NOWHERE:
+      __ add(Operand(esp), Immediate(kPointerSize));
+      break;
+  }
+}


  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Tue Oct 27 06:38:57  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Tue Oct 27 07:52:55  
2009
@@ -539,6 +539,53 @@
        break;
    }
  }
+
+
+void FastCodeGenerator::VisitCallNew(CallNew* node) {
+  Comment cmnt(masm_, "[ CallNew");
+  // According to ECMA-262, section 11.2.2, page 44, the function
+  // expression in new calls must be evaluated before the
+  // arguments.
+  // Push function on the stack.
+  Visit(node->expression());
+  ASSERT(node->expression()->location().is_temporary());
+  // If location is temporary, already on the stack,
+
+  // Push global object (receiver).
+  __ push(CodeGenerator::GlobalObject());
+
+  // Push the arguments ("left-to-right") on the stack.
+  ZoneList<Expression*>* args = node->arguments();
+  int arg_count = args->length();
+  for (int i = 0; i < arg_count; i++) {
+    Visit(args->at(i));
+    ASSERT(args->at(i)->location().is_temporary());
+    // If location is temporary, it is already on the stack,
+    // so nothing to do here.
+  }
+
+  // Call the construct call builtin that handles allocation and
+  // constructor invocation.
+  SetSourcePosition(node->position());
+
+  // Load function, arg_count into rdi and rax.
+  __ Set(rax, arg_count);
+  // Function is in rsp[arg_count + 1].
+  __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize));
+
+  Handle<Code>  
construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
+  __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
+
+  // Replace function on TOS with result in rax, or pop it.
+  switch (node->location().type()) {
+    case Location::TEMP:
+      __ movq(Operand(rsp, 0), rax);
+      break;
+    case Location::NOWHERE:
+      __ addq(rsp, Immediate(kPointerSize));
+      break;
+  }
+}


  void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to