Chromium Code Reviews| Index: runtime/vm/intermediate_language_mips.cc |
| diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc |
| index 286902a260a8705d6f5d5681225ec24b91e4cd41..bc7a78b33a288a0834dbd823e6dc25d55db590c2 100644 |
| --- a/runtime/vm/intermediate_language_mips.cc |
| +++ b/runtime/vm/intermediate_language_mips.cc |
| @@ -2753,12 +2753,41 @@ void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| ASSERT(fp_sp_dist <= 0); |
| __ AddImmediate(SP, FP, fp_sp_dist); |
| - // Restore stack and initialize the two exception variables: |
| - // exception and stack trace variables. |
| - __ StoreToOffset(kExceptionObjectReg, FP, |
| - exception_var().index() * kWordSize); |
| - __ StoreToOffset(kStackTraceObjectReg, FP, |
| - stacktrace_var().index() * kWordSize); |
| + // Auxiliary variables introduced by the try catch can be captured if we are |
| + // inside a function with yield/resume points. In this case we first need |
| + // to restore the context to match the context at entry into the closure. |
| + if (should_restore_closure_context()) { |
| + const ParsedFunction& parsed_function = compiler->parsed_function(); |
| + ASSERT(parsed_function.function().IsClosureFunction()); |
| + LocalScope* scope = parsed_function.node_sequence()->scope(); |
| + |
| + LocalVariable* closure_parameter = scope->VariableAt(0); |
| + ASSERT(!closure_parameter->is_captured()); |
| + __ lw(CTX, Address(FP, closure_parameter->index() * kWordSize)); |
|
zra
2017/04/05 16:10:45
ditto
Vyacheslav Egorov (Google)
2017/04/05 16:23:30
Done.
|
| + __ lw(CTX, FieldAddress(CTX, Closure::context_offset())); |
| + |
| + const intptr_t context_index = |
| + parsed_function.current_context_var()->index(); |
| + __ StoreToOffset(CTX, FP, context_index * kWordSize); |
| + } |
| + |
| + // Initialize exception and stack trace variables. |
| + if (exception_var().is_captured()) { |
| + ASSERT(stacktrace_var().is_captured()); |
| + __ StoreIntoObjectOffset(CTX, |
| + Context::variable_offset(exception_var().index()), |
| + kExceptionObjectReg); |
| + __ StoreIntoObjectOffset(CTX, |
| + Context::variable_offset(stacktrace_var().index()), |
| + kStackTraceObjectReg); |
| + } else { |
| + // Restore stack and initialize the two exception variables: |
| + // exception and stack trace variables. |
| + __ StoreToOffset(kExceptionObjectReg, FP, |
| + exception_var().index() * kWordSize); |
| + __ StoreToOffset(kStackTraceObjectReg, FP, |
| + stacktrace_var().index() * kWordSize); |
| + } |
| } |