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

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

Issue 1125813004: Support 'on T' catch clauses and multiple clauses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 7 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 | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('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.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index d511047e94cea2655050a253f9616fc0f995083e..770e46f5116feb78fbc208f362eaac03d37b297f 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -1786,39 +1786,78 @@ abstract class IrBuilder {
catchBuilder.environment.update(variable, value);
}
- // TODO(kmillikin): Handle multiple catch clauses.
- assert(catchClauseInfos.length == 1);
- for (CatchClauseInfo catchClauseInfo in catchClauseInfos) {
- LocalVariableElement exceptionVariable =
- catchClauseInfo.exceptionVariable;
- ir.Parameter exceptionParameter = new ir.Parameter(exceptionVariable);
- catchBuilder.declareLocalVariable(exceptionVariable,
- initialValue: exceptionParameter);
- ir.Parameter traceParameter;
- LocalVariableElement stackTraceVariable =
- catchClauseInfo.stackTraceVariable;
- if (stackTraceVariable != null) {
- traceParameter = new ir.Parameter(stackTraceVariable);
- catchBuilder.declareLocalVariable(stackTraceVariable,
- initialValue: traceParameter);
- } else {
- // Use a dummy continuation parameter for the stack trace parameter.
- // This will ensure that all handlers have two parameters and so they
- // can be treated uniformly.
- traceParameter = new ir.Parameter(null);
+ // Handlers are always translated as having both exception and stack trace
+ // parameters. Multiple clauses do not have to use the same names for
+ // them. Choose the first of each as the name hint for the respective
+ // handler parameter.
+ ir.Parameter exceptionParameter =
+ new ir.Parameter(catchClauseInfos.first.exceptionVariable);
+ LocalVariableElement traceVariable;
+ CatchClauseInfo catchAll;
+ for (int i = 0; i < catchClauseInfos.length; ++i) {
+ CatchClauseInfo info = catchClauseInfos[i];
+ if (info.type == null) {
+ catchAll = info;
+ catchClauseInfos.length = i;
+ break;
+ }
+ if (traceVariable == null) {
+ traceVariable = info.stackTraceVariable;
+ }
+ }
+ ir.Parameter traceParameter = new ir.Parameter(traceVariable);
+ // Expand multiple catch clauses into an explicit if/then/else. Iterate
+ // them in reverse so the current block becomes the next else block.
+ ir.Expression catchBody;
+ if (catchAll == null) {
+ catchBody = new ir.Rethrow();
+ } else {
+ IrBuilder clauseBuilder = catchBuilder.makeDelimitedBuilder();
Kevin Millikin (Google) 2015/05/05 10:29:12 I'm going to move the next seven or eight lines in
+ clauseBuilder.declareLocalVariable(catchAll.exceptionVariable,
+ initialValue: exceptionParameter);
+ if (catchAll.stackTraceVariable != null) {
+ clauseBuilder.declareLocalVariable(catchAll.stackTraceVariable,
+ initialValue: traceParameter);
}
- catchClauseInfo.buildCatchBlock(catchBuilder);
- if (catchBuilder.isOpen) catchBuilder.jumpTo(join);
- List<ir.Parameter> catchParameters =
- <ir.Parameter>[exceptionParameter, traceParameter];
- ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
- catchContinuation.body = catchBuilder._root;
-
- tryCatchBuilder.add(
- new ir.LetHandler(catchContinuation, tryBuilder._root));
- tryCatchBuilder._current = null;
+ catchAll.buildCatchBlock(clauseBuilder);
+ if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join);
+ catchBody = clauseBuilder._root;
}
+ for (CatchClauseInfo clause in catchClauseInfos.reversed) {
+ IrBuilder clauseBuilder = catchBuilder.makeDelimitedBuilder();
+ clauseBuilder.declareLocalVariable(clause.exceptionVariable,
+ initialValue: exceptionParameter);
+ if (clause.stackTraceVariable != null) {
+ clauseBuilder.declareLocalVariable(clause.stackTraceVariable,
+ initialValue: traceParameter);
+ }
+ clause.buildCatchBlock(clauseBuilder);
+ if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join);
+ ir.Continuation thenContinuation = new ir.Continuation([]);
+ thenContinuation.body = clauseBuilder._root;
+ ir.Continuation elseContinuation = new ir.Continuation([]);
+ elseContinuation.body = catchBody;
+
+ ir.Parameter typeMatches = new ir.Parameter(null);
+ ir.Continuation checkType = new ir.Continuation([typeMatches]);
+ checkType.body =
+ new ir.LetCont.many([thenContinuation, elseContinuation],
+ new ir.Branch(new ir.IsTrue(typeMatches),
+ thenContinuation,
+ elseContinuation));
+ catchBody =
+ new ir.LetCont(checkType,
+ new ir.TypeOperator(exceptionParameter, clause.type, checkType,
+ isTypeTest: true));
+ }
+
+ List<ir.Parameter> catchParameters =
+ <ir.Parameter>[exceptionParameter, traceParameter];
+ ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
+ catchContinuation.body = catchBody;
+ tryCatchBuilder.add(
+ new ir.LetHandler(catchContinuation, tryBuilder._root));
add(new ir.LetCont(join.continuation, tryCatchBuilder._root));
environment = join.environment;
}
@@ -2648,13 +2687,14 @@ class TryStatementInfo {
new Set<LocalVariableElement>();
}
-// TODO(johnniwinther): Support passing of [DartType] for the exception.
class CatchClauseInfo {
+ final DartType type;
final LocalVariableElement exceptionVariable;
final LocalVariableElement stackTraceVariable;
final SubbuildFunction buildCatchBlock;
- CatchClauseInfo({this.exceptionVariable,
+ CatchClauseInfo({this.type,
+ this.exceptionVariable,
this.stackTraceVariable,
this.buildCatchBlock});
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698