Commit 299a491d authored by whesse@chromium.org's avatar whesse@chromium.org

Add VisitCallNew to fast compiler.

Review URL: http://codereview.chromium.org/334041

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3148 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c19d944b
......@@ -536,6 +536,52 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
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) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
......
......@@ -725,7 +725,14 @@ void CodeGenSelector::VisitCall(Call* expr) {
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;
}
}
......
......@@ -356,11 +356,6 @@ void FastCodeGenerator::VisitProperty(Property* expr) {
}
void FastCodeGenerator::VisitCallNew(CallNew* expr) {
UNREACHABLE();
}
void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
UNREACHABLE();
}
......
......@@ -527,6 +527,52 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
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) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
......
......@@ -541,6 +541,53 @@ void FastCodeGenerator::VisitCall(Call* expr) {
}
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) {
Comment cmnt(masm_, "[ CallRuntime");
ZoneList<Expression*>* args = expr->arguments();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment