Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1962)

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1207703002: dart2js CPS: Support try/catch/finally. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Merge, and fix a test expectation. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/pkg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index e7353091daa31b8eabdef88e094c5435d6fad923..76753954f0eb83493e5ec02b875e5802401ba7ff 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -111,7 +111,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
/// The analysis information includes the set of variables that must be
/// copied into [ir.MutableVariable]s on entry to the try and copied out on
/// exit.
- Map<ast.TryStatement, TryStatementInfo> tryStatements = null;
+ Map<ast.Node, TryStatementInfo> tryStatements = null;
// In SSA terms, join-point continuation parameters are the phis and the
// continuation invocation arguments are the corresponding phi inputs. To
@@ -431,11 +431,6 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
}
visitTryStatement(ast.TryStatement node) {
- // Try/catch/finally is not yet implemented.
- if (!node.catchBlocks.isEmpty && node.finallyBlock != null) {
- return giveup(node, 'try/catch/finally');
- }
-
List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
for (ast.CatchBlock catchClause in node.catchBlocks.nodes) {
assert(catchClause.exception != null);
@@ -455,14 +450,29 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
buildCatchBlock: subbuild(catchClause.block)));
}
- SubbuildFunction buildFinallyBlock =
- node.finallyBlock == null ? null : subbuild(node.finallyBlock);
- irBuilder.buildTry(
- tryStatementInfo: tryStatements[node],
- buildTryBlock: subbuild(node.tryBlock),
- catchClauseInfos: catchClauseInfos,
- buildFinallyBlock: buildFinallyBlock,
- closureClassMap: closureClassMap);
+ assert(!node.catchBlocks.isEmpty || node.finallyBlock != null);
+ if (!node.catchBlocks.isEmpty && node.finallyBlock != null) {
+ // Try/catch/finally is encoded in terms of try/catch and try/finally:
+ //
+ // try tryBlock catch (ex, st) catchBlock finally finallyBlock
+ // ==>
+ // try { try tryBlock catch (ex, st) catchBlock } finally finallyBlock
+ irBuilder.buildTryFinally(tryStatements[node.finallyBlock],
+ (IrBuilder inner) {
+ inner.buildTryCatch(tryStatements[node.catchBlocks],
+ subbuild(node.tryBlock),
+ catchClauseInfos);
+ },
+ subbuild(node.finallyBlock));
+ } else if (!node.catchBlocks.isEmpty) {
+ irBuilder.buildTryCatch(tryStatements[node.catchBlocks],
+ subbuild(node.tryBlock),
+ catchClauseInfos);
+ } else {
+ irBuilder.buildTryFinally(tryStatements[node.finallyBlock],
+ subbuild(node.tryBlock),
+ subbuild(node.finallyBlock));
+ }
}
// ## Expressions ##
@@ -1961,8 +1971,13 @@ class DartCapturedVariables extends ast.Visitor {
bool insideInitializer = false;
Set<Local> capturedVariables = new Set<Local>();
- Map<ast.TryStatement, TryStatementInfo> tryStatements =
- <ast.TryStatement, TryStatementInfo>{};
+ /// A map containing variables boxed inside try blocks.
+ ///
+ /// The map is keyed by the [NodeList] of catch clauses for try/catch and
+ /// by the finally block for try/finally. try/catch/finally is treated
+ /// as a try/catch nested in the try block of a try/finally.
+ Map<ast.Node, TryStatementInfo> tryStatements =
+ <ast.Node, TryStatementInfo>{};
List<TryStatementInfo> tryNestingStack = <TryStatementInfo>[];
bool get inTryStatement => tryNestingStack.isNotEmpty;
@@ -2079,15 +2094,42 @@ class DartCapturedVariables extends ast.Visitor {
}
visitTryStatement(ast.TryStatement node) {
- TryStatementInfo info = new TryStatementInfo();
- tryStatements[node] = info;
- tryNestingStack.add(info);
+ // Try/catch/finally is treated as two simpler constructs: try/catch and
+ // try/finally. The encoding is:
+ //
+ // try S0 catch (ex, st) S1 finally S2
+ // ==>
+ // try { try S0 catch (ex, st) S1 } finally S2
+ //
+ // The analysis associates variables assigned in S0 with the catch clauses
+ // and variables assigned in S0 and S1 with the finally block.
+ TryStatementInfo enterTryFor(ast.Node node) {
+ TryStatementInfo info = new TryStatementInfo();
+ tryStatements[node] = info;
+ tryNestingStack.add(info);
+ return info;
+ }
+ void leaveTryFor(TryStatementInfo info) {
+ assert(tryNestingStack.last == info);
+ tryNestingStack.removeLast();
+ }
+ bool hasCatch = !node.catchBlocks.isEmpty;
+ bool hasFinally = node.finallyBlock != null;
+ TryStatementInfo catchInfo, finallyInfo;
+ // There is a nesting stack of try blocks, so the outer try/finally block
+ // is added first.
+ if (hasFinally) finallyInfo = enterTryFor(node.finallyBlock);
+ if (hasCatch) catchInfo = enterTryFor(node.catchBlocks);
visit(node.tryBlock);
- assert(tryNestingStack.last == info);
- tryNestingStack.removeLast();
- visit(node.catchBlocks);
- if (node.finallyBlock != null) visit(node.finallyBlock);
+ if (hasCatch) {
+ leaveTryFor(catchInfo);
+ visit(node.catchBlocks);
+ }
+ if (hasFinally) {
+ leaveTryFor(finallyInfo);
+ visit(node.finallyBlock);
+ }
}
visitVariableDefinitions(ast.VariableDefinitions node) {
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/pkg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698