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

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

Issue 2949293002: Add ScopeInfo class for variable information that doesn't actually involve closures. (Closed)
Patch Set: . Created 3 years, 6 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/kernel/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 16e04cdb17dea8463ba9e8511640ab16f6d41f40..fe91dc9434b41525b105502c0844d2da107ce059 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -43,6 +43,10 @@ abstract class ClosureDataLookup<T> {
/// used inside the scope of [node].
// TODO(johnniwinther): Split this up into two functions, one for members and
// one for local functions.
+ ScopeInfo getScopeInfo(covariant Entity member);
+
+ /// This returns the same information as ScopeInfo, but can be called in
+ /// situations when you are sure you are dealing with a closure specifically.
ClosureRepresentationInfo getClosureRepresentationInfo(
covariant Entity member);
@@ -54,6 +58,35 @@ abstract class ClosureDataLookup<T> {
ClosureAnalysisInfo getClosureAnalysisInfo(T node);
}
+/// Class that represents one level of scoping information, whether this scope
+/// is a closure or not. This is specifically used to store information
+/// about the usage of variables in try or sync blocks, because they need to be
+/// boxed.
+///
+/// Variables that are used in a try must be treated as boxed because the
+/// control flow can be non-linear. Also parameters to a `sync*` generator must
+/// be boxed, because of the way we rewrite sync* functions. See also comments
+/// in [ClosureClassMap.useLocal].
+class ScopeInfo {
+ const ScopeInfo();
+
+ /// Returns true if this [variable] is used inside a `try` block or a `sync*`
+ /// generator (this is important to know because boxing/redirection needs to
+ /// happen for those local variables).
+ ///
+ /// Variables that are used in a try must be treated as boxed because the
+ /// control flow can be non-linear.
+ ///
+ /// 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;
+
+ /// Convenience reference pointer to the element representing `this`.
+ /// If this scope is not in an instance member, it will be null.
+ Local get thisLocal => null;
+}
+
/// Class that provides a black-box interface to information gleaned from
/// analyzing a closure's characteristics, most commonly used to influence how
/// code should be generated in SSA builder stage.
@@ -138,7 +171,7 @@ class LoopClosureRepresentationInfo extends ClosureAnalysisInfo {
/// used in the inner scope of this closure, we say `y` is a "captured"
/// variable.
/// TODO(efortuna): Make interface simpler in subsequent refactorings.
-class ClosureRepresentationInfo {
+class ClosureRepresentationInfo extends ScopeInfo {
const ClosureRepresentationInfo();
/// The original local function before any translation.
@@ -162,26 +195,10 @@ class ClosureRepresentationInfo {
/// accessor to that set of fields.
List<Local> get createdFieldEntities => const <Local>[];
- /// Convenience reference pointer to the element representing `this`.
- /// It is only set for instance-members.
- Local get thisLocal => null;
-
/// Convenience pointer to the field entity representation in the closure
/// class of the element representing `this`.
FieldEntity get thisFieldEntity => null;
- /// Returns true if this [variable] is used inside a `try` block or a `sync*`
- /// generator (this is important to know because boxing/redirection needs to
- /// happen for those local variables).
- ///
- /// Variables that are used in a try must be treated as boxed because the
- /// control flow can be non-linear.
- ///
- /// 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;
-
/// Loop through every variable that has been captured in this closure. This
/// consists of all the free variables (variables captured *just* in this
/// closure) and all variables captured in nested scopes that we may be
@@ -233,6 +250,10 @@ class ClosureTask extends ClosureConversionTask<Node> {
return value == null ? const ClosureAnalysisInfo() : value;
}
+ ScopeInfo getScopeInfo(Element member) {
+ return getClosureToClassMapping(member);
+ }
+
ClosureRepresentationInfo getClosureRepresentationInfo(Element member) {
return getClosureToClassMapping(member);
}
@@ -690,13 +711,17 @@ class ClosureClassMap implements ClosureRepresentationInfo {
/// not contain any nested closure.
final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>();
+ /// Set of [variable]s referenced in this scope that are used inside a
+ /// `try` block or a `sync*` generator (this is important to know because
+ /// boxing/redirection needs to happen for those local variables).
+ ///
/// Variables that are used in a try must be treated as boxed because the
/// control flow can be non-linear.
///
/// 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> variablesUsedInTryOrGenerator = new Set<Local>();
+ final Set<Local> variablesUsedInTryOrSync = new Set<Local>();
ClosureClassMap(this.closureEntity, this.closureClassEntity, this.callMethod,
this.thisLocal);
@@ -728,7 +753,7 @@ class ClosureClassMap implements ClosureRepresentationInfo {
FieldEntity get thisFieldEntity => freeVariableMap[thisLocal];
bool variableIsUsedInTryOrSync(Local variable) =>
- variablesUsedInTryOrGenerator.contains(variable);
+ variablesUsedInTryOrSync.contains(variable);
Local getLocalVariableForClosureField(ClosureFieldElement field) {
return field.local;
@@ -969,13 +994,13 @@ class ClosureTranslator extends Visitor {
if (variable != closureData.thisLocal &&
variable != closureData.closureEntity &&
variable is! TypeVariableLocal) {
- closureData.variablesUsedInTryOrGenerator.add(variable);
+ closureData.variablesUsedInTryOrSync.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.variablesUsedInTryOrGenerator.add(variable);
+ closureData.variablesUsedInTryOrSync.add(variable);
}
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/kernel/closure.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698