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

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

Issue 1414043011: Mark returns from inside the try of a try/catch as ones that exit the try. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 | 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.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 d1353979d145a3d1fa3a0142e9467c7efd29c125..36f569f6a86a4669fe8fb8e13b8722c195ada637 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -159,6 +159,13 @@ abstract class JumpCollector {
if (hasExtraArgument) _continuationEnvironment.extend(null, null);
}
+ /// Construct a collector for collecting only return jumps.
+ ///
+ /// There is no jump target, it is implicitly the exit from the function.
+ /// There is no environment at the destination.
+ JumpCollector.retrn(this._continuation)
+ : _continuationEnvironment = null, target = null;
+
/// True if the collector has not recorded any jumps to its continuation.
bool get isEmpty;
@@ -175,7 +182,8 @@ abstract class JumpCollector {
/// values to finally blocks for returns inside try/finally and to pass
/// values of expressions that have internal control flow to their join-point
/// continuations.
- void addJump(IrBuilder builder, [ir.Primitive value]);
+ void addJump(IrBuilder builder,
+ [ir.Primitive value, SourceInformation sourceInformation]);
/// Add a set of variables that were boxed on entry to a try block.
///
@@ -259,7 +267,8 @@ class ForwardJumpCollector extends JumpCollector {
return _continuationEnvironment;
}
- void addJump(IrBuilder builder, [ir.Primitive value]) {
+ void addJump(IrBuilder builder,
+ [ir.Primitive value, SourceInformation sourceInformation]) {
assert(_continuation == null);
_buildTryExit(builder);
ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized(
@@ -368,7 +377,8 @@ class BackwardJumpCollector extends JumpCollector {
ir.Continuation get continuation => _continuation;
Environment get environment => _continuationEnvironment;
- void addJump(IrBuilder builder, [ir.Primitive value]) {
+ void addJump(IrBuilder builder,
+ [ir.Primitive value, SourceInformation sourceInformation]) {
assert(_continuation.parameters.length <= builder.environment.length);
isEmpty = false;
_buildTryExit(builder);
@@ -388,6 +398,29 @@ class BackwardJumpCollector extends JumpCollector {
}
}
+/// Collect 'return' jumps.
+///
+/// A return jump is one that targets the return continuation of a function.
+/// Thus, returns from inside try/finally are not return jumps because they are
+/// intercepted by a block that contains the finally handler code.
+class ReturnJumpCollector extends JumpCollector {
+ bool isEmpty = true;
+ ir.Continuation get continuation => _continuation;
+ Environment environment = null;
+
+ /// Construct a return jump collector for a given return continuation.
+ ReturnJumpCollector(ir.Continuation continuation) : super.retrn(continuation);
+
+ void addJump(IrBuilder builder,
+ [ir.Primitive value, SourceInformation sourceInformation]) {
+ isEmpty = false;
+ builder.add(new ir.InvokeContinuation(continuation, <ir.Primitive>[value],
+ isEscapingTry: isEscapingTry,
+ sourceInformation: sourceInformation));
+ builder._current = null;
+ }
+}
+
/// Function for building a node in the context of the current builder.
typedef ir.Node BuildFunction(node);
@@ -466,7 +499,7 @@ class IrBuilderSharedState {
/// A null value indicates that the target is the function's return
/// continuation. Otherwise, when inside the try block of try/finally
/// a return is intercepted to give a place to generate the finally code.
- JumpCollector returnCollector = null;
+ JumpCollector returnCollector;
/// Parameter holding the internal value of 'this' passed to the function.
///
@@ -483,7 +516,9 @@ class IrBuilderSharedState {
/// the environment.
final Map<Local, ClosureLocation> boxedVariables = {};
- IrBuilderSharedState(this.program, this.constants, this.currentElement);
+ IrBuilderSharedState(this.program, this.constants, this.currentElement) {
+ returnCollector = new ReturnJumpCollector(returnContinuation);
+ }
}
class ThisParameterLocal implements Local {
@@ -1160,8 +1195,9 @@ class IrBuilder {
}
}
- void jumpTo(JumpCollector collector, [ir.Primitive value]) {
- collector.addJump(this, value);
+ void jumpTo(JumpCollector collector,
+ [ir.Primitive value, SourceInformation sourceInformation]) {
+ collector.addJump(this, value, sourceInformation);
}
void addRecursiveContinuation(BackwardJumpCollector collector) {
@@ -1811,6 +1847,7 @@ class IrBuilder {
}
builder.state.breakCollectors.forEach(interceptJump);
builder.state.continueCollectors.forEach(interceptJump);
+ interceptJump(builder.state.returnCollector);
}
void leaveTry(IrBuilder builder) {
@@ -1821,6 +1858,7 @@ class IrBuilder {
}
builder.state.breakCollectors.forEach(restoreJump);
builder.state.continueCollectors.forEach(restoreJump);
+ restoreJump(builder.state.returnCollector);
}
List<ir.Parameter> buildCatch(IrBuilder builder,
@@ -2029,16 +2067,7 @@ class IrBuilder {
if (value == null) {
value = buildNullConstant();
}
- if (state.returnCollector == null) {
- add(new ir.InvokeContinuation(state.returnContinuation, [value],
- sourceInformation: sourceInformation));
- _current = null;
- } else {
- // Inside the try block of try/finally, all returns go to a join-point
- // continuation that contains the finally code. The return value is
- // passed as an extra argument.
- jumpTo(state.returnCollector, value);
- }
+ jumpTo(state.returnCollector, value, sourceInformation);
}
/// Build a call to the closure conversion helper for the [Function] typed
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698