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); |