| Index: pkg/compiler/lib/src/closure.dart
|
| diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
|
| index 44fcc597ac039edf58f5376b60500ac5a9568348..bd7a1a6205a6b658c9fdbcd22c62b1467c0159cc 100644
|
| --- a/pkg/compiler/lib/src/closure.dart
|
| +++ b/pkg/compiler/lib/src/closure.dart
|
| @@ -100,9 +100,6 @@ class ScopeInfo {
|
|
|
| /// True if [variable] has been mutated and is also used in another scope.
|
| bool isBoxed(Local variable) => false;
|
| -
|
| - /// True if this scope declares any variables that need to be boxed.
|
| - bool get hasBoxedVariables => false;
|
| }
|
|
|
| /// Class representing the usage of a scope that has been captured in the
|
| @@ -141,6 +138,27 @@ class ClosureScope extends ScopeInfo {
|
| /// each iteration, by boxing the iteration variable[s].
|
| class LoopClosureScope extends ClosureScope {
|
| const LoopClosureScope();
|
| +
|
| + /// True if this loop scope declares in the first part of the loop
|
| + /// `for (<here>;...;...)` any variables that need to be boxed.
|
| + bool get hasBoxedLoopVariables => false;
|
| +
|
| + /// The set of iteration variables (or variables declared in the for loop
|
| + /// expression (`for (<here>; ... ; ...)`) that need to be boxed to snapshot
|
| + /// their value. These variables are also included in the set of
|
| + /// `forEachBoxedVariable` method. The distinction between these two sets is
|
| + /// in this example:
|
| + ///
|
| + /// run(f) => f();
|
| + /// var a;
|
| + /// for (int i = 0; i < 3; i++) {
|
| + /// var b = 3;
|
| + /// a = () => b = i;
|
| + /// }
|
| + ///
|
| + /// `i` would be a part of the boxedLoopVariables AND boxedVariables, but b
|
| + /// would only be a part of boxedVariables.
|
| + List<Local> get boxedLoopVariables => const <Local>[];
|
| }
|
|
|
| /// Class that describes the actual mechanics of how the converted, rewritten
|
| @@ -647,18 +665,10 @@ class ClosureScopeImpl implements ClosureScope, LoopClosureScope {
|
| bool get requiresContextBox => capturedVariables.keys.isNotEmpty;
|
|
|
| void forEachBoxedVariable(f(Local local, FieldEntity field)) {
|
| - if (capturedVariables.isNotEmpty) {
|
| - capturedVariables.forEach(f);
|
| - } else {
|
| - for (Local l in boxedLoopVariables) {
|
| - // The boxes for loop variables are constructed on-demand per-iteration
|
| - // in the locals handler.
|
| - f(l, null);
|
| - }
|
| - }
|
| + capturedVariables.forEach(f);
|
| }
|
|
|
| - bool get hasBoxedVariables => !capturedVariables.isEmpty;
|
| + bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
|
|
|
| bool isBoxed(Local variable) {
|
| return capturedVariables.containsKey(variable);
|
| @@ -746,9 +756,6 @@ class ClosureClassMap implements ClosureRepresentationInfo {
|
| ClosureClassMap(this.closureEntity, this.closureClassEntity, this.callMethod,
|
| this.thisLocal);
|
|
|
| - bool get hasBoxedVariables =>
|
| - throw new UnsupportedError("ClosureClassMap.hasBoxedVariables");
|
| -
|
| List<Local> get createdFieldEntities {
|
| List<Local> fields = <Local>[];
|
| if (closureClassEntity == null) return const <Local>[];
|
|
|