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

Side by Side Diff: pkg/compiler/lib/src/js_model/closure.dart

Issue 2981673002: Register created closure class with the world. (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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../common/tasks.dart'; 8 import '../common/tasks.dart';
9 import '../elements/entities.dart'; 9 import '../elements/entities.dart';
10 import '../kernel/element_map.dart'; 10 import '../kernel/element_map.dart';
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 /// The combined steps of generating our intermediate representation of 48 /// The combined steps of generating our intermediate representation of
49 /// closures that need to be rewritten and generating the element model. 49 /// closures that need to be rewritten and generating the element model.
50 /// Ultimately these two steps will be split apart with the second step 50 /// Ultimately these two steps will be split apart with the second step
51 /// happening later in compilation just before codegen. These steps are 51 /// happening later in compilation just before codegen. These steps are
52 /// combined here currently to provide a consistent interface to the rest of 52 /// combined here currently to provide a consistent interface to the rest of
53 /// the compiler until we are ready to separate these phases. 53 /// the compiler until we are ready to separate these phases.
54 @override 54 @override
55 void convertClosures(Iterable<MemberEntity> processedEntities, 55 void convertClosures(Iterable<MemberEntity> processedEntities,
56 ClosedWorldRefiner closedWorldRefiner) { 56 ClosedWorldRefiner closedWorldRefiner) {
57 var closuresToGenerate = <ir.Node, ScopeInfo>{}; 57 var closuresToGenerate = <ir.TreeNode, ScopeInfo>{};
58 processedEntities.forEach((MemberEntity kEntity) { 58 processedEntities.forEach((MemberEntity kEntity) {
59 MemberEntity entity = kEntity; 59 MemberEntity entity = kEntity;
60 if (_kToJElementMap != null) { 60 if (_kToJElementMap != null) {
61 entity = _kToJElementMap.toBackendMember(kEntity); 61 entity = _kToJElementMap.toBackendMember(kEntity);
62 } 62 }
63 if (entity.isAbstract) return; 63 if (entity.isAbstract) return;
64 if (entity.isField && !entity.isInstanceMember) { 64 if (entity.isField && !entity.isInstanceMember) {
65 ir.Field field = _elementMap.getMemberNode(entity); 65 ir.Field field = _elementMap.getMemberNode(entity);
66 // Skip top-level/static fields without an initializer. 66 // Skip top-level/static fields without an initializer.
67 if (field.initializer == null) return; 67 if (field.initializer == null) return;
68 } 68 }
69 _buildClosureModel(entity, closuresToGenerate, closedWorldRefiner); 69 _buildClosureModel(entity, closuresToGenerate, closedWorldRefiner);
70 }); 70 });
71 71
72 for (ir.Node node in closuresToGenerate.keys) { 72 for (ir.TreeNode node in closuresToGenerate.keys) {
73 _produceSyntheticElements( 73 _produceSyntheticElements(
74 node, closuresToGenerate[node], closedWorldRefiner); 74 node, closuresToGenerate[node], closedWorldRefiner);
75 } 75 }
76 } 76 }
77 77
78 /// Inspect members and mark if those members capture any state that needs to 78 /// Inspect members and mark if those members capture any state that needs to
79 /// be marked as free variables. 79 /// be marked as free variables.
80 void _buildClosureModel( 80 void _buildClosureModel(
81 MemberEntity entity, 81 MemberEntity entity,
82 Map<ir.Node, ScopeInfo> closuresToGenerate, 82 Map<ir.TreeNode, ScopeInfo> closuresToGenerate,
83 ClosedWorldRefiner closedWorldRefiner) { 83 ClosedWorldRefiner closedWorldRefiner) {
84 ir.Node node = _elementMap.getMemberNode(entity); 84 ir.Node node = _elementMap.getMemberNode(entity);
85 if (_closureScopeMap.keys.contains(node)) return; 85 if (_closureScopeMap.keys.contains(node)) return;
86 ClosureScopeBuilder translator = new ClosureScopeBuilder(_closureScopeMap, 86 ClosureScopeBuilder translator = new ClosureScopeBuilder(_closureScopeMap,
87 closuresToGenerate, _globalLocalsMap.getLocalsMap(entity), _elementMap); 87 closuresToGenerate, _globalLocalsMap.getLocalsMap(entity), _elementMap);
88 if (entity.isField) { 88 if (entity.isField) {
89 if (node is ir.Field && node.initializer != null) { 89 if (node is ir.Field && node.initializer != null) {
90 translator.translateLazyInitializer(node); 90 translator.translateLazyInitializer(node);
91 } 91 }
92 } else { 92 } else {
93 assert(node is ir.Procedure || node is ir.Constructor); 93 assert(node is ir.Procedure || node is ir.Constructor);
94 translator.translateConstructorOrProcedure(node); 94 translator.translateConstructorOrProcedure(node);
95 } 95 }
96 } 96 }
97 97
98 /// Given what variables are captured at each point, construct closure classes 98 /// Given what variables are captured at each point, construct closure classes
99 /// with fields containing the captured variables to replicate the Dart 99 /// with fields containing the captured variables to replicate the Dart
100 /// closure semantics in JS. 100 /// closure semantics in JS.
101 void _produceSyntheticElements( 101 void _produceSyntheticElements(
102 ir.Node node, ScopeInfo info, ClosedWorldRefiner closedWorldRefiner) { 102 ir.TreeNode /* ir.Field | ir.FunctionNode */ node,
103 ScopeInfo info,
104 ClosedWorldRefiner closedWorldRefiner) {
103 Entity entity; 105 Entity entity;
104 KernelClosureClass closureClass = 106 KernelClosureClass closureClass =
105 new KernelClosureClass.fromScopeInfo(info); 107 new KernelClosureClass.fromScopeInfo(info);
106 if (node is ir.FunctionNode) { 108 if (node is ir.FunctionNode) {
107 // We want the original declaration where that function is used to point 109 // We want the original declaration where that function is used to point
108 // to the correct closure class. 110 // to the correct closure class.
109 // TODO(efortuna): entity equivalent of element.declaration? 111 // TODO(efortuna): entity equivalent of element.declaration?
110 node = (node as ir.FunctionNode).parent; 112 node = (node as ir.FunctionNode).parent;
111 _closureRepresentationMap[closureClass.callMethod] = closureClass; 113 _closureRepresentationMap[closureClass.callMethod] = closureClass;
112 } 114 }
113 115
114 if (node is ir.Member) { 116 if (node is ir.Member) {
115 entity = _elementMap.getMember(node); 117 entity = _elementMap.getMember(node);
116 } else { 118 } else {
117 entity = _elementMap.getLocalFunction(node); 119 entity = _elementMap.getLocalFunction(node);
118 } 120 }
119 assert(entity != null); 121 assert(entity != null);
120 122
121 _closureRepresentationMap[entity] = closureClass; 123 _closureRepresentationMap[entity] = closureClass;
124
125 // Register that a new class has been created.
126 closedWorldRefiner.registerClosureClass(
127 closureClass, node is ir.Member && node.isInstanceMember);
122 } 128 }
123 129
124 @override 130 @override
125 ScopeInfo getScopeInfo(Entity entity) { 131 ScopeInfo getScopeInfo(Entity entity) {
126 return getClosureRepresentationInfo(entity); 132 return getClosureRepresentationInfo(entity);
127 } 133 }
128 134
129 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, 135 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null,
130 // and we should just test that with an assert. 136 // and we should just test that with an assert.
131 ClosureScope _getClosureScope(ir.Node node) => 137 ClosureScope _getClosureScope(ir.Node node) =>
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 219
214 KernelLoopClosureScope(Set<Local> boxedVariables, this.boxedLoopVariables, 220 KernelLoopClosureScope(Set<Local> boxedVariables, this.boxedLoopVariables,
215 Local context, Local thisLocal) 221 Local context, Local thisLocal)
216 : super(boxedVariables, context, thisLocal); 222 : super(boxedVariables, context, thisLocal);
217 223
218 bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty; 224 bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
219 } 225 }
220 226
221 // TODO(johnniwinther): Add unittest for the computed [ClosureClass]. 227 // TODO(johnniwinther): Add unittest for the computed [ClosureClass].
222 class KernelClosureClass extends KernelScopeInfo 228 class KernelClosureClass extends KernelScopeInfo
223 implements ClosureRepresentationInfo { 229 implements ClosureRepresentationInfo, JClass {
224 KernelClosureClass.fromScopeInfo(ScopeInfo info) 230 // TODO(efortuna): Generate unique name for each closure class.
231 final String name = 'ClosureClass';
232
233 /// Index into the classData, classList and classEnvironment lists where this
234 /// entity is stored in [JsToFrontendMapImpl].
235 int classIndex;
236
237 final Map<Local, JField> localToFieldMap = new Map<Local, JField>();
238
239 KernelClosureClass.fromScopeInfo(KernelScopeInfo info)
225 : super.from(info.thisLocal, info); 240 : super.from(info.thisLocal, info);
226 241
227 // TODO(efortuna): Implement. 242 // TODO(efortuna): Implement.
228 Local get closureEntity => null; 243 Local get closureEntity => null;
229 244
230 // TODO(efortuna): Implement. 245 ClassEntity get closureClassEntity => this;
231 ClassEntity get closureClassEntity => null;
232 246
233 // TODO(efortuna): Implement. 247 // TODO(efortuna): Implement.
234 FunctionEntity get callMethod => null; 248 FunctionEntity get callMethod => null;
235 249
236 // TODO(efortuna): Implement. 250 // TODO(efortuna): Implement.
237 List<Local> get createdFieldEntities => const <Local>[]; 251 List<Local> get createdFieldEntities => const <Local>[];
238 252
239 // TODO(efortuna): Implement. 253 // TODO(efortuna): Implement.
240 FieldEntity get thisFieldEntity => null; 254 FieldEntity get thisFieldEntity => null;
241 255
242 // TODO(efortuna): Implement. 256 // TODO(efortuna): Implement.
243 void forEachCapturedVariable(f(Local from, FieldEntity to)) {} 257 void forEachCapturedVariable(f(Local from, FieldEntity to)) {}
244 258
245 // TODO(efortuna): Implement. 259 // TODO(efortuna): Implement.
246 @override 260 @override
247 void forEachBoxedVariable(f(Local local, FieldEntity field)) {} 261 void forEachBoxedVariable(f(Local local, FieldEntity field)) {}
248 262
249 // TODO(efortuna): Implement. 263 // TODO(efortuna): Implement.
250 void forEachFreeVariable(f(Local variable, FieldEntity field)) {} 264 void forEachFreeVariable(f(Local variable, FieldEntity field)) {}
251 265
252 // TODO(efortuna): Implement. 266 // TODO(efortuna): Implement.
253 bool isVariableBoxed(Local variable) => false; 267 bool isVariableBoxed(Local variable) => false;
254 268
255 // TODO(efortuna): Implement. 269 // TODO(efortuna): Implement.
256 // Why is this closure not actually a closure? Well, to properly call 270 // Why is this closure not actually a closure? Well, to properly call
257 // ourselves a closure, we need to register the new closure class with the 271 // ourselves a closure, we need to register the new closure class with the
258 // ClosedWorldRefiner, which currently only takes elements. The change to 272 // ClosedWorldRefiner, which currently only takes elements. The change to
259 // that (and the subsequent adjustment here) will follow soon. 273 // that (and the subsequent adjustment here) will follow soon.
260 bool get isClosure => false; 274 bool get isClosure => false;
275
276 bool get isAbstract => false;
277
278 // TODO(efortuna): Talk to Johnni.
279 JLibrary get library => null;
280
281 String toString() => '${jsElementPrefix}class($name)';
261 } 282 }
OLDNEW
« 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