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

Side by Side Diff: pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart

Issue 2377813002: kernel->ssa: implement for-in loops (Closed)
Patch Set: fix another import Created 4 years, 2 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 '../common.dart'; 7 import '../common.dart';
8 import '../common/names.dart'; 8 import '../common/names.dart';
9 import '../compiler.dart'; 9 import '../compiler.dart';
10 import '../constants/values.dart'; 10 import '../constants/values.dart';
11 import '../dart_types.dart'; 11 import '../dart_types.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../js_backend/js_backend.dart'; 13 import '../js_backend/js_backend.dart';
14 import '../kernel/kernel.dart'; 14 import '../kernel/kernel.dart';
15 import '../resolution/tree_elements.dart'; 15 import '../resolution/tree_elements.dart';
16 import '../tree/tree.dart' as ast; 16 import '../tree/tree.dart' as ast;
17 import '../types/masks.dart'; 17 import '../types/masks.dart';
18 import '../types/types.dart';
18 import '../universe/call_structure.dart'; 19 import '../universe/call_structure.dart';
19 import '../universe/selector.dart'; 20 import '../universe/selector.dart';
20 import '../universe/side_effects.dart'; 21 import '../universe/side_effects.dart';
22 import '../world.dart';
23 import 'locals_handler.dart';
21 import 'types.dart'; 24 import 'types.dart';
22 25
23 /// A helper class that abstracts all accesses of the AST from Kernel nodes. 26 /// A helper class that abstracts all accesses of the AST from Kernel nodes.
24 /// 27 ///
25 /// The goal is to remove all need for the AST from the Kernel SSA builder. 28 /// The goal is to remove all need for the AST from the Kernel SSA builder.
26 class KernelAstAdapter { 29 class KernelAstAdapter {
27 final Kernel kernel; 30 final Kernel kernel;
28 final JavaScriptBackend _backend; 31 final JavaScriptBackend _backend;
29 final ResolvedAst _resolvedAst; 32 final ResolvedAst _resolvedAst;
30 final Map<ir.Node, ast.Node> _nodeToAst; 33 final Map<ir.Node, ast.Node> _nodeToAst;
31 final Map<ir.Node, Element> _nodeToElement; 34 final Map<ir.Node, Element> _nodeToElement;
35 final Map<ir.VariableDeclaration, SyntheticLocal> _syntheticLocals =
36 <ir.VariableDeclaration, SyntheticLocal>{};
32 DartTypeConverter _typeConverter; 37 DartTypeConverter _typeConverter;
33 38
34 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst, 39 KernelAstAdapter(this.kernel, this._backend, this._resolvedAst,
35 this._nodeToAst, this._nodeToElement) { 40 this._nodeToAst, this._nodeToElement) {
36 // TODO(het): Maybe just use all of the kernel maps directly? 41 // TODO(het): Maybe just use all of the kernel maps directly?
37 for (FieldElement fieldElement in kernel.fields.keys) { 42 for (FieldElement fieldElement in kernel.fields.keys) {
38 _nodeToElement[kernel.fields[fieldElement]] = fieldElement; 43 _nodeToElement[kernel.fields[fieldElement]] = fieldElement;
39 } 44 }
40 for (FunctionElement functionElement in kernel.functions.keys) { 45 for (FunctionElement functionElement in kernel.functions.keys) {
41 _nodeToElement[kernel.functions[functionElement]] = functionElement; 46 _nodeToElement[kernel.functions[functionElement]] = functionElement;
42 } 47 }
43 for (ClassElement classElement in kernel.classes.keys) { 48 for (ClassElement classElement in kernel.classes.keys) {
44 _nodeToElement[kernel.classes[classElement]] = classElement; 49 _nodeToElement[kernel.classes[classElement]] = classElement;
45 } 50 }
46 for (LibraryElement libraryElement in kernel.libraries.keys) { 51 for (LibraryElement libraryElement in kernel.libraries.keys) {
47 _nodeToElement[kernel.libraries[libraryElement]] = libraryElement; 52 _nodeToElement[kernel.libraries[libraryElement]] = libraryElement;
48 } 53 }
49 for (LocalFunctionElement localFunction in kernel.localFunctions.keys) { 54 for (LocalFunctionElement localFunction in kernel.localFunctions.keys) {
50 _nodeToElement[kernel.localFunctions[localFunction]] = localFunction; 55 _nodeToElement[kernel.localFunctions[localFunction]] = localFunction;
51 } 56 }
52 _typeConverter = new DartTypeConverter(this); 57 _typeConverter = new DartTypeConverter(this);
53 } 58 }
54 59
55 Compiler get _compiler => _backend.compiler; 60 Compiler get _compiler => _backend.compiler;
56 TreeElements get elements => _resolvedAst.elements; 61 TreeElements get elements => _resolvedAst.elements;
62 GlobalTypeInferenceResults get _inferenceResults =>
63 _compiler.globalInference.results;
57 64
58 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) { 65 ConstantValue getConstantForSymbol(ir.SymbolLiteral node) {
59 ast.Node astNode = getNode(node); 66 ast.Node astNode = getNode(node);
60 ConstantValue constantValue = _backend.constants 67 ConstantValue constantValue = _backend.constants
61 .getConstantValueForNode(astNode, _resolvedAst.elements); 68 .getConstantValueForNode(astNode, _resolvedAst.elements);
62 assert(invariant(astNode, constantValue != null, 69 assert(invariant(astNode, constantValue != null,
63 message: 'No constant computed for $node')); 70 message: 'No constant computed for $node'));
64 return constantValue; 71 return constantValue;
65 } 72 }
66 73
67 Element getElement(ir.Node node) { 74 Element getElement(ir.Node node) {
68 Element result = _nodeToElement[node]; 75 Element result = _nodeToElement[node];
69 assert(result != null); 76 assert(result != null);
70 return result; 77 return result;
71 } 78 }
72 79
73 ast.Node getNode(ir.Node node) { 80 ast.Node getNode(ir.Node node) {
74 ast.Node result = _nodeToAst[node]; 81 ast.Node result = _nodeToAst[node];
75 assert(result != null); 82 assert(result != null);
76 return result; 83 return result;
77 } 84 }
78 85
86 Local getLocal(ir.VariableDeclaration variable) {
87 // If this is a synthetic local, return the synthetic local
88 if (variable.name == null) {
89 return _syntheticLocals.putIfAbsent(
90 variable, () => new SyntheticLocal("x", null));
91 }
92 return getElement(variable) as LocalElement;
93 }
94
79 bool getCanThrow(ir.Node procedure) { 95 bool getCanThrow(ir.Node procedure) {
80 FunctionElement function = getElement(procedure); 96 FunctionElement function = getElement(procedure);
81 return !_compiler.closedWorld.getCannotThrow(function); 97 return !_compiler.closedWorld.getCannotThrow(function);
82 } 98 }
83 99
84 TypeMask returnTypeOf(ir.Member node) { 100 TypeMask returnTypeOf(ir.Member node) {
85 return TypeMaskFactory.inferredReturnTypeForElement( 101 return TypeMaskFactory.inferredReturnTypeForElement(
86 getElement(node), _compiler); 102 getElement(node), _compiler);
87 } 103 }
88 104
89 SideEffects getSideEffects(ir.Node node) { 105 SideEffects getSideEffects(ir.Node node) {
90 return _compiler.closedWorld.getSideEffectsOfElement(getElement(node)); 106 return _compiler.closedWorld.getSideEffectsOfElement(getElement(node));
91 } 107 }
92 108
93 CallStructure getCallStructure(ir.Arguments arguments) { 109 CallStructure getCallStructure(ir.Arguments arguments) {
94 int argumentCount = arguments.positional.length + arguments.named.length; 110 int argumentCount = arguments.positional.length + arguments.named.length;
95 List<String> namedArguments = arguments.named.map((e) => e.name).toList(); 111 List<String> namedArguments = arguments.named.map((e) => e.name).toList();
96 return new CallStructure(argumentCount, namedArguments); 112 return new CallStructure(argumentCount, namedArguments);
97 } 113 }
98 114
99 Name getName(ir.Name name) { 115 Name getName(ir.Name name) {
100 return new Name( 116 return new Name(
101 name.name, name.isPrivate ? getElement(name.library) : null); 117 name.name, name.isPrivate ? getElement(name.library) : null);
102 } 118 }
103 119
104 // TODO(het): Create the selector directly from the invocation 120 Selector getSelector(ir.Expression node) {
105 Selector getSelector(ir.InvocationExpression invocation) { 121 if (node is ir.PropertyGet) return getGetterSelector(node);
122 if (node is ir.InvocationExpression) return getInvocationSelector(node);
123 _compiler.reporter.internalError(getNode(node),
124 "Can only get the selector for a property get or an invocation.");
125 return null;
126 }
127
128 Selector getInvocationSelector(ir.InvocationExpression invocation) {
106 Name name = getName(invocation.name); 129 Name name = getName(invocation.name);
107 SelectorKind kind; 130 SelectorKind kind;
108 if (Elements.isOperatorName(invocation.name.name)) { 131 if (Elements.isOperatorName(invocation.name.name)) {
109 if (name == Names.INDEX_NAME || name == Names.INDEX_SET_NAME) { 132 if (name == Names.INDEX_NAME || name == Names.INDEX_SET_NAME) {
110 kind = SelectorKind.INDEX; 133 kind = SelectorKind.INDEX;
111 } else { 134 } else {
112 kind = SelectorKind.OPERATOR; 135 kind = SelectorKind.OPERATOR;
113 } 136 }
114 } else { 137 } else {
115 kind = SelectorKind.CALL; 138 kind = SelectorKind.CALL;
116 } 139 }
117 140
118 CallStructure callStructure = getCallStructure(invocation.arguments); 141 CallStructure callStructure = getCallStructure(invocation.arguments);
119 return new Selector(kind, name, callStructure); 142 return new Selector(kind, name, callStructure);
120 } 143 }
121 144
122 Selector getGetterSelector(ir.PropertyGet getter) { 145 Selector getGetterSelector(ir.PropertyGet getter) {
123 ir.Name irName = getter.name; 146 ir.Name irName = getter.name;
124 Name name = new Name( 147 Name name = new Name(
125 irName.name, irName.isPrivate ? getElement(irName.library) : null); 148 irName.name, irName.isPrivate ? getElement(irName.library) : null);
126 return new Selector.getter(name); 149 return new Selector.getter(name);
127 } 150 }
128 151
129 TypeMask typeOfInvocation(ir.MethodInvocation invocation) { 152 TypeMask typeOfInvocation(ir.Expression send) {
130 return _compiler.globalInference.results 153 return _inferenceResults.typeOfSend(getNode(send), elements);
131 .typeOfSend(getNode(invocation), elements);
132 } 154 }
133 155
134 TypeMask typeOfGet(ir.PropertyGet getter) { 156 TypeMask typeOfGet(ir.PropertyGet getter) {
135 return _compiler.globalInference.results 157 return _inferenceResults.typeOfSend(getNode(getter), elements);
136 .typeOfSend(getNode(getter), elements); 158 }
159
160 TypeMask typeOfSend(ir.Expression send) {
161 assert(send is ir.InvocationExpression || send is ir.PropertyGet);
162 return _inferenceResults.typeOfSend(getNode(send), elements);
163 }
164
165 TypeMask typeOfNewList(Element owner, ir.ListLiteral listLiteral) {
166 return _inferenceResults.typeOfNewList(owner, getNode(listLiteral)) ??
167 _compiler.commonMasks.dynamicType;
168 }
169
170 TypeMask typeOfIterator(ir.ForInStatement forInStatement) {
171 return _inferenceResults.typeOfIterator(getNode(forInStatement), elements);
172 }
173
174 TypeMask typeOfIteratorCurrent(ir.ForInStatement forInStatement) {
175 return _inferenceResults.typeOfIteratorCurrent(
176 getNode(forInStatement), elements);
177 }
178
179 TypeMask typeOfIteratorMoveNext(ir.ForInStatement forInStatement) {
180 return _inferenceResults.typeOfIteratorMoveNext(
181 getNode(forInStatement), elements);
182 }
183
184 bool isJsIndexableIterator(ir.ForInStatement forInStatement) {
185 TypeMask mask = typeOfIterator(forInStatement);
186 ClosedWorld closedWorld = _compiler.closedWorld;
187 return mask != null &&
188 mask.satisfies(_backend.helpers.jsIndexableClass, closedWorld) &&
189 // String is indexable but not iterable.
190 !mask.satisfies(_backend.helpers.jsStringClass, closedWorld);
191 }
192
193 bool isFixedLength(TypeMask mask) {
194 ClosedWorld closedWorld = _compiler.closedWorld;
195 JavaScriptBackend backend = _compiler.backend;
196 if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
197 // A container on which we have inferred the length.
198 return true;
199 }
200 // TODO(sra): Recognize any combination of fixed length indexables.
201 if (mask.containsOnly(backend.helpers.jsFixedArrayClass) ||
202 mask.containsOnly(backend.helpers.jsUnmodifiableArrayClass) ||
203 mask.containsOnlyString(closedWorld) ||
204 backend.isTypedArray(mask)) {
205 return true;
206 }
207 return false;
208 }
209
210 TypeMask inferredIndexType(ir.ForInStatement forInStatement) {
211 return TypeMaskFactory.inferredTypeForSelector(
212 new Selector.index(), typeOfIterator(forInStatement), _compiler);
137 } 213 }
138 214
139 TypeMask inferredTypeOf(ir.Member node) { 215 TypeMask inferredTypeOf(ir.Member node) {
140 return TypeMaskFactory.inferredTypeForElement(getElement(node), _compiler); 216 return TypeMaskFactory.inferredTypeForElement(getElement(node), _compiler);
141 } 217 }
142 218
143 TypeMask selectorTypeOf(ir.MethodInvocation invocation) { 219 TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
144 return TypeMaskFactory.inferredTypeForSelector( 220 return TypeMaskFactory.inferredTypeForSelector(selector, mask, _compiler);
145 getSelector(invocation), typeOfInvocation(invocation), _compiler);
146 }
147
148 TypeMask selectorGetterTypeOf(ir.PropertyGet getter) {
149 return TypeMaskFactory.inferredTypeForSelector(
150 getGetterSelector(getter), typeOfGet(getter), _compiler);
151 } 221 }
152 222
153 ConstantValue getConstantFor(ir.Node node) { 223 ConstantValue getConstantFor(ir.Node node) {
154 ConstantValue constantValue = 224 ConstantValue constantValue =
155 _backend.constants.getConstantValueForNode(getNode(node), elements); 225 _backend.constants.getConstantValueForNode(getNode(node), elements);
156 assert(invariant(getNode(node), constantValue != null, 226 assert(invariant(getNode(node), constantValue != null,
157 message: 'No constant computed for $node')); 227 message: 'No constant computed for $node'));
158 return constantValue; 228 return constantValue;
159 } 229 }
160 230
161 bool isIntercepted(ir.Node node) { 231 bool isIntercepted(ir.Node node) {
162 Selector selector; 232 Selector selector = getSelector(node);
163 if (node is ir.PropertyGet) {
164 selector = getGetterSelector(node);
165 } else {
166 selector = getSelector(node);
167 }
168 return _backend.isInterceptedSelector(selector); 233 return _backend.isInterceptedSelector(selector);
169 } 234 }
170 235
236 bool isInterceptedSelector(Selector selector) {
237 return _backend.isInterceptedSelector(selector);
238 }
239
171 JumpTarget getTargetDefinition(ir.Node node) => 240 JumpTarget getTargetDefinition(ir.Node node) =>
172 elements.getTargetDefinition(getNode(node)); 241 elements.getTargetDefinition(getNode(node));
173 242
174 ir.Procedure get mapLiteralConstructor => 243 ir.Procedure get mapLiteralConstructor =>
175 kernel.functions[_backend.helpers.mapLiteralConstructor]; 244 kernel.functions[_backend.helpers.mapLiteralConstructor];
176 245
177 ir.Procedure get mapLiteralConstructorEmpty => 246 ir.Procedure get mapLiteralConstructorEmpty =>
178 kernel.functions[_backend.helpers.mapLiteralConstructorEmpty]; 247 kernel.functions[_backend.helpers.mapLiteralConstructorEmpty];
179 248
249 Element get jsIndexableLength => _backend.helpers.jsIndexableLength;
250
251 ir.Procedure get checkConcurrentModificationError =>
252 kernel.functions[_backend.helpers.checkConcurrentModificationError];
253
254 TypeMask get checkConcurrentModificationErrorReturnType =>
255 TypeMaskFactory.inferredReturnTypeForElement(
256 _backend.helpers.checkConcurrentModificationError, _compiler);
257
180 DartType getDartType(ir.DartType type) { 258 DartType getDartType(ir.DartType type) {
181 return type.accept(_typeConverter); 259 return type.accept(_typeConverter);
182 } 260 }
183 261
184 List<DartType> getDartTypes(List<ir.DartType> types) { 262 List<DartType> getDartTypes(List<ir.DartType> types) {
185 return types.map(getDartType).toList(); 263 return types.map(getDartType).toList();
186 } 264 }
187 } 265 }
188 266
189 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { 267 class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 @override 309 @override
232 DartType visitDynamicType(ir.DynamicType node) { 310 DartType visitDynamicType(ir.DynamicType node) {
233 return const DynamicType(); 311 return const DynamicType();
234 } 312 }
235 313
236 @override 314 @override
237 DartType visitInvalidType(ir.InvalidType node) { 315 DartType visitInvalidType(ir.InvalidType node) {
238 throw new UnimplementedError("Invalid types not currently supported"); 316 throw new UnimplementedError("Invalid types not currently supported");
239 } 317 }
240 } 318 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/builder_kernel.dart ('k') | pkg/compiler/lib/src/ssa/locals_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698