Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 57f5ff57acb0ff87fbc2f75913b6c752c4d3b1a6..c703c768effc6a71c9ea3aef1dd2983128fc931f 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -3128,56 +3128,62 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| ASSERT(!HasStackOverflow()); |
| ASSERT(current_block() != NULL); |
| ASSERT(current_block()->HasPredecessor()); |
| - Variable* variable = expr->AsVariable(); |
| - if (variable == NULL) { |
| - return Bailout("reference to rewritten variable"); |
| - } else if (variable->mode() == Variable::LET) { |
| + Variable* variable = expr->var(); |
| + if (variable->mode() == Variable::LET) { |
| return Bailout("reference to let variable"); |
| - } else if (variable->IsStackAllocated()) { |
| - HValue* value = environment()->Lookup(variable); |
| - if (variable->mode() == Variable::CONST && |
| - value == graph()->GetConstantHole()) { |
| - return Bailout("reference to uninitialized const variable"); |
| - } |
| - return ast_context()->ReturnValue(value); |
| - } else if (variable->IsContextSlot()) { |
| - if (variable->mode() == Variable::CONST) { |
| - return Bailout("reference to const context slot"); |
| - } |
| - HValue* context = BuildContextChainWalk(variable); |
| - int index = variable->AsSlot()->index(); |
| - HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, index); |
| - return ast_context()->ReturnInstruction(instr, expr->id()); |
| - } else if (variable->is_global()) { |
| - LookupResult lookup; |
| - GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); |
| + } |
| + switch (variable->location()) { |
| + case Variable::UNALLOCATED: { |
| + LookupResult lookup; |
| + GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); |
|
fschneider
2011/09/06 09:34:22
Long line.
|
| + |
| + if (type == kUseCell && |
| + info()->global_object()->IsAccessCheckNeeded()) { |
| + type = kUseGeneric; |
| + } |
| - if (type == kUseCell && |
| - info()->global_object()->IsAccessCheckNeeded()) { |
| - type = kUseGeneric; |
| + if (type == kUseCell) { |
| + Handle<GlobalObject> global(info()->global_object()); |
| + Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| + bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| + HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); |
| + return ast_context()->ReturnInstruction(instr, expr->id()); |
| + } else { |
| + HValue* context = environment()->LookupContext(); |
| + HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| + AddInstruction(global_object); |
| + HLoadGlobalGeneric* instr = |
| + new(zone()) HLoadGlobalGeneric(context, |
| + global_object, |
| + variable->name(), |
| + ast_context()->is_for_typeof()); |
| + instr->set_position(expr->position()); |
| + return ast_context()->ReturnInstruction(instr, expr->id()); |
| + } |
| } |
| - if (type == kUseCell) { |
| - Handle<GlobalObject> global(info()->global_object()); |
| - Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| - bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| - HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); |
| - return ast_context()->ReturnInstruction(instr, expr->id()); |
| - } else { |
| - HValue* context = environment()->LookupContext(); |
| - HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| - AddInstruction(global_object); |
| - HLoadGlobalGeneric* instr = |
| - new(zone()) HLoadGlobalGeneric(context, |
| - global_object, |
| - variable->name(), |
| - ast_context()->is_for_typeof()); |
| - instr->set_position(expr->position()); |
| - ASSERT(instr->HasSideEffects()); |
| + case Variable::PARAMETER: |
| + case Variable::LOCAL: { |
| + HValue* value = environment()->Lookup(variable); |
| + if (variable->mode() == Variable::CONST && |
| + value == graph()->GetConstantHole()) { |
| + return Bailout("reference to uninitialized const variable"); |
| + } |
| + return ast_context()->ReturnValue(value); |
| + } |
| + |
| + case Variable::CONTEXT:{ |
| + if (variable->mode() == Variable::CONST) { |
| + return Bailout("reference to const context slot"); |
| + } |
| + HValue* context = BuildContextChainWalk(variable); |
| + HLoadContextSlot* instr = |
| + new(zone()) HLoadContextSlot(context, variable->index()); |
| return ast_context()->ReturnInstruction(instr, expr->id()); |
| } |
| - } else { |
| - return Bailout("reference to a variable which requires dynamic lookup"); |
| + |
| + case Variable::LOOKUP: |
| + return Bailout("reference to a variable which requires dynamic lookup"); |
| } |
| } |
| @@ -3589,52 +3595,60 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| Expression* target = expr->target(); |
| VariableProxy* proxy = target->AsVariableProxy(); |
| - Variable* var = proxy->AsVariable(); |
| Property* prop = target->AsProperty(); |
| - ASSERT(var == NULL || prop == NULL); |
| + ASSERT(proxy == NULL || prop == NULL); |
| // We have a second position recorded in the FullCodeGenerator to have |
| // type feedback for the binary operation. |
| BinaryOperation* operation = expr->binary_operation(); |
| - if (var != NULL) { |
| - if (var->mode() == Variable::CONST || |
| - var->mode() == Variable::LET) { |
| + if (proxy != NULL) { |
| + Variable* var = proxy->var(); |
| + if (var->mode() == Variable::CONST || var->mode() == Variable::LET) { |
| return Bailout("unsupported let or const compound assignment"); |
| } |
| CHECK_ALIVE(VisitForValue(operation)); |
| - if (var->is_global()) { |
| - HandleGlobalVariableAssignment(var, |
| - Top(), |
| - expr->position(), |
| - expr->AssignmentId()); |
| - } else if (var->IsStackAllocated()) { |
| - Bind(var, Top()); |
| - } else if (var->IsContextSlot()) { |
| - // Bail out if we try to mutate a parameter value in a function using |
| - // the arguments object. We do not (yet) correctly handle the |
| - // arguments property of the function. |
| - if (info()->scope()->arguments() != NULL) { |
| - // Parameters will rewrite to context slots. We have no direct way |
| - // to detect that the variable is a parameter. |
| - int count = info()->scope()->num_parameters(); |
| - for (int i = 0; i < count; ++i) { |
| - if (var == info()->scope()->parameter(i)) { |
| - Bailout("assignment to parameter, function uses arguments object"); |
| + switch (var->location()) { |
| + case Variable::UNALLOCATED: |
| + HandleGlobalVariableAssignment(var, |
| + Top(), |
| + expr->position(), |
| + expr->AssignmentId()); |
| + break; |
| + |
| + case Variable::PARAMETER: |
| + case Variable::LOCAL: |
| + Bind(var, Top()); |
| + break; |
| + |
| + case Variable::CONTEXT: { |
| + // Bail out if we try to mutate a parameter value in a function |
| + // using the arguments object. We do not (yet) correctly handle the |
| + // arguments property of the function. |
| + if (info()->scope()->arguments() != NULL) { |
| + // Parameters will be allocated to context slots. We have no |
| + // direct way to detect that the variable is a parameter so we do |
| + // a linear search of the parameter variables. |
| + int count = info()->scope()->num_parameters(); |
| + for (int i = 0; i < count; ++i) { |
| + if (var == info()->scope()->parameter(i)) { |
| + Bailout("assignment to parameter, function uses arguments object"); |
|
fschneider
2011/09/06 09:34:22
Long line.
|
| + } |
| } |
| } |
| + |
| + HValue* context = BuildContextChainWalk(var); |
| + HStoreContextSlot* instr = |
| + new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| + AddInstruction(instr); |
| + if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + break; |
| } |
| - HValue* context = BuildContextChainWalk(var); |
| - int index = var->AsSlot()->index(); |
| - HStoreContextSlot* instr = |
| - new(zone()) HStoreContextSlot(context, index, Top()); |
| - AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| - } else { |
| - return Bailout("compound assignment to lookup slot"); |
| + case Variable::LOOKUP: |
| + return Bailout("compound assignment to lookup slot"); |
| } |
| return ast_context()->ReturnValue(Pop()); |
| @@ -3722,16 +3736,18 @@ void HGraphBuilder::VisitAssignment(Assignment* expr) { |
| ASSERT(current_block() != NULL); |
| ASSERT(current_block()->HasPredecessor()); |
| VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| - Variable* var = proxy->AsVariable(); |
| Property* prop = expr->target()->AsProperty(); |
| - ASSERT(var == NULL || prop == NULL); |
| + ASSERT(proxy == NULL || prop == NULL); |
| if (expr->is_compound()) { |
| HandleCompoundAssignment(expr); |
| return; |
| } |
| - if (var != NULL) { |
| + if (prop != NULL) { |
| + HandlePropertyAssignment(expr); |
| + } else if (proxy != NULL) { |
| + Variable* var = proxy->var(); |
| if (var->mode() == Variable::CONST) { |
| if (expr->op() != Token::INIT_CONST) { |
| return Bailout("non-initializer assignment to const"); |
| @@ -3750,54 +3766,54 @@ void HGraphBuilder::VisitAssignment(Assignment* expr) { |
| if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
| // Handle the assignment. |
| - if (var->IsStackAllocated()) { |
| - // We do not allow the arguments object to occur in a context where it |
| - // may escape, but assignments to stack-allocated locals are |
| - // permitted. |
| - CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
| - HValue* value = Pop(); |
| - Bind(var, value); |
| - return ast_context()->ReturnValue(value); |
| + switch (var->location()) { |
| + case Variable::UNALLOCATED: |
| + CHECK_ALIVE(VisitForValue(expr->value())); |
| + HandleGlobalVariableAssignment(var, |
| + Top(), |
| + expr->position(), |
| + expr->AssignmentId()); |
| + return ast_context()->ReturnValue(Pop()); |
| + |
| + case Variable::PARAMETER: |
| + case Variable::LOCAL: { |
| + // We do not allow the arguments object to occur in a context where it |
| + // may escape, but assignments to stack-allocated locals are |
| + // permitted. |
| + CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); |
| + HValue* value = Pop(); |
| + Bind(var, value); |
| + return ast_context()->ReturnValue(value); |
| + } |
| - } else if (var->IsContextSlot()) { |
| - ASSERT(var->mode() != Variable::CONST); |
| - // Bail out if we try to mutate a parameter value in a function using |
| - // the arguments object. We do not (yet) correctly handle the |
| - // arguments property of the function. |
| - if (info()->scope()->arguments() != NULL) { |
| - // Parameters will rewrite to context slots. We have no direct way |
| - // to detect that the variable is a parameter. |
| - int count = info()->scope()->num_parameters(); |
| - for (int i = 0; i < count; ++i) { |
| - if (var == info()->scope()->parameter(i)) { |
| - Bailout("assignment to parameter, function uses arguments object"); |
| + case Variable::CONTEXT: { |
| + ASSERT(var->mode() != Variable::CONST); |
| + // Bail out if we try to mutate a parameter value in a function using |
| + // the arguments object. We do not (yet) correctly handle the |
| + // arguments property of the function. |
| + if (info()->scope()->arguments() != NULL) { |
| + // Parameters will rewrite to context slots. We have no direct way |
| + // to detect that the variable is a parameter. |
| + int count = info()->scope()->num_parameters(); |
| + for (int i = 0; i < count; ++i) { |
| + if (var == info()->scope()->parameter(i)) { |
| + return Bailout("assignment to parameter in arguments object"); |
| + } |
| } |
| } |
| - } |
| - |
| - CHECK_ALIVE(VisitForValue(expr->value())); |
| - HValue* context = BuildContextChainWalk(var); |
| - int index = var->AsSlot()->index(); |
| - HStoreContextSlot* instr = |
| - new(zone()) HStoreContextSlot(context, index, Top()); |
| - AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| - return ast_context()->ReturnValue(Pop()); |
| - } else if (var->is_global()) { |
| - CHECK_ALIVE(VisitForValue(expr->value())); |
| - HandleGlobalVariableAssignment(var, |
| - Top(), |
| - expr->position(), |
| - expr->AssignmentId()); |
| - return ast_context()->ReturnValue(Pop()); |
| + CHECK_ALIVE(VisitForValue(expr->value())); |
| + HValue* context = BuildContextChainWalk(var); |
| + HStoreContextSlot* instr = |
| + new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| + AddInstruction(instr); |
| + if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + return ast_context()->ReturnValue(Pop()); |
| + } |
| - } else { |
| - return Bailout("assignment to LOOKUP or const CONTEXT variable"); |
| + case Variable::LOOKUP: |
| + return Bailout("assignment to LOOKUP variable"); |
| } |
| - |
| - } else if (prop != NULL) { |
| - HandlePropertyAssignment(expr); |
| } else { |
| return Bailout("invalid left-hand side in assignment"); |
| } |
| @@ -4909,10 +4925,12 @@ void HGraphBuilder::VisitCall(Call* expr) { |
| } |
| } else { |
| - Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| - bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
| + VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| + // FIXME. |
|
fschneider
2011/09/06 09:34:22
Is this a TODO?
Kevin Millikin (Chromium)
2011/09/06 10:44:06
Oops. It was a TODO, but it's been fixed and I di
|
| + bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
| if (global_call) { |
| + Variable* var = proxy->var(); |
| bool known_global_function = false; |
| // If there is a global property cell for the name at compile time and |
| // access check is not enabled we assume that the function will not change |
| @@ -5076,20 +5094,8 @@ void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| void HGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| Property* prop = expr->expression()->AsProperty(); |
| - Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| - if (prop == NULL && var == NULL) { |
| - // Result of deleting non-property, non-variable reference is true. |
| - // Evaluate the subexpression for side effects. |
| - CHECK_ALIVE(VisitForEffect(expr->expression())); |
| - return ast_context()->ReturnValue(graph()->GetConstantTrue()); |
| - } else if (var != NULL && |
| - !var->is_global() && |
| - var->AsSlot() != NULL && |
| - var->AsSlot()->type() != Slot::LOOKUP) { |
| - // Result of deleting non-global, non-dynamic variables is false. |
| - // The subexpression does not have side effects. |
| - return ast_context()->ReturnValue(graph()->GetConstantFalse()); |
| - } else if (prop != NULL) { |
| + VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| + if (prop != NULL) { |
| CHECK_ALIVE(VisitForValue(prop->obj())); |
| CHECK_ALIVE(VisitForValue(prop->key())); |
| HValue* key = Pop(); |
| @@ -5097,10 +5103,26 @@ void HGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| HValue* context = environment()->LookupContext(); |
| HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); |
| return ast_context()->ReturnInstruction(instr, expr->id()); |
| - } else if (var->is_global()) { |
| - Bailout("delete with global variable"); |
| + } else if (proxy != NULL) { |
| + Variable* var = proxy->var(); |
| + if (var->IsUnallocated()) { |
| + Bailout("delete with global variable"); |
| + } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| + // Result of deleting non-global variables is false. 'this' is not |
| + // really a variable, though we implement it as one. The |
| + // subexpression does not have side effects. |
| + HValue* value = var->is_this() |
| + ? graph()->GetConstantTrue() |
| + : graph()->GetConstantFalse(); |
| + return ast_context()->ReturnValue(value); |
| + } else { |
| + Bailout("delete with non-global variable"); |
| + } |
| } else { |
| - Bailout("delete with non-global variable"); |
| + // Result of deleting non-property, non-variable reference is true. |
| + // Evaluate the subexpression for side effects. |
| + CHECK_ALIVE(VisitForEffect(expr->expression())); |
| + return ast_context()->ReturnValue(graph()->GetConstantTrue()); |
| } |
| } |
| @@ -5247,9 +5269,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| ASSERT(current_block()->HasPredecessor()); |
| Expression* target = expr->expression(); |
| VariableProxy* proxy = target->AsVariableProxy(); |
| - Variable* var = proxy->AsVariable(); |
| Property* prop = target->AsProperty(); |
| - if (var == NULL && prop == NULL) { |
| + if (proxy == NULL && prop == NULL) { |
| return Bailout("invalid lhs in count operation"); |
| } |
| @@ -5261,7 +5282,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| HValue* input = NULL; // ToNumber(original_input). |
| HValue* after = NULL; // The result after incrementing or decrementing. |
| - if (var != NULL) { |
| + if (proxy != NULL) { |
| + Variable* var = proxy->var(); |
| if (var->mode() == Variable::CONST) { |
| return Bailout("unsupported count operation with const"); |
| } |
| @@ -5273,36 +5295,45 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| input = returns_original_input ? Top() : Pop(); |
| Push(after); |
| - if (var->is_global()) { |
| - HandleGlobalVariableAssignment(var, |
| - after, |
| - expr->position(), |
| - expr->AssignmentId()); |
| - } else if (var->IsStackAllocated()) { |
| - Bind(var, after); |
| - } else if (var->IsContextSlot()) { |
| - // Bail out if we try to mutate a parameter value in a function using |
| - // the arguments object. We do not (yet) correctly handle the |
| - // arguments property of the function. |
| - if (info()->scope()->arguments() != NULL) { |
| - // Parameters will rewrite to context slots. We have no direct way |
| - // to detect that the variable is a parameter. |
| - int count = info()->scope()->num_parameters(); |
| - for (int i = 0; i < count; ++i) { |
| - if (var == info()->scope()->parameter(i)) { |
| - Bailout("assignment to parameter, function uses arguments object"); |
| + switch (var->location()) { |
| + case Variable::UNALLOCATED: |
| + HandleGlobalVariableAssignment(var, |
| + after, |
| + expr->position(), |
| + expr->AssignmentId()); |
| + break; |
| + |
| + case Variable::PARAMETER: |
| + case Variable::LOCAL: |
| + Bind(var, after); |
| + break; |
| + |
| + case Variable::CONTEXT: { |
| + // Bail out if we try to mutate a parameter value in a function |
| + // using the arguments object. We do not (yet) correctly handle the |
| + // arguments property of the function. |
| + if (info()->scope()->arguments() != NULL) { |
| + // Parameters will rewrite to context slots. We have no direct |
| + // way to detect that the variable is a parameter so we use a |
| + // linear search of the parameter list. |
| + int count = info()->scope()->num_parameters(); |
| + for (int i = 0; i < count; ++i) { |
| + if (var == info()->scope()->parameter(i)) { |
| + return Bailout("assignment to parameter in arguments object"); |
| + } |
| } |
| } |
| + |
| + HValue* context = BuildContextChainWalk(var); |
| + HStoreContextSlot* instr = |
| + new(zone()) HStoreContextSlot(context, var->index(), after); |
| + AddInstruction(instr); |
| + if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + break; |
| } |
| - HValue* context = BuildContextChainWalk(var); |
| - int index = var->AsSlot()->index(); |
| - HStoreContextSlot* instr = |
| - new(zone()) HStoreContextSlot(context, index, after); |
| - AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| - } else { |
| - return Bailout("lookup variable in count operation"); |
| + case Variable::LOOKUP: |
| + return Bailout("lookup variable in count operation"); |
| } |
| } else { |
| @@ -5714,12 +5745,12 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| // residing in new space. If it is we assume that the function will stay the |
| // same. |
| Handle<JSFunction> target = Handle<JSFunction>::null(); |
| - Variable* var = expr->right()->AsVariableProxy()->AsVariable(); |
| - bool global_function = (var != NULL) && var->is_global() && !var->is_this(); |
| + VariableProxy* proxy = expr->right()->AsVariableProxy(); |
| + bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
| if (global_function && |
| info()->has_global_object() && |
| !info()->global_object()->IsAccessCheckNeeded()) { |
| - Handle<String> name = var->name(); |
| + Handle<String> name = proxy->name(); |
| Handle<GlobalObject> global(info()->global_object()); |
| LookupResult lookup; |
| global->Lookup(*name, &lookup); |
| @@ -5823,45 +5854,36 @@ void HGraphBuilder::VisitDeclaration(Declaration* decl) { |
| void HGraphBuilder::HandleDeclaration(VariableProxy* proxy, |
| - Variable::Mode mode, |
| - FunctionLiteral* function) { |
| + Variable::Mode mode, |
| + FunctionLiteral* function) { |
| if (mode == Variable::LET) return Bailout("unsupported let declaration"); |
| Variable* var = proxy->var(); |
| - Slot* slot = var->AsSlot(); |
| - ASSERT(slot != NULL); |
| - switch (slot->type()) { |
| - case Slot::PARAMETER: |
| - case Slot::LOCAL: |
| - if (mode == Variable::CONST) { |
| - environment()->Bind(var, graph()->GetConstantHole()); |
| - } else if (function != NULL) { |
| - VisitForValue(function); |
| - HValue* function_value = Pop(); |
| - environment()->Bind(var, function_value); |
| - } |
| - break; |
| - case Slot::CONTEXT: { |
| - HValue* context = environment()->LookupContext(); |
| - if (mode == Variable::CONST) { |
| - HStoreContextSlot* store = |
| - new HStoreContextSlot(context, |
| - slot->index(), |
| - graph()->GetConstantHole()); |
| - AddInstruction(store); |
| - if (store->HasSideEffects()) AddSimulate(proxy->id()); |
| - } else if (function != NULL) { |
| - VisitForValue(function); |
| - HValue* function_value = Pop(); |
| - HStoreContextSlot* store = |
| - new HStoreContextSlot(context, |
| - slot->index(), |
| - function_value); |
| - AddInstruction(store); |
| - if (store->HasSideEffects()) AddSimulate(proxy->id()); |
| + switch (var->location()) { |
| + case Variable::UNALLOCATED: |
| + return Bailout("unsupported global declaration"); |
| + case Variable::PARAMETER: |
| + case Variable::LOCAL: |
| + case Variable::CONTEXT: |
| + if (mode == Variable::CONST || function != NULL) { |
| + HValue* value = NULL; |
| + if (mode == Variable::CONST) { |
| + value = graph()->GetConstantHole(); |
| + } else { |
| + VisitForValue(function); |
| + value = Pop(); |
| + } |
| + if (var->IsContextSlot()) { |
| + HValue* context = environment()->LookupContext(); |
| + HStoreContextSlot* store = |
| + new HStoreContextSlot(context, var->index(), value); |
| + AddInstruction(store); |
| + if (store->HasSideEffects()) AddSimulate(proxy->id()); |
| + } else { |
| + environment()->Bind(var, value); |
| + } |
| } |
| break; |
| - } |
| - case Slot::LOOKUP: |
| + case Variable::LOOKUP: |
| return Bailout("unsupported lookup slot in declaration"); |
| } |
| } |