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

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

Issue 2964113004: Revert "Added for-loop variable tracking and regular closures/initializers captured variable tracki… (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 | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/js_model/closure_visitors.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_model/closure.dart
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 308219bce0cefe83553ea7be24ffe7560ae3c37d..3ba9ec542cdd60ada05161b50796b654f43bf572 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -9,10 +9,54 @@ import '../common/tasks.dart';
import '../elements/entities.dart';
import '../kernel/element_map.dart';
import '../world.dart';
-import 'elements.dart';
-import 'closure_visitors.dart';
import 'locals.dart';
+class KernelClosureDataBuilder extends ir.Visitor {
+ final KernelToLocalsMap _localsMap;
+ final KernelClosureRepresentationInfo info;
+
+ bool _inTry = false;
+
+ KernelClosureDataBuilder(this._localsMap, ThisLocal thisLocal)
+ : info = new KernelClosureRepresentationInfo(thisLocal);
+
+ @override
+ defaultNode(ir.Node node) {
+ node.visitChildren(this);
+ }
+
+ @override
+ visitTryCatch(ir.TryCatch node) {
+ bool oldInTry = _inTry;
+ _inTry = true;
+ node.visitChildren(this);
+ _inTry = oldInTry;
+ }
+
+ @override
+ visitTryFinally(ir.TryFinally node) {
+ bool oldInTry = _inTry;
+ _inTry = true;
+ node.visitChildren(this);
+ _inTry = oldInTry;
+ }
+
+ @override
+ visitVariableGet(ir.VariableGet node) {
+ if (_inTry) {
+ info.registerUsedInTryOrSync(_localsMap.getLocal(node.variable));
+ }
+ }
+
+ @override
+ visitVariableSet(ir.VariableSet node) {
+ if (_inTry) {
+ info.registerUsedInTryOrSync(_localsMap.getLocal(node.variable));
+ }
+ node.visitChildren(this);
+ }
+}
+
/// Closure conversion code using our new Entity model. Closure conversion is
/// necessary because the semantics of closures are slightly different in Dart
/// than JavaScript. Closure conversion is separated out into two phases:
@@ -25,24 +69,14 @@ import 'locals.dart';
/// check out:
/// http://siek.blogspot.com/2012/07/essence-of-closure-conversion.html or
/// http://matt.might.net/articles/closure-conversion/.
-// TODO(efortuna): Change inheritance hierarchy so that the
-// ClosureConversionTask doesn't inherit from ClosureTask because it's just a
-// glorified timer.
class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
final KernelToElementMapForBuilding _elementMap;
final GlobalLocalsMap _globalLocalsMap;
- Map<ir.Node, ClosureScope> _closureScopeMap = <ir.Node, ClosureScope>{};
-
- Map<Entity, ClosureRepresentationInfo> _closureRepresentationMap =
+ Map<Entity, ClosureRepresentationInfo> _infoMap =
<Entity, ClosureRepresentationInfo>{};
- /// Should only be used at the very beginning to ensure we are looking at the
- /// right kind of elements.
- // TODO(efortuna): Remove this map once we have one kernel backend strategy.
- final JsToFrontendMap _kToJElementMap;
-
- KernelClosureConversionTask(Measurer measurer, this._elementMap,
- this._kToJElementMap, this._globalLocalsMap)
+ KernelClosureConversionTask(
+ Measurer measurer, this._elementMap, this._globalLocalsMap)
: super(measurer);
/// The combined steps of generating our intermediate representation of
@@ -54,192 +88,67 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
@override
void convertClosures(Iterable<MemberEntity> processedEntities,
ClosedWorldRefiner closedWorldRefiner) {
- var closuresToGenerate = <ir.Node, ScopeInfo>{};
- processedEntities.forEach((MemberEntity kEntity) {
- MemberEntity entity = kEntity;
- if (_kToJElementMap != null) {
- entity = _kToJElementMap.toBackendMember(kEntity);
- }
- if (entity.isAbstract) return;
- if (entity.isField && !entity.isInstanceMember) {
- ir.Field field = _elementMap.getMemberNode(entity);
- // Skip top-level/static fields without an initializer.
- if (field.initializer == null) return;
- }
- _buildClosureModel(entity, closuresToGenerate, closedWorldRefiner);
- });
-
- for (ir.Node node in closuresToGenerate.keys) {
- _produceSyntheticElements(
- node, closuresToGenerate[node], closedWorldRefiner);
- }
- }
-
- /// Inspect members and mark if those members capture any state that needs to
- /// be marked as free variables.
- void _buildClosureModel(
- MemberEntity entity,
- Map<ir.Node, ScopeInfo> closuresToGenerate,
- ClosedWorldRefiner closedWorldRefiner) {
- ir.Node node = _elementMap.getMemberNode(entity);
- if (_closureScopeMap.keys.contains(node)) return;
- ClosureScopeBuilder translator = new ClosureScopeBuilder(_closureScopeMap,
- closuresToGenerate, _globalLocalsMap.getLocalsMap(entity), _elementMap);
- if (entity.isField) {
- if (node is ir.Field && node.initializer != null) {
- translator.translateLazyInitializer(node);
- }
- } else {
- assert(node is ir.Procedure || node is ir.Constructor);
- translator.translateConstructorOrProcedure(node);
- }
+ // TODO(efortuna): implement.
}
- /// Given what variables are captured at each point, construct closure classes
- /// with fields containing the captured variables to replicate the Dart
- /// closure semantics in JS.
- void _produceSyntheticElements(
- ir.Node node, ScopeInfo info, ClosedWorldRefiner closedWorldRefiner) {
- Entity entity;
- KernelClosureClass closureClass =
- new KernelClosureClass.fromScopeInfo(info);
- if (node is ir.FunctionNode) {
- // We want the original declaration where that function is used to point
- // to the correct closure class.
- // TODO(efortuna): entity equivalent of element.declaration?
- node = (node as ir.FunctionNode).parent;
- _closureRepresentationMap[closureClass.callMethod] = closureClass;
- }
-
- if (node is ir.Member) {
- entity = _elementMap.getMember(node);
- } else {
- entity = _elementMap.getLocalFunction(node);
- }
- assert(entity != null);
-
- _closureRepresentationMap[entity] = closureClass;
+ /// TODO(johnniwinther,efortuna): Implement this.
+ @override
+ ClosureScope getClosureScope(ir.Node node) {
+ return const ClosureScope();
}
@override
ScopeInfo getScopeInfo(Entity entity) {
+ // TODO(efortuna): Specialize this function from the one below.
return getClosureRepresentationInfo(entity);
}
+ /// TODO(johnniwinther,efortuna): Implement this.
@override
- // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null,
- // and we should just test that with an assert.
- ClosureScope getClosureScope(ir.Node node) =>
- _closureScopeMap[node] ?? const ClosureScope();
+ LoopClosureScope getLoopClosureScope(ir.Node loopNode) {
+ return const LoopClosureScope();
+ }
@override
- // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null,
- // and we should just test that with an assert.
- LoopClosureScope getLoopClosureScope(ir.Node loopNode) =>
- _closureScopeMap[node] ?? const LoopClosureScope();
+ ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) {
+ return _infoMap.putIfAbsent(entity, () {
+ if (entity is MemberEntity) {
+ ir.Member node = _elementMap.getMemberNode(entity);
+ ThisLocal thisLocal;
+ if (entity.isInstanceMember) {
+ thisLocal = new ThisLocal(entity);
+ }
+ KernelClosureDataBuilder builder = new KernelClosureDataBuilder(
+ _globalLocalsMap.getLocalsMap(entity), thisLocal);
+ node.accept(builder);
+ return builder.info;
+ }
- @override
- // TODO(efortuna): Eventually closureRepresentationMap[node] should always be
- // non-null, and we should just test that with an assert.
- ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) =>
- _closureRepresentationMap[entity] ?? const ClosureRepresentationInfo();
+ /// TODO(johnniwinther,efortuna): Implement this.
+ return const ClosureRepresentationInfo();
+ });
+ }
}
-class KernelScopeInfo extends ScopeInfo {
- final Set<Local> localsUsedInTryOrSync;
- final Local thisLocal;
- final Set<Local> boxedVariables = new Set<Local>();
-
- /// The set of variables that were defined in another scope, but are used in
- /// this scope.
- Set<ir.VariableDeclaration> freeVariables = new Set<ir.VariableDeclaration>();
+// TODO(johnniwinther): Add unittest for the computed
+// [ClosureRepresentationInfo].
+class KernelClosureRepresentationInfo extends ClosureRepresentationInfo {
+ final ThisLocal thisLocal;
+ final Set<Local> _localsUsedInTryOrSync = new Set<Local>();
- KernelScopeInfo(this.thisLocal) : localsUsedInTryOrSync = new Set<Local>();
+ KernelClosureRepresentationInfo(this.thisLocal);
- KernelScopeInfo.from(this.thisLocal, KernelScopeInfo info)
- : localsUsedInTryOrSync = info.variablesUsedInTryOrSync,
- boxedVariables = info.boxedVariables;
-
- KernelScopeInfo.withBoxedVariables(this.boxedVariables, this.thisLocal);
-
- void forEachBoxedVariable(f(Local local, FieldEntity field)) {
- boxedVariables.forEach((Local l) {
- // TODO(efortuna): add FieldEntities as created.
- f(l, null);
- });
+ void registerUsedInTryOrSync(Local local) {
+ _localsUsedInTryOrSync.add(local);
}
- bool localIsUsedInTryOrSync(Local variable) =>
- localsUsedInTryOrSync.contains(variable);
+ bool variableIsUsedInTryOrSync(Local variable) =>
+ _localsUsedInTryOrSync.contains(variable);
String toString() {
StringBuffer sb = new StringBuffer();
sb.write('this=$thisLocal,');
- sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}');
+ sb.write('localsUsedInTryOrSync={${_localsUsedInTryOrSync.join(', ')}}');
return sb.toString();
}
-
- bool isBoxed(Local variable) => boxedVariables.contains(variable);
-}
-
-class KernelClosureScope extends KernelScopeInfo implements ClosureScope {
- final Local context;
-
- KernelClosureScope(Set<Local> boxedVariables, this.context, Local thisLocal)
- : super.withBoxedVariables(boxedVariables, thisLocal);
-
- bool get requiresContextBox => boxedVariables.isNotEmpty;
-}
-
-class KernelLoopClosureScope extends KernelClosureScope
- implements LoopClosureScope {
- final List<Local> boxedLoopVariables;
-
- KernelLoopClosureScope(Set<Local> boxedVariables, this.boxedLoopVariables,
- Local context, Local thisLocal)
- : super(boxedVariables, context, thisLocal);
-
- bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
-}
-
-// TODO(johnniwinther): Add unittest for the computed [ClosureClass].
-class KernelClosureClass extends KernelScopeInfo
- implements ClosureRepresentationInfo {
- KernelClosureClass.fromScopeInfo(ScopeInfo info)
- : super.from(info.thisLocal, info);
-
- // TODO(efortuna): Implement.
- Local get closureEntity => null;
-
- // TODO(efortuna): Implement.
- ClassEntity get closureClassEntity => null;
-
- // TODO(efortuna): Implement.
- FunctionEntity get callMethod => null;
-
- // TODO(efortuna): Implement.
- List<Local> get createdFieldEntities => const <Local>[];
-
- // TODO(efortuna): Implement.
- FieldEntity get thisFieldEntity => null;
-
- // TODO(efortuna): Implement.
- void forEachCapturedVariable(f(Local from, FieldEntity to)) {}
-
- // TODO(efortuna): Implement.
- @override
- void forEachBoxedVariable(f(Local local, FieldEntity field)) {}
-
- // TODO(efortuna): Implement.
- void forEachFreeVariable(f(Local variable, FieldEntity field)) {}
-
- // TODO(efortuna): Implement.
- bool isVariableBoxed(Local variable) => false;
-
- // TODO(efortuna): Implement.
- // Why is this closure not actually a closure? Well, to properly call
- // ourselves a closure, we need to register the new closure class with the
- // ClosedWorldRefiner, which currently only takes elements. The change to
- // that (and the subsequent adjustment here) will follow soon.
- bool get isClosure => false;
}
« no previous file with comments | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/js_model/closure_visitors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698