Chromium Code Reviews| Index: runtime/vm/intermediate_language_arm64.cc |
| diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc |
| index b8abb9a3bd2f4bf44a1515326715ad3b3e937a99..f162a617b325e7f6ddb5035ddcb21d99f4b7c071 100644 |
| --- a/runtime/vm/intermediate_language_arm64.cc |
| +++ b/runtime/vm/intermediate_language_arm64.cc |
| @@ -2617,12 +2617,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()); |
| + __ ldr(CTX, Address(FP, closure_parameter->index() * kWordSize)); |
|
zra
2017/04/05 16:10:45
Is the closure_parameter index known to be somethi
Vyacheslav Egorov (Google)
2017/04/05 16:23:30
Done (both arm and arm64)
|
| + __ ldr(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); |
| + } |
| } |