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

Unified Diff: pkg/compiler/lib/src/closure.dart

Issue 2964783002: Reapply "Added for-loop variable tracking and regular closures/initializers captured variable track… (Closed)
Patch Set: . Created 3 years, 5 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 | « no previous file | pkg/compiler/lib/src/js_model/closure.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..5bdd71b6038b2462da84182c986a4cf119f19a6c 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -84,13 +84,13 @@ class ScopeInfo {
/// Also parameters to a `sync*` generator must be boxed, because of the way
/// we rewrite sync* functions. See also comments in
/// [ClosureClassMap.useLocal].
- bool variableIsUsedInTryOrSync(Local variable) => false;
+ bool localIsUsedInTryOrSync(Local variable) => false;
/// Loop through each variable that has been defined in this scope, modified
/// anywhere (this scope or another scope) and used in another scope. Because
/// it is used in another scope, these variables need to be "boxed", creating
/// a thin wrapper around accesses to these variables so that accesses get
- /// the correct updated value. The variables in variablesUsedInTryOrSync may
+ /// the correct updated value. The variables in localsUsedInTryOrSync may
/// be included in this set.
///
/// In the case of loops, this is the set of iteration variables (or any
@@ -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);
@@ -670,8 +680,8 @@ class ClosureScopeImpl implements ClosureScope, LoopClosureScope {
}
// Should not be called. Added to make the new interface happy.
- bool variableIsUsedInTryOrSync(Local variable) =>
- throw new UnsupportedError("ClosureScopeImpl.variableIsUsedInTryOrSync");
+ bool localIsUsedInTryOrSync(Local variable) =>
+ throw new UnsupportedError("ClosureScopeImpl.localIsUsedInTryOrSync");
// Should not be called. Added to make the new interface happy.
Local get thisLocal =>
@@ -741,14 +751,11 @@ class ClosureClassMap implements ClosureRepresentationInfo {
/// Also parameters to a `sync*` generator must be boxed, because of the way
/// we rewrite sync* functions. See also comments in [useLocal].
// TODO(johnniwinther): Add variables to this only if the variable is mutated.
- final Set<Local> variablesUsedInTryOrSync = new Set<Local>();
+ final Set<Local> localsUsedInTryOrSync = new Set<Local>();
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>[];
@@ -775,8 +782,8 @@ class ClosureClassMap implements ClosureRepresentationInfo {
FieldEntity get thisFieldEntity => freeVariableMap[thisLocal];
- bool variableIsUsedInTryOrSync(Local variable) =>
- variablesUsedInTryOrSync.contains(variable);
+ bool localIsUsedInTryOrSync(Local variable) =>
+ localsUsedInTryOrSync.contains(variable);
Local getLocalVariableForClosureField(ClosureFieldElement field) {
return field.local;
@@ -1025,13 +1032,13 @@ class ClosureTranslator extends Visitor {
if (variable != closureData.thisLocal &&
variable != closureData.closureEntity &&
variable is! TypeVariableLocal) {
- closureData.variablesUsedInTryOrSync.add(variable);
+ closureData.localsUsedInTryOrSync.add(variable);
}
} else if (variable is LocalParameterElement &&
variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) {
// Parameters in a sync* function are shared between each Iterator created
// by the Iterable returned by the function, therefore they must be boxed.
- closureData.variablesUsedInTryOrSync.add(variable);
+ closureData.localsUsedInTryOrSync.add(variable);
}
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_model/closure.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698