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

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

Issue 979813002: Support simple try in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 5 years, 10 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') | no next file » | 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_visitor.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
index 5c8313bdace0c090f944f4babfe2479ebc0ff5b5..45aa779f74af8d91ad87ae9daa9ceb2793880105 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
@@ -453,8 +453,7 @@ abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
return null;
}
- ir.Primitive visitTryStatement(ast.TryStatement node) {
- assert(this.irBuilder.isOpen);
+ visitTryStatement(ast.TryStatement node) {
// Try/catch is not yet implemented in the JS backend.
if (this.irBuilder.tryStatements == null) {
return giveup(node, 'try/catch in the JS backend');
@@ -473,130 +472,24 @@ abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
return giveup(node, 'try/finally');
}
- // Catch handlers are in scope for their body. The CPS translation of
- // [[try tryBlock catch (e) catchBlock; successor]] is:
- //
- // let cont join(v0, v1, ...) = [[successor]] in
- // let mutable m0 = x0 in
- // let mutable m1 = x1 in
- // ...
- // let handler catch_(e) =
- // let prim p0 = GetMutable(m0) in
- // let prim p1 = GetMutable(m1) in
- // ...
- // [[catchBlock]]
- // join(p0, p1, ...)
- // in
- // [[tryBlock]]
- // let prim p0' = GetMutable(m0) in
- // let prim p1' = GetMutable(m1) in
- // ...
- // join(p0', p1', ...)
- //
- // In other words, both the try and catch block are in the scope of the
- // join-point continuation, and they are both in the scope of a sequence
- // of mutable bindings for the variables assigned in the try. The join-
- // point continuation is not in the scope of these mutable bindings.
- // The tryBlock is in the scope of a binding for the catch handler. Each
- // instruction (specifically, each call) in the tryBlock is in the dynamic
- // scope of the handler. The mutable bindings are dereferenced at the end
- // of the try block and at the beginning of the catch block, so the
- // variables are unboxed in the catch block and at the join point.
-
- IrBuilder tryCatchBuilder = irBuilder.makeDelimitedBuilder();
- TryStatementInfo tryInfo = tryCatchBuilder.tryStatements[node];
- // Variables that are boxed due to being captured in a closure are boxed
- // for their entire lifetime, and so they do not need to be boxed on
- // entry to any try block. We check for them here because we can not
- // identify all of them in the same pass where we identify the variables
- // assigned in the try (the may be captured by a closure after the try
- // statement).
- Iterable<LocalVariableElement> boxedOnEntry =
- tryInfo.boxedOnEntry.where((LocalVariableElement variable) {
- return !tryCatchBuilder.mutableCapturedVariables.contains(variable);
- });
- for (LocalVariableElement variable in boxedOnEntry) {
- assert(!tryCatchBuilder.isInMutableVariable(variable));
- ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
- tryCatchBuilder.makeMutableVariable(variable);
- tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
- }
-
- IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
- IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
- List<ir.Parameter> joinParameters =
- new List<ir.Parameter>.generate(irBuilder.environment.length, (i) {
- return new ir.Parameter(irBuilder.environment.index2variable[i]);
- });
- ir.Continuation joinContinuation = new ir.Continuation(joinParameters);
-
- void interceptJumps(JumpCollector collector) {
- collector.enterTry(boxedOnEntry);
- }
- void restoreJumps(JumpCollector collector) {
- collector.leaveTry();
- }
- tryBuilder.state.breakCollectors.forEach(interceptJumps);
- tryBuilder.state.continueCollectors.forEach(interceptJumps);
- withBuilder(tryBuilder, () {
- visit(node.tryBlock);
- });
- tryBuilder.state.breakCollectors.forEach(restoreJumps);
- tryBuilder.state.continueCollectors.forEach(restoreJumps);
- if (tryBuilder.isOpen) {
- for (LocalVariableElement variable in boxedOnEntry) {
- assert(tryBuilder.isInMutableVariable(variable));
- ir.Primitive value = tryBuilder.buildLocalGet(variable);
- tryBuilder.environment.update(variable, value);
+ List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
+ for (ast.CatchBlock catchClause in node.catchBlocks.nodes) {
+ assert(catchClause.exception != null);
+ LocalVariableElement exceptionVariable = elements[catchClause.exception];
+ LocalVariableElement stackTraceVariable;
+ if (catchClause.trace != null) {
+ stackTraceVariable = elements[catchClause.trace];
}
- tryBuilder.jumpTo(joinContinuation);
+ catchClauseInfos.add(new CatchClauseInfo(
+ exceptionVariable: exceptionVariable,
+ stackTraceVariable: stackTraceVariable,
+ buildCatchBlock: subbuild(catchClause.block)));
}
- for (LocalVariableElement variable in boxedOnEntry) {
- assert(catchBuilder.isInMutableVariable(variable));
- ir.Primitive value = catchBuilder.buildLocalGet(variable);
- // Note that we remove the variable from the set of mutable variables
- // here (and not above for the try body). This is because the set of
- // mutable variables is global for the whole function and not local to
- // a delimited builder.
- catchBuilder.removeMutableVariable(variable);
- catchBuilder.environment.update(variable, value);
- }
- ast.CatchBlock catchClause = node.catchBlocks.nodes.head;
- assert(catchClause.exception != null);
- LocalVariableElement exceptionElement = elements[catchClause.exception];
- ir.Parameter exceptionParameter = new ir.Parameter(exceptionElement);
- catchBuilder.environment.extend(exceptionElement, exceptionParameter);
- ir.Parameter traceParameter;
- if (catchClause.trace != null) {
- LocalVariableElement traceElement = elements[catchClause.trace];
- traceParameter = new ir.Parameter(traceElement);
- catchBuilder.environment.extend(traceElement, 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);
- }
- withBuilder(catchBuilder, () {
- visit(catchClause.block);
- });
- if (catchBuilder.isOpen) {
- catchBuilder.jumpTo(joinContinuation);
- }
- 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;
-
- irBuilder.add(new ir.LetCont(joinContinuation, tryCatchBuilder._root));
- for (int i = 0; i < irBuilder.environment.length; ++i) {
- irBuilder.environment.index2value[i] = joinParameters[i];
- }
- return null;
+ irBuilder.buildTry(
+ tryStatementInfo: irBuilder.tryStatements[node],
+ buildTryBlock: subbuild(node.tryBlock),
+ catchClauseInfos: catchClauseInfos);
}
// ==== Expressions ====
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698