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

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

Issue 923013002: dart2dart: Implementation of simple try/catch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed break/continue, incorporated 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
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 e45762e17e6cc81c29a39a56869bd915c10d8273..b9702dcaaf3635c66a6463f66e91a64b0105d9c7 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -111,6 +111,8 @@ class JumpCollector {
final JumpTarget target;
final List<ir.InvokeContinuation> _invocations = <ir.InvokeContinuation>[];
final List<Environment> _environments = <Environment>[];
+ final List<Iterable<LocalVariableElement>> boxedTryVariables =
+ <Iterable<LocalVariableElement>>[];
JumpCollector(this.target);
@@ -120,6 +122,15 @@ class JumpCollector {
List<Environment> get environments => _environments;
void addJump(IrBuilder builder) {
+ // Unbox all variables that were boxed on entry to try blocks between the
+ // jump and the target.
+ for (Iterable<LocalVariableElement> boxedOnEntry in boxedTryVariables) {
+ for (LocalVariableElement variable in boxedOnEntry) {
+ assert(builder.isInMutableVariable(variable));
+ ir.Primitive value = builder.buildLocalGet(variable);
+ builder.environment.update(variable, value);
+ }
+ }
ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized();
builder.add(invoke);
_invocations.add(invoke);
@@ -128,6 +139,26 @@ class JumpCollector {
// TODO(kmillikin): Can we set builder.environment to null to make it
// less likely to mutate it?
}
+
+ /// Add a set of variables that were boxed on entry to a try block.
+ ///
+ /// Jumps from a try block to targets outside have to unbox the variables
+ /// that were boxed on entry before invoking the target continuation. Call
+ /// this function before translating a try block and call [leaveTry] after
+ /// translating it.
+ void enterTry(Iterable<LocalVariableElement> boxedOnEntry) {
+ // The boxed variables are maintained as a stack to make leaving easy.
+ boxedTryVariables.add(boxedOnEntry);
+ }
+
+ /// Remove the most recently added set of variables boxed on entry to a try
+ /// block.
+ ///
+ /// Call [enterTry] before translating a try block and call this function
+ /// after translating it.
+ void leaveTry() {
+ boxedTryVariables.removeLast();
+ }
}
/// Function for building a node in the context of the current builder.
@@ -208,6 +239,30 @@ class IrBuilderDelimitedState {
abstract class IrBuilder {
IrBuilder _makeInstance();
+ /// A map from TryStatements in the AST to their analysis information.
+ ///
+ /// This includes which variables should be copied into [ir.MutableVariable]s
+ /// on entry to the try and copied out on exit.
+ Map<ast.TryStatement, TryStatementInfo> get tryStatements;
+
+ /// The set of local variables that will spend their lifetime as
+ /// [ir.MutableVariable]s due to being captured by a nested function.
+ Set<Local> get mutableCapturedVariables;
+
+ /// True if [local] should currently be accessed from a [ir.MutableVariable].
+ bool isInMutableVariable(Local local);
+
+ /// Creates a [ir.MutableVariable] for the given local.
+ void makeMutableVariable(Local local);
+
+ /// Remove an [ir.MutableVariable] for a local.
+ ///
+ /// Subsequent access to the local will be direct rather than through the
+ /// mutable variable. This is used for variables that do not spend their
+ /// entire lifetime as mutable variables (e.g., variables that are boxed
+ /// in mutable variables for a try block).
+ void removeMutableVariable(Local local);
+
void declareLocalVariable(LocalVariableElement element,
{ir.Primitive initialValue});
ir.Primitive buildLocalGet(LocalElement element);
@@ -816,6 +871,19 @@ abstract class IrBuilder {
}
}
+ void jumpTo(ir.Continuation continuation) {
+ assert(isOpen);
+ assert(environment.length >= continuation.parameters.length);
+ ir.InvokeContinuation jump = new ir.InvokeContinuation.uninitialized();
+ jump.continuation = new ir.Reference(continuation);
+ jump.arguments = new List<ir.Reference>.generate(
+ continuation.parameters.length, (i) {
+ return new ir.Reference(environment[i]);
+ });
+ add(jump);
+ _current = null;
+ }
+
/// Invoke a join-point continuation that contains arguments for all local
/// variables.
///
@@ -824,6 +892,9 @@ abstract class IrBuilder {
void invokeFullJoin(ir.Continuation join,
JumpCollector jumps,
{recursive: false}) {
+ // TODO(kmillikin): If the JumpCollector collected open IrBuilders instead
+ // of pairs of invocations and environments, we could use IrBuilder.jumpTo
+ // here --- the code is almost the same.
join.isRecursive = recursive;
for (int i = 0; i < jumps.length; ++i) {
Environment currentEnvironment = jumps.environments[i];
@@ -1518,7 +1589,7 @@ class DartIrBuilderSharedState {
final Map<Local, ir.MutableVariable> local2mutable =
<Local, ir.MutableVariable>{};
- final DartCapturedVariableInfo capturedVariables;
+ final DartCapturedVariables capturedVariables;
/// Creates a [MutableVariable] for the given local.
void makeMutableVariable(Local local) {
@@ -1550,17 +1621,32 @@ class DartIrBuilder extends IrBuilder {
DartIrBuilder(ConstantSystem constantSystem,
ExecutableElement currentElement,
- DartCapturedVariableInfo capturedVariables)
+ DartCapturedVariables capturedVariables)
: dartState = new DartIrBuilderSharedState(capturedVariables) {
_init(constantSystem, currentElement);
}
- /// True if [local] should currently be accessed from a [MutableVariable].
+ Map<ast.TryStatement, TryStatementInfo> get tryStatements {
+ return dartState.capturedVariables.tryStatements;
+ }
+
+ Set<Local> get mutableCapturedVariables {
+ return dartState.capturedVariables.capturedVariables;
+ }
+
bool isInMutableVariable(Local local) {
return dartState.local2mutable.containsKey(local) &&
!dartState.registerizedMutableVariables.contains(local);
}
+ void makeMutableVariable(Local local) {
+ dartState.makeMutableVariable(local);
+ }
+
+ void removeMutableVariable(Local local) {
+ dartState.local2mutable.remove(local);
+ }
+
/// Gets the [MutableVariable] containing the value of [local].
ir.MutableVariable getMutableVariable(Local local) {
return dartState.local2mutable[local];
@@ -1734,6 +1820,12 @@ class JsIrBuilder extends IrBuilder {
_init(constantSystem, currentElement);
}
+ Map<ast.TryStatement, TryStatementInfo> get tryStatements => null;
+ Set<Local> get mutableCapturedVariables => null;
+ bool isInMutableVariable(Local local) => false;
+ void makeMutableVariable(Local local) {}
+ void removeMutableVariable(Local local) {}
+
void _enterClosureEnvironment(ClosureEnvironment env) {
if (env == null) return;
@@ -2012,10 +2104,8 @@ class ClosureEnvironment {
ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
}
-/// Information about which variables are captured by a nested function.
-///
-/// This is used by the [DartIrBuilder] instead of [ClosureScope] and
-/// [ClosureEnvironment].
-abstract class DartCapturedVariableInfo {
- Iterable<Local> get capturedVariables;
+class TryStatementInfo {
+ final Set<LocalVariableElement> declared = new Set<LocalVariableElement>();
+ final Set<LocalVariableElement> boxedOnEntry =
+ new Set<LocalVariableElement>();
}

Powered by Google App Engine
This is Rietveld 408576698