| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 6e94b5f0791182803076d8dbb550f1dfec075652..f5df790e719cde0efe7fffef6f89e0328a9585c9 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -899,21 +899,65 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
|
|
|
|
|
| void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
| - if (FLAG_ignition_fake_try_catch) {
|
| - Visit(stmt->try_block());
|
| - return;
|
| - }
|
| - UNIMPLEMENTED();
|
| + TryCatchBuilder try_control_builder(builder());
|
| + if (!FLAG_ignition_fake_try_catch) UNIMPLEMENTED();
|
| +
|
| + // Preserve the context in a dedicated register, so that it can be restored
|
| + // when the handler is entered by the stack-unwinding machinery.
|
| + // TODO(mstarzinger): Be smarter about register allocation.
|
| + Register context = register_allocator()->NewRegister();
|
| +
|
| + // Evaluate the try-block inside a control scope. This simulates a handler
|
| + // that is intercepting 'throw' control commands.
|
| + try_control_builder.BeginTry(context);
|
| + // TODO(mstarzinger): Control scope is missing!
|
| + Visit(stmt->try_block());
|
| + try_control_builder.EndTry();
|
| +
|
| + // Clear message object as we enter the catch block.
|
| + // TODO(mstarzinger): Implement this!
|
| +
|
| + // Create a catch scope that binds the exception.
|
| + register_allocator()->PrepareForConsecutiveAllocations(3);
|
| + Register name = register_allocator()->NextConsecutiveRegister();
|
| + Register exception = register_allocator()->NextConsecutiveRegister();
|
| + Register closure = register_allocator()->NextConsecutiveRegister();
|
| + builder()
|
| + ->StoreAccumulatorInRegister(exception)
|
| + .LoadLiteral(stmt->variable()->name())
|
| + .StoreAccumulatorInRegister(name);
|
| + VisitFunctionClosureForContext();
|
| + builder()->StoreAccumulatorInRegister(closure).CallRuntime(
|
| + Runtime::kPushCatchContext, name, 3);
|
| +
|
| + // Evaluate the catch-block.
|
| + Visit(stmt->catch_block());
|
| + try_control_builder.EndCatch();
|
| }
|
|
|
|
|
| void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
| - if (FLAG_ignition_fake_try_catch) {
|
| - Visit(stmt->try_block());
|
| - Visit(stmt->finally_block());
|
| - return;
|
| - }
|
| - UNIMPLEMENTED();
|
| + TryFinallyBuilder try_control_builder(builder());
|
| + if (!FLAG_ignition_fake_try_catch) UNIMPLEMENTED();
|
| +
|
| + // Preserve the context in a dedicated register, so that it can be restored
|
| + // when the handler is entered by the stack-unwinding machinery.
|
| + // TODO(mstarzinger): Be smarter about register allocation.
|
| + Register context = register_allocator()->NewRegister();
|
| +
|
| + // Evaluate the try-block inside a control scope. This simulates a handler
|
| + // that is intercepting all control commands.
|
| + try_control_builder.BeginTry(context);
|
| + // TODO(mstarzinger): Control scope is missing!
|
| + Visit(stmt->try_block());
|
| + try_control_builder.EndTry();
|
| +
|
| + // Clear message object as we enter the finally block.
|
| + // TODO(mstarzinger): Implement this!
|
| +
|
| + // Evaluate the finally-block.
|
| + Visit(stmt->finally_block());
|
| + try_control_builder.EndFinally();
|
| }
|
|
|
|
|
|
|