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

Side by Side Diff: pkg/compiler/lib/src/inferrer/builder_kernel.dart

Issue 3008133002: Handle local invoke in inferrer (Closed)
Patch Set: dartfmt Created 3 years, 3 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
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.dart'; 8 import '../common.dart';
9 import '../constants/constant_system.dart'; 9 import '../constants/constant_system.dart';
10 import '../elements/entities.dart'; 10 import '../elements/entities.dart';
11 import '../elements/types.dart'; 11 import '../elements/types.dart';
12 import '../kernel/element_map.dart'; 12 import '../kernel/element_map.dart';
13 import '../options.dart'; 13 import '../options.dart';
14 import '../types/constants.dart'; 14 import '../types/constants.dart';
15 import '../types/types.dart';
16 import '../universe/selector.dart';
17 import '../universe/side_effects.dart';
15 import '../world.dart'; 18 import '../world.dart';
16 import 'inferrer_engine.dart'; 19 import 'inferrer_engine.dart';
17 import 'locals_handler.dart'; 20 import 'locals_handler.dart';
18 import 'type_graph_nodes.dart'; 21 import 'type_graph_nodes.dart';
19 import 'type_system.dart'; 22 import 'type_system.dart';
20 23
21 /// [KernelTypeGraphBuilder] constructs a type-inference graph for a particular 24 /// [KernelTypeGraphBuilder] constructs a type-inference graph for a particular
22 /// element. 25 /// element.
23 /// 26 ///
24 /// Calling [run] will start the work of visiting the body of the code to 27 /// Calling [run] will start the work of visiting the body of the code to
25 /// construct a set of inference-nodes that abstractly represent what the code 28 /// construct a set of inference-nodes that abstractly represent what the code
26 /// is doing. 29 /// is doing.
27 class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> { 30 class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
28 final CompilerOptions _options; 31 final CompilerOptions _options;
29 final ClosedWorld _closedWorld; 32 final ClosedWorld _closedWorld;
30 final ClosureDataLookup<ir.Node> _closureDataLookup; 33 final ClosureDataLookup<ir.Node> _closureDataLookup;
31 final InferrerEngine<ir.Node> _inferrer; 34 final InferrerEngine<ir.Node> _inferrer;
32 final TypeSystem<ir.Node> _types; 35 final TypeSystem<ir.Node> _types;
33 final MemberEntity _analyzedMember; 36 final MemberEntity _analyzedMember;
34 final ir.Node _analyzedNode; 37 final ir.Node _analyzedNode;
35 final KernelToElementMapForBuilding _elementMap; 38 final KernelToElementMapForBuilding _elementMap;
36 final KernelToLocalsMap _localsMap; 39 final KernelToLocalsMap _localsMap;
37 LocalsHandler _locals; 40 LocalsHandler _locals;
41 final GlobalTypeInferenceElementData<ir.Node> _memberData;
42 SideEffects _sideEffects = new SideEffects.empty();
38 43
39 TypeInformation _returnType; 44 TypeInformation _returnType;
40 45
41 KernelTypeGraphBuilder( 46 KernelTypeGraphBuilder(
42 this._options, 47 this._options,
43 this._closedWorld, 48 this._closedWorld,
44 this._closureDataLookup, 49 this._closureDataLookup,
45 this._inferrer, 50 this._inferrer,
46 this._analyzedMember, 51 this._analyzedMember,
47 this._analyzedNode, 52 this._analyzedNode,
48 this._elementMap, 53 this._elementMap,
49 this._localsMap, 54 this._localsMap,
50 [this._locals]) 55 [this._locals])
51 : this._types = _inferrer.types { 56 : this._types = _inferrer.types,
57 this._memberData = _inferrer.dataOfMember(_analyzedMember) {
52 if (_locals != null) return; 58 if (_locals != null) return;
53 59
54 FieldInitializationScope<ir.Node> fieldScope = 60 FieldInitializationScope<ir.Node> fieldScope =
55 _analyzedNode is ir.Constructor 61 _analyzedNode is ir.Constructor
56 ? new FieldInitializationScope(_types) 62 ? new FieldInitializationScope(_types)
57 : null; 63 : null;
58 _locals = new LocalsHandler( 64 _locals = new LocalsHandler(
59 _inferrer, _types, _options, _analyzedNode, fieldScope); 65 _inferrer, _types, _options, _analyzedNode, fieldScope);
60 } 66 }
61 67
68 int _loopLevel = 0;
69
70 bool get inLoop => _loopLevel > 0;
71
62 TypeInformation run() { 72 TypeInformation run() {
63 if (_analyzedMember.isField) { 73 if (_analyzedMember.isField) {
64 if (_analyzedNode == null || _analyzedNode is ir.NullLiteral) { 74 if (_analyzedNode == null || _analyzedNode is ir.NullLiteral) {
65 // Eagerly bailout, because computing the closure data only 75 // Eagerly bailout, because computing the closure data only
66 // works for functions and field assignments. 76 // works for functions and field assignments.
67 return _types.nullType; 77 return _types.nullType;
68 } 78 }
69 } 79 }
70 80
71 // Update the locals that are boxed in [locals]. These locals will 81 // Update the locals that are boxed in [locals]. These locals will
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 257 }
248 258
249 @override 259 @override
250 TypeInformation visitVariableSet(ir.VariableSet node) { 260 TypeInformation visitVariableSet(ir.VariableSet node) {
251 Local local = _localsMap.getLocalVariable(node.variable); 261 Local local = _localsMap.getLocalVariable(node.variable);
252 DartType type = _localsMap.getLocalType(_elementMap, local); 262 DartType type = _localsMap.getLocalType(_elementMap, local);
253 TypeInformation rhsType = visit(node.value); 263 TypeInformation rhsType = visit(node.value);
254 _locals.update(local, rhsType, node, type); 264 _locals.update(local, rhsType, node, type);
255 return rhsType; 265 return rhsType;
256 } 266 }
267
268 ArgumentsTypes analyzeArguments(ir.Arguments arguments) {
269 List<TypeInformation> positional = <TypeInformation>[];
270 Map<String, TypeInformation> named;
271 for (ir.Expression argument in arguments.positional) {
272 positional.add(argument.accept(this));
273 }
274 for (ir.NamedExpression argument in arguments.named) {
275 named ??= <String, TypeInformation>{};
276 named[argument.name] = argument.value.accept(this);
277 }
278
279 /// TODO(johnniwinther): Track `isThisExposed`.
280 return new ArgumentsTypes(positional, named);
281 }
282
283 @override
284 TypeInformation visitMethodInvocation(ir.MethodInvocation node) {
285 TypeInformation receiverType = visit(node.receiver);
286 Selector selector = _elementMap.getSelector(node);
287 TypeMask mask = _memberData.typeOfSend(node);
288
289 ArgumentsTypes arguments = analyzeArguments(node.arguments);
290 if (selector.name == '==' || selector.name == '!=') {
291 if (_types.isNull(receiverType)) {
292 // TODO(johnniwinther): Add null check.
293 return _types.boolType;
294 } else if (_types.isNull(arguments.positional[0])) {
295 // TODO(johnniwinther): Add null check.
296 return _types.boolType;
297 }
298 }
299 return handleDynamicInvoke(
300 CallType.access, node, selector, mask, receiverType, arguments);
301 }
302
303 TypeInformation handleDynamicInvoke(
304 CallType callType,
305 ir.Node node,
306 Selector selector,
307 TypeMask mask,
308 TypeInformation receiverType,
309 ArgumentsTypes arguments) {
310 assert(receiverType != null);
311 if (_types.selectorNeedsUpdate(receiverType, mask)) {
312 mask = receiverType == _types.dynamicType
313 ? null
314 : _types.newTypedSelector(receiverType, mask);
315 _inferrer.updateSelectorInMember(
316 _analyzedMember, callType, node, selector, mask);
317 }
318
319 // TODO(johnniwinther): Refine receiver on non-captured locals.
320
321 return _inferrer.registerCalledSelector(callType, node, selector, mask,
322 receiverType, _analyzedMember, arguments, _sideEffects,
323 inLoop: inLoop, isConditional: false);
324 }
257 } 325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698