| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 41f5003d97791bec3e6b7859a4a577e0a089270a..6254281e310d6429d3fe93633f2cf34b4a1089bc 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -923,8 +923,9 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| break;
|
| case VariableLocation::CONTEXT:
|
| if (variable->binding_needs_init()) {
|
| + DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
|
| builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
|
| - variable->index());
|
| + variable->index(), 0);
|
| }
|
| break;
|
| case VariableLocation::LOOKUP: {
|
| @@ -963,8 +964,8 @@ void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| case VariableLocation::CONTEXT: {
|
| DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
|
| VisitForAccumulatorValue(decl->fun());
|
| - builder()->StoreContextSlot(execution_context()->reg(),
|
| - variable->index());
|
| + builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
|
| + 0);
|
| break;
|
| }
|
| case VariableLocation::LOOKUP: {
|
| @@ -1953,24 +1954,12 @@ void BytecodeGenerator::VisitVariableLoad(Variable* variable,
|
| Register context_reg;
|
| if (context) {
|
| context_reg = context->reg();
|
| + depth = 0;
|
| } else {
|
| - context_reg = register_allocator()->NewRegister();
|
| - // Walk the context chain to find the context at the given depth.
|
| - // TODO(rmcilroy): Perform this work in a bytecode handler once we have
|
| - // a generic mechanism for performing jumps in interpreter.cc.
|
| - // TODO(mythria): Also update bytecode graph builder with correct depth
|
| - // when this changes.
|
| - builder()
|
| - ->LoadAccumulatorWithRegister(execution_context()->reg())
|
| - .StoreAccumulatorInRegister(context_reg);
|
| - for (int i = 0; i < depth; ++i) {
|
| - builder()
|
| - ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
|
| - .StoreAccumulatorInRegister(context_reg);
|
| - }
|
| + context_reg = execution_context()->reg();
|
| }
|
|
|
| - builder()->LoadContextSlot(context_reg, variable->index());
|
| + builder()->LoadContextSlot(context_reg, variable->index(), depth);
|
| BuildHoleCheckForVariableLoad(variable);
|
| break;
|
| }
|
| @@ -2135,24 +2124,9 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
|
|
| if (context) {
|
| context_reg = context->reg();
|
| + depth = 0;
|
| } else {
|
| - Register value_temp = register_allocator()->NewRegister();
|
| - context_reg = register_allocator()->NewRegister();
|
| - // Walk the context chain to find the context at the given depth.
|
| - // TODO(rmcilroy): Perform this work in a bytecode handler once we have
|
| - // a generic mechanism for performing jumps in interpreter.cc.
|
| - // TODO(mythria): Also update bytecode graph builder with correct depth
|
| - // when this changes.
|
| - builder()
|
| - ->StoreAccumulatorInRegister(value_temp)
|
| - .LoadAccumulatorWithRegister(execution_context()->reg())
|
| - .StoreAccumulatorInRegister(context_reg);
|
| - for (int i = 0; i < depth; ++i) {
|
| - builder()
|
| - ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
|
| - .StoreAccumulatorInRegister(context_reg);
|
| - }
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| + context_reg = execution_context()->reg();
|
| }
|
|
|
| if (hole_check_required) {
|
| @@ -2160,14 +2134,14 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| Register value_temp = register_allocator()->NewRegister();
|
| builder()
|
| ->StoreAccumulatorInRegister(value_temp)
|
| - .LoadContextSlot(context_reg, variable->index());
|
| + .LoadContextSlot(context_reg, variable->index(), depth);
|
|
|
| BuildHoleCheckForVariableAssignment(variable, op);
|
| builder()->LoadAccumulatorWithRegister(value_temp);
|
| }
|
|
|
| if (mode != CONST || op == Token::INIT) {
|
| - builder()->StoreContextSlot(context_reg, variable->index());
|
| + builder()->StoreContextSlot(context_reg, variable->index(), depth);
|
| } else if (variable->throw_on_const_assignment(language_mode())) {
|
| builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
|
| }
|
| @@ -2833,9 +2807,9 @@ void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
|
| Register global_object = register_allocator()->NewRegister();
|
| builder()
|
| ->LoadContextSlot(execution_context()->reg(),
|
| - Context::NATIVE_CONTEXT_INDEX)
|
| + Context::NATIVE_CONTEXT_INDEX, 0)
|
| .StoreAccumulatorInRegister(native_context)
|
| - .LoadContextSlot(native_context, Context::EXTENSION_INDEX)
|
| + .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0)
|
| .StoreAccumulatorInRegister(global_object)
|
| .LoadLiteral(variable->name())
|
| .Delete(global_object, language_mode());
|
| @@ -3163,7 +3137,7 @@ void BytecodeGenerator::BuildLocalActivationContextInitialization() {
|
| // Context variable (at bottom of the context chain).
|
| DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
|
| builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
|
| - execution_context()->reg(), variable->index());
|
| + execution_context()->reg(), variable->index(), 0);
|
| }
|
|
|
| // Copy parameters into context if necessary.
|
| @@ -3177,8 +3151,8 @@ void BytecodeGenerator::BuildLocalActivationContextInitialization() {
|
| Register parameter(builder()->Parameter(i + 1));
|
| // Context variable (at bottom of the context chain).
|
| DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
|
| - builder()->LoadAccumulatorWithRegister(parameter)
|
| - .StoreContextSlot(execution_context()->reg(), variable->index());
|
| + builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
|
| + execution_context()->reg(), variable->index(), 0);
|
| }
|
| }
|
|
|
| @@ -3300,15 +3274,15 @@ void BytecodeGenerator::VisitFunctionClosureForContext() {
|
| Register native_context = register_allocator()->NewRegister();
|
| builder()
|
| ->LoadContextSlot(execution_context()->reg(),
|
| - Context::NATIVE_CONTEXT_INDEX)
|
| + Context::NATIVE_CONTEXT_INDEX, 0)
|
| .StoreAccumulatorInRegister(native_context)
|
| - .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
|
| + .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0);
|
| } else if (closure_scope->is_eval_scope()) {
|
| // Contexts created by a call to eval have the same closure as the
|
| // context calling eval, not the anonymous closure containing the eval
|
| // code. Fetch it from the context.
|
| builder()->LoadContextSlot(execution_context()->reg(),
|
| - Context::CLOSURE_INDEX);
|
| + Context::CLOSURE_INDEX, 0);
|
| } else {
|
| DCHECK(closure_scope->is_function_scope());
|
| builder()->LoadAccumulatorWithRegister(Register::function_closure());
|
|
|