Chromium Code Reviews| Index: src/interpreter/bytecode-generator.cc |
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
| index 4ef0506a12388cf0f534058b33b98e21f3689169..90c2b81e47133db764fc8c99ffbd4ea0ae0e582e 100644 |
| --- a/src/interpreter/bytecode-generator.cc |
| +++ b/src/interpreter/bytecode-generator.cc |
| @@ -859,7 +859,10 @@ void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
| - UNIMPLEMENTED(); |
| + VisitForAccumulatorValue(stmt->expression()); |
| + builder()->CastAccumulatorToJSObject(); |
| + VisitNewLocalWithContext(); |
| + VisitInScope(stmt->statement(), stmt->scope()); |
| } |
| @@ -2363,6 +2366,19 @@ void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { |
| execution_result()->SetResultInAccumulator(); |
| } |
| +void BytecodeGenerator::VisitNewLocalWithContext() { |
| + AccumulatorResultScope accumulator_execution_result(this); |
| + |
| + register_allocator()->PrepareForConsecutiveAllocations(2); |
| + Register extension_object = register_allocator()->NextConsecutiveRegister(); |
| + Register closure = register_allocator()->NextConsecutiveRegister(); |
| + |
| + builder()->StoreAccumulatorInRegister(extension_object); |
| + VisitFunctionClosureForContext(); |
| + builder()->StoreAccumulatorInRegister(closure).CallRuntime( |
| + Runtime::kPushWithContext, extension_object, 2); |
| + execution_result()->SetResultInAccumulator(); |
| +} |
| void BytecodeGenerator::VisitNewLocalCatchContext(Variable* variable) { |
| AccumulatorResultScope accumulator_execution_result(this); |
| @@ -2458,6 +2474,12 @@ void BytecodeGenerator::VisitFunctionClosureForContext() { |
| Context::NATIVE_CONTEXT_INDEX) |
| .StoreAccumulatorInRegister(native_context) |
| .LoadContextSlot(native_context, Context::CLOSURE_INDEX); |
| + } else if (closure_scope->is_eval_scope()) { |
|
mythria
2016/02/01 16:14:42
Turbofan never hits this. I implemented this from
rmcilroy
2016/02/02 17:05:22
This looks right to me, thanks!
|
| + // 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); |
| } else { |
| DCHECK(closure_scope->is_function_scope()); |
| builder()->LoadAccumulatorWithRegister(Register::function_closure()); |