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
This commit is contained in:
parent
c19d944bed
commit
299a491d7a
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user