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
-~----------~----~----~----~------~----~------~--~---