| 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
|
|
|