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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 266913017: Convert property methods into getters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to implement [TypedElement.type] because our 9 * methods. We need to implement [TypedElement.type] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 29 matching lines...) Expand all
40 HGraph graph; 40 HGraph graph;
41 ElementKind kind = element.kind; 41 ElementKind kind = element.kind;
42 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 42 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
43 graph = compileConstructor(builder, work); 43 graph = compileConstructor(builder, work);
44 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 44 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
45 kind == ElementKind.FUNCTION || 45 kind == ElementKind.FUNCTION ||
46 kind == ElementKind.GETTER || 46 kind == ElementKind.GETTER ||
47 kind == ElementKind.SETTER) { 47 kind == ElementKind.SETTER) {
48 graph = builder.buildMethod(element); 48 graph = builder.buildMethod(element);
49 } else if (kind == ElementKind.FIELD) { 49 } else if (kind == ElementKind.FIELD) {
50 if (element.isInstanceMember()) { 50 if (element.isInstanceMember) {
51 assert(compiler.enableTypeAssertions); 51 assert(compiler.enableTypeAssertions);
52 graph = builder.buildCheckedSetter(element); 52 graph = builder.buildCheckedSetter(element);
53 } else { 53 } else {
54 graph = builder.buildLazyInitializer(element); 54 graph = builder.buildLazyInitializer(element);
55 } 55 }
56 } else { 56 } else {
57 compiler.internalError(element, 'Unexpected element kind $kind.'); 57 compiler.internalError(element, 'Unexpected element kind $kind.');
58 } 58 }
59 assert(graph.isValid()); 59 assert(graph.isValid());
60 if (!identical(kind, ElementKind.FIELD)) { 60 if (!identical(kind, ElementKind.FIELD)) {
61 FunctionElement function = element; 61 FunctionElement function = element;
62 FunctionSignature signature = function.functionSignature; 62 FunctionSignature signature = function.functionSignature;
63 signature.forEachOptionalParameter((Element parameter) { 63 signature.forEachOptionalParameter((Element parameter) {
64 // This ensures the default value will be computed. 64 // This ensures the default value will be computed.
65 Constant constant = 65 Constant constant =
66 backend.constants.getConstantForVariable(parameter); 66 backend.constants.getConstantForVariable(parameter);
67 backend.registerCompileTimeConstant(constant, work.resolutionTree); 67 backend.registerCompileTimeConstant(constant, work.resolutionTree);
68 backend.constants.addCompileTimeConstantForEmission(constant); 68 backend.constants.addCompileTimeConstantForEmission(constant);
69 }); 69 });
70 } 70 }
71 if (compiler.tracer.enabled) { 71 if (compiler.tracer.enabled) {
72 String name; 72 String name;
73 if (element.isMember()) { 73 if (element.isMember) {
74 String className = element.getEnclosingClass().name; 74 String className = element.enclosingClass.name;
75 String memberName = element.name; 75 String memberName = element.name;
76 name = "$className.$memberName"; 76 name = "$className.$memberName";
77 if (element.isGenerativeConstructorBody()) { 77 if (element.isGenerativeConstructorBody) {
78 name = "$name (body)"; 78 name = "$name (body)";
79 } 79 }
80 } else { 80 } else {
81 name = "${element.name}"; 81 name = "${element.name}";
82 } 82 }
83 compiler.tracer.traceCompilation( 83 compiler.tracer.traceCompilation(
84 name, work.compilationContext, compiler); 84 name, work.compilationContext, compiler);
85 compiler.tracer.traceGraph('builder', graph); 85 compiler.tracer.traceGraph('builder', graph);
86 } 86 }
87 return graph; 87 return graph;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 * If the scope (function or loop) [node] has captured variables then this 157 * If the scope (function or loop) [node] has captured variables then this
158 * method creates a box and sets up the redirections. 158 * method creates a box and sets up the redirections.
159 */ 159 */
160 void enterScope(ast.Node node, Element element) { 160 void enterScope(ast.Node node, Element element) {
161 // See if any variable in the top-scope of the function is captured. If yes 161 // See if any variable in the top-scope of the function is captured. If yes
162 // we need to create a box-object. 162 // we need to create a box-object.
163 ClosureScope scopeData = closureData.capturingScopes[node]; 163 ClosureScope scopeData = closureData.capturingScopes[node];
164 if (scopeData == null) return; 164 if (scopeData == null) return;
165 HInstruction box; 165 HInstruction box;
166 // The scope has captured variables. 166 // The scope has captured variables.
167 if (element != null && element.isGenerativeConstructorBody()) { 167 if (element != null && element.isGenerativeConstructorBody) {
168 // The box is passed as a parameter to a generative 168 // The box is passed as a parameter to a generative
169 // constructor body. 169 // constructor body.
170 JavaScriptBackend backend = builder.backend; 170 JavaScriptBackend backend = builder.backend;
171 box = builder.addParameter(scopeData.boxElement, backend.nonNullType); 171 box = builder.addParameter(scopeData.boxElement, backend.nonNullType);
172 } else { 172 } else {
173 box = createBox(); 173 box = createBox();
174 } 174 }
175 // Add the box to the known locals. 175 // Add the box to the known locals.
176 directLocals[scopeData.boxElement] = box; 176 directLocals[scopeData.boxElement] = box;
177 // Make sure that accesses to the boxed locals go into the box. We also 177 // Make sure that accesses to the boxed locals go into the box. We also
178 // need to make sure that parameters are copied into the box if necessary. 178 // need to make sure that parameters are copied into the box if necessary.
179 scopeData.capturedVariableMapping.forEach((Element from, Element to) { 179 scopeData.capturedVariableMapping.forEach((Element from, Element to) {
180 // The [from] can only be a parameter for function-scopes and not 180 // The [from] can only be a parameter for function-scopes and not
181 // loop scopes. 181 // loop scopes.
182 if (from.isParameter() && !element.isGenerativeConstructorBody()) { 182 if (from.isParameter && !element.isGenerativeConstructorBody) {
183 // Now that the redirection is set up, the update to the local will 183 // Now that the redirection is set up, the update to the local will
184 // write the parameter value into the box. 184 // write the parameter value into the box.
185 // Store the captured parameter in the box. Get the current value 185 // Store the captured parameter in the box. Get the current value
186 // before we put the redirection in place. 186 // before we put the redirection in place.
187 // We don't need to update the local for a generative 187 // We don't need to update the local for a generative
188 // constructor body, because it receives a box that already 188 // constructor body, because it receives a box that already
189 // contains the updates as the last parameter. 189 // contains the updates as the last parameter.
190 HInstruction instruction = readLocal(from); 190 HInstruction instruction = readLocal(from);
191 redirectElement(from, to); 191 redirectElement(from, to);
192 updateLocal(from, instruction); 192 updateLocal(from, instruction);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 void startFunction(Element element, ast.Node node) { 224 void startFunction(Element element, ast.Node node) {
225 assert(invariant(element, element.isImplementation)); 225 assert(invariant(element, element.isImplementation));
226 Compiler compiler = builder.compiler; 226 Compiler compiler = builder.compiler;
227 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 227 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
228 element, node, builder.elements); 228 element, node, builder.elements);
229 229
230 if (element is FunctionElement) { 230 if (element is FunctionElement) {
231 FunctionElement functionElement = element; 231 FunctionElement functionElement = element;
232 FunctionSignature params = functionElement.functionSignature; 232 FunctionSignature params = functionElement.functionSignature;
233 params.orderedForEachParameter((Element parameterElement) { 233 params.orderedForEachParameter((Element parameterElement) {
234 if (element.isGenerativeConstructorBody()) { 234 if (element.isGenerativeConstructorBody) {
235 ClosureScope scopeData = closureData.capturingScopes[node]; 235 ClosureScope scopeData = closureData.capturingScopes[node];
236 if (scopeData != null 236 if (scopeData != null
237 && scopeData.capturedVariableMapping.containsKey( 237 && scopeData.capturedVariableMapping.containsKey(
238 parameterElement)) { 238 parameterElement)) {
239 // The parameter will be a field in the box passed as the 239 // The parameter will be a field in the box passed as the
240 // last parameter. So no need to have it. 240 // last parameter. So no need to have it.
241 return; 241 return;
242 } 242 }
243 } 243 }
244 HInstruction parameter = builder.addParameter( 244 HInstruction parameter = builder.addParameter(
245 parameterElement, 245 parameterElement,
246 TypeMaskFactory.inferredTypeForElement(parameterElement, compiler)); 246 TypeMaskFactory.inferredTypeForElement(parameterElement, compiler));
247 builder.parameters[parameterElement] = parameter; 247 builder.parameters[parameterElement] = parameter;
248 directLocals[parameterElement] = parameter; 248 directLocals[parameterElement] = parameter;
249 }); 249 });
250 } 250 }
251 251
252 enterScope(node, element); 252 enterScope(node, element);
253 253
254 // If the freeVariableMapping is not empty, then this function was a 254 // If the freeVariableMapping is not empty, then this function was a
255 // nested closure that captures variables. Redirect the captured 255 // nested closure that captures variables. Redirect the captured
256 // variables to fields in the closure. 256 // variables to fields in the closure.
257 closureData.freeVariableMapping.forEach((Element from, Element to) { 257 closureData.freeVariableMapping.forEach((Element from, Element to) {
258 redirectElement(from, to); 258 redirectElement(from, to);
259 }); 259 });
260 JavaScriptBackend backend = compiler.backend; 260 JavaScriptBackend backend = compiler.backend;
261 if (closureData.isClosure()) { 261 if (closureData.isClosure) {
262 // Inside closure redirect references to itself to [:this:]. 262 // Inside closure redirect references to itself to [:this:].
263 HThis thisInstruction = new HThis(closureData.thisElement, 263 HThis thisInstruction = new HThis(closureData.thisElement,
264 backend.nonNullType); 264 backend.nonNullType);
265 builder.graph.thisInstruction = thisInstruction; 265 builder.graph.thisInstruction = thisInstruction;
266 builder.graph.entry.addAtEntry(thisInstruction); 266 builder.graph.entry.addAtEntry(thisInstruction);
267 updateLocal(closureData.closureElement, thisInstruction); 267 updateLocal(closureData.closureElement, thisInstruction);
268 } else if (element.isInstanceMember()) { 268 } else if (element.isInstanceMember) {
269 // Once closures have been mapped to classes their instance members might 269 // Once closures have been mapped to classes their instance members might
270 // not have any thisElement if the closure was created inside a static 270 // not have any thisElement if the closure was created inside a static
271 // context. 271 // context.
272 HThis thisInstruction = new HThis( 272 HThis thisInstruction = new HThis(
273 closureData.thisElement, builder.getTypeOfThis()); 273 closureData.thisElement, builder.getTypeOfThis());
274 builder.graph.thisInstruction = thisInstruction; 274 builder.graph.thisInstruction = thisInstruction;
275 builder.graph.entry.addAtEntry(thisInstruction); 275 builder.graph.entry.addAtEntry(thisInstruction);
276 directLocals[closureData.thisElement] = thisInstruction; 276 directLocals[closureData.thisElement] = thisInstruction;
277 } 277 }
278 278
279 // If this method is an intercepted method, add the extra 279 // If this method is an intercepted method, add the extra
280 // parameter to it, that is the actual receiver for intercepted 280 // parameter to it, that is the actual receiver for intercepted
281 // classes, or the same as [:this:] for non-intercepted classes. 281 // classes, or the same as [:this:] for non-intercepted classes.
282 ClassElement cls = element.getEnclosingClass(); 282 ClassElement cls = element.enclosingClass;
283 283
284 // When the class extends a native class, the instance is pre-constructed 284 // When the class extends a native class, the instance is pre-constructed
285 // and passed to the generative constructor factory function as a parameter. 285 // and passed to the generative constructor factory function as a parameter.
286 // Instead of allocating and initializing the object, the constructor 286 // Instead of allocating and initializing the object, the constructor
287 // 'upgrades' the native subclass object by initializing the Dart fields. 287 // 'upgrades' the native subclass object by initializing the Dart fields.
288 bool isNativeUpgradeFactory = element.isGenerativeConstructor() 288 bool isNativeUpgradeFactory = element.isGenerativeConstructor
289 && Elements.isNativeOrExtendsNative(cls); 289 && Elements.isNativeOrExtendsNative(cls);
290 if (backend.isInterceptedMethod(element)) { 290 if (backend.isInterceptedMethod(element)) {
291 bool isInterceptorClass = backend.isInterceptorClass(cls.declaration); 291 bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
292 String name = isInterceptorClass ? 'receiver' : '_'; 292 String name = isInterceptorClass ? 'receiver' : '_';
293 Element parameter = new InterceptedElement( 293 Element parameter = new InterceptedElement(
294 cls.thisType, name, element); 294 cls.thisType, name, element);
295 HParameterValue value = 295 HParameterValue value =
296 new HParameterValue(parameter, builder.getTypeOfThis()); 296 new HParameterValue(parameter, builder.getTypeOfThis());
297 builder.graph.explicitReceiverParameter = value; 297 builder.graph.explicitReceiverParameter = value;
298 builder.graph.entry.addAfter( 298 builder.graph.entry.addAfter(
(...skipping 22 matching lines...) Expand all
321 assert(element != null); 321 assert(element != null);
322 return redirectionMapping[element] == null 322 return redirectionMapping[element] == null
323 && !closureData.usedVariablesInTry.contains(element); 323 && !closureData.usedVariablesInTry.contains(element);
324 } 324 }
325 325
326 bool isStoredInClosureField(Element element) { 326 bool isStoredInClosureField(Element element) {
327 assert(element != null); 327 assert(element != null);
328 if (isAccessedDirectly(element)) return false; 328 if (isAccessedDirectly(element)) return false;
329 Element redirectTarget = redirectionMapping[element]; 329 Element redirectTarget = redirectionMapping[element];
330 if (redirectTarget == null) return false; 330 if (redirectTarget == null) return false;
331 if (redirectTarget.isMember()) { 331 if (redirectTarget.isMember) {
332 assert(redirectTarget is ClosureFieldElement); 332 assert(redirectTarget is ClosureFieldElement);
333 return true; 333 return true;
334 } 334 }
335 return false; 335 return false;
336 } 336 }
337 337
338 bool isBoxed(Element element) { 338 bool isBoxed(Element element) {
339 if (isAccessedDirectly(element)) return false; 339 if (isAccessedDirectly(element)) return false;
340 if (isStoredInClosureField(element)) return false; 340 if (isStoredInClosureField(element)) return false;
341 return redirectionMapping[element] != null; 341 return redirectionMapping[element] != null;
342 } 342 }
343 343
344 bool isUsedInTry(Element element) { 344 bool isUsedInTry(Element element) {
345 return closureData.usedVariablesInTry.contains(element); 345 return closureData.usedVariablesInTry.contains(element);
346 } 346 }
347 347
348 /** 348 /**
349 * Returns an [HInstruction] for the given element. If the element is 349 * Returns an [HInstruction] for the given element. If the element is
350 * boxed or stored in a closure then the method generates code to retrieve 350 * boxed or stored in a closure then the method generates code to retrieve
351 * the value. 351 * the value.
352 */ 352 */
353 HInstruction readLocal(Element element) { 353 HInstruction readLocal(Element element) {
354 if (isAccessedDirectly(element)) { 354 if (isAccessedDirectly(element)) {
355 if (directLocals[element] == null) { 355 if (directLocals[element] == null) {
356 if (element.isTypeVariable()) { 356 if (element.isTypeVariable) {
357 builder.compiler.internalError(builder.compiler.currentElement, 357 builder.compiler.internalError(builder.compiler.currentElement,
358 "Runtime type information not available for $element."); 358 "Runtime type information not available for $element.");
359 } else { 359 } else {
360 builder.compiler.internalError(element, 360 builder.compiler.internalError(element,
361 "Cannot find value $element."); 361 "Cannot find value $element.");
362 } 362 }
363 } 363 }
364 return directLocals[element]; 364 return directLocals[element];
365 } else if (isStoredInClosureField(element)) { 365 } else if (isStoredInClosureField(element)) {
366 Element redirect = redirectionMapping[element]; 366 Element redirect = redirectionMapping[element];
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 403 }
404 return res; 404 return res;
405 } 405 }
406 406
407 HLocalValue getLocal(Element element) { 407 HLocalValue getLocal(Element element) {
408 // If the element is a parameter, we already have a 408 // If the element is a parameter, we already have a
409 // HParameterValue for it. We cannot create another one because 409 // HParameterValue for it. We cannot create another one because
410 // it could then have another name than the real parameter. And 410 // it could then have another name than the real parameter. And
411 // the other one would not know it is just a copy of the real 411 // the other one would not know it is just a copy of the real
412 // parameter. 412 // parameter.
413 if (element.isParameter()) return builder.parameters[element]; 413 if (element.isParameter) return builder.parameters[element];
414 414
415 return builder.activationVariables.putIfAbsent(element, () { 415 return builder.activationVariables.putIfAbsent(element, () {
416 JavaScriptBackend backend = builder.backend; 416 JavaScriptBackend backend = builder.backend;
417 HLocalValue local = new HLocalValue(element, backend.nonNullType); 417 HLocalValue local = new HLocalValue(element, backend.nonNullType);
418 builder.graph.entry.addAtExit(local); 418 builder.graph.entry.addAtExit(local);
419 return local; 419 return local;
420 }); 420 });
421 } 421 }
422 422
423 /** 423 /**
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 add(attachPosition(instruction, node)); 1031 add(attachPosition(instruction, node));
1032 } 1032 }
1033 1033
1034 SourceFile currentSourceFile() { 1034 SourceFile currentSourceFile() {
1035 Element element = sourceElement; 1035 Element element = sourceElement;
1036 // TODO(johnniwinther): remove the 'element.patch' hack. 1036 // TODO(johnniwinther): remove the 'element.patch' hack.
1037 if (element is FunctionElement) { 1037 if (element is FunctionElement) {
1038 FunctionElement functionElement = element; 1038 FunctionElement functionElement = element;
1039 if (functionElement.patch != null) element = functionElement.patch; 1039 if (functionElement.patch != null) element = functionElement.patch;
1040 } 1040 }
1041 Script script = element.getCompilationUnit().script; 1041 Script script = element.compilationUnit.script;
1042 return script.file; 1042 return script.file;
1043 } 1043 }
1044 1044
1045 void checkValidSourceFileLocation( 1045 void checkValidSourceFileLocation(
1046 SourceFileLocation location, SourceFile sourceFile, int offset) { 1046 SourceFileLocation location, SourceFile sourceFile, int offset) {
1047 if (!location.isValid()) { 1047 if (!location.isValid()) {
1048 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message( 1048 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
1049 {'offset': offset, 1049 {'offset': offset,
1050 'fileName': sourceFile.filename, 1050 'fileName': sourceFile.filename,
1051 'length': sourceFile.length}); 1051 'length': sourceFile.length});
1052 } 1052 }
1053 } 1053 }
1054 1054
1055 /** 1055 /**
1056 * Returns a complete argument list for a call of [function]. 1056 * Returns a complete argument list for a call of [function].
1057 */ 1057 */
1058 List<HInstruction> completeSendArgumentsList( 1058 List<HInstruction> completeSendArgumentsList(
1059 FunctionElement function, 1059 FunctionElement function,
1060 Selector selector, 1060 Selector selector,
1061 List<HInstruction> providedArguments, 1061 List<HInstruction> providedArguments,
1062 ast.Node currentNode) { 1062 ast.Node currentNode) {
1063 assert(invariant(function, function.isImplementation)); 1063 assert(invariant(function, function.isImplementation));
1064 assert(providedArguments != null); 1064 assert(providedArguments != null);
1065 1065
1066 bool isInstanceMember = function.isInstanceMember(); 1066 bool isInstanceMember = function.isInstanceMember;
1067 // For static calls, [providedArguments] is complete, default arguments 1067 // For static calls, [providedArguments] is complete, default arguments
1068 // have been included if necessary, see [addStaticSendArgumentsToList]. 1068 // have been included if necessary, see [addStaticSendArgumentsToList].
1069 if (!isInstanceMember 1069 if (!isInstanceMember
1070 || currentNode == null // In erroneous code, currentNode can be null. 1070 || currentNode == null // In erroneous code, currentNode can be null.
1071 || providedArgumentsKnownToBeComplete(currentNode) 1071 || providedArgumentsKnownToBeComplete(currentNode)
1072 || function.isGenerativeConstructorBody() 1072 || function.isGenerativeConstructorBody
1073 || selector.isGetter()) { 1073 || selector.isGetter) {
1074 // For these cases, the provided argument list is known to be complete. 1074 // For these cases, the provided argument list is known to be complete.
1075 return providedArguments; 1075 return providedArguments;
1076 } else { 1076 } else {
1077 return completeDynamicSendArgumentsList( 1077 return completeDynamicSendArgumentsList(
1078 selector, function, providedArguments); 1078 selector, function, providedArguments);
1079 } 1079 }
1080 } 1080 }
1081 1081
1082 /** 1082 /**
1083 * Returns a complete argument list for a dynamic call of [function]. The 1083 * Returns a complete argument list for a dynamic call of [function]. The
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 // Don't inline from one output unit to another. If something is deferred 1173 // Don't inline from one output unit to another. If something is deferred
1174 // it is to save space in the loading code. 1174 // it is to save space in the loading code.
1175 if (!compiler.deferredLoadTask 1175 if (!compiler.deferredLoadTask
1176 .inSameOutputUnit(element,compiler.currentElement)) { 1176 .inSameOutputUnit(element,compiler.currentElement)) {
1177 return false; 1177 return false;
1178 } 1178 }
1179 if (compiler.disableInlining) return false; 1179 if (compiler.disableInlining) return false;
1180 1180
1181 assert(selector != null 1181 assert(selector != null
1182 || Elements.isStaticOrTopLevel(element) 1182 || Elements.isStaticOrTopLevel(element)
1183 || element.isGenerativeConstructorBody()); 1183 || element.isGenerativeConstructorBody);
1184 if (selector != null && !selector.applies(function, compiler)) { 1184 if (selector != null && !selector.applies(function, compiler)) {
1185 return false; 1185 return false;
1186 } 1186 }
1187 1187
1188 // Don't inline operator== methods if the parameter can be null. 1188 // Don't inline operator== methods if the parameter can be null.
1189 if (element.name == '==') { 1189 if (element.name == '==') {
1190 if (element.getEnclosingClass() != compiler.objectClass 1190 if (element.enclosingClass != compiler.objectClass
1191 && providedArguments[1].canBeNull()) { 1191 && providedArguments[1].canBeNull()) {
1192 return false; 1192 return false;
1193 } 1193 }
1194 } 1194 }
1195 1195
1196 // Generative constructors of native classes should not be called directly 1196 // Generative constructors of native classes should not be called directly
1197 // and have an extra argument that causes problems with inlining. 1197 // and have an extra argument that causes problems with inlining.
1198 if (element.isGenerativeConstructor() 1198 if (element.isGenerativeConstructor
1199 && Elements.isNativeOrExtendsNative(element.getEnclosingClass())) { 1199 && Elements.isNativeOrExtendsNative(element.enclosingClass)) {
1200 return false; 1200 return false;
1201 } 1201 }
1202 1202
1203 // A generative constructor body is not seen by global analysis, 1203 // A generative constructor body is not seen by global analysis,
1204 // so we should not query for its type. 1204 // so we should not query for its type.
1205 if (!element.isGenerativeConstructorBody()) { 1205 if (!element.isGenerativeConstructorBody) {
1206 // Don't inline if the return type was inferred to be non-null empty. 1206 // Don't inline if the return type was inferred to be non-null empty.
1207 // This means that the function always throws an exception. 1207 // This means that the function always throws an exception.
1208 TypeMask returnType = 1208 TypeMask returnType =
1209 compiler.typesTask.getGuaranteedReturnTypeOfElement(element); 1209 compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
1210 if (returnType != null 1210 if (returnType != null
1211 && returnType.isEmpty 1211 && returnType.isEmpty
1212 && !returnType.isNullable) { 1212 && !returnType.isNullable) {
1213 isReachable = false; 1213 isReachable = false;
1214 return false; 1214 return false;
1215 } 1215 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 } else { 1259 } else {
1260 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); 1260 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
1261 } 1261 }
1262 return canInline; 1262 return canInline;
1263 } 1263 }
1264 1264
1265 void doInlining() { 1265 void doInlining() {
1266 // Add an explicit null check on the receiver before doing the 1266 // Add an explicit null check on the receiver before doing the
1267 // inlining. We use [element] to get the same name in the 1267 // inlining. We use [element] to get the same name in the
1268 // NoSuchMethodError message as if we had called it. 1268 // NoSuchMethodError message as if we had called it.
1269 if (element.isInstanceMember() 1269 if (element.isInstanceMember
1270 && !element.isGenerativeConstructorBody() 1270 && !element.isGenerativeConstructorBody
1271 && (selector.mask == null || selector.mask.isNullable)) { 1271 && (selector.mask == null || selector.mask.isNullable)) {
1272 addWithPosition( 1272 addWithPosition(
1273 new HFieldGet(null, providedArguments[0], backend.dynamicType, 1273 new HFieldGet(null, providedArguments[0], backend.dynamicType,
1274 isAssignable: false), 1274 isAssignable: false),
1275 currentNode); 1275 currentNode);
1276 } 1276 }
1277 List<HInstruction> compiledArguments = completeSendArgumentsList( 1277 List<HInstruction> compiledArguments = completeSendArgumentsList(
1278 function, selector, providedArguments, currentNode); 1278 function, selector, providedArguments, currentNode);
1279 enterInlinedMethod(function, currentNode, compiledArguments); 1279 enterInlinedMethod(function, currentNode, compiledArguments);
1280 inlinedFrom(function, () { 1280 inlinedFrom(function, () {
(...skipping 27 matching lines...) Expand all
1308 1308
1309 HInstruction handleConstantForOptionalParameter(Element parameter) { 1309 HInstruction handleConstantForOptionalParameter(Element parameter) {
1310 Constant constant = 1310 Constant constant =
1311 backend.constants.getConstantForVariable(parameter); 1311 backend.constants.getConstantForVariable(parameter);
1312 assert(invariant(parameter, constant != null, 1312 assert(invariant(parameter, constant != null,
1313 message: 'No constant computed for $parameter')); 1313 message: 'No constant computed for $parameter'));
1314 return graph.addConstant(constant, compiler); 1314 return graph.addConstant(constant, compiler);
1315 } 1315 }
1316 1316
1317 Element get currentNonClosureClass { 1317 Element get currentNonClosureClass {
1318 ClassElement cls = sourceElement.getEnclosingClass(); 1318 ClassElement cls = sourceElement.enclosingClass;
1319 if (cls != null && cls.isClosure()) { 1319 if (cls != null && cls.isClosure) {
1320 var closureClass = cls; 1320 var closureClass = cls;
1321 return closureClass.methodElement.getEnclosingClass(); 1321 return closureClass.methodElement.enclosingClass;
1322 } else { 1322 } else {
1323 return cls; 1323 return cls;
1324 } 1324 }
1325 } 1325 }
1326 1326
1327 /** 1327 /**
1328 * Returns whether this builder is building code for [element]. 1328 * Returns whether this builder is building code for [element].
1329 */ 1329 */
1330 bool isBuildingFor(Element element) { 1330 bool isBuildingFor(Element element) {
1331 return work.element == element; 1331 return work.element == element;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 backend.constants.getConstantForVariable(element); 1363 backend.constants.getConstantForVariable(element);
1364 return initialValue == null; 1364 return initialValue == null;
1365 } 1365 }
1366 1366
1367 TypeMask cachedTypeOfThis; 1367 TypeMask cachedTypeOfThis;
1368 1368
1369 TypeMask getTypeOfThis() { 1369 TypeMask getTypeOfThis() {
1370 TypeMask result = cachedTypeOfThis; 1370 TypeMask result = cachedTypeOfThis;
1371 if (result == null) { 1371 if (result == null) {
1372 Element element = localsHandler.closureData.thisElement; 1372 Element element = localsHandler.closureData.thisElement;
1373 ClassElement cls = element.enclosingElement.getEnclosingClass(); 1373 ClassElement cls = element.enclosingElement.enclosingClass;
1374 if (compiler.world.isUsedAsMixin(cls)) { 1374 if (compiler.world.isUsedAsMixin(cls)) {
1375 // If the enclosing class is used as a mixin, [:this:] can be 1375 // If the enclosing class is used as a mixin, [:this:] can be
1376 // of the class that mixins the enclosing class. These two 1376 // of the class that mixins the enclosing class. These two
1377 // classes do not have a subclass relationship, so, for 1377 // classes do not have a subclass relationship, so, for
1378 // simplicity, we mark the type as an interface type. 1378 // simplicity, we mark the type as an interface type.
1379 result = new TypeMask.nonNullSubtype(cls.declaration); 1379 result = new TypeMask.nonNullSubtype(cls.declaration);
1380 } else { 1380 } else {
1381 result = new TypeMask.nonNullSubclass(cls.declaration); 1381 result = new TypeMask.nonNullSubclass(cls.declaration);
1382 } 1382 }
1383 cachedTypeOfThis = result; 1383 cachedTypeOfThis = result;
1384 } 1384 }
1385 return result; 1385 return result;
1386 } 1386 }
1387 1387
1388 Map<Element, TypeMask> cachedTypesOfCapturedVariables = 1388 Map<Element, TypeMask> cachedTypesOfCapturedVariables =
1389 new Map<Element, TypeMask>(); 1389 new Map<Element, TypeMask>();
1390 1390
1391 TypeMask getTypeOfCapturedVariable(Element element) { 1391 TypeMask getTypeOfCapturedVariable(Element element) {
1392 assert(element.isField()); 1392 assert(element.isField);
1393 return cachedTypesOfCapturedVariables.putIfAbsent(element, () { 1393 return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
1394 return TypeMaskFactory.inferredTypeForElement(element, compiler); 1394 return TypeMaskFactory.inferredTypeForElement(element, compiler);
1395 }); 1395 });
1396 } 1396 }
1397 1397
1398 /** 1398 /**
1399 * Documentation wanted -- johnniwinther 1399 * Documentation wanted -- johnniwinther
1400 * 1400 *
1401 * Invariant: [functionElement] must be an implementation element. 1401 * Invariant: [functionElement] must be an implementation element.
1402 */ 1402 */
1403 HGraph buildMethod(FunctionElement functionElement) { 1403 HGraph buildMethod(FunctionElement functionElement) {
1404 assert(invariant(functionElement, functionElement.isImplementation)); 1404 assert(invariant(functionElement, functionElement.isImplementation));
1405 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); 1405 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
1406 ast.FunctionExpression function = functionElement.parseNode(compiler); 1406 ast.FunctionExpression function = functionElement.parseNode(compiler);
1407 assert(function != null); 1407 assert(function != null);
1408 assert(!function.modifiers.isExternal()); 1408 assert(!function.modifiers.isExternal);
1409 assert(elements[function] != null); 1409 assert(elements[function] != null);
1410 openFunction(functionElement, function); 1410 openFunction(functionElement, function);
1411 String name = functionElement.name; 1411 String name = functionElement.name;
1412 // If [functionElement] is `operator==` we explicitely add a null check at 1412 // If [functionElement] is `operator==` we explicitely add a null check at
1413 // the beginning of the method. This is to avoid having call sites do the 1413 // the beginning of the method. This is to avoid having call sites do the
1414 // null check. 1414 // null check.
1415 if (name == '==') { 1415 if (name == '==') {
1416 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 1416 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
1417 handleIf( 1417 handleIf(
1418 function, 1418 function,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 return closeFunction(); 1460 return closeFunction();
1461 } 1461 }
1462 1462
1463 /** 1463 /**
1464 * Returns the constructor body associated with the given constructor or 1464 * Returns the constructor body associated with the given constructor or
1465 * creates a new constructor body, if none can be found. 1465 * creates a new constructor body, if none can be found.
1466 * 1466 *
1467 * Returns [:null:] if the constructor does not have a body. 1467 * Returns [:null:] if the constructor does not have a body.
1468 */ 1468 */
1469 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 1469 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
1470 assert(constructor.isGenerativeConstructor()); 1470 assert(constructor.isGenerativeConstructor);
1471 assert(invariant(constructor, constructor.isImplementation)); 1471 assert(invariant(constructor, constructor.isImplementation));
1472 if (constructor.isSynthesized) return null; 1472 if (constructor.isSynthesized) return null;
1473 ast.FunctionExpression node = constructor.parseNode(compiler); 1473 ast.FunctionExpression node = constructor.parseNode(compiler);
1474 // If we know the body doesn't have any code, we don't generate it. 1474 // If we know the body doesn't have any code, we don't generate it.
1475 if (!node.hasBody()) return null; 1475 if (!node.hasBody()) return null;
1476 if (node.hasEmptyBody()) return null; 1476 if (node.hasEmptyBody()) return null;
1477 ClassElement classElement = constructor.getEnclosingClass(); 1477 ClassElement classElement = constructor.enclosingClass;
1478 ConstructorBodyElement bodyElement; 1478 ConstructorBodyElement bodyElement;
1479 classElement.forEachBackendMember((Element backendMember) { 1479 classElement.forEachBackendMember((Element backendMember) {
1480 if (backendMember.isGenerativeConstructorBody()) { 1480 if (backendMember.isGenerativeConstructorBody) {
1481 ConstructorBodyElement body = backendMember; 1481 ConstructorBodyElement body = backendMember;
1482 if (body.constructor == constructor) { 1482 if (body.constructor == constructor) {
1483 // TODO(kasperl): Find a way of stopping the iteration 1483 // TODO(kasperl): Find a way of stopping the iteration
1484 // through the backend members. 1484 // through the backend members.
1485 bodyElement = backendMember; 1485 bodyElement = backendMember;
1486 } 1486 }
1487 } 1487 }
1488 }); 1488 });
1489 if (bodyElement == null) { 1489 if (bodyElement == null) {
1490 bodyElement = new ConstructorBodyElementX(constructor); 1490 bodyElement = new ConstructorBodyElementX(constructor);
1491 classElement.addBackendMember(bodyElement); 1491 classElement.addBackendMember(bodyElement);
1492 1492
1493 if (constructor.isPatch) { 1493 if (constructor.isPatch) {
1494 // Create origin body element for patched constructors. 1494 // Create origin body element for patched constructors.
1495 ConstructorBodyElementX patch = bodyElement; 1495 ConstructorBodyElementX patch = bodyElement;
1496 ConstructorBodyElementX origin = 1496 ConstructorBodyElementX origin =
1497 new ConstructorBodyElementX(constructor.origin); 1497 new ConstructorBodyElementX(constructor.origin);
1498 origin.applyPatch(patch); 1498 origin.applyPatch(patch);
1499 classElement.origin.addBackendMember(bodyElement.origin); 1499 classElement.origin.addBackendMember(bodyElement.origin);
1500 } 1500 }
1501 } 1501 }
1502 assert(bodyElement.isGenerativeConstructorBody()); 1502 assert(bodyElement.isGenerativeConstructorBody);
1503 return bodyElement; 1503 return bodyElement;
1504 } 1504 }
1505 1505
1506 HParameterValue addParameter(Element element, TypeMask type) { 1506 HParameterValue addParameter(Element element, TypeMask type) {
1507 assert(inliningStack.isEmpty); 1507 assert(inliningStack.isEmpty);
1508 HParameterValue result = new HParameterValue(element, type); 1508 HParameterValue result = new HParameterValue(element, type);
1509 if (lastAddedParameter == null) { 1509 if (lastAddedParameter == null) {
1510 graph.entry.addBefore(graph.entry.first, result); 1510 graph.entry.addBefore(graph.entry.first, result);
1511 } else { 1511 } else {
1512 graph.entry.addAfter(lastAddedParameter, result); 1512 graph.entry.addAfter(lastAddedParameter, result);
(...skipping 19 matching lines...) Expand all
1532 function, function.parseNode(compiler), elements); 1532 function, function.parseNode(compiler), elements);
1533 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. 1533 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
1534 returnElement = new VariableElementX.synthetic("result", 1534 returnElement = new VariableElementX.synthetic("result",
1535 ElementKind.VARIABLE, function); 1535 ElementKind.VARIABLE, function);
1536 localsHandler.updateLocal(returnElement, 1536 localsHandler.updateLocal(returnElement,
1537 graph.addConstantNull(compiler)); 1537 graph.addConstantNull(compiler));
1538 1538
1539 inTryStatement = false; // TODO(lry): why? Document. 1539 inTryStatement = false; // TODO(lry): why? Document.
1540 1540
1541 int argumentIndex = 0; 1541 int argumentIndex = 0;
1542 if (function.isInstanceMember()) { 1542 if (function.isInstanceMember) {
1543 localsHandler.updateLocal(localsHandler.closureData.thisElement, 1543 localsHandler.updateLocal(localsHandler.closureData.thisElement,
1544 compiledArguments[argumentIndex++]); 1544 compiledArguments[argumentIndex++]);
1545 } 1545 }
1546 1546
1547 FunctionSignature signature = function.functionSignature; 1547 FunctionSignature signature = function.functionSignature;
1548 signature.orderedForEachParameter((Element parameter) { 1548 signature.orderedForEachParameter((Element parameter) {
1549 HInstruction argument = compiledArguments[argumentIndex++]; 1549 HInstruction argument = compiledArguments[argumentIndex++];
1550 localsHandler.updateLocal(parameter, argument); 1550 localsHandler.updateLocal(parameter, argument);
1551 }); 1551 });
1552 1552
1553 ClassElement enclosing = function.getEnclosingClass(); 1553 ClassElement enclosing = function.enclosingClass;
1554 if ((function.isConstructor() || function.isGenerativeConstructorBody()) 1554 if ((function.isConstructor || function.isGenerativeConstructorBody)
1555 && backend.classNeedsRti(enclosing)) { 1555 && backend.classNeedsRti(enclosing)) {
1556 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1556 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1557 HInstruction argument = compiledArguments[argumentIndex++]; 1557 HInstruction argument = compiledArguments[argumentIndex++];
1558 localsHandler.updateLocal(typeVariable.element, argument); 1558 localsHandler.updateLocal(typeVariable.element, argument);
1559 }); 1559 });
1560 } 1560 }
1561 assert(argumentIndex == compiledArguments.length); 1561 assert(argumentIndex == compiledArguments.length);
1562 1562
1563 elements = compiler.enqueuer.resolution.getCachedElements(function); 1563 elements = compiler.enqueuer.resolution.getCachedElements(function);
1564 assert(elements != null); 1564 assert(elements != null);
1565 returnType = signature.type.returnType; 1565 returnType = signature.type.returnType;
1566 stack = <HInstruction>[]; 1566 stack = <HInstruction>[];
1567 } 1567 }
1568 1568
1569 void restoreState(AstInliningState state) { 1569 void restoreState(AstInliningState state) {
1570 localsHandler = state.oldLocalsHandler; 1570 localsHandler = state.oldLocalsHandler;
1571 returnElement = state.oldReturnElement; 1571 returnElement = state.oldReturnElement;
1572 inTryStatement = state.inTryStatement; 1572 inTryStatement = state.inTryStatement;
1573 elements = state.oldElements; 1573 elements = state.oldElements;
1574 returnType = state.oldReturnType; 1574 returnType = state.oldReturnType;
1575 assert(stack.isEmpty); 1575 assert(stack.isEmpty);
1576 stack = state.oldStack; 1576 stack = state.oldStack;
1577 } 1577 }
1578 1578
1579 /** 1579 /**
1580 * Run this builder on the body of the [function] to be inlined. 1580 * Run this builder on the body of the [function] to be inlined.
1581 */ 1581 */
1582 void visitInlinedFunction(FunctionElement function) { 1582 void visitInlinedFunction(FunctionElement function) {
1583 potentiallyCheckInlinedParameterTypes(function); 1583 potentiallyCheckInlinedParameterTypes(function);
1584 if (function.isGenerativeConstructor()) { 1584 if (function.isGenerativeConstructor) {
1585 buildFactory(function); 1585 buildFactory(function);
1586 } else { 1586 } else {
1587 ast.FunctionExpression functionNode = function.parseNode(compiler); 1587 ast.FunctionExpression functionNode = function.parseNode(compiler);
1588 functionNode.body.accept(this); 1588 functionNode.body.accept(this);
1589 } 1589 }
1590 } 1590 }
1591 1591
1592 1592
1593 addInlinedInstantiation(DartType type) { 1593 addInlinedInstantiation(DartType type) {
1594 if (type != null) { 1594 if (type != null) {
(...skipping 20 matching lines...) Expand all
1615 /** 1615 /**
1616 * In checked mode, generate type tests for the parameters of the inlined 1616 * In checked mode, generate type tests for the parameters of the inlined
1617 * function. 1617 * function.
1618 */ 1618 */
1619 void potentiallyCheckInlinedParameterTypes(FunctionElement function) { 1619 void potentiallyCheckInlinedParameterTypes(FunctionElement function) {
1620 if (!compiler.enableTypeAssertions) return; 1620 if (!compiler.enableTypeAssertions) return;
1621 1621
1622 FunctionSignature signature = function.functionSignature; 1622 FunctionSignature signature = function.functionSignature;
1623 1623
1624 InterfaceType contextType; 1624 InterfaceType contextType;
1625 if (function.isSynthesized && function.isGenerativeConstructor()) { 1625 if (function.isSynthesized && function.isGenerativeConstructor) {
1626 // Synthesized constructors reuse the parameters from the 1626 // Synthesized constructors reuse the parameters from the
1627 // [targetConstructor]. In face of generic types, the type variables 1627 // [targetConstructor]. In face of generic types, the type variables
1628 // occurring in the parameter types must be substituted by the type 1628 // occurring in the parameter types must be substituted by the type
1629 // arguments of the enclosing class. 1629 // arguments of the enclosing class.
1630 FunctionElement target = function; 1630 FunctionElement target = function;
1631 while (target.targetConstructor != null) { 1631 while (target.targetConstructor != null) {
1632 target = target.targetConstructor; 1632 target = target.targetConstructor;
1633 } 1633 }
1634 if (target != function) { 1634 if (target != function) {
1635 ClassElement functionClass = function.getEnclosingClass(); 1635 ClassElement functionClass = function.enclosingClass;
1636 ClassElement targetClass = target.getEnclosingClass(); 1636 ClassElement targetClass = target.enclosingClass;
1637 contextType = functionClass.thisType.asInstanceOf(targetClass); 1637 contextType = functionClass.thisType.asInstanceOf(targetClass);
1638 } 1638 }
1639 } 1639 }
1640 1640
1641 signature.orderedForEachParameter((ParameterElement parameter) { 1641 signature.orderedForEachParameter((ParameterElement parameter) {
1642 HInstruction argument = localsHandler.readLocal(parameter); 1642 HInstruction argument = localsHandler.readLocal(parameter);
1643 DartType parameterType = parameter.type; 1643 DartType parameterType = parameter.type;
1644 if (contextType != null) { 1644 if (contextType != null) {
1645 parameterType = parameterType.substByContext(contextType); 1645 parameterType = parameterType.substByContext(contextType);
1646 } 1646 }
1647 potentiallyCheckType(argument, parameterType); 1647 potentiallyCheckType(argument, parameterType);
1648 }); 1648 });
1649 } 1649 }
1650 1650
1651 /** 1651 /**
1652 * Documentation wanted -- johnniwinther 1652 * Documentation wanted -- johnniwinther
1653 * 1653 *
1654 * Invariant: [constructors] must contain only implementation elements. 1654 * Invariant: [constructors] must contain only implementation elements.
1655 */ 1655 */
1656 void inlineSuperOrRedirect(FunctionElement callee, 1656 void inlineSuperOrRedirect(FunctionElement callee,
1657 List<HInstruction> compiledArguments, 1657 List<HInstruction> compiledArguments,
1658 List<FunctionElement> constructors, 1658 List<FunctionElement> constructors,
1659 Map<Element, HInstruction> fieldValues, 1659 Map<Element, HInstruction> fieldValues,
1660 FunctionElement caller) { 1660 FunctionElement caller) {
1661 callee = callee.implementation; 1661 callee = callee.implementation;
1662 compiler.withCurrentElement(callee, () { 1662 compiler.withCurrentElement(callee, () {
1663 constructors.add(callee); 1663 constructors.add(callee);
1664 ClassElement enclosingClass = callee.getEnclosingClass(); 1664 ClassElement enclosingClass = callee.enclosingClass;
1665 if (backend.classNeedsRti(enclosingClass)) { 1665 if (backend.classNeedsRti(enclosingClass)) {
1666 // If [enclosingClass] needs RTI, we have to give a value to its 1666 // If [enclosingClass] needs RTI, we have to give a value to its
1667 // type parameters. 1667 // type parameters.
1668 ClassElement currentClass = caller.getEnclosingClass(); 1668 ClassElement currentClass = caller.enclosingClass;
1669 // For a super constructor call, the type is the supertype of 1669 // For a super constructor call, the type is the supertype of
1670 // [currentClass]. For a redirecting constructor, the type is 1670 // [currentClass]. For a redirecting constructor, the type is
1671 // the current type. [InterfaceType.asInstanceOf] takes care 1671 // the current type. [InterfaceType.asInstanceOf] takes care
1672 // of both. 1672 // of both.
1673 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass); 1673 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass);
1674 Link<DartType> typeVariables = enclosingClass.typeVariables; 1674 Link<DartType> typeVariables = enclosingClass.typeVariables;
1675 type.typeArguments.forEach((DartType argument) { 1675 type.typeArguments.forEach((DartType argument) {
1676 localsHandler.updateLocal( 1676 localsHandler.updateLocal(
1677 typeVariables.head.element, 1677 typeVariables.head.element,
1678 analyzeTypeArgument(argument)); 1678 analyzeTypeArgument(argument));
1679 typeVariables = typeVariables.tail; 1679 typeVariables = typeVariables.tail;
1680 }); 1680 });
1681 // If the supertype is a raw type, we need to set to null the 1681 // If the supertype is a raw type, we need to set to null the
1682 // type variables. 1682 // type variables.
1683 assert(typeVariables.isEmpty 1683 assert(typeVariables.isEmpty
1684 || enclosingClass.typeVariables == typeVariables); 1684 || enclosingClass.typeVariables == typeVariables);
1685 while (!typeVariables.isEmpty) { 1685 while (!typeVariables.isEmpty) {
1686 localsHandler.updateLocal(typeVariables.head.element, 1686 localsHandler.updateLocal(typeVariables.head.element,
1687 graph.addConstantNull(compiler)); 1687 graph.addConstantNull(compiler));
1688 typeVariables = typeVariables.tail; 1688 typeVariables = typeVariables.tail;
1689 } 1689 }
1690 } 1690 }
1691 1691
1692 // For redirecting constructors, the fields have already been 1692 // For redirecting constructors, the fields have already been
1693 // initialized by the caller. 1693 // initialized by the caller.
1694 if (callee.getEnclosingClass() != caller.getEnclosingClass()) { 1694 if (callee.enclosingClass != caller.enclosingClass) {
1695 inlinedFrom(callee, () { 1695 inlinedFrom(callee, () {
1696 buildFieldInitializers(callee.enclosingElement.implementation, 1696 buildFieldInitializers(callee.enclosingElement.implementation,
1697 fieldValues); 1697 fieldValues);
1698 }); 1698 });
1699 } 1699 }
1700 1700
1701 int index = 0; 1701 int index = 0;
1702 FunctionSignature params = callee.functionSignature; 1702 FunctionSignature params = callee.functionSignature;
1703 params.orderedForEachParameter((Element parameter) { 1703 params.orderedForEachParameter((Element parameter) {
1704 HInstruction argument = compiledArguments[index++]; 1704 HInstruction argument = compiledArguments[index++];
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 visit(arguments.head); 1804 visit(arguments.head);
1805 }); 1805 });
1806 fieldValues[elements[init]] = pop(); 1806 fieldValues[elements[init]] = pop();
1807 } 1807 }
1808 } 1808 }
1809 } 1809 }
1810 1810
1811 if (!foundSuperOrRedirect) { 1811 if (!foundSuperOrRedirect) {
1812 // No super initializer found. Try to find the default constructor if 1812 // No super initializer found. Try to find the default constructor if
1813 // the class is not Object. 1813 // the class is not Object.
1814 ClassElement enclosingClass = constructor.getEnclosingClass(); 1814 ClassElement enclosingClass = constructor.enclosingClass;
1815 ClassElement superClass = enclosingClass.superclass; 1815 ClassElement superClass = enclosingClass.superclass;
1816 if (!enclosingClass.isObject(compiler)) { 1816 if (!enclosingClass.isObject(compiler)) {
1817 assert(superClass != null); 1817 assert(superClass != null);
1818 assert(superClass.resolutionState == STATE_DONE); 1818 assert(superClass.resolutionState == STATE_DONE);
1819 Selector selector = 1819 Selector selector =
1820 new Selector.callDefaultConstructor(enclosingClass.getLibrary()); 1820 new Selector.callDefaultConstructor(enclosingClass.library);
1821 // TODO(johnniwinther): Should we find injected constructors as well? 1821 // TODO(johnniwinther): Should we find injected constructors as well?
1822 FunctionElement target = superClass.lookupConstructor(selector); 1822 FunctionElement target = superClass.lookupConstructor(selector);
1823 if (target == null) { 1823 if (target == null) {
1824 compiler.internalError(superClass, 1824 compiler.internalError(superClass,
1825 "No default constructor available."); 1825 "No default constructor available.");
1826 } 1826 }
1827 List<HInstruction> arguments = <HInstruction>[]; 1827 List<HInstruction> arguments = <HInstruction>[];
1828 selector.addArgumentsToList(const Link<ast.Node>(), 1828 selector.addArgumentsToList(const Link<ast.Node>(),
1829 arguments, 1829 arguments,
1830 target.implementation, 1830 target.implementation,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 * [functionElement]: 1882 * [functionElement]:
1883 * - Initialize fields with the values of the field initializers of the 1883 * - Initialize fields with the values of the field initializers of the
1884 * current constructor and super constructors or constructors redirected 1884 * current constructor and super constructors or constructors redirected
1885 * to, starting from the current constructor. 1885 * to, starting from the current constructor.
1886 * - Call the constructor bodies, starting from the constructor(s) in the 1886 * - Call the constructor bodies, starting from the constructor(s) in the
1887 * super class(es). 1887 * super class(es).
1888 */ 1888 */
1889 HGraph buildFactory(FunctionElement functionElement) { 1889 HGraph buildFactory(FunctionElement functionElement) {
1890 functionElement = functionElement.implementation; 1890 functionElement = functionElement.implementation;
1891 ClassElement classElement = 1891 ClassElement classElement =
1892 functionElement.getEnclosingClass().implementation; 1892 functionElement.enclosingClass.implementation;
1893 bool isNativeUpgradeFactory = 1893 bool isNativeUpgradeFactory =
1894 Elements.isNativeOrExtendsNative(classElement); 1894 Elements.isNativeOrExtendsNative(classElement);
1895 ast.FunctionExpression function = functionElement.parseNode(compiler); 1895 ast.FunctionExpression function = functionElement.parseNode(compiler);
1896 // Note that constructors (like any other static function) do not need 1896 // Note that constructors (like any other static function) do not need
1897 // to deal with optional arguments. It is the callers job to provide all 1897 // to deal with optional arguments. It is the callers job to provide all
1898 // arguments as if they were positional. 1898 // arguments as if they were positional.
1899 1899
1900 if (inliningStack.isEmpty) { 1900 if (inliningStack.isEmpty) {
1901 // The initializer list could contain closures. 1901 // The initializer list could contain closures.
1902 openFunction(functionElement, function); 1902 openFunction(functionElement, function);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 HConstant index = invoke.inputs[1]; 2011 HConstant index = invoke.inputs[1];
2012 HInstruction newSource = invoke.inputs[0]; 2012 HInstruction newSource = invoke.inputs[0];
2013 if (newSource is! HThis) { 2013 if (newSource is! HThis) {
2014 return false; 2014 return false;
2015 } 2015 }
2016 if (source == null) { 2016 if (source == null) {
2017 // This is the first match. Extract the context class for the type 2017 // This is the first match. Extract the context class for the type
2018 // variables and get the list of type variables to keep track of how 2018 // variables and get the list of type variables to keep track of how
2019 // many arguments we need to process. 2019 // many arguments we need to process.
2020 source = newSource; 2020 source = newSource;
2021 contextClass = source.sourceElement.getEnclosingClass(); 2021 contextClass = source.sourceElement.enclosingClass;
2022 typeVariables = contextClass.typeVariables; 2022 typeVariables = contextClass.typeVariables;
2023 } else { 2023 } else {
2024 assert(source == newSource); 2024 assert(source == newSource);
2025 } 2025 }
2026 // If there are no more type variables, then there are more type 2026 // If there are no more type variables, then there are more type
2027 // arguments for the new object than the source has, and it can't be 2027 // arguments for the new object than the source has, and it can't be
2028 // a copy. Otherwise remove one argument. 2028 // a copy. Otherwise remove one argument.
2029 if (typeVariables.isEmpty) return false; 2029 if (typeVariables.isEmpty) return false;
2030 typeVariables = typeVariables.tail; 2030 typeVariables = typeVariables.tail;
2031 // Check that the index is the one we expect. 2031 // Check that the index is the one we expect.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 FunctionSignature functionSignature = body.functionSignature; 2076 FunctionSignature functionSignature = body.functionSignature;
2077 // Provide the parameters to the generative constructor body. 2077 // Provide the parameters to the generative constructor body.
2078 functionSignature.orderedForEachParameter((parameter) { 2078 functionSignature.orderedForEachParameter((parameter) {
2079 // If [parameter] is boxed, it will be a field in the box passed as the 2079 // If [parameter] is boxed, it will be a field in the box passed as the
2080 // last parameter. So no need to directly pass it. 2080 // last parameter. So no need to directly pass it.
2081 if (!localsHandler.isBoxed(parameter)) { 2081 if (!localsHandler.isBoxed(parameter)) {
2082 bodyCallInputs.add(localsHandler.readLocal(parameter)); 2082 bodyCallInputs.add(localsHandler.readLocal(parameter));
2083 } 2083 }
2084 }); 2084 });
2085 2085
2086 ClassElement currentClass = constructor.getEnclosingClass(); 2086 ClassElement currentClass = constructor.enclosingClass;
2087 if (backend.classNeedsRti(currentClass)) { 2087 if (backend.classNeedsRti(currentClass)) {
2088 // If [currentClass] needs RTI, we add the type variables as 2088 // If [currentClass] needs RTI, we add the type variables as
2089 // parameters of the generative constructor body. 2089 // parameters of the generative constructor body.
2090 currentClass.typeVariables.forEach((DartType argument) { 2090 currentClass.typeVariables.forEach((DartType argument) {
2091 bodyCallInputs.add(localsHandler.readLocal(argument.element)); 2091 bodyCallInputs.add(localsHandler.readLocal(argument.element));
2092 }); 2092 });
2093 } 2093 }
2094 2094
2095 // If there are locals that escape (ie mutated in closures), we 2095 // If there are locals that escape (ie mutated in closures), we
2096 // pass the box to the constructor. 2096 // pass the box to the constructor.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 2131
2132 localsHandler.startFunction(element, node); 2132 localsHandler.startFunction(element, node);
2133 close(new HGoto()).addSuccessor(block); 2133 close(new HGoto()).addSuccessor(block);
2134 2134
2135 open(block); 2135 open(block);
2136 2136
2137 // Add the type parameters of the class as parameters of this method. This 2137 // Add the type parameters of the class as parameters of this method. This
2138 // must be done before adding the normal parameters, because their types 2138 // must be done before adding the normal parameters, because their types
2139 // may contain references to type variables. 2139 // may contain references to type variables.
2140 var enclosing = element.enclosingElement; 2140 var enclosing = element.enclosingElement;
2141 if ((element.isConstructor() || element.isGenerativeConstructorBody()) 2141 if ((element.isConstructor || element.isGenerativeConstructorBody)
2142 && backend.classNeedsRti(enclosing)) { 2142 && backend.classNeedsRti(enclosing)) {
2143 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 2143 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
2144 HParameterValue param = addParameter( 2144 HParameterValue param = addParameter(
2145 typeVariable.element, backend.nonNullType); 2145 typeVariable.element, backend.nonNullType);
2146 localsHandler.directLocals[typeVariable.element] = param; 2146 localsHandler.directLocals[typeVariable.element] = param;
2147 }); 2147 });
2148 } 2148 }
2149 2149
2150 if (element is FunctionElement) { 2150 if (element is FunctionElement) {
2151 FunctionElement functionElement = element; 2151 FunctionElement functionElement = element;
2152 FunctionSignature signature = functionElement.functionSignature; 2152 FunctionSignature signature = functionElement.functionSignature;
2153 2153
2154 // Put the type checks in the first successor of the entry, 2154 // Put the type checks in the first successor of the entry,
2155 // because that is where the type guards will also be inserted. 2155 // because that is where the type guards will also be inserted.
2156 // This way we ensure that a type guard will dominate the type 2156 // This way we ensure that a type guard will dominate the type
2157 // check. 2157 // check.
2158 signature.orderedForEachParameter((ParameterElement parameterElement) { 2158 signature.orderedForEachParameter((ParameterElement parameterElement) {
2159 if (element.isGenerativeConstructorBody()) { 2159 if (element.isGenerativeConstructorBody) {
2160 ClosureScope scopeData = 2160 ClosureScope scopeData =
2161 localsHandler.closureData.capturingScopes[node]; 2161 localsHandler.closureData.capturingScopes[node];
2162 if (scopeData != null 2162 if (scopeData != null
2163 && scopeData.capturedVariableMapping.containsKey( 2163 && scopeData.capturedVariableMapping.containsKey(
2164 parameterElement)) { 2164 parameterElement)) {
2165 // The parameter will be a field in the box passed as the 2165 // The parameter will be a field in the box passed as the
2166 // last parameter. So no need to have it. 2166 // last parameter. So no need to have it.
2167 return; 2167 return;
2168 } 2168 }
2169 } 2169 }
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
2814 // TODO(ahe): This should be registered in codegen, not here. 2814 // TODO(ahe): This should be registered in codegen, not here.
2815 compiler.enqueuer.codegen.addToWorkList(callElement); 2815 compiler.enqueuer.codegen.addToWorkList(callElement);
2816 // TODO(ahe): This should be registered in codegen, not here. 2816 // TODO(ahe): This should be registered in codegen, not here.
2817 compiler.enqueuer.codegen.registerInstantiatedClass( 2817 compiler.enqueuer.codegen.registerInstantiatedClass(
2818 closureClassElement, work.resolutionTree); 2818 closureClassElement, work.resolutionTree);
2819 2819
2820 List<HInstruction> capturedVariables = <HInstruction>[]; 2820 List<HInstruction> capturedVariables = <HInstruction>[];
2821 closureClassElement.forEachMember((_, Element member) { 2821 closureClassElement.forEachMember((_, Element member) {
2822 // The backendMembers also contains the call method(s). We are only 2822 // The backendMembers also contains the call method(s). We are only
2823 // interested in the fields. 2823 // interested in the fields.
2824 if (member.isField()) { 2824 if (member.isField) {
2825 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2825 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2826 assert(capturedLocal != null); 2826 assert(capturedLocal != null);
2827 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2827 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2828 } 2828 }
2829 }); 2829 });
2830 2830
2831 TypeMask type = new TypeMask.nonNullExact(compiler.functionClass); 2831 TypeMask type = new TypeMask.nonNullExact(compiler.functionClass);
2832 push(new HForeignNew(closureClassElement, type, capturedVariables)); 2832 push(new HForeignNew(closureClassElement, type, capturedVariables));
2833 2833
2834 Element methodElement = nestedClosureData.closureElement; 2834 Element methodElement = nestedClosureData.closureElement;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2943 } 2943 }
2944 2944
2945 /** 2945 /**
2946 * Returns a set of interceptor classes that contain the given 2946 * Returns a set of interceptor classes that contain the given
2947 * [selector]. 2947 * [selector].
2948 */ 2948 */
2949 void generateInstanceGetterWithCompiledReceiver(ast.Send send, 2949 void generateInstanceGetterWithCompiledReceiver(ast.Send send,
2950 Selector selector, 2950 Selector selector,
2951 HInstruction receiver) { 2951 HInstruction receiver) {
2952 assert(Elements.isInstanceSend(send, elements)); 2952 assert(Elements.isInstanceSend(send, elements));
2953 assert(selector.isGetter()); 2953 assert(selector.isGetter);
2954 pushInvokeDynamic(send, selector, [receiver]); 2954 pushInvokeDynamic(send, selector, [receiver]);
2955 } 2955 }
2956 2956
2957 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that 2957 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that
2958 /// resolves to a deferred library. 2958 /// resolves to a deferred library.
2959 void generateIsDeferredLoadedCheckIfNeeded(ast.Send node) { 2959 void generateIsDeferredLoadedCheckIfNeeded(ast.Send node) {
2960 DeferredLoadTask deferredTask = compiler.deferredLoadTask; 2960 DeferredLoadTask deferredTask = compiler.deferredLoadTask;
2961 PrefixElement prefixElement = 2961 PrefixElement prefixElement =
2962 deferredTask.deferredPrefixElement(node, elements); 2962 deferredTask.deferredPrefixElement(node, elements);
2963 if (prefixElement != null) { 2963 if (prefixElement != null) {
2964 String loadId = 2964 String loadId =
2965 deferredTask.importDeferName[prefixElement.deferredImport]; 2965 deferredTask.importDeferName[prefixElement.deferredImport];
2966 HInstruction loadIdConstant = addConstantString(loadId); 2966 HInstruction loadIdConstant = addConstantString(loadId);
2967 String uri = prefixElement.deferredImport.uri.dartString.slowToString(); 2967 String uri = prefixElement.deferredImport.uri.dartString.slowToString();
2968 HInstruction uriConstant = addConstantString(uri); 2968 HInstruction uriConstant = addConstantString(uri);
2969 Element helper = backend.getCheckDeferredIsLoaded(); 2969 Element helper = backend.getCheckDeferredIsLoaded();
2970 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]); 2970 pushInvokeStatic(node, helper, [loadIdConstant, uriConstant]);
2971 pop(); 2971 pop();
2972 } 2972 }
2973 } 2973 }
2974 2974
2975 void generateGetter(ast.Send send, Element element) { 2975 void generateGetter(ast.Send send, Element element) {
2976 if (element != null && element.isForeign(compiler)) { 2976 if (element != null && element.isForeign(compiler)) {
2977 visitForeignGetter(send); 2977 visitForeignGetter(send);
2978 } else if (Elements.isStaticOrTopLevelField(element)) { 2978 } else if (Elements.isStaticOrTopLevelField(element)) {
2979 Constant value; 2979 Constant value;
2980 if (element.isField() && !element.isAssignable()) { 2980 if (element.isField && !element.isAssignable) {
2981 // A static final or const. Get its constant value and inline it if 2981 // A static final or const. Get its constant value and inline it if
2982 // the value can be compiled eagerly. 2982 // the value can be compiled eagerly.
2983 value = backend.constants.getConstantForVariable(element); 2983 value = backend.constants.getConstantForVariable(element);
2984 } 2984 }
2985 if (value != null) { 2985 if (value != null) {
2986 HConstant instruction = graph.addConstant(value, compiler); 2986 HConstant instruction = graph.addConstant(value, compiler);
2987 stack.add(instruction); 2987 stack.add(instruction);
2988 // The inferrer may have found a better type than the constant 2988 // The inferrer may have found a better type than the constant
2989 // handler in the case of lists, because the constant handler 2989 // handler in the case of lists, because the constant handler
2990 // does not look at elements in the list. 2990 // does not look at elements in the list.
2991 TypeMask type = 2991 TypeMask type =
2992 TypeMaskFactory.inferredTypeForElement(element, compiler); 2992 TypeMaskFactory.inferredTypeForElement(element, compiler);
2993 if (!type.containsAll(compiler) && !instruction.isConstantNull()) { 2993 if (!type.containsAll(compiler) && !instruction.isConstantNull()) {
2994 // TODO(13429): The inferrer should know that an element 2994 // TODO(13429): The inferrer should know that an element
2995 // cannot be null. 2995 // cannot be null.
2996 instruction.instructionType = type.nonNullable(); 2996 instruction.instructionType = type.nonNullable();
2997 } 2997 }
2998 } else if (element.isField() && isLazilyInitialized(element)) { 2998 } else if (element.isField && isLazilyInitialized(element)) {
2999 HInstruction instruction = new HLazyStatic( 2999 HInstruction instruction = new HLazyStatic(
3000 element, 3000 element,
3001 TypeMaskFactory.inferredTypeForElement(element, compiler)); 3001 TypeMaskFactory.inferredTypeForElement(element, compiler));
3002 push(instruction); 3002 push(instruction);
3003 } else { 3003 } else {
3004 if (element.isGetter()) { 3004 if (element.isGetter) {
3005 pushInvokeStatic(send, element, <HInstruction>[]); 3005 pushInvokeStatic(send, element, <HInstruction>[]);
3006 } else { 3006 } else {
3007 // TODO(5346): Try to avoid the need for calling [declaration] before 3007 // TODO(5346): Try to avoid the need for calling [declaration] before
3008 // creating an [HStatic]. 3008 // creating an [HStatic].
3009 HInstruction instruction = new HStatic( 3009 HInstruction instruction = new HStatic(
3010 element.declaration, 3010 element.declaration,
3011 TypeMaskFactory.inferredTypeForElement(element, compiler)); 3011 TypeMaskFactory.inferredTypeForElement(element, compiler));
3012 push(instruction); 3012 push(instruction);
3013 } 3013 }
3014 } 3014 }
(...skipping 25 matching lines...) Expand all
3040 ast.Node location}) { 3040 ast.Node location}) {
3041 assert(send == null || Elements.isInstanceSend(send, elements)); 3041 assert(send == null || Elements.isInstanceSend(send, elements));
3042 if (selector == null) { 3042 if (selector == null) {
3043 assert(send != null); 3043 assert(send != null);
3044 selector = elements.getSelector(send); 3044 selector = elements.getSelector(send);
3045 } 3045 }
3046 if (location == null) { 3046 if (location == null) {
3047 assert(send != null); 3047 assert(send != null);
3048 location = send; 3048 location = send;
3049 } 3049 }
3050 assert(selector.isSetter()); 3050 assert(selector.isSetter);
3051 pushInvokeDynamic(location, selector, [receiver, value]); 3051 pushInvokeDynamic(location, selector, [receiver, value]);
3052 pop(); 3052 pop();
3053 stack.add(value); 3053 stack.add(value);
3054 } 3054 }
3055 3055
3056 void generateNonInstanceSetter(ast.SendSet send, 3056 void generateNonInstanceSetter(ast.SendSet send,
3057 Element element, 3057 Element element,
3058 HInstruction value, 3058 HInstruction value,
3059 {ast.Node location}) { 3059 {ast.Node location}) {
3060 assert(send == null || !Elements.isInstanceSend(send, elements)); 3060 assert(send == null || !Elements.isInstanceSend(send, elements));
3061 if (location == null) { 3061 if (location == null) {
3062 assert(send != null); 3062 assert(send != null);
3063 location = send; 3063 location = send;
3064 } 3064 }
3065 if (Elements.isStaticOrTopLevelField(element)) { 3065 if (Elements.isStaticOrTopLevelField(element)) {
3066 if (element.isSetter()) { 3066 if (element.isSetter) {
3067 pushInvokeStatic(location, element, <HInstruction>[value]); 3067 pushInvokeStatic(location, element, <HInstruction>[value]);
3068 pop(); 3068 pop();
3069 } else { 3069 } else {
3070 VariableElement field = element; 3070 VariableElement field = element;
3071 value = 3071 value =
3072 potentiallyCheckType(value, field.type); 3072 potentiallyCheckType(value, field.type);
3073 addWithPosition(new HStaticStore(element, value), location); 3073 addWithPosition(new HStaticStore(element, value), location);
3074 } 3074 }
3075 stack.add(value); 3075 stack.add(value);
3076 } else if (Elements.isErroneousElement(element)) { 3076 } else if (Elements.isErroneousElement(element)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 } 3112 }
3113 3113
3114 // TODO(karlklose): change construction of the representations to be GVN'able 3114 // TODO(karlklose): change construction of the representations to be GVN'able
3115 // (dartbug.com/7182). 3115 // (dartbug.com/7182).
3116 HInstruction buildTypeArgumentRepresentations(DartType type) { 3116 HInstruction buildTypeArgumentRepresentations(DartType type) {
3117 // Compute the representation of the type arguments, including access 3117 // Compute the representation of the type arguments, including access
3118 // to the runtime type information for type variables as instructions. 3118 // to the runtime type information for type variables as instructions.
3119 if (type.kind == TypeKind.TYPE_VARIABLE) { 3119 if (type.kind == TypeKind.TYPE_VARIABLE) {
3120 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); 3120 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]);
3121 } else { 3121 } else {
3122 assert(type.element.isClass()); 3122 assert(type.element.isClass);
3123 InterfaceType interface = type; 3123 InterfaceType interface = type;
3124 List<HInstruction> inputs = <HInstruction>[]; 3124 List<HInstruction> inputs = <HInstruction>[];
3125 bool first = true; 3125 bool first = true;
3126 List<String> templates = <String>[]; 3126 List<String> templates = <String>[];
3127 for (DartType argument in interface.typeArguments) { 3127 for (DartType argument in interface.typeArguments) {
3128 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { 3128 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) {
3129 HInstruction runtimeType = addTypeVariableReference(variable); 3129 HInstruction runtimeType = addTypeVariableReference(variable);
3130 inputs.add(runtimeType); 3130 inputs.add(runtimeType);
3131 })); 3131 }));
3132 } 3132 }
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 3310
3311 visitDynamicSend(ast.Send node) { 3311 visitDynamicSend(ast.Send node) {
3312 Selector selector = elements.getSelector(node); 3312 Selector selector = elements.getSelector(node);
3313 3313
3314 List<HInstruction> inputs = <HInstruction>[]; 3314 List<HInstruction> inputs = <HInstruction>[];
3315 HInstruction receiver = generateInstanceSendReceiver(node); 3315 HInstruction receiver = generateInstanceSendReceiver(node);
3316 inputs.add(receiver); 3316 inputs.add(receiver);
3317 addDynamicSendArgumentsToList(node, inputs); 3317 addDynamicSendArgumentsToList(node, inputs);
3318 3318
3319 pushInvokeDynamic(node, selector, inputs); 3319 pushInvokeDynamic(node, selector, inputs);
3320 if (selector.isSetter() || selector.isIndexSet()) { 3320 if (selector.isSetter || selector.isIndexSet) {
3321 pop(); 3321 pop();
3322 stack.add(inputs.last); 3322 stack.add(inputs.last);
3323 } 3323 }
3324 } 3324 }
3325 3325
3326 visitClosureSend(ast.Send node) { 3326 visitClosureSend(ast.Send node) {
3327 Selector selector = elements.getSelector(node); 3327 Selector selector = elements.getSelector(node);
3328 assert(node.receiver == null); 3328 assert(node.receiver == null);
3329 Element element = elements[node]; 3329 Element element = elements[node];
3330 HInstruction closureTarget; 3330 HInstruction closureTarget;
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 } else if (name == 'JS_STRING_CONCAT') { 3676 } else if (name == 'JS_STRING_CONCAT') {
3677 handleJsStringConcat(node); 3677 handleJsStringConcat(node);
3678 } else { 3678 } else {
3679 throw "Unknown foreign: ${selector}"; 3679 throw "Unknown foreign: ${selector}";
3680 } 3680 }
3681 } 3681 }
3682 3682
3683 visitForeignGetter(ast.Send node) { 3683 visitForeignGetter(ast.Send node) {
3684 Element element = elements[node]; 3684 Element element = elements[node];
3685 // Until now we only handle these as getters. 3685 // Until now we only handle these as getters.
3686 invariant(node, element.isDeferredLoaderGetter()); 3686 invariant(node, element.isDeferredLoaderGetter);
3687 FunctionElement deferredLoader = element; 3687 FunctionElement deferredLoader = element;
3688 Element loadFunction = compiler.loadLibraryFunction; 3688 Element loadFunction = compiler.loadLibraryFunction;
3689 PrefixElement prefixElement = deferredLoader.enclosingElement; 3689 PrefixElement prefixElement = deferredLoader.enclosingElement;
3690 String loadId = compiler.deferredLoadTask 3690 String loadId = compiler.deferredLoadTask
3691 .importDeferName[prefixElement.deferredImport]; 3691 .importDeferName[prefixElement.deferredImport];
3692 var inputs = [graph.addConstantString( 3692 var inputs = [graph.addConstantString(
3693 new ast.DartString.literal(loadId), compiler)]; 3693 new ast.DartString.literal(loadId), compiler)];
3694 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType, 3694 push(new HInvokeStatic(loadFunction, inputs, backend.nonNullType,
3695 targetCanThrow: false)); 3695 targetCanThrow: false));
3696 } 3696 }
3697 3697
3698 generateSuperNoSuchMethodSend(ast.Send node, 3698 generateSuperNoSuchMethodSend(ast.Send node,
3699 Selector selector, 3699 Selector selector,
3700 List<HInstruction> arguments) { 3700 List<HInstruction> arguments) {
3701 String name = selector.name; 3701 String name = selector.name;
3702 3702
3703 ClassElement cls = currentNonClosureClass; 3703 ClassElement cls = currentNonClosureClass;
3704 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); 3704 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
3705 if (compiler.enabledInvokeOn 3705 if (compiler.enabledInvokeOn
3706 && element.enclosingElement.declaration != compiler.objectClass) { 3706 && element.enclosingElement.declaration != compiler.objectClass) {
3707 // Register the call as dynamic if [noSuchMethod] on the super 3707 // Register the call as dynamic if [noSuchMethod] on the super
3708 // class is _not_ the default implementation from [Object], in 3708 // class is _not_ the default implementation from [Object], in
3709 // case the [noSuchMethod] implementation calls 3709 // case the [noSuchMethod] implementation calls
3710 // [JSInvocationMirror._invokeOn]. 3710 // [JSInvocationMirror._invokeOn].
3711 compiler.enqueuer.codegen.registerSelectorUse(selector.asUntyped); 3711 compiler.enqueuer.codegen.registerSelectorUse(selector.asUntyped);
3712 } 3712 }
3713 String publicName = name; 3713 String publicName = name;
3714 if (selector.isSetter()) publicName += '='; 3714 if (selector.isSetter) publicName += '=';
3715 3715
3716 Constant nameConstant = constantSystem.createString( 3716 Constant nameConstant = constantSystem.createString(
3717 new ast.DartString.literal(publicName)); 3717 new ast.DartString.literal(publicName));
3718 3718
3719 String internalName = backend.namer.invocationName(selector); 3719 String internalName = backend.namer.invocationName(selector);
3720 Constant internalNameConstant = 3720 Constant internalNameConstant =
3721 constantSystem.createString(new ast.DartString.literal(internalName)); 3721 constantSystem.createString(new ast.DartString.literal(internalName));
3722 3722
3723 Element createInvocationMirror = backend.getCreateInvocationMirror(); 3723 Element createInvocationMirror = backend.getCreateInvocationMirror();
3724 var argumentsInstruction = buildLiteralList(arguments); 3724 var argumentsInstruction = buildLiteralList(arguments);
(...skipping 30 matching lines...) Expand all
3755 if (Elements.isUnresolved(element)) { 3755 if (Elements.isUnresolved(element)) {
3756 List<HInstruction> arguments = <HInstruction>[]; 3756 List<HInstruction> arguments = <HInstruction>[];
3757 if (!node.isPropertyAccess) { 3757 if (!node.isPropertyAccess) {
3758 addGenericSendArgumentsToList(node.arguments, arguments); 3758 addGenericSendArgumentsToList(node.arguments, arguments);
3759 } 3759 }
3760 return generateSuperNoSuchMethodSend(node, selector, arguments); 3760 return generateSuperNoSuchMethodSend(node, selector, arguments);
3761 } 3761 }
3762 List<HInstruction> inputs = <HInstruction>[]; 3762 List<HInstruction> inputs = <HInstruction>[];
3763 if (node.isPropertyAccess) { 3763 if (node.isPropertyAccess) {
3764 push(buildInvokeSuper(selector, element, inputs)); 3764 push(buildInvokeSuper(selector, element, inputs));
3765 } else if (element.isFunction() || element.isGenerativeConstructor()) { 3765 } else if (element.isFunction || element.isGenerativeConstructor) {
3766 if (selector.applies(element, compiler)) { 3766 if (selector.applies(element, compiler)) {
3767 // TODO(5347): Try to avoid the need for calling [implementation] before 3767 // TODO(5347): Try to avoid the need for calling [implementation] before
3768 // calling [addStaticSendArgumentsToList]. 3768 // calling [addStaticSendArgumentsToList].
3769 FunctionElement function = element.implementation; 3769 FunctionElement function = element.implementation;
3770 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 3770 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
3771 function, inputs); 3771 function, inputs);
3772 assert(succeeded); 3772 assert(succeeded);
3773 push(buildInvokeSuper(selector, element, inputs)); 3773 push(buildInvokeSuper(selector, element, inputs));
3774 } else if (element.isGenerativeConstructor()) { 3774 } else if (element.isGenerativeConstructor) {
3775 generateWrongArgumentCountError(node, element, node.arguments); 3775 generateWrongArgumentCountError(node, element, node.arguments);
3776 } else { 3776 } else {
3777 addGenericSendArgumentsToList(node.arguments, inputs); 3777 addGenericSendArgumentsToList(node.arguments, inputs);
3778 generateSuperNoSuchMethodSend(node, selector, inputs); 3778 generateSuperNoSuchMethodSend(node, selector, inputs);
3779 } 3779 }
3780 } else { 3780 } else {
3781 HInstruction target = buildInvokeSuper(selector, element, inputs); 3781 HInstruction target = buildInvokeSuper(selector, element, inputs);
3782 add(target); 3782 add(target);
3783 inputs = <HInstruction>[target]; 3783 inputs = <HInstruction>[target];
3784 addDynamicSendArgumentsToList(node, inputs); 3784 addDynamicSendArgumentsToList(node, inputs);
(...skipping 12 matching lines...) Expand all
3797 } 3797 }
3798 3798
3799 /** 3799 /**
3800 * Generate code to extract the type arguments from the object, substitute 3800 * Generate code to extract the type arguments from the object, substitute
3801 * them as an instance of the type we are testing against (if necessary), and 3801 * them as an instance of the type we are testing against (if necessary), and
3802 * extract the type argument by the index of the variable in the list of type 3802 * extract the type argument by the index of the variable in the list of type
3803 * variables for that class. 3803 * variables for that class.
3804 */ 3804 */
3805 HInstruction readTypeVariable(ClassElement cls, 3805 HInstruction readTypeVariable(ClassElement cls,
3806 TypeVariableElement variable) { 3806 TypeVariableElement variable) {
3807 assert(sourceElement.isInstanceMember()); 3807 assert(sourceElement.isInstanceMember);
3808 3808
3809 HInstruction target = localsHandler.readThis(); 3809 HInstruction target = localsHandler.readThis();
3810 HConstant index = graph.addConstantInt( 3810 HConstant index = graph.addConstantInt(
3811 RuntimeTypes.getTypeVariableIndex(variable), 3811 RuntimeTypes.getTypeVariableIndex(variable),
3812 compiler); 3812 compiler);
3813 3813
3814 if (needsSubstitutionForTypeVariableAccess(cls)) { 3814 if (needsSubstitutionForTypeVariableAccess(cls)) {
3815 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to 3815 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to
3816 // string concatenation in the implementation), and may prevent 3816 // string concatenation in the implementation), and may prevent
3817 // segmentation of '$'. 3817 // segmentation of '$'.
(...skipping 18 matching lines...) Expand all
3836 bool hasDirectLocal(Element element) { 3836 bool hasDirectLocal(Element element) {
3837 return !localsHandler.isAccessedDirectly(element) || 3837 return !localsHandler.isAccessedDirectly(element) ||
3838 localsHandler.directLocals[element] != null; 3838 localsHandler.directLocals[element] != null;
3839 } 3839 }
3840 3840
3841 /** 3841 /**
3842 * Helper to create an instruction that gets the value of a type variable. 3842 * Helper to create an instruction that gets the value of a type variable.
3843 */ 3843 */
3844 HInstruction addTypeVariableReference(TypeVariableType type) { 3844 HInstruction addTypeVariableReference(TypeVariableType type) {
3845 Element member = sourceElement; 3845 Element member = sourceElement;
3846 bool isClosure = member.enclosingElement.isClosure(); 3846 bool isClosure = member.enclosingElement.isClosure;
3847 if (isClosure) { 3847 if (isClosure) {
3848 ClosureClassElement closureClass = member.enclosingElement; 3848 ClosureClassElement closureClass = member.enclosingElement;
3849 member = closureClass.methodElement; 3849 member = closureClass.methodElement;
3850 member = member.getOutermostEnclosingMemberOrTopLevel(); 3850 member = member.outermostEnclosingMemberOrTopLevel;
3851 } 3851 }
3852 bool isInConstructorContext = member.isConstructor() || 3852 bool isInConstructorContext = member.isConstructor ||
3853 member.isGenerativeConstructorBody(); 3853 member.isGenerativeConstructorBody;
3854 if (isClosure) { 3854 if (isClosure) {
3855 if (member.isFactoryConstructor() || 3855 if (member.isFactoryConstructor ||
3856 (isInConstructorContext && hasDirectLocal(type.element))) { 3856 (isInConstructorContext && hasDirectLocal(type.element))) {
3857 // The type variable is used from a closure in a factory constructor. 3857 // The type variable is used from a closure in a factory constructor.
3858 // The value of the type argument is stored as a local on the closure 3858 // The value of the type argument is stored as a local on the closure
3859 // itself. 3859 // itself.
3860 return localsHandler.readLocal(type.element); 3860 return localsHandler.readLocal(type.element);
3861 } else if (member.isFunction() || 3861 } else if (member.isFunction ||
3862 member.isGetter() || 3862 member.isGetter ||
3863 member.isSetter() || 3863 member.isSetter ||
3864 isInConstructorContext) { 3864 isInConstructorContext) {
3865 // The type variable is stored on the "enclosing object" and needs to be 3865 // The type variable is stored on the "enclosing object" and needs to be
3866 // accessed using the this-reference in the closure. 3866 // accessed using the this-reference in the closure.
3867 return readTypeVariable(member.getEnclosingClass(), type.element); 3867 return readTypeVariable(member.enclosingClass, type.element);
3868 } else { 3868 } else {
3869 assert(member.isField()); 3869 assert(member.isField);
3870 // The type variable is stored in a parameter of the method. 3870 // The type variable is stored in a parameter of the method.
3871 return localsHandler.readLocal(type.element); 3871 return localsHandler.readLocal(type.element);
3872 } 3872 }
3873 } else if (isInConstructorContext || 3873 } else if (isInConstructorContext ||
3874 // When [member] is a field, we can be either 3874 // When [member] is a field, we can be either
3875 // generating a checked setter or inlining its 3875 // generating a checked setter or inlining its
3876 // initializer in a constructor. An initializer is 3876 // initializer in a constructor. An initializer is
3877 // never built standalone, so [isBuildingFor] will 3877 // never built standalone, so [isBuildingFor] will
3878 // always return true when seeing one. 3878 // always return true when seeing one.
3879 (member.isField() && !isBuildingFor(member))) { 3879 (member.isField && !isBuildingFor(member))) {
3880 // The type variable is stored in a parameter of the method. 3880 // The type variable is stored in a parameter of the method.
3881 return localsHandler.readLocal(type.element); 3881 return localsHandler.readLocal(type.element);
3882 } else if (member.isInstanceMember()) { 3882 } else if (member.isInstanceMember) {
3883 // The type variable is stored on the object. 3883 // The type variable is stored on the object.
3884 return readTypeVariable(member.getEnclosingClass(), 3884 return readTypeVariable(member.enclosingClass,
3885 type.element); 3885 type.element);
3886 } else { 3886 } else {
3887 // TODO(ngeoffray): Match the VM behavior and throw an 3887 // TODO(ngeoffray): Match the VM behavior and throw an
3888 // exception at runtime. 3888 // exception at runtime.
3889 compiler.internalError(type.element, 3889 compiler.internalError(type.element,
3890 'Unimplemented unresolved type variable.'); 3890 'Unimplemented unresolved type variable.');
3891 return null; 3891 return null;
3892 } 3892 }
3893 } 3893 }
3894 3894
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3986 TypeMask inferred = 3986 TypeMask inferred =
3987 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); 3987 TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
3988 return inferred.containsAll(compiler) 3988 return inferred.containsAll(compiler)
3989 ? backend.extendableArrayType 3989 ? backend.extendableArrayType
3990 : inferred; 3990 : inferred;
3991 } else if (Elements.isConstructorOfTypedArraySubclass( 3991 } else if (Elements.isConstructorOfTypedArraySubclass(
3992 originalElement, compiler)) { 3992 originalElement, compiler)) {
3993 isFixedList = true; 3993 isFixedList = true;
3994 TypeMask inferred = 3994 TypeMask inferred =
3995 TypeMaskFactory.inferredForNode(sourceElement, send, compiler); 3995 TypeMaskFactory.inferredForNode(sourceElement, send, compiler);
3996 ClassElement cls = element.getEnclosingClass(); 3996 ClassElement cls = element.enclosingClass;
3997 assert(cls.thisType.element.isNative()); 3997 assert(cls.thisType.element.isNative);
3998 return inferred.containsAll(compiler) 3998 return inferred.containsAll(compiler)
3999 ? new TypeMask.nonNullExact(cls.thisType.element) 3999 ? new TypeMask.nonNullExact(cls.thisType.element)
4000 : inferred; 4000 : inferred;
4001 } else if (element.isGenerativeConstructor()) { 4001 } else if (element.isGenerativeConstructor) {
4002 ClassElement cls = element.getEnclosingClass(); 4002 ClassElement cls = element.enclosingClass;
4003 return new TypeMask.nonNullExact(cls.thisType.element); 4003 return new TypeMask.nonNullExact(cls.thisType.element);
4004 } else { 4004 } else {
4005 return TypeMaskFactory.inferredReturnTypeForElement( 4005 return TypeMaskFactory.inferredReturnTypeForElement(
4006 originalElement, compiler); 4006 originalElement, compiler);
4007 } 4007 }
4008 } 4008 }
4009 4009
4010 Element constructor = elements[send]; 4010 Element constructor = elements[send];
4011 Selector selector = elements.getSelector(send); 4011 Selector selector = elements.getSelector(send);
4012 FunctionElement functionElement = constructor; 4012 FunctionElement functionElement = constructor;
(...skipping 13 matching lines...) Expand all
4026 message: 'Constructor Symbol.validated is missing')); 4026 message: 'Constructor Symbol.validated is missing'));
4027 } 4027 }
4028 4028
4029 bool isRedirected = functionElement.isRedirectingFactory; 4029 bool isRedirected = functionElement.isRedirectingFactory;
4030 InterfaceType type = elements.getType(node); 4030 InterfaceType type = elements.getType(node);
4031 InterfaceType expectedType = functionElement.computeTargetType(type); 4031 InterfaceType expectedType = functionElement.computeTargetType(type);
4032 4032
4033 if (checkTypeVariableBounds(node, type)) return; 4033 if (checkTypeVariableBounds(node, type)) return;
4034 4034
4035 var inputs = <HInstruction>[]; 4035 var inputs = <HInstruction>[];
4036 if (constructor.isGenerativeConstructor() && 4036 if (constructor.isGenerativeConstructor &&
4037 Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) { 4037 Elements.isNativeOrExtendsNative(constructor.enclosingClass)) {
4038 // Native class generative constructors take a pre-constructed object. 4038 // Native class generative constructors take a pre-constructed object.
4039 inputs.add(graph.addConstantNull(compiler)); 4039 inputs.add(graph.addConstantNull(compiler));
4040 } 4040 }
4041 // TODO(5347): Try to avoid the need for calling [implementation] before 4041 // TODO(5347): Try to avoid the need for calling [implementation] before
4042 // calling [addStaticSendArgumentsToList]. 4042 // calling [addStaticSendArgumentsToList].
4043 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, 4043 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments,
4044 constructor.implementation, 4044 constructor.implementation,
4045 inputs); 4045 inputs);
4046 if (!succeeded) { 4046 if (!succeeded) {
4047 generateWrongArgumentCountError(send, constructor, send.arguments); 4047 generateWrongArgumentCountError(send, constructor, send.arguments);
4048 return; 4048 return;
4049 } 4049 }
4050 4050
4051 if (constructor.isFactoryConstructor() && 4051 if (constructor.isFactoryConstructor &&
4052 !expectedType.typeArguments.isEmpty) { 4052 !expectedType.typeArguments.isEmpty) {
4053 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); 4053 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
4054 } 4054 }
4055 4055
4056 TypeMask elementType = computeType(constructor); 4056 TypeMask elementType = computeType(constructor);
4057 if (isFixedListConstructorCall) { 4057 if (isFixedListConstructorCall) {
4058 if (!inputs[0].isNumber(compiler)) { 4058 if (!inputs[0].isNumber(compiler)) {
4059 HTypeConversion conversion = new HTypeConversion( 4059 HTypeConversion conversion = new HTypeConversion(
4060 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType, 4060 null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType,
4061 inputs[0], null); 4061 inputs[0], null);
(...skipping 19 matching lines...) Expand all
4081 js.Template code = js.js.parseForeignJS(r'#.fixed$length = init'); 4081 js.Template code = js.js.parseForeignJS(r'#.fixed$length = init');
4082 // We set the instruction as [canThrow] to avoid it being dead code. 4082 // We set the instruction as [canThrow] to avoid it being dead code.
4083 // We need a finer grained side effect. 4083 // We need a finer grained side effect.
4084 add(new HForeign( 4084 add(new HForeign(
4085 code, backend.nullType, [stack.last], canThrow: true)); 4085 code, backend.nullType, [stack.last], canThrow: true));
4086 } 4086 }
4087 } else if (isGrowableListConstructorCall) { 4087 } else if (isGrowableListConstructorCall) {
4088 push(buildLiteralList(<HInstruction>[])); 4088 push(buildLiteralList(<HInstruction>[]));
4089 stack.last.instructionType = elementType; 4089 stack.last.instructionType = elementType;
4090 } else { 4090 } else {
4091 ClassElement cls = constructor.getEnclosingClass(); 4091 ClassElement cls = constructor.enclosingClass;
4092 if (cls.isAbstract && constructor.isGenerativeConstructor()) { 4092 if (cls.isAbstract && constructor.isGenerativeConstructor) {
4093 generateAbstractClassInstantiationError(send, cls.name); 4093 generateAbstractClassInstantiationError(send, cls.name);
4094 return; 4094 return;
4095 } 4095 }
4096 if (backend.classNeedsRti(cls)) { 4096 if (backend.classNeedsRti(cls)) {
4097 Link<DartType> typeVariable = cls.typeVariables; 4097 Link<DartType> typeVariable = cls.typeVariables;
4098 expectedType.typeArguments.forEach((DartType argument) { 4098 expectedType.typeArguments.forEach((DartType argument) {
4099 inputs.add(analyzeTypeArgument(argument)); 4099 inputs.add(analyzeTypeArgument(argument));
4100 typeVariable = typeVariable.tail; 4100 typeVariable = typeVariable.tail;
4101 }); 4101 });
4102 assert(typeVariable.isEmpty); 4102 assert(typeVariable.isEmpty);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 if (!compiler.enableUserAssertions) { 4196 if (!compiler.enableUserAssertions) {
4197 stack.add(graph.addConstantNull(compiler)); 4197 stack.add(graph.addConstantNull(compiler));
4198 return; 4198 return;
4199 } 4199 }
4200 visitStaticSend(node); 4200 visitStaticSend(node);
4201 } 4201 }
4202 4202
4203 visitStaticSend(ast.Send node) { 4203 visitStaticSend(ast.Send node) {
4204 Selector selector = elements.getSelector(node); 4204 Selector selector = elements.getSelector(node);
4205 Element element = elements[node]; 4205 Element element = elements[node];
4206 if (element.isForeign(compiler) && element.isFunction()) { 4206 if (element.isForeign(compiler) && element.isFunction) {
4207 visitForeignSend(node); 4207 visitForeignSend(node);
4208 return; 4208 return;
4209 } 4209 }
4210 if (element.isErroneous()) { 4210 if (element.isErroneous) {
4211 // An erroneous element indicates that the funciton could not be resolved 4211 // An erroneous element indicates that the funciton could not be resolved
4212 // (a warning has been issued). 4212 // (a warning has been issued).
4213 generateThrowNoSuchMethod(node, 4213 generateThrowNoSuchMethod(node,
4214 getTargetName(element), 4214 getTargetName(element),
4215 argumentNodes: node.arguments); 4215 argumentNodes: node.arguments);
4216 return; 4216 return;
4217 } 4217 }
4218 invariant(element, !element.isGenerativeConstructor()); 4218 invariant(element, !element.isGenerativeConstructor);
4219 generateIsDeferredLoadedCheckIfNeeded(node); 4219 generateIsDeferredLoadedCheckIfNeeded(node);
4220 if (element.isFunction()) { 4220 if (element.isFunction) {
4221 var inputs = <HInstruction>[]; 4221 var inputs = <HInstruction>[];
4222 // TODO(5347): Try to avoid the need for calling [implementation] before 4222 // TODO(5347): Try to avoid the need for calling [implementation] before
4223 // calling [addStaticSendArgumentsToList]. 4223 // calling [addStaticSendArgumentsToList].
4224 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 4224 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
4225 element.implementation, 4225 element.implementation,
4226 inputs); 4226 inputs);
4227 if (!succeeded) { 4227 if (!succeeded) {
4228 generateWrongArgumentCountError(node, element, node.arguments); 4228 generateWrongArgumentCountError(node, element, node.arguments);
4229 return; 4229 return;
4230 } 4230 }
(...skipping 17 matching lines...) Expand all
4248 } 4248 }
4249 4249
4250 HConstant addConstantString(String string) { 4250 HConstant addConstantString(String string) {
4251 ast.DartString dartString = new ast.DartString.literal(string); 4251 ast.DartString dartString = new ast.DartString.literal(string);
4252 Constant constant = constantSystem.createString(dartString); 4252 Constant constant = constantSystem.createString(dartString);
4253 return graph.addConstant(constant, compiler); 4253 return graph.addConstant(constant, compiler);
4254 } 4254 }
4255 4255
4256 visitTypeReferenceSend(ast.Send node) { 4256 visitTypeReferenceSend(ast.Send node) {
4257 Element element = elements[node]; 4257 Element element = elements[node];
4258 if (element.isClass() || element.isTypedef()) { 4258 if (element.isClass || element.isTypedef) {
4259 // TODO(karlklose): add type representation 4259 // TODO(karlklose): add type representation
4260 if (node.isCall) { 4260 if (node.isCall) {
4261 // The node itself is not a constant but we register the selector (the 4261 // The node itself is not a constant but we register the selector (the
4262 // identifier that refers to the class/typedef) as a constant. 4262 // identifier that refers to the class/typedef) as a constant.
4263 stack.add(addConstant(node.selector)); 4263 stack.add(addConstant(node.selector));
4264 } else { 4264 } else {
4265 stack.add(addConstant(node)); 4265 stack.add(addConstant(node));
4266 } 4266 }
4267 } else if (element.isTypeVariable()) { 4267 } else if (element.isTypeVariable) {
4268 TypeVariableElement typeVariable = element; 4268 TypeVariableElement typeVariable = element;
4269 HInstruction value = addTypeVariableReference(typeVariable.type); 4269 HInstruction value = addTypeVariableReference(typeVariable.type);
4270 pushInvokeStatic(node, 4270 pushInvokeStatic(node,
4271 backend.getRuntimeTypeToString(), 4271 backend.getRuntimeTypeToString(),
4272 [value], 4272 [value],
4273 backend.stringType); 4273 backend.stringType);
4274 pushInvokeStatic(node, 4274 pushInvokeStatic(node,
4275 backend.getCreateRuntimeType(), 4275 backend.getCreateRuntimeType(),
4276 [pop()]); 4276 [pop()]);
4277 } else { 4277 } else {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
4389 if (Elements.isErroneousElement(element)) { 4389 if (Elements.isErroneousElement(element)) {
4390 ErroneousElement error = element; 4390 ErroneousElement error = element;
4391 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { 4391 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
4392 generateThrowNoSuchMethod(node.send, 4392 generateThrowNoSuchMethod(node.send,
4393 getTargetName(error, 'constructor'), 4393 getTargetName(error, 'constructor'),
4394 argumentNodes: node.send.arguments); 4394 argumentNodes: node.send.arguments);
4395 } else { 4395 } else {
4396 Message message = error.messageKind.message(error.messageArguments); 4396 Message message = error.messageKind.message(error.messageArguments);
4397 generateRuntimeError(node.send, message.toString()); 4397 generateRuntimeError(node.send, message.toString());
4398 } 4398 }
4399 } else if (node.isConst()) { 4399 } else if (node.isConst) {
4400 stack.add(addConstant(node)); 4400 stack.add(addConstant(node));
4401 if (isSymbolConstructor) { 4401 if (isSymbolConstructor) {
4402 ConstructedConstant symbol = getConstantForNode(node); 4402 ConstructedConstant symbol = getConstantForNode(node);
4403 StringConstant stringConstant = symbol.fields.single; 4403 StringConstant stringConstant = symbol.fields.single;
4404 String nameString = stringConstant.toDartString().slowToString(); 4404 String nameString = stringConstant.toDartString().slowToString();
4405 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); 4405 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements);
4406 } 4406 }
4407 } else { 4407 } else {
4408 handleNewSend(node); 4408 handleNewSend(node);
4409 } 4409 }
4410 } 4410 }
4411 4411
4412 void pushInvokeDynamic(ast.Node node, 4412 void pushInvokeDynamic(ast.Node node,
4413 Selector selector, 4413 Selector selector,
4414 List<HInstruction> arguments, 4414 List<HInstruction> arguments,
4415 {ast.Node location}) { 4415 {ast.Node location}) {
4416 if (location == null) location = node; 4416 if (location == null) location = node;
4417 4417
4418 // We prefer to not inline certain operations on indexables, 4418 // We prefer to not inline certain operations on indexables,
4419 // because the constant folder will handle them better and turn 4419 // because the constant folder will handle them better and turn
4420 // them into simpler instructions that allow further 4420 // them into simpler instructions that allow further
4421 // optimizations. 4421 // optimizations.
4422 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { 4422 bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
4423 bool isLength = selector.isGetter() 4423 bool isLength = selector.isGetter
4424 && selector.name == "length"; 4424 && selector.name == "length";
4425 if (isLength || selector.isIndex()) { 4425 if (isLength || selector.isIndex) {
4426 TypeMask type = new TypeMask.nonNullExact( 4426 TypeMask type = new TypeMask.nonNullExact(
4427 element.getEnclosingClass().declaration); 4427 element.enclosingClass.declaration);
4428 return type.satisfies(backend.jsIndexableClass, compiler); 4428 return type.satisfies(backend.jsIndexableClass, compiler);
4429 } else if (selector.isIndexSet()) { 4429 } else if (selector.isIndexSet) {
4430 TypeMask type = new TypeMask.nonNullExact( 4430 TypeMask type = new TypeMask.nonNullExact(
4431 element.getEnclosingClass().declaration); 4431 element.enclosingClass.declaration);
4432 return type.satisfies(backend.jsMutableIndexableClass, compiler); 4432 return type.satisfies(backend.jsMutableIndexableClass, compiler);
4433 } else { 4433 } else {
4434 return false; 4434 return false;
4435 } 4435 }
4436 } 4436 }
4437 4437
4438 bool isOptimizableOperation(Selector selector, Element element) { 4438 bool isOptimizableOperation(Selector selector, Element element) {
4439 ClassElement cls = element.getEnclosingClass(); 4439 ClassElement cls = element.enclosingClass;
4440 if (isOptimizableOperationOnIndexable(selector, element)) return true; 4440 if (isOptimizableOperationOnIndexable(selector, element)) return true;
4441 if (!backend.interceptedClasses.contains(cls)) return false; 4441 if (!backend.interceptedClasses.contains(cls)) return false;
4442 if (selector.isOperator()) return true; 4442 if (selector.isOperator) return true;
4443 if (selector.isSetter()) return true; 4443 if (selector.isSetter) return true;
4444 if (selector.isIndex()) return true; 4444 if (selector.isIndex) return true;
4445 if (selector.isIndexSet()) return true; 4445 if (selector.isIndexSet) return true;
4446 if (element == backend.jsArrayAdd 4446 if (element == backend.jsArrayAdd
4447 || element == backend.jsArrayRemoveLast 4447 || element == backend.jsArrayRemoveLast
4448 || element == backend.jsStringSplit) { 4448 || element == backend.jsStringSplit) {
4449 return true; 4449 return true;
4450 } 4450 }
4451 return false; 4451 return false;
4452 } 4452 }
4453 4453
4454 Element element = compiler.world.locateSingleElement(selector); 4454 Element element = compiler.world.locateSingleElement(selector);
4455 if (element != null 4455 if (element != null
4456 && !element.isField() 4456 && !element.isField
4457 && !(element.isGetter() && selector.isCall()) 4457 && !(element.isGetter && selector.isCall)
4458 && !(element.isFunction() && selector.isGetter()) 4458 && !(element.isFunction && selector.isGetter)
4459 && !isOptimizableOperation(selector, element)) { 4459 && !isOptimizableOperation(selector, element)) {
4460 if (tryInlineMethod(element, selector, arguments, node)) { 4460 if (tryInlineMethod(element, selector, arguments, node)) {
4461 return; 4461 return;
4462 } 4462 }
4463 } 4463 }
4464 4464
4465 HInstruction receiver = arguments[0]; 4465 HInstruction receiver = arguments[0];
4466 List<HInstruction> inputs = <HInstruction>[]; 4466 List<HInstruction> inputs = <HInstruction>[];
4467 bool isIntercepted = backend.isInterceptedSelector(selector); 4467 bool isIntercepted = backend.isInterceptedSelector(selector);
4468 if (isIntercepted) { 4468 if (isIntercepted) {
4469 inputs.add(invokeInterceptor(receiver)); 4469 inputs.add(invokeInterceptor(receiver));
4470 } 4470 }
4471 inputs.addAll(arguments); 4471 inputs.addAll(arguments);
4472 TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler); 4472 TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
4473 if (selector.isGetter()) { 4473 if (selector.isGetter) {
4474 pushWithPosition( 4474 pushWithPosition(
4475 new HInvokeDynamicGetter(selector, null, inputs, type), 4475 new HInvokeDynamicGetter(selector, null, inputs, type),
4476 location); 4476 location);
4477 } else if (selector.isSetter()) { 4477 } else if (selector.isSetter) {
4478 pushWithPosition( 4478 pushWithPosition(
4479 new HInvokeDynamicSetter(selector, null, inputs, type), 4479 new HInvokeDynamicSetter(selector, null, inputs, type),
4480 location); 4480 location);
4481 } else { 4481 } else {
4482 pushWithPosition( 4482 pushWithPosition(
4483 new HInvokeDynamicMethod(selector, inputs, type, isIntercepted), 4483 new HInvokeDynamicMethod(selector, inputs, type, isIntercepted),
4484 location); 4484 location);
4485 } 4485 }
4486 } 4486 }
4487 4487
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4522 List<HInstruction> inputs = <HInstruction>[]; 4522 List<HInstruction> inputs = <HInstruction>[];
4523 if (backend.isInterceptedSelector(selector) && 4523 if (backend.isInterceptedSelector(selector) &&
4524 // Fields don't need an interceptor; consider generating HFieldGet/Set 4524 // Fields don't need an interceptor; consider generating HFieldGet/Set
4525 // instead. 4525 // instead.
4526 element.kind != ElementKind.FIELD) { 4526 element.kind != ElementKind.FIELD) {
4527 inputs.add(invokeInterceptor(receiver)); 4527 inputs.add(invokeInterceptor(receiver));
4528 } 4528 }
4529 inputs.add(receiver); 4529 inputs.add(receiver);
4530 inputs.addAll(arguments); 4530 inputs.addAll(arguments);
4531 TypeMask type; 4531 TypeMask type;
4532 if (!element.isGetter() && selector.isGetter()) { 4532 if (!element.isGetter && selector.isGetter) {
4533 type = TypeMaskFactory.inferredTypeForElement(element, compiler); 4533 type = TypeMaskFactory.inferredTypeForElement(element, compiler);
4534 } else { 4534 } else {
4535 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 4535 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
4536 } 4536 }
4537 HInstruction instruction = new HInvokeSuper( 4537 HInstruction instruction = new HInvokeSuper(
4538 element, 4538 element,
4539 currentNonClosureClass, 4539 currentNonClosureClass,
4540 selector, 4540 selector,
4541 inputs, 4541 inputs,
4542 type, 4542 type,
4543 isSetter: selector.isSetter() || selector.isIndexSet()); 4543 isSetter: selector.isSetter || selector.isIndexSet);
4544 instruction.sideEffects = compiler.world.getSideEffectsOfSelector(selector); 4544 instruction.sideEffects = compiler.world.getSideEffectsOfSelector(selector);
4545 return instruction; 4545 return instruction;
4546 } 4546 }
4547 4547
4548 void handleComplexOperatorSend(ast.SendSet node, 4548 void handleComplexOperatorSend(ast.SendSet node,
4549 HInstruction receiver, 4549 HInstruction receiver,
4550 Link<ast.Node> arguments) { 4550 Link<ast.Node> arguments) {
4551 HInstruction rhs; 4551 HInstruction rhs;
4552 if (node.isPrefix || node.isPostfix) { 4552 if (node.isPrefix || node.isPostfix) {
4553 rhs = graph.addConstantInt(1, compiler); 4553 rhs = graph.addConstantInt(1, compiler);
4554 } else { 4554 } else {
4555 visit(arguments.head); 4555 visit(arguments.head);
4556 assert(arguments.tail.isEmpty); 4556 assert(arguments.tail.isEmpty);
4557 rhs = pop(); 4557 rhs = pop();
4558 } 4558 }
4559 visitBinary(receiver, node.assignmentOperator, rhs, 4559 visitBinary(receiver, node.assignmentOperator, rhs,
4560 elements.getOperatorSelectorInComplexSendSet(node), node); 4560 elements.getOperatorSelectorInComplexSendSet(node), node);
4561 } 4561 }
4562 4562
4563 visitSendSet(ast.SendSet node) { 4563 visitSendSet(ast.SendSet node) {
4564 generateIsDeferredLoadedCheckIfNeeded(node); 4564 generateIsDeferredLoadedCheckIfNeeded(node);
4565 Element element = elements[node]; 4565 Element element = elements[node];
4566 if (!Elements.isUnresolved(element) && element.impliesType()) { 4566 if (!Elements.isUnresolved(element) && element.impliesType) {
4567 ast.Identifier selector = node.selector; 4567 ast.Identifier selector = node.selector;
4568 generateThrowNoSuchMethod(node, selector.source, 4568 generateThrowNoSuchMethod(node, selector.source,
4569 argumentNodes: node.arguments); 4569 argumentNodes: node.arguments);
4570 return; 4570 return;
4571 } 4571 }
4572 ast.Operator op = node.assignmentOperator; 4572 ast.Operator op = node.assignmentOperator;
4573 if (node.isSuperCall) { 4573 if (node.isSuperCall) {
4574 HInstruction result; 4574 HInstruction result;
4575 List<HInstruction> setterInputs = <HInstruction>[]; 4575 List<HInstruction> setterInputs = <HInstruction>[];
4576 if (identical(node.assignmentOperator.source, '=')) { 4576 if (identical(node.assignmentOperator.source, '=')) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4671 } else if (identical(op.source, "is")) { 4671 } else if (identical(op.source, "is")) {
4672 compiler.internalError(op, "is-operator as SendSet."); 4672 compiler.internalError(op, "is-operator as SendSet.");
4673 } else { 4673 } else {
4674 assert("++" == op.source || "--" == op.source || 4674 assert("++" == op.source || "--" == op.source ||
4675 node.assignmentOperator.source.endsWith("=")); 4675 node.assignmentOperator.source.endsWith("="));
4676 4676
4677 // [receiver] is only used if the node is an instance send. 4677 // [receiver] is only used if the node is an instance send.
4678 HInstruction receiver = null; 4678 HInstruction receiver = null;
4679 Element getter = elements[node.selector]; 4679 Element getter = elements[node.selector];
4680 4680
4681 if (!Elements.isUnresolved(getter) && getter.impliesType()) { 4681 if (!Elements.isUnresolved(getter) && getter.impliesType) {
4682 ast.Identifier selector = node.selector; 4682 ast.Identifier selector = node.selector;
4683 generateThrowNoSuchMethod(node, selector.source, 4683 generateThrowNoSuchMethod(node, selector.source,
4684 argumentNodes: node.arguments); 4684 argumentNodes: node.arguments);
4685 return; 4685 return;
4686 } else if (Elements.isInstanceSend(node, elements)) { 4686 } else if (Elements.isInstanceSend(node, elements)) {
4687 receiver = generateInstanceSendReceiver(node); 4687 receiver = generateInstanceSendReceiver(node);
4688 generateInstanceGetterWithCompiledReceiver( 4688 generateInstanceGetterWithCompiledReceiver(
4689 node, elements.getGetterSelectorInComplexSendSet(node), receiver); 4689 node, elements.getGetterSelectorInComplexSendSet(node), receiver);
4690 } else { 4690 } else {
4691 generateGetter(node, getter); 4691 generateGetter(node, getter);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4790 if (exception == null) { 4790 if (exception == null) {
4791 exception = graph.addConstantNull(compiler); 4791 exception = graph.addConstantNull(compiler);
4792 compiler.internalError(node, 4792 compiler.internalError(node,
4793 'rethrowableException should not be null.'); 4793 'rethrowableException should not be null.');
4794 } 4794 }
4795 handleInTryStatement(); 4795 handleInTryStatement();
4796 closeAndGotoExit(new HThrow(exception, isRethrow: true)); 4796 closeAndGotoExit(new HThrow(exception, isRethrow: true));
4797 } 4797 }
4798 4798
4799 visitReturn(ast.Return node) { 4799 visitReturn(ast.Return node) {
4800 if (identical(node.getBeginToken().stringValue, 'native')) { 4800 if (identical(node.beginToken.stringValue, 'native')) {
4801 native.handleSsaNative(this, node.expression); 4801 native.handleSsaNative(this, node.expression);
4802 return; 4802 return;
4803 } 4803 }
4804 HInstruction value; 4804 HInstruction value;
4805 if (node.isRedirectingFactoryBody) { 4805 if (node.isRedirectingFactoryBody) {
4806 FunctionElement targetConstructor = 4806 FunctionElement targetConstructor =
4807 elements[node.expression].implementation; 4807 elements[node.expression].implementation;
4808 FunctionElement redirectingConstructor = sourceElement; 4808 FunctionElement redirectingConstructor = sourceElement;
4809 List<HInstruction> inputs = <HInstruction>[]; 4809 List<HInstruction> inputs = <HInstruction>[];
4810 FunctionSignature targetSignature = targetConstructor.functionSignature; 4810 FunctionSignature targetSignature = targetConstructor.functionSignature;
4811 FunctionSignature redirectingSignature = 4811 FunctionSignature redirectingSignature =
4812 redirectingConstructor.functionSignature; 4812 redirectingConstructor.functionSignature;
4813 redirectingSignature.forEachRequiredParameter((Element element) { 4813 redirectingSignature.forEachRequiredParameter((Element element) {
4814 inputs.add(localsHandler.readLocal(element)); 4814 inputs.add(localsHandler.readLocal(element));
4815 }); 4815 });
4816 List<Element> targetOptionals = 4816 List<Element> targetOptionals =
4817 targetSignature.orderedOptionalParameters; 4817 targetSignature.orderedOptionalParameters;
4818 List<Element> redirectingOptionals = 4818 List<Element> redirectingOptionals =
4819 redirectingSignature.orderedOptionalParameters; 4819 redirectingSignature.orderedOptionalParameters;
4820 int i = 0; 4820 int i = 0;
4821 for (; i < redirectingOptionals.length; i++) { 4821 for (; i < redirectingOptionals.length; i++) {
4822 inputs.add(localsHandler.readLocal(redirectingOptionals[i])); 4822 inputs.add(localsHandler.readLocal(redirectingOptionals[i]));
4823 } 4823 }
4824 for (; i < targetOptionals.length; i++) { 4824 for (; i < targetOptionals.length; i++) {
4825 inputs.add(handleConstantForOptionalParameter(targetOptionals[i])); 4825 inputs.add(handleConstantForOptionalParameter(targetOptionals[i]));
4826 } 4826 }
4827 4827
4828 ClassElement targetClass = targetConstructor.getEnclosingClass(); 4828 ClassElement targetClass = targetConstructor.enclosingClass;
4829 if (backend.classNeedsRti(targetClass)) { 4829 if (backend.classNeedsRti(targetClass)) {
4830 ClassElement cls = redirectingConstructor.getEnclosingClass(); 4830 ClassElement cls = redirectingConstructor.enclosingClass;
4831 InterfaceType targetType = 4831 InterfaceType targetType =
4832 redirectingConstructor.computeTargetType(cls.thisType); 4832 redirectingConstructor.computeTargetType(cls.thisType);
4833 targetType.typeArguments.forEach((DartType argument) { 4833 targetType.typeArguments.forEach((DartType argument) {
4834 inputs.add(analyzeTypeArgument(argument)); 4834 inputs.add(analyzeTypeArgument(argument));
4835 }); 4835 });
4836 } 4836 }
4837 pushInvokeStatic(node, targetConstructor, inputs); 4837 pushInvokeStatic(node, targetConstructor, inputs);
4838 value = pop(); 4838 value = pop();
4839 } else if (node.expression == null) { 4839 } else if (node.expression == null) {
4840 value = graph.addConstantNull(compiler); 4840 value = graph.addConstantNull(compiler);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4889 arguments.add(analyzeTypeArgument(argument)); 4889 arguments.add(analyzeTypeArgument(argument));
4890 } 4890 }
4891 // TODO(15489): Register at codegen. 4891 // TODO(15489): Register at codegen.
4892 compiler.enqueuer.codegen.registerInstantiatedType(type, elements); 4892 compiler.enqueuer.codegen.registerInstantiatedType(type, elements);
4893 return callSetRuntimeTypeInfo(type.element, arguments, object); 4893 return callSetRuntimeTypeInfo(type.element, arguments, object);
4894 } 4894 }
4895 4895
4896 visitLiteralList(ast.LiteralList node) { 4896 visitLiteralList(ast.LiteralList node) {
4897 HInstruction instruction; 4897 HInstruction instruction;
4898 4898
4899 if (node.isConst()) { 4899 if (node.isConst) {
4900 instruction = addConstant(node); 4900 instruction = addConstant(node);
4901 } else { 4901 } else {
4902 List<HInstruction> inputs = <HInstruction>[]; 4902 List<HInstruction> inputs = <HInstruction>[];
4903 for (Link<ast.Node> link = node.elements.nodes; 4903 for (Link<ast.Node> link = node.elements.nodes;
4904 !link.isEmpty; 4904 !link.isEmpty;
4905 link = link.tail) { 4905 link = link.tail) {
4906 visit(link.head); 4906 visit(link.head);
4907 inputs.add(pop()); 4907 inputs.add(pop());
4908 } 4908 }
4909 instruction = buildLiteralList(inputs); 4909 instruction = buildLiteralList(inputs);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
5088 // There was at least one reachable break, so the label is needed. 5088 // There was at least one reachable break, so the label is needed.
5089 entryBlock.setBlockFlow( 5089 entryBlock.setBlockFlow(
5090 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph), 5090 new HLabeledBlockInformation(new HSubGraphBlockInformation(bodyGraph),
5091 handler.labels()), 5091 handler.labels()),
5092 joinBlock); 5092 joinBlock);
5093 } 5093 }
5094 handler.close(); 5094 handler.close();
5095 } 5095 }
5096 5096
5097 visitLiteralMap(ast.LiteralMap node) { 5097 visitLiteralMap(ast.LiteralMap node) {
5098 if (node.isConst()) { 5098 if (node.isConst) {
5099 stack.add(addConstant(node)); 5099 stack.add(addConstant(node));
5100 return; 5100 return;
5101 } 5101 }
5102 List<HInstruction> listInputs = <HInstruction>[]; 5102 List<HInstruction> listInputs = <HInstruction>[];
5103 for (Link<ast.Node> link = node.entries.nodes; 5103 for (Link<ast.Node> link = node.entries.nodes;
5104 !link.isEmpty; 5104 !link.isEmpty;
5105 link = link.tail) { 5105 link = link.tail) {
5106 visit(link.head); 5106 visit(link.head);
5107 listInputs.add(pop()); 5107 listInputs.add(pop());
5108 listInputs.add(pop()); 5108 listInputs.add(pop());
5109 } 5109 }
5110 5110
5111 Element constructor; 5111 Element constructor;
5112 List<HInstruction> inputs = <HInstruction>[]; 5112 List<HInstruction> inputs = <HInstruction>[];
5113 5113
5114 if (listInputs.isEmpty) { 5114 if (listInputs.isEmpty) {
5115 constructor = backend.mapLiteralConstructorEmpty; 5115 constructor = backend.mapLiteralConstructorEmpty;
5116 } else { 5116 } else {
5117 constructor = backend.mapLiteralConstructor; 5117 constructor = backend.mapLiteralConstructor;
5118 HLiteralList keyValuePairs = buildLiteralList(listInputs); 5118 HLiteralList keyValuePairs = buildLiteralList(listInputs);
5119 add(keyValuePairs); 5119 add(keyValuePairs);
5120 inputs.add(keyValuePairs); 5120 inputs.add(keyValuePairs);
5121 } 5121 }
5122 5122
5123 assert(constructor.isFactoryConstructor()); 5123 assert(constructor.isFactoryConstructor);
5124 5124
5125 FunctionElement functionElement = constructor; 5125 FunctionElement functionElement = constructor;
5126 constructor = functionElement.redirectionTarget; 5126 constructor = functionElement.redirectionTarget;
5127 5127
5128 InterfaceType type = elements.getType(node); 5128 InterfaceType type = elements.getType(node);
5129 InterfaceType expectedType = functionElement.computeTargetType(type); 5129 InterfaceType expectedType = functionElement.computeTargetType(type);
5130 5130
5131 if (constructor.isFactoryConstructor()) { 5131 if (constructor.isFactoryConstructor) {
5132 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements); 5132 compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
5133 } 5133 }
5134 5134
5135 ClassElement cls = constructor.getEnclosingClass(); 5135 ClassElement cls = constructor.enclosingClass;
5136 5136
5137 if (backend.classNeedsRti(cls)) { 5137 if (backend.classNeedsRti(cls)) {
5138 Link<DartType> typeVariable = cls.typeVariables; 5138 Link<DartType> typeVariable = cls.typeVariables;
5139 expectedType.typeArguments.forEach((DartType argument) { 5139 expectedType.typeArguments.forEach((DartType argument) {
5140 inputs.add(analyzeTypeArgument(argument)); 5140 inputs.add(analyzeTypeArgument(argument));
5141 typeVariable = typeVariable.tail; 5141 typeVariable = typeVariable.tail;
5142 }); 5142 });
5143 assert(typeVariable.isEmpty); 5143 assert(typeVariable.isEmpty);
5144 } 5144 }
5145 5145
(...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after
5937 } 5937 }
5938 5938
5939 void visitRethrow(ast.Rethrow node) { 5939 void visitRethrow(ast.Rethrow node) {
5940 if (!registerNode()) return; 5940 if (!registerNode()) return;
5941 tooDifficult = true; 5941 tooDifficult = true;
5942 } 5942 }
5943 5943
5944 void visitReturn(ast.Return node) { 5944 void visitReturn(ast.Return node) {
5945 if (!registerNode()) return; 5945 if (!registerNode()) return;
5946 if (seenReturn 5946 if (seenReturn
5947 || identical(node.getBeginToken().stringValue, 'native') 5947 || identical(node.beginToken.stringValue, 'native')
5948 || node.isRedirectingFactoryBody) { 5948 || node.isRedirectingFactoryBody) {
5949 tooDifficult = true; 5949 tooDifficult = true;
5950 return; 5950 return;
5951 } 5951 }
5952 node.visitChildren(this); 5952 node.visitChildren(this);
5953 seenReturn = true; 5953 seenReturn = true;
5954 } 5954 }
5955 5955
5956 void visitTryStatement(ast.Node node) { 5956 void visitTryStatement(ast.Node node) {
5957 if (!registerNode()) return; 5957 if (!registerNode()) return;
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
6240 6240
6241 void visitVoidType(VoidType type, SsaBuilder builder) { 6241 void visitVoidType(VoidType type, SsaBuilder builder) {
6242 ClassElement cls = builder.compiler.findHelper('VoidRuntimeType'); 6242 ClassElement cls = builder.compiler.findHelper('VoidRuntimeType');
6243 builder.push(new HVoidType(type, new TypeMask.exact(cls))); 6243 builder.push(new HVoidType(type, new TypeMask.exact(cls)));
6244 } 6244 }
6245 6245
6246 void visitTypeVariableType(TypeVariableType type, 6246 void visitTypeVariableType(TypeVariableType type,
6247 SsaBuilder builder) { 6247 SsaBuilder builder) {
6248 ClassElement cls = builder.compiler.findHelper('RuntimeType'); 6248 ClassElement cls = builder.compiler.findHelper('RuntimeType');
6249 TypeMask instructionType = new TypeMask.subclass(cls); 6249 TypeMask instructionType = new TypeMask.subclass(cls);
6250 if (!builder.sourceElement.enclosingElement.isClosure() && 6250 if (!builder.sourceElement.enclosingElement.isClosure &&
6251 builder.sourceElement.isInstanceMember()) { 6251 builder.sourceElement.isInstanceMember) {
6252 HInstruction receiver = builder.localsHandler.readThis(); 6252 HInstruction receiver = builder.localsHandler.readThis();
6253 builder.push(new HReadTypeVariable(type, receiver, instructionType)); 6253 builder.push(new HReadTypeVariable(type, receiver, instructionType));
6254 } else { 6254 } else {
6255 builder.push( 6255 builder.push(
6256 new HReadTypeVariable.noReceiver( 6256 new HReadTypeVariable.noReceiver(
6257 type, builder.addTypeVariableReference(type), instructionType)); 6257 type, builder.addTypeVariableReference(type), instructionType));
6258 } 6258 }
6259 } 6259 }
6260 6260
6261 void visitFunctionType(FunctionType type, SsaBuilder builder) { 6261 void visitFunctionType(FunctionType type, SsaBuilder builder) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
6318 DartType unaliased = type.unalias(builder.compiler); 6318 DartType unaliased = type.unalias(builder.compiler);
6319 if (unaliased is TypedefType) throw 'unable to unalias $type'; 6319 if (unaliased is TypedefType) throw 'unable to unalias $type';
6320 unaliased.accept(this, builder); 6320 unaliased.accept(this, builder);
6321 } 6321 }
6322 6322
6323 void visitDynamicType(DynamicType type, SsaBuilder builder) { 6323 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6324 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); 6324 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType');
6325 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); 6325 builder.push(new HDynamicType(type, new TypeMask.exact(cls)));
6326 } 6326 }
6327 } 6327 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698