Chromium Code Reviews| Index: src/codegen-ia32.cc |
| =================================================================== |
| --- src/codegen-ia32.cc (revision 461) |
| +++ src/codegen-ia32.cc (working copy) |
| @@ -57,6 +57,7 @@ |
| // on the execution stack to represent the reference. |
| enum InitState { CONST_INIT, NOT_CONST_INIT }; |
| +enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; |
| class Reference BASE_EMBEDDED { |
| public: |
| @@ -79,6 +80,18 @@ |
| bool is_slot() const { return type_ == SLOT; } |
| bool is_property() const { return type_ == NAMED || type_ == KEYED; } |
| + // Return the name. Only valid for named property references. |
| + Handle<String> GetName(); |
| + |
| + // Generate code to push the value of the reference on top of the |
| + // expression stack. The reference is expected to be already on top of |
| + // the expression stack, and it is left in place with its value above it. |
| + void GetValue(TypeofState typeof_state); |
| + |
| + // Generate code to store the value on top of the expression stack in the |
| + // reference. The reference is expected to be immediately below the value |
| + // on the expression stack. The stored value is left in place (with the |
| + // reference intact below it) to support chained assignments. |
| void SetValue(InitState init_state); |
| private: |
| @@ -98,42 +111,29 @@ |
| class CodeGenState BASE_EMBEDDED { |
| public: |
| - enum AccessType { |
| - UNDEFINED, |
| - LOAD, |
| - LOAD_TYPEOF_EXPR |
| - }; |
| - |
| // Create an initial code generator state. Destroying the initial state |
| // leaves the code generator with a NULL state. |
| explicit CodeGenState(Ia32CodeGenerator* owner); |
| // Create a code generator state based on a code generator's current |
| - // state. The new state has its own access type and pair of branch |
| - // labels, and no reference. |
| + // state. The new state has its own typeof state and pair of branch |
| + // labels. |
| CodeGenState(Ia32CodeGenerator* owner, |
| - AccessType access, |
| + TypeofState typeof_state, |
| Label* true_target, |
| Label* false_target); |
| - // Create a code generator state based on a code generator's current |
| - // state. The new state has an access type of LOAD, its own reference, |
| - // and inherits the pair of branch labels of the current state. |
| - CodeGenState(Ia32CodeGenerator* owner, Reference* ref); |
| - |
| // Destroy a code generator state and restore the owning code generator's |
| // previous state. |
| ~CodeGenState(); |
| - AccessType access() const { return access_; } |
| - Reference* ref() const { return ref_; } |
| + TypeofState typeof_state() const { return typeof_state_; } |
| Label* true_target() const { return true_target_; } |
| Label* false_target() const { return false_target_; } |
| private: |
| Ia32CodeGenerator* owner_; |
| - AccessType access_; |
| - Reference* ref_; |
| + TypeofState typeof_state_; |
| Label* true_target_; |
| Label* false_target_; |
| CodeGenState* previous_; |
| @@ -185,9 +185,7 @@ |
| // State |
| bool has_cc() const { return cc_reg_ >= 0; } |
| - CodeGenState::AccessType access() const { return state_->access(); } |
| - Reference* ref() const { return state_->ref(); } |
| - bool is_referenced() const { return state_->ref() != NULL; } |
| + TypeofState typeof_state() const { return state_->typeof_state(); } |
| Label* true_target() const { return state_->true_target(); } |
| Label* false_target() const { return state_->false_target(); } |
| @@ -216,14 +214,16 @@ |
| Operand SlotOperand(Slot* slot, Register tmp); |
| void LoadCondition(Expression* x, |
| - CodeGenState::AccessType access, |
| + TypeofState typeof_state, |
| Label* true_target, |
| Label* false_target, |
| bool force_cc); |
| - void Load(Expression* x, |
| - CodeGenState::AccessType access = CodeGenState::LOAD); |
| + void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); |
| void LoadGlobal(); |
| + // Read a value from a slot and leave it on top of the expression stack. |
| + void LoadFromSlot(Slot* slot, TypeofState typeof_state); |
| + |
| // Special code for typeof expressions: Unfortunately, we must |
| // be careful when loading the expression in 'typeof' |
| // expressions. We are not allowed to throw reference errors for |
| @@ -232,23 +232,6 @@ |
| // through the context chain. |
| void LoadTypeofExpression(Expression* x); |
| - // References |
| - |
| - // Generate code to fetch the value of a reference. The reference is |
| - // expected to be on top of the expression stack. It is left in place and |
| - // its value is pushed on top of it. |
| - void GetValue(Reference* ref) { |
| - ASSERT(!has_cc()); |
| - ASSERT(!ref->is_illegal()); |
| - CodeGenState new_state(this, ref); |
| - Visit(ref->expression()); |
| - } |
| - |
| - // Generate code to fetch a value from a property of a reference. The |
| - // reference is expected on top of the expression stack. It is left in |
| - // place and its value is pushed on top of it. |
| - void GetReferenceProperty(Expression* key); |
| - |
| void ToBoolean(Label* true_target, Label* false_target); |
| void GenericBinaryOperation( |
| @@ -340,8 +323,7 @@ |
| CodeGenState::CodeGenState(Ia32CodeGenerator* owner) |
| : owner_(owner), |
| - access_(UNDEFINED), |
| - ref_(NULL), |
| + typeof_state_(NOT_INSIDE_TYPEOF), |
| true_target_(NULL), |
| false_target_(NULL), |
| previous_(NULL) { |
| @@ -350,12 +332,11 @@ |
| CodeGenState::CodeGenState(Ia32CodeGenerator* owner, |
| - AccessType access, |
| + TypeofState typeof_state, |
| Label* true_target, |
| Label* false_target) |
| : owner_(owner), |
| - access_(access), |
| - ref_(NULL), |
| + typeof_state_(typeof_state), |
| true_target_(true_target), |
| false_target_(false_target), |
| previous_(owner->state()) { |
| @@ -363,17 +344,6 @@ |
| } |
| -CodeGenState::CodeGenState(Ia32CodeGenerator* owner, Reference* ref) |
| - : owner_(owner), |
| - access_(LOAD), |
| - ref_(ref), |
| - true_target_(owner->state()->true_target_), |
| - false_target_(owner->state()->false_target_), |
| - previous_(owner->state()) { |
| - owner_->set_state(this); |
| -} |
| - |
| - |
| CodeGenState::~CodeGenState() { |
| ASSERT(owner_->state() == this); |
| owner_->set_state(previous_); |
| @@ -759,15 +729,13 @@ |
| // register and no value is pushed. If the condition code register was set, |
| // has_cc() is true and cc_reg_ contains the condition to test for 'true'. |
| void Ia32CodeGenerator::LoadCondition(Expression* x, |
| - CodeGenState::AccessType access, |
| + TypeofState typeof_state, |
| Label* true_target, |
| Label* false_target, |
| bool force_cc) { |
| - ASSERT(access == CodeGenState::LOAD || |
| - access == CodeGenState::LOAD_TYPEOF_EXPR); |
| - ASSERT(!has_cc() && !is_referenced()); |
| + ASSERT(!has_cc()); |
| - { CodeGenState new_state(this, access, true_target, false_target); |
| + { CodeGenState new_state(this, typeof_state, true_target, false_target); |
| Visit(x); |
| } |
| if (force_cc && !has_cc()) { |
| @@ -777,13 +745,10 @@ |
| } |
| -void Ia32CodeGenerator::Load(Expression* x, CodeGenState::AccessType access) { |
| - ASSERT(access == CodeGenState::LOAD || |
| - access == CodeGenState::LOAD_TYPEOF_EXPR); |
| - |
| +void Ia32CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
| Label true_target; |
| Label false_target; |
| - LoadCondition(x, access, &true_target, &false_target, false); |
| + LoadCondition(x, typeof_state, &true_target, &false_target, false); |
| if (has_cc()) { |
| // convert cc_reg_ into a bool |
| @@ -832,8 +797,8 @@ |
| // TODO(1241834): Get rid of this function in favor of just using Load, now |
| -// that we have the LOAD_TYPEOF_EXPR access type. => Need to handle |
| -// global variables w/o reference errors elsewhere. |
| +// that we have the INSIDE_TYPEOF typeof state. => Need to handle global |
| +// variables w/o reference errors elsewhere. |
| void Ia32CodeGenerator::LoadTypeofExpression(Expression* x) { |
| Variable* variable = x->AsVariableProxy()->AsVariable(); |
| if (variable != NULL && !variable->is_this() && variable->is_global()) { |
| @@ -847,7 +812,7 @@ |
| Property property(&global, &key, RelocInfo::kNoPosition); |
| Load(&property); |
| } else { |
| - Load(x, CodeGenState::LOAD_TYPEOF_EXPR); |
| + Load(x, INSIDE_TYPEOF); |
| } |
| } |
| @@ -864,6 +829,7 @@ |
| void Ia32CodeGenerator::LoadReference(Reference* ref) { |
| + Comment cmnt(masm_, "[ LoadReference"); |
| Expression* e = ref->expression(); |
| Property* property = e->AsProperty(); |
| Variable* var = e->AsVariableProxy()->AsVariable(); |
| @@ -905,7 +871,7 @@ |
| void Ia32CodeGenerator::UnloadReference(Reference* ref) { |
| - // Pop n references on the stack while preserving TOS |
| + // Pop a reference from the stack while preserving TOS. |
| Comment cmnt(masm_, "[ UnloadReference"); |
| int size = ref->size(); |
| if (size <= 0) { |
| @@ -985,47 +951,6 @@ |
| } |
| -void Ia32CodeGenerator::GetReferenceProperty(Expression* key) { |
| - ASSERT(!ref()->is_illegal()); |
| - |
| - // TODO(1241834): Make sure that this it is safe to ignore the distinction |
| - // between access types LOAD and LOAD_TYPEOF_EXPR. If there is a chance |
| - // that reference errors can be thrown below, we must distinguish between |
| - // the two kinds of loads (typeof expression loads must not throw a |
| - // reference error). |
| - if (ref()->type() == Reference::NAMED) { |
| - // Compute the name of the property. |
| - Literal* literal = key->AsLiteral(); |
| - Handle<String> name(String::cast(*literal->handle())); |
| - |
| - Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| - Variable* var = ref()->expression()->AsVariableProxy()->AsVariable(); |
| - // Setup the name register. |
| - __ Set(ecx, Immediate(name)); |
| - if (var != NULL) { |
| - ASSERT(var->is_global()); |
| - __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| - } else { |
| - __ call(ic, RelocInfo::CODE_TARGET); |
| - } |
| - } else { |
| - // Access keyed property. |
| - ASSERT(ref()->type() == Reference::KEYED); |
| - |
| - // Call IC code. |
| - Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| - Variable* var = ref()->expression()->AsVariableProxy()->AsVariable(); |
| - if (var != NULL) { |
| - ASSERT(var->is_global()); |
| - __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| - } else { |
| - __ call(ic, RelocInfo::CODE_TARGET); |
| - } |
| - } |
| - __ push(eax); // IC call leaves result in eax, push it out |
| -} |
| - |
| - |
| class FloatingPointHelper : public AllStatic { |
| public: |
| // Code pattern for loading floating point values. Input values must |
| @@ -1676,7 +1601,9 @@ |
| void Ia32CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
| int position) { |
| // Push the arguments ("left-to-right") on the stack. |
| - for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
| + for (int i = 0; i < args->length(); i++) { |
| + Load(args->at(i)); |
| + } |
|
iposva
2008/10/07 19:43:31
Thanks!
|
| // Record the position for debugging purposes. |
| __ RecordPosition(position); |
| @@ -1821,7 +1748,7 @@ |
| Label then; |
| Label else_; |
| // if (cond) |
| - LoadCondition(node->condition(), CodeGenState::LOAD, &then, &else_, true); |
| + LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
| Branch(false, &else_); |
| // then |
| __ bind(&then); |
| @@ -1835,7 +1762,7 @@ |
| ASSERT(!has_else_stm); |
| Label then; |
| // if (cond) |
| - LoadCondition(node->condition(), CodeGenState::LOAD, &then, &exit, true); |
| + LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &exit, true); |
| Branch(false, &exit); |
| // then |
| __ bind(&then); |
| @@ -1845,7 +1772,7 @@ |
| ASSERT(!has_then_stm); |
| Label else_; |
| // if (!cond) |
| - LoadCondition(node->condition(), CodeGenState::LOAD, &exit, &else_, true); |
| + LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &else_, true); |
| Branch(true, &exit); |
| // else |
| __ bind(&else_); |
| @@ -1854,7 +1781,7 @@ |
| } else { |
| ASSERT(!has_then_stm && !has_else_stm); |
| // if (cond) |
| - LoadCondition(node->condition(), CodeGenState::LOAD, &exit, &exit, false); |
| + LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &exit, false); |
| if (has_cc()) { |
| cc_reg_ = no_condition; |
| } else { |
| @@ -2139,7 +2066,7 @@ |
| case ALWAYS_FALSE: |
| break; |
| case DONT_KNOW: |
| - LoadCondition(node->cond(), CodeGenState::LOAD, &loop, |
| + LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, &loop, |
| node->break_target(), true); |
| Branch(true, &loop); |
| break; |
| @@ -2608,78 +2535,71 @@ |
| void Ia32CodeGenerator::VisitConditional(Conditional* node) { |
| Comment cmnt(masm_, "[ Conditional"); |
| Label then, else_, exit; |
| - LoadCondition(node->condition(), CodeGenState::LOAD, &then, &else_, true); |
| + LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); |
| Branch(false, &else_); |
| __ bind(&then); |
| - Load(node->then_expression(), access()); |
| + Load(node->then_expression(), typeof_state()); |
| __ jmp(&exit); |
| __ bind(&else_); |
| - Load(node->else_expression(), access()); |
| + Load(node->else_expression(), typeof_state()); |
| __ bind(&exit); |
| } |
| -void Ia32CodeGenerator::VisitSlot(Slot* node) { |
| - ASSERT(access() != CodeGenState::UNDEFINED); |
| - Comment cmnt(masm_, "[ Slot"); |
| +void Ia32CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
| + if (slot->type() == Slot::LOOKUP) { |
| + ASSERT(slot->var()->mode() == Variable::DYNAMIC); |
| - if (node->type() == Slot::LOOKUP) { |
| - ASSERT(node->var()->mode() == Variable::DYNAMIC); |
| - |
| // For now, just do a runtime call. |
| - __ push(Operand(esi)); |
| - __ push(Immediate(node->var()->name())); |
| + __ push(esi); |
| + __ push(Immediate(slot->var()->name())); |
| - if (access() == CodeGenState::LOAD) { |
| - __ CallRuntime(Runtime::kLoadContextSlot, 2); |
| - } else { |
| - ASSERT(access() == CodeGenState::LOAD_TYPEOF_EXPR); |
| + if (typeof_state == INSIDE_TYPEOF) { |
| __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| + } else { |
| + __ CallRuntime(Runtime::kLoadContextSlot, 2); |
| } |
| __ push(eax); |
| } else { |
| // Note: We would like to keep the assert below, but it fires because of |
| // some nasty code in LoadTypeofExpression() which should be removed... |
| - // ASSERT(node->var()->mode() != Variable::DYNAMIC); |
| - |
| - if (node->var()->mode() == Variable::CONST) { |
| + // ASSERT(slot->var()->mode() != Variable::DYNAMIC); |
| + if (slot->var()->mode() == Variable::CONST) { |
| // Const slots may contain 'the hole' value (the constant hasn't been |
| // initialized yet) which needs to be converted into the 'undefined' |
| // value. |
| Comment cmnt(masm_, "[ Load const"); |
| - Label L; |
| - __ mov(eax, SlotOperand(node, ecx)); |
| + Label exit; |
| + __ mov(eax, SlotOperand(slot, ecx)); |
| __ cmp(eax, Factory::the_hole_value()); |
| - __ j(not_equal, &L); |
| + __ j(not_equal, &exit); |
| __ mov(eax, Factory::undefined_value()); |
| - __ bind(&L); |
| + __ bind(&exit); |
| __ push(eax); |
| } else { |
| - __ push(SlotOperand(node, ecx)); |
| + __ push(SlotOperand(slot, ecx)); |
| } |
| } |
| } |
| +void Ia32CodeGenerator::VisitSlot(Slot* node) { |
| + Comment cmnt(masm_, "[ Slot"); |
| + LoadFromSlot(node, typeof_state()); |
| +} |
| + |
| + |
| void Ia32CodeGenerator::VisitVariableProxy(VariableProxy* node) { |
| Comment cmnt(masm_, "[ VariableProxy"); |
| - Variable* var_node = node->var(); |
| - |
| - Expression* expr = var_node->rewrite(); |
| + Variable* var = node->var(); |
| + Expression* expr = var->rewrite(); |
| if (expr != NULL) { |
| Visit(expr); |
| } else { |
| - ASSERT(var_node->is_global()); |
| - if (is_referenced()) { |
| - if (var_node->AsProperty() != NULL) { |
| - __ RecordPosition(var_node->AsProperty()->position()); |
| - } |
| - GetReferenceProperty(new Literal(var_node->name())); |
| - } else { |
| - Reference property(this, node); |
| - GetValue(&property); |
| - } |
| + ASSERT(var->is_global()); |
| + Reference ref(this, node); |
| + ref.GetValue(typeof_state()); |
| } |
| } |
| @@ -2942,7 +2862,7 @@ |
| Load(node->value()); |
| } else { |
| - GetValue(&target); |
| + target.GetValue(NOT_INSIDE_TYPEOF); |
| Literal* literal = node->value()->AsLiteral(); |
| if (IsInlineSmi(literal)) { |
| SmiOperation(node->binary_op(), literal->handle(), false, NO_OVERWRITE); |
| @@ -2983,15 +2903,8 @@ |
| void Ia32CodeGenerator::VisitProperty(Property* node) { |
| Comment cmnt(masm_, "[ Property"); |
| - |
| - if (is_referenced()) { |
| - __ RecordPosition(node->position()); |
| - GetReferenceProperty(node->key()); |
| - } else { |
| - Reference property(this, node); |
| - __ RecordPosition(node->position()); |
| - GetValue(&property); |
| - } |
| + Reference property(this, node); |
| + property.GetValue(typeof_state()); |
| } |
| @@ -3090,7 +3003,7 @@ |
| // Load the function to call from the property through a reference. |
| Reference ref(this, property); |
| - GetValue(&ref); |
| + ref.GetValue(NOT_INSIDE_TYPEOF); |
| // Pass receiver to called function. |
| // The reference's size is non-negative. |
| @@ -3456,7 +3369,7 @@ |
| Token::Value op = node->op(); |
| if (op == Token::NOT) { |
| - LoadCondition(node->expression(), CodeGenState::LOAD, |
| + LoadCondition(node->expression(), NOT_INSIDE_TYPEOF, |
| false_target(), true_target(), true); |
| cc_reg_ = NegateCondition(cc_reg_); |
| @@ -3677,7 +3590,7 @@ |
| { Reference target(this, node->expression()); |
| if (target.is_illegal()) return; |
| - GetValue(&target); |
| + target.GetValue(NOT_INSIDE_TYPEOF); |
| int result_offset = target.size() * kPointerSize; |
| CountOperationDeferred* deferred = |
| @@ -3732,14 +3645,14 @@ |
| if (op == Token::AND) { |
| Label is_true; |
| - LoadCondition(node->left(), CodeGenState::LOAD, &is_true, |
| + LoadCondition(node->left(), NOT_INSIDE_TYPEOF, &is_true, |
| false_target(), false); |
| if (has_cc()) { |
| Branch(false, false_target()); |
| // Evaluate right side expression. |
| __ bind(&is_true); |
| - LoadCondition(node->right(), CodeGenState::LOAD, true_target(), |
| + LoadCondition(node->right(), NOT_INSIDE_TYPEOF, true_target(), |
| false_target(), false); |
| } else { |
| @@ -3768,14 +3681,14 @@ |
| } else if (op == Token::OR) { |
| Label is_false; |
| - LoadCondition(node->left(), CodeGenState::LOAD, true_target(), |
| + LoadCondition(node->left(), NOT_INSIDE_TYPEOF, true_target(), |
| &is_false, false); |
| if (has_cc()) { |
| Branch(true, true_target()); |
| // Evaluate right side expression. |
| __ bind(&is_false); |
| - LoadCondition(node->right(), CodeGenState::LOAD, true_target(), |
| + LoadCondition(node->right(), NOT_INSIDE_TYPEOF, true_target(), |
| false_target(), false); |
| } else { |
| @@ -4090,6 +4003,87 @@ |
| #undef __ |
| #define __ masm-> |
| +Handle<String> Reference::GetName() { |
| + ASSERT(type_ == NAMED); |
| + Property* property = expression_->AsProperty(); |
| + if (property == NULL) { |
| + // Global variable reference treated as a named property reference. |
| + VariableProxy* proxy = expression_->AsVariableProxy(); |
| + ASSERT(proxy->AsVariable() != NULL); |
| + ASSERT(proxy->AsVariable()->is_global()); |
| + return proxy->name(); |
| + } else { |
| + MacroAssembler* masm = cgen_->masm(); |
| + __ RecordPosition(property->position()); |
| + Literal* raw_name = property->key()->AsLiteral(); |
| + ASSERT(raw_name != NULL); |
| + return Handle<String>(String::cast(*raw_name->handle())); |
| + } |
| +} |
| + |
| + |
| +void Reference::GetValue(TypeofState typeof_state) { |
| + ASSERT(!is_illegal()); |
| + ASSERT(!cgen_->has_cc()); |
| + MacroAssembler* masm = cgen_->masm(); |
| + switch (type_) { |
| + case SLOT: { |
| + Comment cmnt(masm, "[ Load from Slot"); |
| + Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
| + ASSERT(slot != NULL); |
| + cgen_->LoadFromSlot(slot, typeof_state); |
| + break; |
| + } |
| + |
| + case NAMED: { |
| + // TODO(1241834): Make sure that this it is safe to ignore the |
| + // distinction between expressions in a typeof and not in a typeof. If |
| + // there is a chance that reference errors can be thrown below, we |
| + // must distinguish between the two kinds of loads (typeof expression |
| + // loads must not throw a reference error). |
| + Comment cmnt(masm, "[ Load from named Property"); |
| + Handle<String> name(GetName()); |
| + Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| + // Setup the name register. |
| + __ mov(ecx, name); |
| + |
| + Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| + if (var != NULL) { |
| + ASSERT(var->is_global()); |
| + __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| + } else { |
| + __ call(ic, RelocInfo::CODE_TARGET); |
| + } |
| + __ push(eax); // IC call leaves result in eax, push it out |
| + break; |
| + } |
| + |
| + case KEYED: { |
| + // TODO(1241834): Make sure that this it is safe to ignore the |
| + // distinction between expressions in a typeof and not in a typeof. |
| + Comment cmnt(masm, "[ Load from keyed Property"); |
| + Property* property = expression_->AsProperty(); |
| + ASSERT(property != NULL); |
| + __ RecordPosition(property->position()); |
| + Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| + |
| + Variable* var = expression_->AsVariableProxy()->AsVariable(); |
| + if (var != NULL) { |
| + ASSERT(var->is_global()); |
| + __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| + } else { |
| + __ call(ic, RelocInfo::CODE_TARGET); |
| + } |
| + __ push(eax); // IC call leaves result in eax, push it out |
| + break; |
| + } |
| + |
| + default: |
| + UNREACHABLE(); |
| + } |
| +} |
| + |
| + |
| void Reference::SetValue(InitState init_state) { |
| ASSERT(!is_illegal()); |
| ASSERT(!cgen_->has_cc()); |
| @@ -4172,22 +4166,8 @@ |
| case NAMED: { |
| Comment cmnt(masm, "[ Store to named Property"); |
| - Property* property = expression_->AsProperty(); |
| - Handle<String> name; |
| - if (property == NULL) { |
| - // Global variable reference treated as named property access. |
| - VariableProxy* proxy = expression_->AsVariableProxy(); |
| - ASSERT(proxy->AsVariable() != NULL); |
| - ASSERT(proxy->AsVariable()->is_global()); |
| - name = proxy->name(); |
| - } else { |
| - Literal* raw_name = property->key()->AsLiteral(); |
| - ASSERT(raw_name != NULL); |
| - name = Handle<String>(String::cast(*raw_name->handle())); |
| - __ RecordPosition(property->position()); |
| - } |
| - |
| // Call the appropriate IC code. |
| + Handle<String> name(GetName()); |
| Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| // TODO(1222589): Make the IC grab the values from the stack. |
| __ pop(eax); |