}
+void FastCodeGenerator::DropAndMove(Location destination, Register source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ __ pop();
+ break;
+ case Location::TEMP:
+ __ str(source, MemOperand(sp));
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
// The context is the first argument.
__ mov(r2, Operand(expr->name()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ pop();
- break;
- case Location::TEMP:
- // Replace the global object with the result.
- __ str(r0, MemOperand(sp));
- break;
- }
-
+ DropAndMove(expr->location(), r0);
} else {
Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ pop();
- break;
- case Location::TEMP:
- __ str(r0, MemOperand(sp));
- break;
- }
-
+ DropAndMove(expr->location(), r0);
} else {
// Local or parameter assignment.
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ pop();
- break;
- case Location::TEMP:
- __ str(r0, MemOperand(sp));
- break;
- }
+ DropAndMove(expr->location(), r0);
}
__ 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;
- }
+ DropAndMove(node->location(), r0);
}
void Move(Register destination, Location source);
void Move(Slot* destination, Location source);
+ // Drop the TOS, and store source to destination.
+ // If destination is TOS, just overwrite TOS with source.
+ void DropAndMove(Location destination, Register source);
+
void VisitDeclarations(ZoneList<Declaration*>* declarations);
Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun);
void DeclareGlobals(Handle<FixedArray> pairs);
}
+void FastCodeGenerator::DropAndMove(Location destination, Register source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ mov(Operand(esp, 0), source);
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(esi); // The context is the first argument.
// (eg, push/pop elimination).
__ nop();
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ add(Operand(esp), Immediate(kPointerSize));
- break;
- case Location::TEMP:
- // Replace the global object with the result.
- __ mov(Operand(esp, 0), eax);
- break;
- }
-
+ DropAndMove(expr->location(), eax);
} else {
Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ add(Operand(esp), Immediate(kPointerSize));
- break;
- case Location::TEMP:
- __ mov(Operand(esp, 0), eax);
- break;
- }
+ DropAndMove(expr->location(), eax);
} else {
// Local or parameter assignment.
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ add(Operand(esp), Immediate(kPointerSize));
- break;
- case Location::TEMP:
- __ mov(Operand(esp, 0), eax);
- break;
- }
+ DropAndMove(expr->location(), eax);
}
__ 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;
- }
+ DropAndMove(node->location(), eax);
}
}
+void FastCodeGenerator::DropAndMove(Location destination, Register source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ movq(Operand(rsp, 0), source);
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(rsi); // The context is the first argument.
// A test rax instruction following the call is used by the IC to
// indicate that the inobject property case was inlined. Ensure there
// is no test rax instruction here.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ addq(rsp, Immediate(kPointerSize));
- break;
- case Location::TEMP:
- // Replace the global object with the result.
- __ movq(Operand(rsp, 0), rax);
- break;
- }
-
+ DropAndMove(expr->location(), rax);
} else {
Comment cmnt(masm_, "Stack slot");
Move(expr->location(), rewrite->AsSlot());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ addq(rsp, Immediate(kPointerSize));
- break;
- case Location::TEMP:
- __ movq(Operand(rsp, 0), rax);
- break;
- }
+ DropAndMove(expr->location(), rax);
} else {
// Local or parameter assignment.
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
- switch (expr->location().type()) {
- case Location::NOWHERE:
- __ addq(rsp, Immediate(kPointerSize));
- break;
- case Location::TEMP:
- __ movq(Operand(rsp, 0), rax);
- break;
- }
+ DropAndMove(expr->location(), rax);
}
__ 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;
- }
+ DropAndMove(node->location(), rax);
}