| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 6c7ca344cb323cfee4dc49397e6c271f4be17917..05470cdb634afdd3e8bf562ff384f1969dac4807 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -860,7 +860,10 @@ void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
|
|
|
|
| void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
|
| - UNIMPLEMENTED();
|
| + VisitForAccumulatorValue(stmt->expression());
|
| + builder()->CastAccumulatorToJSObject();
|
| + VisitNewLocalWithContext();
|
| + VisitInScope(stmt->statement(), stmt->scope());
|
| }
|
|
|
|
|
| @@ -2364,6 +2367,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);
|
| @@ -2459,6 +2475,12 @@ void BytecodeGenerator::VisitFunctionClosureForContext() {
|
| Context::NATIVE_CONTEXT_INDEX)
|
| .StoreAccumulatorInRegister(native_context)
|
| .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
|
| + } 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);
|
| } else {
|
| DCHECK(closure_scope->is_function_scope());
|
| builder()->LoadAccumulatorWithRegister(Register::function_closure());
|
|
|