Index: src/codegen-ia32.cc |
=================================================================== |
--- src/codegen-ia32.cc (revision 405) |
+++ src/codegen-ia32.cc (working copy) |
@@ -64,7 +64,7 @@ |
Expression* expression() const { return expression_; } |
Type type() const { return type_; } |
- void set_type(Type value) { |
+ void set_type(Type value) { |
ASSERT(type_ == ILLEGAL); |
type_ = value; |
} |
@@ -144,8 +144,10 @@ |
Handle<Script> script, |
bool is_eval); |
- MacroAssembler* masm() { return masm_; } |
+ MacroAssembler* masm() { return masm_; } |
+ Scope* scope() const { return scope_; } |
+ |
CodeGenState* state() { return state_; } |
void set_state(CodeGenState* state) { state_ = state; } |
@@ -167,7 +169,7 @@ |
Ia32CodeGenerator(int buffer_size, |
Handle<Script> script, |
bool is_eval); |
- virtual ~Ia32CodeGenerator() { delete masm_; } |
+ virtual ~Ia32CodeGenerator() { delete masm_; } |
// Main code generation function |
void GenCode(FunctionLiteral* fun); |
@@ -191,13 +193,14 @@ |
// Support functions for accessing parameters. Static versions can |
// require some code generator state to be passed in as arguments. |
- static Operand ParameterOperand(Scope* scope, int index) { |
- ASSERT(-2 <= index && index < scope->num_parameters()); |
- return Operand(ebp, (1 + scope->num_parameters() - index) * kPointerSize); |
+ static Operand ParameterOperand(const CodeGenerator* cgen, int index) { |
Kasper Lund
2008/10/02 08:57:58
Extra whitespace at end of line?
|
+ int num_parameters = cgen->scope()->num_parameters(); |
+ ASSERT(-2 <= index && index < num_parameters); |
+ return Operand(ebp, (1 + num_parameters - index) * kPointerSize); |
} |
Operand ParameterOperand(int index) const { |
- return ParameterOperand(scope_, index); |
+ return ParameterOperand(this, index); |
} |
Operand ReceiverOperand() const { return ParameterOperand(-1); } |
@@ -210,13 +213,12 @@ |
return Operand(context, Context::SlotOffset(index)); |
} |
- static Operand SlotOperand(MacroAssembler* masm, |
- Scope* scope, |
+ static Operand SlotOperand(CodeGenerator* cgen, |
Slot* slot, |
Register tmp); |
Operand SlotOperand(Slot* slot, Register tmp) { |
- return SlotOperand(masm_, scope_, slot, tmp); |
+ return SlotOperand(this, slot, tmp); |
} |
void LoadCondition(Expression* x, |
@@ -254,14 +256,14 @@ |
void SetValue(Reference* ref) { |
ASSERT(!has_cc()); |
ASSERT(!ref->is_illegal()); |
- ref->expression()->GenerateStoreCode(masm_, scope_, ref, NOT_CONST_INIT); |
+ ref->expression()->GenerateStoreCode(this, ref, NOT_CONST_INIT); |
} |
// Same as SetValue, used to set the initial value of a constant. |
void InitConst(Reference* ref) { |
ASSERT(!has_cc()); |
ASSERT(!ref->is_illegal()); |
- ref->expression()->GenerateStoreCode(masm_, scope_, ref, CONST_INIT); |
+ ref->expression()->GenerateStoreCode(this, ref, CONST_INIT); |
} |
// Generate code to fetch a value from a property of a reference. The |
@@ -273,7 +275,7 @@ |
// stored value is expected on top of the expression stack, with the |
// reference immediately below it. The expression stack is left |
// unchanged. |
- static void SetReferenceProperty(MacroAssembler* masm, |
+ static void SetReferenceProperty(CodeGenerator* cgen, |
Reference* ref, |
Expression* key); |
@@ -423,9 +425,8 @@ |
// ----------------------------------------------------------------------------- |
// Ia32CodeGenerator implementation |
-#define __ masm_-> |
+#define __ masm_-> |
- |
Handle<Code> Ia32CodeGenerator::MakeCode(FunctionLiteral* flit, |
Handle<Script> script, |
bool is_eval) { |
@@ -731,8 +732,10 @@ |
} |
-Operand Ia32CodeGenerator::SlotOperand(MacroAssembler* masm, |
- Scope* scope, |
+#undef __ |
+#define __ masm-> |
+ |
+Operand Ia32CodeGenerator::SlotOperand(CodeGenerator* cgen, |
Slot* slot, |
Register tmp) { |
// Currently, this assertion will fail if we try to assign to |
@@ -746,27 +749,29 @@ |
ASSERT(slot != NULL); |
int index = slot->index(); |
switch (slot->type()) { |
- case Slot::PARAMETER: return ParameterOperand(scope, index); |
+ case Slot::PARAMETER: return ParameterOperand(cgen, index); |
case Slot::LOCAL: { |
- ASSERT(0 <= index && index < scope->num_stack_slots()); |
+ ASSERT(0 <= index && index < cgen->scope()->num_stack_slots()); |
const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; |
return Operand(ebp, kLocal0Offset - index * kPointerSize); |
} |
case Slot::CONTEXT: { |
+ MacroAssembler* masm = cgen->masm(); |
// Follow the context chain if necessary. |
ASSERT(!tmp.is(esi)); // do not overwrite context register |
Register context = esi; |
- int chain_length = scope->ContextChainLength(slot->var()->scope()); |
+ int chain_length = |
+ cgen->scope()->ContextChainLength(slot->var()->scope()); |
for (int i = chain_length; i-- > 0;) { |
// Load the closure. |
// (All contexts, even 'with' contexts, have a closure, |
// and it is the same for all contexts inside a function. |
// There is no need to go to the function context first.) |
- masm->mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
+ __ mov(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
// Load the function context (which is the incoming, outer context). |
- masm->mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset)); |
+ __ mov(tmp, FieldOperand(tmp, JSFunction::kContextOffset)); |
context = tmp; |
} |
// We may have a 'with' context now. Get the function context. |
@@ -776,7 +781,7 @@ |
// cause the function context of a function context is itself. Before |
// deleting this mov we should try to create a counter-example first, |
// though...) |
- masm->mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); |
+ __ mov(tmp, ContextOperand(context, Context::FCONTEXT_INDEX)); |
return ContextOperand(tmp, index); |
} |
@@ -787,6 +792,9 @@ |
} |
+#undef __ |
+#define __ masm_-> |
+ |
// Loads a value on TOS. If it is a boolean value, the result may have been |
// (partially) translated into branches, or it may have set the condition code |
// register. If force_cc is set, the value is forced to set the condition code |
@@ -951,49 +959,52 @@ |
} |
-void Property::GenerateStoreCode(MacroAssembler* masm, |
- Scope* scope, |
+#undef __ |
+#define __ masm-> |
+ |
+void Property::GenerateStoreCode(CodeGenerator* cgen, |
Reference* ref, |
InitState init_state) { |
+ MacroAssembler* masm = cgen->masm(); |
Comment cmnt(masm, "[ Store to Property"); |
- masm->RecordPosition(position()); |
- Ia32CodeGenerator::SetReferenceProperty(masm, ref, key()); |
+ __ RecordPosition(position()); |
+ Ia32CodeGenerator::SetReferenceProperty(cgen, ref, key()); |
} |
-void VariableProxy::GenerateStoreCode(MacroAssembler* masm, |
- Scope* scope, |
+void VariableProxy::GenerateStoreCode(CodeGenerator* cgen, |
Reference* ref, |
InitState init_state) { |
+ MacroAssembler* masm = cgen->masm(); |
Comment cmnt(masm, "[ Store to VariableProxy"); |
Variable* node = var(); |
Expression* expr = node->rewrite(); |
if (expr != NULL) { |
- expr->GenerateStoreCode(masm, scope, ref, init_state); |
+ expr->GenerateStoreCode(cgen, ref, init_state); |
} else { |
ASSERT(node->is_global()); |
if (node->AsProperty() != NULL) { |
- masm->RecordPosition(node->AsProperty()->position()); |
+ __ RecordPosition(node->AsProperty()->position()); |
} |
- Ia32CodeGenerator::SetReferenceProperty(masm, ref, |
- new Literal(node->name())); |
+ Expression* key = new Literal(node->name()); |
+ Ia32CodeGenerator::SetReferenceProperty(cgen, ref, key); |
} |
} |
-void Slot::GenerateStoreCode(MacroAssembler* masm, |
- Scope* scope, |
+void Slot::GenerateStoreCode(CodeGenerator* cgen, |
Reference* ref, |
InitState init_state) { |
+ MacroAssembler* masm = cgen->masm(); |
Comment cmnt(masm, "[ Store to Slot"); |
if (type() == Slot::LOOKUP) { |
ASSERT(var()->mode() == Variable::DYNAMIC); |
// For now, just do a runtime call. |
- masm->push(Operand(esi)); |
- masm->push(Immediate(var()->name())); |
+ __ push(esi); |
+ __ push(Immediate(var()->name())); |
if (init_state == CONST_INIT) { |
// Same as the case for a normal store, but ignores attribute |
@@ -1010,13 +1021,13 @@ |
// the expression operands are defined and valid, and thus we need the |
// split into 2 operations: declaration of the context slot followed |
// by initialization. |
- masm->CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
+ __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); |
} else { |
- masm->CallRuntime(Runtime::kStoreContextSlot, 3); |
+ __ CallRuntime(Runtime::kStoreContextSlot, 3); |
} |
// Storing a variable must keep the (new) value on the expression |
// stack. This is necessary for compiling assignment expressions. |
- masm->push(eax); |
+ __ push(eax); |
} else { |
ASSERT(var()->mode() != Variable::DYNAMIC); |
@@ -1028,9 +1039,9 @@ |
// still contains 'the hole' value). When the assignment is executed, |
// the code is identical to a normal store (see below). |
Comment cmnt(masm, "[ Init const"); |
- masm->mov(eax, Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx)); |
- masm->cmp(eax, Factory::the_hole_value()); |
- masm->j(not_equal, &exit); |
+ __ mov(eax, Ia32CodeGenerator::SlotOperand(cgen, this, ecx)); |
+ __ cmp(eax, Factory::the_hole_value()); |
+ __ j(not_equal, &exit); |
} |
// We must execute the store. |
@@ -1042,24 +1053,21 @@ |
// Variable::CONST because of const declarations which will initialize |
// consts to 'the hole' value and by doing so, end up calling this |
// code. |
- masm->pop(eax); |
- masm->mov(Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx), eax); |
- masm->push(eax); // RecordWrite may destroy the value in eax. |
+ __ pop(eax); |
+ __ mov(Ia32CodeGenerator::SlotOperand(cgen, this, ecx), eax); |
+ __ push(eax); // RecordWrite may destroy the value in eax. |
if (type() == Slot::CONTEXT) { |
// ecx is loaded with context when calling SlotOperand above. |
int offset = FixedArray::kHeaderSize + index() * kPointerSize; |
- masm->RecordWrite(ecx, offset, eax, ebx); |
+ __ RecordWrite(ecx, offset, eax, ebx); |
} |
// If we definitely did not jump over the assignment, we do not need to |
// bind the exit label. Doing so can defeat peephole optimization. |
- if (init_state == CONST_INIT) masm->bind(&exit); |
+ if (init_state == CONST_INIT) __ bind(&exit); |
} |
} |
-#undef __ |
-#define __ masm-> |
- |
class ToBooleanStub: public CodeStub { |
public: |
ToBooleanStub() { } |
@@ -1138,10 +1146,10 @@ |
__ ret(1 * kPointerSize); |
} |
+ |
#undef __ |
-#define __ masm_-> |
+#define __ masm_-> |
- |
// ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and |
// convert it to a boolean in the condition code register or jump to |
// 'false_target'/'true_target' as appropriate. |
@@ -1226,13 +1234,16 @@ |
} |
-void Ia32CodeGenerator::SetReferenceProperty(MacroAssembler* masm, |
+#undef __ |
+#define __ masm-> |
+ |
+void Ia32CodeGenerator::SetReferenceProperty(CodeGenerator* cgen, |
Reference* ref, |
Expression* key) { |
ASSERT(!ref->is_illegal()); |
- Reference::Type type = ref->type(); |
+ MacroAssembler* masm = cgen->masm(); |
- if (type == Reference::NAMED) { |
+ if (ref->type() == Reference::NAMED) { |
// Compute the name of the property. |
Literal* literal = key->AsLiteral(); |
Handle<String> name(String::cast(*literal->handle())); |
@@ -1240,28 +1251,24 @@ |
// Call the appropriate IC code. |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
// TODO(1222589): Make the IC grab the values from the stack. |
- masm->pop(eax); |
+ __ pop(eax); |
// Setup the name register. |
- masm->Set(ecx, Immediate(name)); |
- masm->call(ic, RelocInfo::CODE_TARGET); |
+ __ Set(ecx, Immediate(name)); |
+ __ call(ic, RelocInfo::CODE_TARGET); |
} else { |
// Access keyed property. |
- ASSERT(type == Reference::KEYED); |
+ ASSERT(ref->type() == Reference::KEYED); |
// Call IC code. |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
// TODO(1222589): Make the IC grab the values from the stack. |
- masm->pop(eax); |
- masm->call(ic, RelocInfo::CODE_TARGET); |
+ __ pop(eax); |
+ __ call(ic, RelocInfo::CODE_TARGET); |
} |
- masm->push(eax); // IC call leaves result in eax, push it out |
+ __ push(eax); // IC call leaves result in eax, push it out |
} |
-#undef __ |
-#define __ masm-> |
- |
- |
class FloatingPointHelper : public AllStatic { |
public: |
// Code pattern for loading floating point values. Input values must |
@@ -1771,10 +1778,6 @@ |
} |
-#undef __ |
-#define __ masm-> |
- |
- |
void UnarySubStub::Generate(MacroAssembler* masm) { |
Label undo; |
Label slow; |
@@ -1827,7 +1830,7 @@ |
__ bind(&done); |
- masm->StubReturn(1); |
+ __ StubReturn(1); |
} |
@@ -1926,9 +1929,8 @@ |
#undef __ |
-#define __ masm_-> |
+#define __ masm_-> |
- |
void Ia32CodeGenerator::GenericBinaryOperation(Token::Value op, |
OverwriteMode overwrite_mode) { |
Comment cmnt(masm_, "[ BinaryOperation"); |
@@ -2365,7 +2367,7 @@ |
#undef __ |
-#define __ masm-> |
+#define __ masm-> |
class CompareStub: public CodeStub { |
public: |
@@ -2481,9 +2483,8 @@ |
#undef __ |
-#define __ masm_-> |
+#define __ masm_-> |
- |
void Ia32CodeGenerator::Comparison(Condition cc, bool strict) { |
// Strict only makes sense for equality comparisons. |
ASSERT(!strict || cc == equal); |
@@ -2592,36 +2593,42 @@ |
}; |
+#undef __ |
+#define __ masm-> |
+ |
void CallFunctionStub::Generate(MacroAssembler* masm) { |
Label slow; |
// Get the function to call from the stack. |
// +2 ~ receiver, return address |
- masm->mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); |
+ __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); |
// Check that the function really is a JavaScript function. |
- masm->test(edi, Immediate(kSmiTagMask)); |
- masm->j(zero, &slow, not_taken); |
+ __ test(edi, Immediate(kSmiTagMask)); |
+ __ j(zero, &slow, not_taken); |
// Get the map. |
- masm->mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); |
- masm->movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
- masm->cmp(ecx, JS_FUNCTION_TYPE); |
- masm->j(not_equal, &slow, not_taken); |
+ __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); |
+ __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
+ __ cmp(ecx, JS_FUNCTION_TYPE); |
+ __ j(not_equal, &slow, not_taken); |
// Fast-case: Just invoke the function. |
ParameterCount actual(argc_); |
- masm->InvokeFunction(edi, actual, JUMP_FUNCTION); |
+ __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
// Slow-case: Non-function called. |
- masm->bind(&slow); |
- masm->Set(eax, Immediate(argc_)); |
- masm->Set(ebx, Immediate(0)); |
- masm->GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
+ __ bind(&slow); |
+ __ Set(eax, Immediate(argc_)); |
+ __ Set(ebx, Immediate(0)); |
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
Handle<Code> adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
- masm->jmp(adaptor, RelocInfo::CODE_TARGET); |
+ __ jmp(adaptor, RelocInfo::CODE_TARGET); |
} |
+#undef __ |
+#define __ masm_-> |
+ |
// Call the function just below TOS on the stack with the given |
// arguments. The receiver is the TOS. |
void Ia32CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
@@ -4628,9 +4635,8 @@ |
#undef __ |
-#define __ masm-> |
+#define __ masm-> |
- |
class RevertToNumberStub: public CodeStub { |
public: |
explicit RevertToNumberStub(bool is_increment) |
@@ -4733,9 +4739,8 @@ |
#undef __ |
-#define __ masm_-> |
+#define __ masm_-> |
- |
void CountOperationDeferred::Generate() { |
if (is_postfix_) { |
RevertToNumberStub to_number_stub(is_increment_); |
@@ -5171,9 +5176,8 @@ |
#undef __ |
-#define __ masm-> |
+#define __ masm-> |
- |
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code |
ExternalReference handler_address(Top::k_handler_address); |