Fix restoring of contexts in inlined finally code

When inlining code from a finally block before return or jump
instructions, do not restore the saved_try_context since the
inlined code is running in the context of the return or
jump instruction.

This is an old bug that surfaced in async code, since async code
deals with captured variables (contexts) much more than regular
code.

R=srdjan@google.com

Review URL: https://codereview.chromium.org//1006463003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44465 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
hausner@google.com 2015-03-13 15:53:03 +00:00
parent 36175534cb
commit a7b1765187
3 changed files with 31 additions and 5 deletions

View file

@ -4292,7 +4292,10 @@ void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
intptr_t outer_try_index = node->try_index();
owner()->set_try_index(outer_try_index);
}
BuildRestoreContext(node->context_var());
// Note: do not restore the saved_try_context here since the inlined
// code is running at he context level of the return or jump instruction
// that follows the inlined code. See issue 22822.
JoinEntryInstr* finally_entry =
new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());

View file

@ -39,16 +39,12 @@ cyclic_type_test/02: Fail, OK
cyclic_type_test/04: Fail, OK
cyclic_type2_test: Fail, OK
least_upper_bound_expansive_test/*: Fail, OK
async_throw_in_catch_test: Crash, RuntimeError # Issue 21404 or it could be a test error
async_star_test/01: CompileTimeError, RuntimeError # drt only runtime-errs.
async_star_test/02: RuntimeError
async_star_test/03: RuntimeError
async_star_test/04: RuntimeError
async_star_test/05: Timeout, RuntimeError
[ $compiler == none && ($runtime == drt || $runtime == dartium|| $runtime == ContentShellOnAndroid) ]
async_throw_in_catch_test: Timeout, Fail # Issue 21404 or it could be a test error
[ $compiler == none && $runtime == vm ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627

View file

@ -0,0 +1,27 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Regression test for issue 22822. The assignment in the finally block
// used to crash because it was executed at context level 1 instead of
// context level 2.
import 'package:expect/expect.dart';
test(b) {
try {
for (int i = 0; i < 10; i++) {
// Closurizing i and b, thus the return statement
// executes at context level 2, and the code in
// the finally block runs at context level 1.
return () => i + b;
}
} finally {
b = 10;
}
}
main() {
var c = test(0);
Expect.equals(10, c());
}