OLD | NEW |
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 js_backend; | 5 part of js_backend; |
6 | 6 |
7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
8 | 8 |
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 } | 213 } |
214 | 214 |
215 enum SyntheticConstantKind { | 215 enum SyntheticConstantKind { |
216 DUMMY_INTERCEPTOR, | 216 DUMMY_INTERCEPTOR, |
217 EMPTY_VALUE, | 217 EMPTY_VALUE, |
218 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. | 218 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. |
219 NAME | 219 NAME |
220 } | 220 } |
221 | 221 |
222 class JavaScriptBackend extends Backend { | 222 class JavaScriptBackend extends Backend { |
223 static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper'); | |
224 static final Uri DART_INTERCEPTORS = | |
225 new Uri(scheme: 'dart', path: '_interceptors'); | |
226 static final Uri DART_FOREIGN_HELPER = | |
227 new Uri(scheme: 'dart', path: '_foreign_helper'); | |
228 static final Uri DART_JS_MIRRORS = | |
229 new Uri(scheme: 'dart', path: '_js_mirrors'); | |
230 static final Uri DART_JS_NAMES = | |
231 new Uri(scheme: 'dart', path: '_js_names'); | |
232 static final Uri DART_EMBEDDED_NAMES = | |
233 new Uri(scheme: 'dart', path: '_js_embedded_names'); | |
234 static final Uri DART_ISOLATE_HELPER = | |
235 new Uri(scheme: 'dart', path: '_isolate_helper'); | |
236 static final Uri PACKAGE_JS = | |
237 new Uri(scheme: 'package', path: 'js/js.dart'); | |
238 static final Uri PACKAGE_LOOKUP_MAP = | |
239 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); | |
240 | |
241 static const String INVOKE_ON = '_getCachedInvocation'; | |
242 static const String START_ROOT_ISOLATE = 'startRootIsolate'; | |
243 | |
244 | |
245 String get patchVersion => emitter.patchVersion; | 223 String get patchVersion => emitter.patchVersion; |
246 | 224 |
247 bool get supportsReflection => emitter.emitter.supportsReflection; | 225 bool get supportsReflection => emitter.emitter.supportsReflection; |
248 | 226 |
249 final Annotations annotations; | 227 final Annotations annotations; |
250 | 228 |
251 /// Reference to the internal library to lookup functions to always inline. | |
252 LibraryElement internalLibrary; | |
253 | |
254 | 229 |
255 /// Set of classes that need to be considered for reflection although not | 230 /// Set of classes that need to be considered for reflection although not |
256 /// otherwise visible during resolution. | 231 /// otherwise visible during resolution. |
257 Iterable<ClassElement> get classesRequiredForReflection { | 232 Iterable<ClassElement> get classesRequiredForReflection { |
258 // TODO(herhut): Clean this up when classes needed for rti are tracked. | 233 // TODO(herhut): Clean this up when classes needed for rti are tracked. |
259 return [closureClass, jsIndexableClass]; | 234 return [helpers.closureClass, helpers.jsIndexableClass]; |
260 } | 235 } |
261 | 236 |
262 FunctionCompiler functionCompiler; | 237 FunctionCompiler functionCompiler; |
263 | 238 |
264 CodeEmitterTask emitter; | 239 CodeEmitterTask emitter; |
265 | 240 |
266 /** | 241 /** |
267 * The generated code as a js AST for compiled methods. | 242 * The generated code as a js AST for compiled methods. |
268 */ | 243 */ |
269 Map<Element, jsAst.Expression> get generatedCode { | 244 Map<Element, jsAst.Expression> get generatedCode { |
270 return compiler.enqueuer.codegen.generatedCode; | 245 return compiler.enqueuer.codegen.generatedCode; |
271 } | 246 } |
272 | 247 |
273 FunctionInlineCache inlineCache = new FunctionInlineCache(); | 248 FunctionInlineCache inlineCache = new FunctionInlineCache(); |
274 | 249 |
275 LibraryElement jsHelperLibrary; | |
276 LibraryElement asyncLibrary; | |
277 LibraryElement interceptorsLibrary; | |
278 LibraryElement foreignLibrary; | |
279 LibraryElement isolateHelperLibrary; | |
280 | |
281 ClassElement closureClass; | |
282 ClassElement boundClosureClass; | |
283 Element assertUnreachableMethod; | |
284 Element invokeOnMethod; | |
285 | |
286 ClassElement jsInterceptorClass; | |
287 ClassElement jsStringClass; | |
288 ClassElement jsArrayClass; | |
289 ClassElement jsNumberClass; | |
290 ClassElement jsIntClass; | |
291 ClassElement jsDoubleClass; | |
292 ClassElement jsNullClass; | |
293 ClassElement jsBoolClass; | |
294 ClassElement jsPlainJavaScriptObjectClass; | |
295 ClassElement jsUnknownJavaScriptObjectClass; | |
296 ClassElement jsJavaScriptFunctionClass; | |
297 ClassElement jsJavaScriptObjectClass; | |
298 | |
299 ClassElement jsIndexableClass; | |
300 ClassElement jsMutableIndexableClass; | |
301 | |
302 ClassElement jsMutableArrayClass; | |
303 ClassElement jsFixedArrayClass; | |
304 ClassElement jsExtendableArrayClass; | |
305 ClassElement jsUnmodifiableArrayClass; | |
306 ClassElement jsPositiveIntClass; | |
307 ClassElement jsUInt32Class; | |
308 ClassElement jsUInt31Class; | |
309 | |
310 Element jsIndexableLength; | |
311 Element jsArrayTypedConstructor; | |
312 Element jsArrayRemoveLast; | |
313 Element jsArrayAdd; | |
314 Element jsStringSplit; | |
315 Element jsStringToString; | |
316 Element jsStringOperatorAdd; | |
317 Element objectEquals; | |
318 | |
319 ClassElement typeLiteralClass; | |
320 ClassElement mapLiteralClass; | |
321 ClassElement constMapLiteralClass; | |
322 ClassElement typeVariableClass; | |
323 ConstructorElement mapLiteralConstructor; | |
324 ConstructorElement mapLiteralConstructorEmpty; | |
325 Element mapLiteralUntypedMaker; | |
326 Element mapLiteralUntypedEmptyMaker; | |
327 | |
328 ClassElement noSideEffectsClass; | |
329 ClassElement noThrowsClass; | |
330 ClassElement noInlineClass; | |
331 ClassElement forceInlineClass; | |
332 ClassElement irRepresentationClass; | |
333 | |
334 ClassElement jsAnnotationClass; | |
335 | |
336 Element getInterceptorMethod; | |
337 | |
338 ClassElement jsInvocationMirrorClass; | |
339 | |
340 ClassElement typedArrayClass; | |
341 ClassElement typedArrayOfIntClass; | |
342 | |
343 /// If [true], the compiler will emit code that logs whenever a method is | 250 /// If [true], the compiler will emit code that logs whenever a method is |
344 /// called. When TRACE_METHOD is 'console' this will be logged | 251 /// called. When TRACE_METHOD is 'console' this will be logged |
345 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the | 252 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the |
346 /// information will be sent to a server via a POST request. | 253 /// information will be sent to a server via a POST request. |
347 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); | 254 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); |
348 static const bool TRACE_CALLS = | 255 static const bool TRACE_CALLS = |
349 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; | 256 TRACE_METHOD == 'post' || TRACE_METHOD == 'console'; |
350 Element traceHelper; | 257 Element traceHelper; |
351 | 258 |
352 TypeMask get stringType => compiler.typesTask.stringType; | 259 TypeMask get stringType => compiler.typesTask.stringType; |
353 TypeMask get doubleType => compiler.typesTask.doubleType; | 260 TypeMask get doubleType => compiler.typesTask.doubleType; |
354 TypeMask get intType => compiler.typesTask.intType; | 261 TypeMask get intType => compiler.typesTask.intType; |
355 TypeMask get uint32Type => compiler.typesTask.uint32Type; | 262 TypeMask get uint32Type => compiler.typesTask.uint32Type; |
356 TypeMask get uint31Type => compiler.typesTask.uint31Type; | 263 TypeMask get uint31Type => compiler.typesTask.uint31Type; |
357 TypeMask get positiveIntType => compiler.typesTask.positiveIntType; | 264 TypeMask get positiveIntType => compiler.typesTask.positiveIntType; |
358 TypeMask get numType => compiler.typesTask.numType; | 265 TypeMask get numType => compiler.typesTask.numType; |
359 TypeMask get boolType => compiler.typesTask.boolType; | 266 TypeMask get boolType => compiler.typesTask.boolType; |
360 TypeMask get dynamicType => compiler.typesTask.dynamicType; | 267 TypeMask get dynamicType => compiler.typesTask.dynamicType; |
361 TypeMask get nullType => compiler.typesTask.nullType; | 268 TypeMask get nullType => compiler.typesTask.nullType; |
362 TypeMask get emptyType => const TypeMask.nonNullEmpty(); | 269 TypeMask get emptyType => const TypeMask.nonNullEmpty(); |
363 | 270 |
364 TypeMask _indexablePrimitiveTypeCache; | 271 TypeMask _indexablePrimitiveTypeCache; |
365 TypeMask get indexablePrimitiveType { | 272 TypeMask get indexablePrimitiveType { |
366 if (_indexablePrimitiveTypeCache == null) { | 273 if (_indexablePrimitiveTypeCache == null) { |
367 _indexablePrimitiveTypeCache = | 274 _indexablePrimitiveTypeCache = new TypeMask.nonNullSubtype( |
368 new TypeMask.nonNullSubtype(jsIndexableClass, compiler.world); | 275 helpers.jsIndexableClass, compiler.world); |
369 } | 276 } |
370 return _indexablePrimitiveTypeCache; | 277 return _indexablePrimitiveTypeCache; |
371 } | 278 } |
372 | 279 |
373 TypeMask _readableArrayTypeCache; | 280 TypeMask _readableArrayTypeCache; |
374 TypeMask get readableArrayType { | 281 TypeMask get readableArrayType { |
375 if (_readableArrayTypeCache == null) { | 282 if (_readableArrayTypeCache == null) { |
376 _readableArrayTypeCache = new TypeMask.nonNullSubclass(jsArrayClass, | 283 _readableArrayTypeCache = new TypeMask.nonNullSubclass( |
377 compiler.world); | 284 helpers.jsArrayClass, compiler.world); |
378 } | 285 } |
379 return _readableArrayTypeCache; | 286 return _readableArrayTypeCache; |
380 } | 287 } |
381 | 288 |
382 TypeMask _mutableArrayTypeCache; | 289 TypeMask _mutableArrayTypeCache; |
383 TypeMask get mutableArrayType { | 290 TypeMask get mutableArrayType { |
384 if (_mutableArrayTypeCache == null) { | 291 if (_mutableArrayTypeCache == null) { |
385 _mutableArrayTypeCache = new TypeMask.nonNullSubclass(jsMutableArrayClass, | 292 _mutableArrayTypeCache = new TypeMask.nonNullSubclass( |
386 compiler.world); | 293 helpers.jsMutableArrayClass, compiler.world); |
387 } | 294 } |
388 return _mutableArrayTypeCache; | 295 return _mutableArrayTypeCache; |
389 } | 296 } |
390 | 297 |
391 TypeMask _fixedArrayTypeCache; | 298 TypeMask _fixedArrayTypeCache; |
392 TypeMask get fixedArrayType { | 299 TypeMask get fixedArrayType { |
393 if (_fixedArrayTypeCache == null) { | 300 if (_fixedArrayTypeCache == null) { |
394 _fixedArrayTypeCache = new TypeMask.nonNullExact(jsFixedArrayClass, | 301 _fixedArrayTypeCache = new TypeMask.nonNullExact( |
395 compiler.world); | 302 helpers.jsFixedArrayClass, compiler.world); |
396 } | 303 } |
397 return _fixedArrayTypeCache; | 304 return _fixedArrayTypeCache; |
398 } | 305 } |
399 | 306 |
400 TypeMask _extendableArrayTypeCache; | 307 TypeMask _extendableArrayTypeCache; |
401 TypeMask get extendableArrayType { | 308 TypeMask get extendableArrayType { |
402 if (_extendableArrayTypeCache == null) { | 309 if (_extendableArrayTypeCache == null) { |
403 _extendableArrayTypeCache = | 310 _extendableArrayTypeCache = new TypeMask.nonNullExact( |
404 new TypeMask.nonNullExact(jsExtendableArrayClass, compiler.world); | 311 helpers.jsExtendableArrayClass, compiler.world); |
405 } | 312 } |
406 return _extendableArrayTypeCache; | 313 return _extendableArrayTypeCache; |
407 } | 314 } |
408 | 315 |
409 TypeMask _unmodifiableArrayTypeCache; | 316 TypeMask _unmodifiableArrayTypeCache; |
410 TypeMask get unmodifiableArrayType { | 317 TypeMask get unmodifiableArrayType { |
411 if (_unmodifiableArrayTypeCache == null) { | 318 if (_unmodifiableArrayTypeCache == null) { |
412 _unmodifiableArrayTypeCache = | 319 _unmodifiableArrayTypeCache = new TypeMask.nonNullExact( |
413 new TypeMask.nonNullExact(jsUnmodifiableArrayClass, compiler.world); | 320 helpers.jsUnmodifiableArrayClass, compiler.world); |
414 } | 321 } |
415 return _fixedArrayTypeCache; | 322 return _fixedArrayTypeCache; |
416 } | 323 } |
417 | 324 |
418 TypeMask _nonNullTypeCache; | 325 TypeMask _nonNullTypeCache; |
419 TypeMask get nonNullType { | 326 TypeMask get nonNullType { |
420 if (_nonNullTypeCache == null) { | 327 if (_nonNullTypeCache == null) { |
421 _nonNullTypeCache = | 328 _nonNullTypeCache = |
422 compiler.typesTask.dynamicType.nonNullable(); | 329 compiler.typesTask.dynamicType.nonNullable(); |
423 } | 330 } |
424 return _nonNullTypeCache; | 331 return _nonNullTypeCache; |
425 } | 332 } |
426 | 333 |
427 /// Maps special classes to their implementation (JSXxx) class. | 334 /// Maps special classes to their implementation (JSXxx) class. |
428 Map<ClassElement, ClassElement> implementationClasses; | 335 Map<ClassElement, ClassElement> implementationClasses; |
429 | 336 |
430 Element getNativeInterceptorMethod; | |
431 bool needToInitializeIsolateAffinityTag = false; | 337 bool needToInitializeIsolateAffinityTag = false; |
432 bool needToInitializeDispatchProperty = false; | 338 bool needToInitializeDispatchProperty = false; |
433 | 339 |
434 /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been | |
435 /// loaded. | |
436 FunctionElement getIsolateAffinityTagMarker; | |
437 | |
438 final Namer namer; | 340 final Namer namer; |
439 | 341 |
440 /** | 342 /** |
441 * Interface used to determine if an object has the JavaScript | |
442 * indexing behavior. The interface is only visible to specific | |
443 * libraries. | |
444 */ | |
445 ClassElement jsIndexingBehaviorInterface; | |
446 | |
447 /** | |
448 * A collection of selectors that must have a one shot interceptor | 343 * A collection of selectors that must have a one shot interceptor |
449 * generated. | 344 * generated. |
450 */ | 345 */ |
451 final Map<jsAst.Name, Selector> oneShotInterceptors; | 346 final Map<jsAst.Name, Selector> oneShotInterceptors; |
452 | 347 |
453 /** | 348 /** |
454 * The members of instantiated interceptor classes: maps a member name to the | 349 * The members of instantiated interceptor classes: maps a member name to the |
455 * list of members that have that name. This map is used by the codegen to | 350 * list of members that have that name. This map is used by the codegen to |
456 * know whether a send must be intercepted or not. | 351 * know whether a send must be intercepted or not. |
457 */ | 352 */ |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 List<CompilerTask> get tasks { | 403 List<CompilerTask> get tasks { |
509 List<CompilerTask> result = functionCompiler.tasks; | 404 List<CompilerTask> result = functionCompiler.tasks; |
510 result.add(emitter); | 405 result.add(emitter); |
511 result.add(patchResolverTask); | 406 result.add(patchResolverTask); |
512 return result; | 407 return result; |
513 } | 408 } |
514 | 409 |
515 final RuntimeTypes rti; | 410 final RuntimeTypes rti; |
516 final RuntimeTypesEncoder rtiEncoder; | 411 final RuntimeTypesEncoder rtiEncoder; |
517 | 412 |
518 /// Holds the method "disableTreeShaking" in js_mirrors when | |
519 /// dart:mirrors has been loaded. | |
520 FunctionElement disableTreeShakingMarker; | |
521 | |
522 /// Holds the method "preserveNames" in js_mirrors when | |
523 /// dart:mirrors has been loaded. | |
524 FunctionElement preserveNamesMarker; | |
525 | |
526 /// Holds the method "preserveMetadata" in js_mirrors when | |
527 /// dart:mirrors has been loaded. | |
528 FunctionElement preserveMetadataMarker; | |
529 | |
530 /// Holds the method "preserveUris" in js_mirrors when | |
531 /// dart:mirrors has been loaded. | |
532 FunctionElement preserveUrisMarker; | |
533 | |
534 /// Holds the method "preserveLibraryNames" in js_mirrors when | |
535 /// dart:mirrors has been loaded. | |
536 FunctionElement preserveLibraryNamesMarker; | |
537 | |
538 /// Holds the method "requiresPreamble" in _js_helper. | |
539 FunctionElement requiresPreambleMarker; | |
540 | |
541 /// Holds the class for the [JsGetName] enum. | |
542 EnumClassElement jsGetNameEnum; | |
543 | |
544 /// Holds the class for the [JsBuiltins] enum. | |
545 EnumClassElement jsBuiltinEnum; | |
546 | |
547 /// True if a call to preserveMetadataMarker has been seen. This means that | 413 /// True if a call to preserveMetadataMarker has been seen. This means that |
548 /// metadata must be retained for dart:mirrors to work correctly. | 414 /// metadata must be retained for dart:mirrors to work correctly. |
549 bool mustRetainMetadata = false; | 415 bool mustRetainMetadata = false; |
550 | 416 |
551 /// True if any metadata has been retained. This is slightly different from | 417 /// True if any metadata has been retained. This is slightly different from |
552 /// [mustRetainMetadata] and tells us if any metadata was retained. For | 418 /// [mustRetainMetadata] and tells us if any metadata was retained. For |
553 /// example, if [mustRetainMetadata] is true but there is no metadata in the | 419 /// example, if [mustRetainMetadata] is true but there is no metadata in the |
554 /// program, this variable will stil be false. | 420 /// program, this variable will stil be false. |
555 bool hasRetainedMetadata = false; | 421 bool hasRetainedMetadata = false; |
556 | 422 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 return constantCompilerTask.jsConstantCompiler; | 559 return constantCompilerTask.jsConstantCompiler; |
694 } | 560 } |
695 | 561 |
696 FunctionElement resolveExternalFunction(FunctionElement element) { | 562 FunctionElement resolveExternalFunction(FunctionElement element) { |
697 if (isForeign(element) || isJsInterop(element)) return element; | 563 if (isForeign(element) || isJsInterop(element)) return element; |
698 return patchResolverTask.measure(() { | 564 return patchResolverTask.measure(() { |
699 return patchResolverTask.resolveExternalFunction(element); | 565 return patchResolverTask.resolveExternalFunction(element); |
700 }); | 566 }); |
701 } | 567 } |
702 | 568 |
703 // TODO(karlklose): Split into findHelperFunction and findHelperClass and | 569 bool isForeign(Element element) => element.library == helpers.foreignLibrary; |
704 // add a check that the element has the expected kind. | |
705 Element findHelper(String name) => find(jsHelperLibrary, name); | |
706 Element findAsyncHelper(String name) => find(asyncLibrary, name); | |
707 Element findInterceptor(String name) => find(interceptorsLibrary, name); | |
708 | |
709 Element find(LibraryElement library, String name) { | |
710 Element element = library.implementation.findLocal(name); | |
711 assert(invariant(library, element != null, | |
712 message: "Element '$name' not found in '${library.canonicalUri}'.")); | |
713 return element; | |
714 } | |
715 | |
716 bool isForeign(Element element) => element.library == foreignLibrary; | |
717 | 570 |
718 bool isBackendLibrary(LibraryElement library) { | 571 bool isBackendLibrary(LibraryElement library) { |
719 return library == interceptorsLibrary || | 572 return library == helpers.interceptorsLibrary || |
720 library == jsHelperLibrary; | 573 library == helpers.jsHelperLibrary; |
721 } | 574 } |
722 | 575 |
723 static Namer determineNamer(Compiler compiler) { | 576 static Namer determineNamer(Compiler compiler) { |
724 return compiler.enableMinification ? | 577 return compiler.enableMinification ? |
725 compiler.useFrequencyNamer ? | 578 compiler.useFrequencyNamer ? |
726 new FrequencyBasedNamer(compiler) : | 579 new FrequencyBasedNamer(compiler) : |
727 new MinifyNamer(compiler) : | 580 new MinifyNamer(compiler) : |
728 new Namer(compiler); | 581 new Namer(compiler); |
729 } | 582 } |
730 | 583 |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); | 963 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); |
1111 } | 964 } |
1112 } | 965 } |
1113 } | 966 } |
1114 } | 967 } |
1115 | 968 |
1116 void addInterceptors(ClassElement cls, | 969 void addInterceptors(ClassElement cls, |
1117 Enqueuer enqueuer, | 970 Enqueuer enqueuer, |
1118 Registry registry) { | 971 Registry registry) { |
1119 if (enqueuer.isResolutionQueue) { | 972 if (enqueuer.isResolutionQueue) { |
1120 _interceptedClasses.add(jsInterceptorClass); | 973 _interceptedClasses.add(helpers.jsInterceptorClass); |
1121 _interceptedClasses.add(cls); | 974 _interceptedClasses.add(cls); |
1122 cls.ensureResolved(resolution); | 975 cls.ensureResolved(resolution); |
1123 cls.forEachMember((ClassElement classElement, Element member) { | 976 cls.forEachMember((ClassElement classElement, Element member) { |
1124 // All methods on [Object] are shadowed by [Interceptor]. | 977 // All methods on [Object] are shadowed by [Interceptor]. |
1125 if (classElement == coreClasses.objectClass) return; | 978 if (classElement == coreClasses.objectClass) return; |
1126 Set<Element> set = interceptedElements.putIfAbsent( | 979 Set<Element> set = interceptedElements.putIfAbsent( |
1127 member.name, () => new Set<Element>()); | 980 member.name, () => new Set<Element>()); |
1128 set.add(member); | 981 set.add(member); |
1129 }, | 982 }, |
1130 includeSuperAndInjectedMembers: true); | 983 includeSuperAndInjectedMembers: true); |
1131 } | 984 } |
1132 enqueueClass(enqueuer, cls, registry); | 985 enqueueClass(enqueuer, cls, registry); |
1133 } | 986 } |
1134 | 987 |
1135 Set<ClassElement> get interceptedClasses { | 988 Set<ClassElement> get interceptedClasses { |
1136 assert(compiler.enqueuer.resolution.queueIsClosed); | 989 assert(compiler.enqueuer.resolution.queueIsClosed); |
1137 return _interceptedClasses; | 990 return _interceptedClasses; |
1138 } | 991 } |
1139 | 992 |
1140 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 993 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
1141 jsAst.Name name = namer.nameForGetInterceptor(classes); | 994 jsAst.Name name = namer.nameForGetInterceptor(classes); |
1142 if (classes.contains(jsInterceptorClass)) { | 995 if (classes.contains(helpers.jsInterceptorClass)) { |
1143 // We can't use a specialized [getInterceptorMethod], so we make | 996 // We can't use a specialized [getInterceptorMethod], so we make |
1144 // sure we emit the one with all checks. | 997 // sure we emit the one with all checks. |
1145 specializedGetInterceptors[name] = interceptedClasses; | 998 specializedGetInterceptors[name] = interceptedClasses; |
1146 } else { | 999 } else { |
1147 specializedGetInterceptors[name] = classes; | 1000 specializedGetInterceptors[name] = classes; |
1148 } | 1001 } |
1149 } | 1002 } |
1150 | 1003 |
1151 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { | 1004 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { |
1152 registerCompileTimeConstantInternal(constant, registry); | 1005 registerCompileTimeConstantInternal(constant, registry); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 registry); | 1085 registry); |
1233 } | 1086 } |
1234 | 1087 |
1235 // Register any helper that will be needed by the backend. | 1088 // Register any helper that will be needed by the backend. |
1236 if (enqueuer.isResolutionQueue) { | 1089 if (enqueuer.isResolutionQueue) { |
1237 if (cls == coreClasses.intClass || | 1090 if (cls == coreClasses.intClass || |
1238 cls == coreClasses.doubleClass || | 1091 cls == coreClasses.doubleClass || |
1239 cls == coreClasses.numClass) { | 1092 cls == coreClasses.numClass) { |
1240 // The backend will try to optimize number operations and use the | 1093 // The backend will try to optimize number operations and use the |
1241 // `iae` helper directly. | 1094 // `iae` helper directly. |
1242 enqueue(enqueuer, findHelper('iae'), registry); | 1095 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); |
1243 } else if (cls == coreClasses.listClass || | 1096 } else if (cls == coreClasses.listClass || |
1244 cls == coreClasses.stringClass) { | 1097 cls == coreClasses.stringClass) { |
1245 // The backend will try to optimize array and string access and use the | 1098 // The backend will try to optimize array and string access and use the |
1246 // `ioore` and `iae` helpers directly. | 1099 // `ioore` and `iae` helpers directly. |
1247 enqueue(enqueuer, findHelper('ioore'), registry); | 1100 enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry); |
1248 enqueue(enqueuer, findHelper('iae'), registry); | 1101 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); |
1249 } else if (cls == coreClasses.functionClass) { | 1102 } else if (cls == coreClasses.functionClass) { |
1250 enqueueClass(enqueuer, closureClass, registry); | 1103 enqueueClass(enqueuer, helpers.closureClass, registry); |
1251 } else if (cls == coreClasses.mapClass) { | 1104 } else if (cls == coreClasses.mapClass) { |
1252 // The backend will use a literal list to initialize the entries | 1105 // The backend will use a literal list to initialize the entries |
1253 // of the map. | 1106 // of the map. |
1254 enqueueClass(enqueuer, coreClasses.listClass, registry); | 1107 enqueueClass(enqueuer, coreClasses.listClass, registry); |
1255 enqueueClass(enqueuer, mapLiteralClass, registry); | 1108 enqueueClass(enqueuer, helpers.mapLiteralClass, registry); |
1256 // For map literals, the dependency between the implementation class | 1109 // For map literals, the dependency between the implementation class |
1257 // and [Map] is not visible, so we have to add it manually. | 1110 // and [Map] is not visible, so we have to add it manually. |
1258 rti.registerRtiDependency(mapLiteralClass, cls); | 1111 rti.registerRtiDependency(helpers.mapLiteralClass, cls); |
1259 } else if (cls == boundClosureClass) { | 1112 } else if (cls == helpers.boundClosureClass) { |
1260 // TODO(johnniwinther): Is this a noop? | 1113 // TODO(johnniwinther): Is this a noop? |
1261 enqueueClass(enqueuer, boundClosureClass, registry); | 1114 enqueueClass(enqueuer, helpers.boundClosureClass, registry); |
1262 } else if (isNativeOrExtendsNative(cls)) { | 1115 } else if (isNativeOrExtendsNative(cls)) { |
1263 enqueue(enqueuer, getNativeInterceptorMethod, registry); | 1116 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); |
1264 enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies); | 1117 enqueueClass(enqueuer, helpers.jsInterceptorClass, |
1265 enqueueClass(enqueuer, jsJavaScriptObjectClass, registry); | 1118 compiler.globalDependencies); |
1266 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); | 1119 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); |
1267 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry); | 1120 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); |
1268 } else if (cls == mapLiteralClass) { | 1121 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); |
| 1122 } else if (cls == helpers.mapLiteralClass) { |
1269 // For map literals, the dependency between the implementation class | 1123 // For map literals, the dependency between the implementation class |
1270 // and [Map] is not visible, so we have to add it manually. | 1124 // and [Map] is not visible, so we have to add it manually. |
1271 Element getFactory(String name, int arity) { | 1125 Element getFactory(String name, int arity) { |
1272 // The constructor is on the patch class, but dart2js unit tests don't | 1126 // The constructor is on the patch class, but dart2js unit tests don't |
1273 // have a patch class. | 1127 // have a patch class. |
1274 ClassElement implementation = cls.patch != null ? cls.patch : cls; | 1128 ClassElement implementation = cls.patch != null ? cls.patch : cls; |
1275 ConstructorElement ctor = implementation.lookupConstructor(name); | 1129 ConstructorElement ctor = implementation.lookupConstructor(name); |
1276 if (ctor == null | 1130 if (ctor == null || |
1277 || (Name.isPrivateName(name) | 1131 (Name.isPrivateName(name) && |
1278 && ctor.library != mapLiteralClass.library)) { | 1132 ctor.library != helpers.mapLiteralClass.library)) { |
1279 reporter.internalError(mapLiteralClass, | 1133 reporter.internalError( |
1280 "Map literal class $mapLiteralClass missing " | 1134 helpers.mapLiteralClass, |
1281 "'$name' constructor" | 1135 "Map literal class ${helpers.mapLiteralClass} missing " |
1282 " ${mapLiteralClass.constructors}"); | 1136 "'$name' constructor" |
| 1137 " ${helpers.mapLiteralClass.constructors}"); |
1283 } | 1138 } |
1284 return ctor; | 1139 return ctor; |
1285 } | 1140 } |
1286 Element getMember(String name) { | 1141 Element getMember(String name) { |
1287 // The constructor is on the patch class, but dart2js unit tests don't | 1142 // The constructor is on the patch class, but dart2js unit tests don't |
1288 // have a patch class. | 1143 // have a patch class. |
1289 ClassElement implementation = cls.patch != null ? cls.patch : cls; | 1144 ClassElement implementation = cls.patch != null ? cls.patch : cls; |
1290 Element element = implementation.lookupLocalMember(name); | 1145 Element element = implementation.lookupLocalMember(name); |
1291 if (element == null || !element.isFunction || !element.isStatic) { | 1146 if (element == null || !element.isFunction || !element.isStatic) { |
1292 reporter.internalError(mapLiteralClass, | 1147 reporter.internalError(helpers.mapLiteralClass, |
1293 "Map literal class $mapLiteralClass missing " | 1148 "Map literal class ${helpers.mapLiteralClass} missing " |
1294 "'$name' static member function"); | 1149 "'$name' static member function"); |
1295 } | 1150 } |
1296 return element; | 1151 return element; |
1297 } | 1152 } |
1298 mapLiteralConstructor = getFactory('_literal', 1); | 1153 helpers.mapLiteralConstructor = getFactory('_literal', 1); |
1299 mapLiteralConstructorEmpty = getFactory('_empty', 0); | 1154 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); |
1300 enqueueInResolution(mapLiteralConstructor, registry); | 1155 enqueueInResolution(helpers.mapLiteralConstructor, registry); |
1301 enqueueInResolution(mapLiteralConstructorEmpty, registry); | 1156 enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry); |
1302 | 1157 |
1303 mapLiteralUntypedMaker = getMember('_makeLiteral'); | 1158 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral'); |
1304 mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); | 1159 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); |
1305 enqueueInResolution(mapLiteralUntypedMaker, registry); | 1160 enqueueInResolution(helpers.mapLiteralUntypedMaker, registry); |
1306 enqueueInResolution(mapLiteralUntypedEmptyMaker, registry); | 1161 enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry); |
1307 } | 1162 } |
1308 } | 1163 } |
1309 if (cls == closureClass) { | 1164 if (cls == helpers.closureClass) { |
1310 enqueue(enqueuer, findHelper('closureFromTearOff'), registry); | 1165 enqueue(enqueuer, helpers.closureFromTearOff, registry); |
1311 } | 1166 } |
1312 if (cls == coreClasses.stringClass || | 1167 if (cls == coreClasses.stringClass || |
1313 cls == jsStringClass) { | 1168 cls == helpers.jsStringClass) { |
1314 addInterceptors(jsStringClass, enqueuer, registry); | 1169 addInterceptors(helpers.jsStringClass, enqueuer, registry); |
1315 } else if (cls == coreClasses.listClass || | 1170 } else if (cls == coreClasses.listClass || |
1316 cls == jsArrayClass || | 1171 cls == helpers.jsArrayClass || |
1317 cls == jsFixedArrayClass || | 1172 cls == helpers.jsFixedArrayClass || |
1318 cls == jsExtendableArrayClass || | 1173 cls == helpers.jsExtendableArrayClass || |
1319 cls == jsUnmodifiableArrayClass) { | 1174 cls == helpers.jsUnmodifiableArrayClass) { |
1320 addInterceptors(jsArrayClass, enqueuer, registry); | 1175 addInterceptors(helpers.jsArrayClass, enqueuer, registry); |
1321 addInterceptors(jsMutableArrayClass, enqueuer, registry); | 1176 addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry); |
1322 addInterceptors(jsFixedArrayClass, enqueuer, registry); | 1177 addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry); |
1323 addInterceptors(jsExtendableArrayClass, enqueuer, registry); | 1178 addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry); |
1324 addInterceptors(jsUnmodifiableArrayClass, enqueuer, registry); | 1179 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry); |
1325 } else if (cls == coreClasses.intClass || | 1180 } else if (cls == coreClasses.intClass || |
1326 cls == jsIntClass) { | 1181 cls == helpers.jsIntClass) { |
1327 addInterceptors(jsIntClass, enqueuer, registry); | 1182 addInterceptors(helpers.jsIntClass, enqueuer, registry); |
1328 addInterceptors(jsPositiveIntClass, enqueuer, registry); | 1183 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); |
1329 addInterceptors(jsUInt32Class, enqueuer, registry); | 1184 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); |
1330 addInterceptors(jsUInt31Class, enqueuer, registry); | 1185 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); |
1331 addInterceptors(jsNumberClass, enqueuer, registry); | 1186 addInterceptors(helpers.jsNumberClass, enqueuer, registry); |
1332 } else if (cls == coreClasses.doubleClass || | 1187 } else if (cls == coreClasses.doubleClass || |
1333 cls == jsDoubleClass) { | 1188 cls == helpers.jsDoubleClass) { |
1334 addInterceptors(jsDoubleClass, enqueuer, registry); | 1189 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); |
1335 addInterceptors(jsNumberClass, enqueuer, registry); | 1190 addInterceptors(helpers.jsNumberClass, enqueuer, registry); |
1336 } else if (cls == coreClasses.boolClass || | 1191 } else if (cls == coreClasses.boolClass || |
1337 cls == jsBoolClass) { | 1192 cls == helpers.jsBoolClass) { |
1338 addInterceptors(jsBoolClass, enqueuer, registry); | 1193 addInterceptors(helpers.jsBoolClass, enqueuer, registry); |
1339 } else if (cls == coreClasses.nullClass || | 1194 } else if (cls == coreClasses.nullClass || |
1340 cls == jsNullClass) { | 1195 cls == helpers.jsNullClass) { |
1341 addInterceptors(jsNullClass, enqueuer, registry); | 1196 addInterceptors(helpers.jsNullClass, enqueuer, registry); |
1342 } else if (cls == coreClasses.numClass || | 1197 } else if (cls == coreClasses.numClass || |
1343 cls == jsNumberClass) { | 1198 cls == helpers.jsNumberClass) { |
1344 addInterceptors(jsIntClass, enqueuer, registry); | 1199 addInterceptors(helpers.jsIntClass, enqueuer, registry); |
1345 addInterceptors(jsPositiveIntClass, enqueuer, registry); | 1200 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); |
1346 addInterceptors(jsUInt32Class, enqueuer, registry); | 1201 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); |
1347 addInterceptors(jsUInt31Class, enqueuer, registry); | 1202 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); |
1348 addInterceptors(jsDoubleClass, enqueuer, registry); | 1203 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); |
1349 addInterceptors(jsNumberClass, enqueuer, registry); | 1204 addInterceptors(helpers.jsNumberClass, enqueuer, registry); |
1350 } else if (cls == jsJavaScriptObjectClass) { | 1205 } else if (cls == helpers.jsJavaScriptObjectClass) { |
1351 addInterceptors(jsJavaScriptObjectClass, enqueuer, registry); | 1206 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry); |
1352 } else if (cls == jsPlainJavaScriptObjectClass) { | 1207 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { |
1353 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry); | 1208 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry); |
1354 } else if (cls == jsUnknownJavaScriptObjectClass) { | 1209 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { |
1355 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry); | 1210 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry
); |
1356 } else if (cls == jsJavaScriptFunctionClass) { | 1211 } else if (cls == helpers.jsJavaScriptFunctionClass) { |
1357 addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry); | 1212 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry); |
1358 } else if (isNativeOrExtendsNative(cls)) { | 1213 } else if (isNativeOrExtendsNative(cls)) { |
1359 addInterceptorsForNativeClassMembers(cls, enqueuer); | 1214 addInterceptorsForNativeClassMembers(cls, enqueuer); |
1360 } else if (cls == jsIndexingBehaviorInterface) { | 1215 } else if (cls == helpers.jsIndexingBehaviorInterface) { |
1361 // These two helpers are used by the emitter and the codegen. | 1216 // These two helpers are used by the emitter and the codegen. |
1362 // Because we cannot enqueue elements at the time of emission, | 1217 // Because we cannot enqueue elements at the time of emission, |
1363 // we make sure they are always generated. | 1218 // we make sure they are always generated. |
1364 enqueue(enqueuer, findHelper('isJsIndexable'), registry); | 1219 enqueue(enqueuer, helpers.isJsIndexable, registry); |
1365 } | 1220 } |
1366 | 1221 |
1367 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); | 1222 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); |
1368 if (!enqueuer.isResolutionQueue) { | 1223 if (!enqueuer.isResolutionQueue) { |
1369 lookupMapAnalysis.registerInstantiatedClass(cls); | 1224 lookupMapAnalysis.registerInstantiatedClass(cls); |
1370 } | 1225 } |
1371 } | 1226 } |
1372 | 1227 |
1373 void registerInstantiatedType(InterfaceType type, | 1228 void registerInstantiatedType(InterfaceType type, |
1374 Enqueuer enqueuer, | 1229 Enqueuer enqueuer, |
1375 Registry registry, | 1230 Registry registry, |
1376 {bool mirrorUsage: false}) { | 1231 {bool mirrorUsage: false}) { |
1377 lookupMapAnalysis.registerInstantiatedType(type, registry); | 1232 lookupMapAnalysis.registerInstantiatedType(type, registry); |
1378 super.registerInstantiatedType( | 1233 super.registerInstantiatedType( |
1379 type, enqueuer, registry, mirrorUsage: mirrorUsage); | 1234 type, enqueuer, registry, mirrorUsage: mirrorUsage); |
1380 } | 1235 } |
1381 | 1236 |
1382 void registerUseInterceptor(Enqueuer enqueuer) { | 1237 void registerUseInterceptor(Enqueuer enqueuer) { |
1383 assert(!enqueuer.isResolutionQueue); | 1238 assert(!enqueuer.isResolutionQueue); |
1384 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; | 1239 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; |
1385 Registry registry = compiler.globalDependencies; | 1240 Registry registry = compiler.globalDependencies; |
1386 enqueue(enqueuer, getNativeInterceptorMethod, registry); | 1241 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); |
1387 enqueueClass(enqueuer, jsJavaScriptObjectClass, registry); | 1242 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); |
1388 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); | 1243 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); |
1389 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry); | 1244 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); |
1390 needToInitializeIsolateAffinityTag = true; | 1245 needToInitializeIsolateAffinityTag = true; |
1391 needToInitializeDispatchProperty = true; | 1246 needToInitializeDispatchProperty = true; |
1392 } | 1247 } |
1393 | 1248 |
1394 JavaScriptItemCompilationContext createItemCompilationContext() { | 1249 JavaScriptItemCompilationContext createItemCompilationContext() { |
1395 return new JavaScriptItemCompilationContext(); | 1250 return new JavaScriptItemCompilationContext(); |
1396 } | 1251 } |
1397 | 1252 |
1398 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { | 1253 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { |
1399 assert(interceptorsLibrary != null); | 1254 assert(helpers.interceptorsLibrary != null); |
1400 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1255 // TODO(ngeoffray): Not enqueuing those two classes currently make |
1401 // the compiler potentially crash. However, any reasonable program | 1256 // the compiler potentially crash. However, any reasonable program |
1402 // will instantiate those two classes. | 1257 // will instantiate those two classes. |
1403 addInterceptors(jsBoolClass, world, registry); | 1258 addInterceptors(helpers.jsBoolClass, world, registry); |
1404 addInterceptors(jsNullClass, world, registry); | 1259 addInterceptors(helpers.jsNullClass, world, registry); |
1405 if (compiler.enableTypeAssertions) { | 1260 if (compiler.enableTypeAssertions) { |
1406 // Unconditionally register the helper that checks if the | 1261 // Unconditionally register the helper that checks if the |
1407 // expression in an if/while/for is a boolean. | 1262 // expression in an if/while/for is a boolean. |
1408 // TODO(ngeoffray): Should we have the resolver register those instead? | 1263 // TODO(ngeoffray): Should we have the resolver register those instead? |
1409 Element e = findHelper('boolConversionCheck'); | 1264 Element e = helpers.boolConversionCheck; |
1410 if (e != null) enqueue(world, e, registry); | 1265 if (e != null) enqueue(world, e, registry); |
1411 } | 1266 } |
1412 | 1267 |
1413 if (TRACE_CALLS) { | 1268 if (TRACE_CALLS) { |
1414 traceHelper = findHelper( | 1269 traceHelper = TRACE_METHOD == 'console' |
1415 TRACE_METHOD == 'console' ? 'consoleTraceHelper' : 'postTraceHelper'); | 1270 ? helpers.consoleTraceHelper : helpers.postTraceHelper; |
1416 assert(traceHelper != null); | 1271 assert(traceHelper != null); |
1417 enqueueInResolution(traceHelper, registry); | 1272 enqueueInResolution(traceHelper, registry); |
1418 } | 1273 } |
1419 enqueueInResolution(assertUnreachableMethod, registry); | 1274 enqueueInResolution(helpers.assertUnreachableMethod, registry); |
1420 registerCheckedModeHelpers(registry); | 1275 registerCheckedModeHelpers(registry); |
1421 } | 1276 } |
1422 | 1277 |
1423 onResolutionComplete() { | 1278 onResolutionComplete() { |
1424 super.onResolutionComplete(); | 1279 super.onResolutionComplete(); |
1425 computeMembersNeededForReflection(); | 1280 computeMembersNeededForReflection(); |
1426 rti.computeClassesNeedingRti(); | 1281 rti.computeClassesNeedingRti(); |
1427 } | 1282 } |
1428 | 1283 |
1429 onTypeInferenceComplete() { | 1284 onTypeInferenceComplete() { |
(...skipping 29 matching lines...) Expand all Loading... |
1459 | 1314 |
1460 /// Call during codegen if an instance of [closure] is being created. | 1315 /// Call during codegen if an instance of [closure] is being created. |
1461 void registerInstantiatedClosure(LocalFunctionElement closure, | 1316 void registerInstantiatedClosure(LocalFunctionElement closure, |
1462 CodegenRegistry registry) { | 1317 CodegenRegistry registry) { |
1463 if (methodNeedsRti(closure)) { | 1318 if (methodNeedsRti(closure)) { |
1464 registerComputeSignature(compiler.enqueuer.codegen, registry); | 1319 registerComputeSignature(compiler.enqueuer.codegen, registry); |
1465 } | 1320 } |
1466 } | 1321 } |
1467 | 1322 |
1468 void registerBoundClosure(Enqueuer enqueuer) { | 1323 void registerBoundClosure(Enqueuer enqueuer) { |
1469 boundClosureClass.ensureResolved(resolution); | 1324 helpers.boundClosureClass.ensureResolved(resolution); |
1470 registerInstantiatedType( | 1325 registerInstantiatedType( |
1471 boundClosureClass.rawType, | 1326 helpers.boundClosureClass.rawType, |
1472 enqueuer, | 1327 enqueuer, |
1473 // Precise dependency is not important here. | 1328 // Precise dependency is not important here. |
1474 compiler.globalDependencies); | 1329 compiler.globalDependencies); |
1475 } | 1330 } |
1476 | 1331 |
1477 void registerGetOfStaticFunction(Enqueuer enqueuer) { | 1332 void registerGetOfStaticFunction(Enqueuer enqueuer) { |
1478 closureClass.ensureResolved(resolution); | 1333 helpers.closureClass.ensureResolved(resolution); |
1479 registerInstantiatedType( | 1334 registerInstantiatedType( |
1480 closureClass.rawType, | 1335 helpers.closureClass.rawType, |
1481 enqueuer, | 1336 enqueuer, |
1482 compiler.globalDependencies); | 1337 compiler.globalDependencies); |
1483 } | 1338 } |
1484 | 1339 |
1485 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { | 1340 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { |
1486 // Calls to [:computeSignature:] are generated by the emitter and we | 1341 // Calls to [:computeSignature:] are generated by the emitter and we |
1487 // therefore need to enqueue the used elements in the codegen enqueuer as | 1342 // therefore need to enqueue the used elements in the codegen enqueuer as |
1488 // well as in the resolution enqueuer. | 1343 // well as in the resolution enqueuer. |
1489 enqueueImpact(enqueuer, impacts.computeSignature, registry); | 1344 enqueueImpact(enqueuer, impacts.computeSignature, registry); |
1490 } | 1345 } |
(...skipping 30 matching lines...) Expand all Loading... |
1521 enqueue(world, helper.getElement(compiler), registry); | 1376 enqueue(world, helper.getElement(compiler), registry); |
1522 } | 1377 } |
1523 } | 1378 } |
1524 if (!type.treatAsRaw || type.containsTypeVariables) { | 1379 if (!type.treatAsRaw || type.containsTypeVariables) { |
1525 enqueueClass(world, coreClasses.listClass, registry); | 1380 enqueueClass(world, coreClasses.listClass, registry); |
1526 } | 1381 } |
1527 if (type.element != null && isNative(type.element)) { | 1382 if (type.element != null && isNative(type.element)) { |
1528 // We will neeed to add the "$is" and "$as" properties on the | 1383 // We will neeed to add the "$is" and "$as" properties on the |
1529 // JavaScript object prototype, so we make sure | 1384 // JavaScript object prototype, so we make sure |
1530 // [:defineProperty:] is compiled. | 1385 // [:defineProperty:] is compiled. |
1531 enqueue(world, findHelper('defineProperty'), registry); | 1386 enqueue(world, helpers.defineProperty, registry); |
1532 } | 1387 } |
1533 } | 1388 } |
1534 | 1389 |
1535 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, | 1390 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, |
1536 DartType bound) { | 1391 DartType bound) { |
1537 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1392 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
1538 } | 1393 } |
1539 | 1394 |
1540 void registerCheckDeferredIsLoaded(Registry registry) { | 1395 void registerCheckDeferredIsLoaded(Registry registry) { |
1541 enqueueInResolution(helpers.checkDeferredIsLoaded, registry); | 1396 enqueueInResolution(helpers.checkDeferredIsLoaded, registry); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 // The JavaScript backend implements [Isolate.spawn] by looking up | 1450 // The JavaScript backend implements [Isolate.spawn] by looking up |
1596 // top-level functions by name. So all top-level function tear-off | 1451 // top-level functions by name. So all top-level function tear-off |
1597 // closures have a private name field. | 1452 // closures have a private name field. |
1598 // | 1453 // |
1599 // The JavaScript backend of [Isolate.spawnUri] uses the same internal | 1454 // The JavaScript backend of [Isolate.spawnUri] uses the same internal |
1600 // implementation as [Isolate.spawn], and fails if it cannot look main up | 1455 // implementation as [Isolate.spawn], and fails if it cannot look main up |
1601 // by name. | 1456 // by name. |
1602 enqueuer.registerGetOfStaticFunction(compiler.mainFunction); | 1457 enqueuer.registerGetOfStaticFunction(compiler.mainFunction); |
1603 } | 1458 } |
1604 if (enqueuer.isResolutionQueue) { | 1459 if (enqueuer.isResolutionQueue) { |
1605 for (String name in const [START_ROOT_ISOLATE, | 1460 |
1606 '_currentIsolate', | 1461 void enqueue(Element element) { |
1607 '_callInIsolate']) { | |
1608 Element element = find(isolateHelperLibrary, name); | |
1609 enqueuer.addToWorkList(element); | 1462 enqueuer.addToWorkList(element); |
1610 compiler.globalDependencies.registerDependency(element); | 1463 compiler.globalDependencies.registerDependency(element); |
1611 helpersUsed.add(element.declaration); | 1464 helpersUsed.add(element.declaration); |
1612 } | 1465 } |
| 1466 |
| 1467 enqueue(helpers.startRootIsolate); |
| 1468 enqueue(helpers.currentIsolate); |
| 1469 enqueue(helpers.callInIsolate); |
1613 } else { | 1470 } else { |
1614 enqueuer.addToWorkList(find(isolateHelperLibrary, START_ROOT_ISOLATE)); | 1471 enqueuer.addToWorkList(helpers.startRootIsolate); |
1615 } | 1472 } |
1616 } | 1473 } |
1617 | 1474 |
1618 bool classNeedsRti(ClassElement cls) { | 1475 bool classNeedsRti(ClassElement cls) { |
1619 return rti.classesNeedingRti.contains(cls.declaration) || | 1476 return rti.classesNeedingRti.contains(cls.declaration) || |
1620 compiler.enabledRuntimeType; | 1477 compiler.enabledRuntimeType; |
1621 } | 1478 } |
1622 | 1479 |
1623 bool isComplexNoSuchMethod(FunctionElement element) => | 1480 bool isComplexNoSuchMethod(FunctionElement element) => |
1624 noSuchMethodRegistry.isComplex(element); | 1481 noSuchMethodRegistry.isComplex(element); |
1625 | 1482 |
1626 bool isDefaultEqualityImplementation(Element element) { | 1483 bool isDefaultEqualityImplementation(Element element) { |
1627 assert(element.name == '=='); | 1484 assert(element.name == '=='); |
1628 ClassElement classElement = element.enclosingClass; | 1485 ClassElement classElement = element.enclosingClass; |
1629 return classElement == coreClasses.objectClass | 1486 return classElement == coreClasses.objectClass |
1630 || classElement == jsInterceptorClass | 1487 || classElement == helpers.jsInterceptorClass |
1631 || classElement == jsNullClass; | 1488 || classElement == helpers.jsNullClass; |
1632 } | 1489 } |
1633 | 1490 |
1634 bool methodNeedsRti(FunctionElement function) { | 1491 bool methodNeedsRti(FunctionElement function) { |
1635 return rti.methodsNeedingRti.contains(function) || | 1492 return rti.methodsNeedingRti.contains(function) || |
1636 compiler.enabledRuntimeType; | 1493 compiler.enabledRuntimeType; |
1637 } | 1494 } |
1638 | 1495 |
1639 /// The backend must *always* call this method when enqueuing an | 1496 /// The backend must *always* call this method when enqueuing an |
1640 /// element. Calls done by the backend are not seen by global | 1497 /// element. Calls done by the backend are not seen by global |
1641 /// optimizations, so they would make these optimizations unsound. | 1498 /// optimizations, so they would make these optimizations unsound. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 Element element = work.element; | 1579 Element element = work.element; |
1723 if (compiler.elementHasCompileTimeError(element)) { | 1580 if (compiler.elementHasCompileTimeError(element)) { |
1724 generatedCode[element] = jsAst.js( | 1581 generatedCode[element] = jsAst.js( |
1725 "function () { throw new Error('Compile time error in $element') }"); | 1582 "function () { throw new Error('Compile time error in $element') }"); |
1726 return const WorldImpact(); | 1583 return const WorldImpact(); |
1727 } | 1584 } |
1728 var kind = element.kind; | 1585 var kind = element.kind; |
1729 if (kind == ElementKind.TYPEDEF) { | 1586 if (kind == ElementKind.TYPEDEF) { |
1730 return const WorldImpact(); | 1587 return const WorldImpact(); |
1731 } | 1588 } |
1732 if (element.isConstructor && element.enclosingClass == jsNullClass) { | 1589 if (element.isConstructor && |
| 1590 element.enclosingClass == helpers.jsNullClass) { |
1733 // Work around a problem compiling JSNull's constructor. | 1591 // Work around a problem compiling JSNull's constructor. |
1734 return const WorldImpact(); | 1592 return const WorldImpact(); |
1735 } | 1593 } |
1736 if (kind.category == ElementCategory.VARIABLE) { | 1594 if (kind.category == ElementCategory.VARIABLE) { |
1737 ConstantValue initialValue = | 1595 ConstantValue initialValue = |
1738 constants.getConstantValueForVariable(element); | 1596 constants.getConstantValueForVariable(element); |
1739 if (initialValue != null) { | 1597 if (initialValue != null) { |
1740 registerCompileTimeConstant(initialValue, work.registry); | 1598 registerCompileTimeConstant(initialValue, work.registry); |
1741 addCompileTimeConstantForEmission(initialValue); | 1599 addCompileTimeConstantForEmission(initialValue); |
1742 // We don't need to generate code for static or top-level | 1600 // We don't need to generate code for static or top-level |
(...skipping 18 matching lines...) Expand all Loading... |
1761 | 1619 |
1762 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { | 1620 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { |
1763 return new native.NativeResolutionEnqueuer(world, compiler); | 1621 return new native.NativeResolutionEnqueuer(world, compiler); |
1764 } | 1622 } |
1765 | 1623 |
1766 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { | 1624 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { |
1767 return new native.NativeCodegenEnqueuer(world, compiler, emitter); | 1625 return new native.NativeCodegenEnqueuer(world, compiler, emitter); |
1768 } | 1626 } |
1769 | 1627 |
1770 ClassElement defaultSuperclass(ClassElement element) { | 1628 ClassElement defaultSuperclass(ClassElement element) { |
1771 if (isJsInterop(element)) return jsJavaScriptObjectClass; | 1629 if (isJsInterop(element)) { |
| 1630 return helpers.jsJavaScriptObjectClass; |
| 1631 } |
1772 // Native classes inherit from Interceptor. | 1632 // Native classes inherit from Interceptor. |
1773 return isNative(element) ? jsInterceptorClass : coreClasses.objectClass; | 1633 return isNative(element) |
| 1634 ? helpers.jsInterceptorClass : coreClasses.objectClass; |
1774 } | 1635 } |
1775 | 1636 |
1776 /** | 1637 /** |
1777 * Unit test hook that returns code of an element as a String. | 1638 * Unit test hook that returns code of an element as a String. |
1778 * | 1639 * |
1779 * Invariant: [element] must be a declaration element. | 1640 * Invariant: [element] must be a declaration element. |
1780 */ | 1641 */ |
1781 String getGeneratedCode(Element element) { | 1642 String getGeneratedCode(Element element) { |
1782 assert(invariant(element, element.isDeclaration)); | 1643 assert(invariant(element, element.isDeclaration)); |
1783 return jsAst.prettyPrint(generatedCode[element], compiler).getText(); | 1644 return jsAst.prettyPrint(generatedCode[element], compiler).getText(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1876 | 1737 |
1877 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 1738 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
1878 // interceptor. The interceptor should be an argument to HTypeConversion so | 1739 // interceptor. The interceptor should be an argument to HTypeConversion so |
1879 // that it can be optimized by standard interceptor optimizations. | 1740 // that it can be optimized by standard interceptor optimizations. |
1880 nativeCheck = true; | 1741 nativeCheck = true; |
1881 | 1742 |
1882 if (type.isVoid) { | 1743 if (type.isVoid) { |
1883 assert(!typeCast); // Cannot cast to void. | 1744 assert(!typeCast); // Cannot cast to void. |
1884 if (nativeCheckOnly) return null; | 1745 if (nativeCheckOnly) return null; |
1885 return 'voidTypeCheck'; | 1746 return 'voidTypeCheck'; |
1886 } else if (element == jsStringClass || | 1747 } else if (element == helpers.jsStringClass || |
1887 element == coreClasses.stringClass) { | 1748 element == coreClasses.stringClass) { |
1888 if (nativeCheckOnly) return null; | 1749 if (nativeCheckOnly) return null; |
1889 return typeCast | 1750 return typeCast |
1890 ? 'stringTypeCast' | 1751 ? 'stringTypeCast' |
1891 : 'stringTypeCheck'; | 1752 : 'stringTypeCheck'; |
1892 } else if (element == jsDoubleClass || | 1753 } else if (element == helpers.jsDoubleClass || |
1893 element == coreClasses.doubleClass) { | 1754 element == coreClasses.doubleClass) { |
1894 if (nativeCheckOnly) return null; | 1755 if (nativeCheckOnly) return null; |
1895 return typeCast | 1756 return typeCast |
1896 ? 'doubleTypeCast' | 1757 ? 'doubleTypeCast' |
1897 : 'doubleTypeCheck'; | 1758 : 'doubleTypeCheck'; |
1898 } else if (element == jsNumberClass || | 1759 } else if (element == helpers.jsNumberClass || |
1899 element == coreClasses.numClass) { | 1760 element == coreClasses.numClass) { |
1900 if (nativeCheckOnly) return null; | 1761 if (nativeCheckOnly) return null; |
1901 return typeCast | 1762 return typeCast |
1902 ? 'numTypeCast' | 1763 ? 'numTypeCast' |
1903 : 'numTypeCheck'; | 1764 : 'numTypeCheck'; |
1904 } else if (element == jsBoolClass || | 1765 } else if (element == helpers.jsBoolClass || |
1905 element == coreClasses.boolClass) { | 1766 element == coreClasses.boolClass) { |
1906 if (nativeCheckOnly) return null; | 1767 if (nativeCheckOnly) return null; |
1907 return typeCast | 1768 return typeCast |
1908 ? 'boolTypeCast' | 1769 ? 'boolTypeCast' |
1909 : 'boolTypeCheck'; | 1770 : 'boolTypeCheck'; |
1910 } else if (element == jsIntClass || | 1771 } else if (element == helpers.jsIntClass || |
1911 element == coreClasses.intClass || | 1772 element == coreClasses.intClass || |
1912 element == jsUInt32Class || | 1773 element == helpers.jsUInt32Class || |
1913 element == jsUInt31Class || | 1774 element == helpers.jsUInt31Class || |
1914 element == jsPositiveIntClass) { | 1775 element == helpers.jsPositiveIntClass) { |
1915 if (nativeCheckOnly) return null; | 1776 if (nativeCheckOnly) return null; |
1916 return typeCast | 1777 return typeCast |
1917 ? 'intTypeCast' | 1778 ? 'intTypeCast' |
1918 : 'intTypeCheck'; | 1779 : 'intTypeCheck'; |
1919 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { | 1780 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { |
1920 if (nativeCheck) { | 1781 if (nativeCheck) { |
1921 return typeCast | 1782 return typeCast |
1922 ? 'numberOrStringSuperNativeTypeCast' | 1783 ? 'numberOrStringSuperNativeTypeCast' |
1923 : 'numberOrStringSuperNativeTypeCheck'; | 1784 : 'numberOrStringSuperNativeTypeCheck'; |
1924 } else { | 1785 } else { |
1925 return typeCast | 1786 return typeCast |
1926 ? 'numberOrStringSuperTypeCast' | 1787 ? 'numberOrStringSuperTypeCast' |
1927 : 'numberOrStringSuperTypeCheck'; | 1788 : 'numberOrStringSuperTypeCheck'; |
1928 } | 1789 } |
1929 } else if (Elements.isStringOnlySupertype(element, compiler)) { | 1790 } else if (Elements.isStringOnlySupertype(element, compiler)) { |
1930 if (nativeCheck) { | 1791 if (nativeCheck) { |
1931 return typeCast | 1792 return typeCast |
1932 ? 'stringSuperNativeTypeCast' | 1793 ? 'stringSuperNativeTypeCast' |
1933 : 'stringSuperNativeTypeCheck'; | 1794 : 'stringSuperNativeTypeCheck'; |
1934 } else { | 1795 } else { |
1935 return typeCast | 1796 return typeCast |
1936 ? 'stringSuperTypeCast' | 1797 ? 'stringSuperTypeCast' |
1937 : 'stringSuperTypeCheck'; | 1798 : 'stringSuperTypeCheck'; |
1938 } | 1799 } |
1939 } else if ((element == coreClasses.listClass || | 1800 } else if ((element == coreClasses.listClass || |
1940 element == jsArrayClass) && | 1801 element == helpers.jsArrayClass) && |
1941 type.treatAsRaw) { | 1802 type.treatAsRaw) { |
1942 if (nativeCheckOnly) return null; | 1803 if (nativeCheckOnly) return null; |
1943 return typeCast | 1804 return typeCast |
1944 ? 'listTypeCast' | 1805 ? 'listTypeCast' |
1945 : 'listTypeCheck'; | 1806 : 'listTypeCheck'; |
1946 } else { | 1807 } else { |
1947 if (Elements.isListSupertype(element, compiler)) { | 1808 if (Elements.isListSupertype(element, compiler)) { |
1948 if (nativeCheck) { | 1809 if (nativeCheck) { |
1949 return typeCast | 1810 return typeCast |
1950 ? 'listSuperNativeTypeCast' | 1811 ? 'listSuperNativeTypeCast' |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1994 * Returns [:true:] if the checking of [type] is performed directly on the | 1855 * Returns [:true:] if the checking of [type] is performed directly on the |
1995 * object and not on an interceptor. | 1856 * object and not on an interceptor. |
1996 */ | 1857 */ |
1997 bool hasDirectCheckFor(DartType type) { | 1858 bool hasDirectCheckFor(DartType type) { |
1998 Element element = type.element; | 1859 Element element = type.element; |
1999 return element == coreClasses.stringClass || | 1860 return element == coreClasses.stringClass || |
2000 element == coreClasses.boolClass || | 1861 element == coreClasses.boolClass || |
2001 element == coreClasses.numClass || | 1862 element == coreClasses.numClass || |
2002 element == coreClasses.intClass || | 1863 element == coreClasses.intClass || |
2003 element == coreClasses.doubleClass || | 1864 element == coreClasses.doubleClass || |
2004 element == jsArrayClass || | 1865 element == helpers.jsArrayClass || |
2005 element == jsMutableArrayClass || | 1866 element == helpers.jsMutableArrayClass || |
2006 element == jsExtendableArrayClass || | 1867 element == helpers.jsExtendableArrayClass || |
2007 element == jsFixedArrayClass || | 1868 element == helpers.jsFixedArrayClass || |
2008 element == jsUnmodifiableArrayClass; | 1869 element == helpers.jsUnmodifiableArrayClass; |
2009 } | 1870 } |
2010 | 1871 |
2011 bool mayGenerateInstanceofCheck(DartType type) { | 1872 bool mayGenerateInstanceofCheck(DartType type) { |
2012 // We can use an instanceof check for raw types that have no subclass that | 1873 // We can use an instanceof check for raw types that have no subclass that |
2013 // is mixed-in or in an implements clause. | 1874 // is mixed-in or in an implements clause. |
2014 | 1875 |
2015 if (!type.isRaw) return false; | 1876 if (!type.isRaw) return false; |
2016 ClassElement classElement = type.element; | 1877 ClassElement classElement = type.element; |
2017 if (isInterceptorClass(classElement)) return false; | 1878 if (isInterceptorClass(classElement)) return false; |
2018 return compiler.world.hasOnlySubclasses(classElement); | 1879 return compiler.world.hasOnlySubclasses(classElement); |
2019 } | 1880 } |
2020 | 1881 |
2021 bool isNullImplementation(ClassElement cls) { | 1882 bool isNullImplementation(ClassElement cls) { |
2022 return cls == jsNullClass; | 1883 return cls == helpers.jsNullClass; |
2023 } | 1884 } |
2024 | 1885 |
2025 ClassElement get intImplementation => jsIntClass; | 1886 ClassElement get intImplementation => helpers.jsIntClass; |
2026 ClassElement get uint32Implementation => jsUInt32Class; | 1887 ClassElement get uint32Implementation => helpers.jsUInt32Class; |
2027 ClassElement get uint31Implementation => jsUInt31Class; | 1888 ClassElement get uint31Implementation => helpers.jsUInt31Class; |
2028 ClassElement get positiveIntImplementation => jsPositiveIntClass; | 1889 ClassElement get positiveIntImplementation => helpers.jsPositiveIntClass; |
2029 ClassElement get doubleImplementation => jsDoubleClass; | 1890 ClassElement get doubleImplementation => helpers.jsDoubleClass; |
2030 ClassElement get numImplementation => jsNumberClass; | 1891 ClassElement get numImplementation => helpers.jsNumberClass; |
2031 ClassElement get stringImplementation => jsStringClass; | 1892 ClassElement get stringImplementation => helpers.jsStringClass; |
2032 ClassElement get listImplementation => jsArrayClass; | 1893 ClassElement get listImplementation => helpers.jsArrayClass; |
2033 ClassElement get constListImplementation => jsUnmodifiableArrayClass; | 1894 ClassElement get constListImplementation => helpers.jsUnmodifiableArrayClass; |
2034 ClassElement get fixedListImplementation => jsFixedArrayClass; | 1895 ClassElement get fixedListImplementation => helpers.jsFixedArrayClass; |
2035 ClassElement get growableListImplementation => jsExtendableArrayClass; | 1896 ClassElement get growableListImplementation => helpers.jsExtendableArrayClass; |
2036 ClassElement get mapImplementation => mapLiteralClass; | 1897 ClassElement get mapImplementation => helpers.mapLiteralClass; |
2037 ClassElement get constMapImplementation => constMapLiteralClass; | 1898 ClassElement get constMapImplementation => helpers.constMapLiteralClass; |
2038 ClassElement get typeImplementation => typeLiteralClass; | 1899 ClassElement get typeImplementation => helpers.typeLiteralClass; |
2039 ClassElement get boolImplementation => jsBoolClass; | 1900 ClassElement get boolImplementation => helpers.jsBoolClass; |
2040 ClassElement get nullImplementation => jsNullClass; | 1901 ClassElement get nullImplementation => helpers.jsNullClass; |
2041 | 1902 |
2042 void registerStaticUse(Element element, Enqueuer enqueuer) { | 1903 void registerStaticUse(Element element, Enqueuer enqueuer) { |
2043 if (element == disableTreeShakingMarker) { | 1904 if (element == helpers.disableTreeShakingMarker) { |
2044 compiler.disableTypeInferenceForMirrors = true; | 1905 compiler.disableTypeInferenceForMirrors = true; |
2045 isTreeShakingDisabled = true; | 1906 isTreeShakingDisabled = true; |
2046 } else if (element == preserveNamesMarker) { | 1907 } else if (element == helpers.preserveNamesMarker) { |
2047 mustPreserveNames = true; | 1908 mustPreserveNames = true; |
2048 } else if (element == preserveMetadataMarker) { | 1909 } else if (element == helpers.preserveMetadataMarker) { |
2049 mustRetainMetadata = true; | 1910 mustRetainMetadata = true; |
2050 } else if (element == preserveUrisMarker) { | 1911 } else if (element == helpers.preserveUrisMarker) { |
2051 if (compiler.preserveUris) mustPreserveUris = true; | 1912 if (compiler.preserveUris) mustPreserveUris = true; |
2052 } else if (element == preserveLibraryNamesMarker) { | 1913 } else if (element == helpers.preserveLibraryNamesMarker) { |
2053 mustRetainLibraryNames = true; | 1914 mustRetainLibraryNames = true; |
2054 } else if (element == getIsolateAffinityTagMarker) { | 1915 } else if (element == helpers.getIsolateAffinityTagMarker) { |
2055 needToInitializeIsolateAffinityTag = true; | 1916 needToInitializeIsolateAffinityTag = true; |
2056 } else if (element.isDeferredLoaderGetter) { | 1917 } else if (element.isDeferredLoaderGetter) { |
2057 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1918 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
2058 if (compiler.loadLibraryFunction == null) { | 1919 if (compiler.loadLibraryFunction == null) { |
2059 compiler.loadLibraryFunction = | 1920 compiler.loadLibraryFunction = helpers.loadLibraryWrapper; |
2060 findHelper("_loadLibraryWrapper"); | |
2061 enqueueInResolution(compiler.loadLibraryFunction, | 1921 enqueueInResolution(compiler.loadLibraryFunction, |
2062 compiler.globalDependencies); | 1922 compiler.globalDependencies); |
2063 } | 1923 } |
2064 } else if (element == requiresPreambleMarker) { | 1924 } else if (element == helpers.requiresPreambleMarker) { |
2065 requiresPreamble = true; | 1925 requiresPreamble = true; |
2066 } | 1926 } |
2067 customElementsAnalysis.registerStaticUse(element, enqueuer); | 1927 customElementsAnalysis.registerStaticUse(element, enqueuer); |
2068 } | 1928 } |
2069 | 1929 |
2070 /// Called when [:const Symbol(name):] is seen. | 1930 /// Called when [:const Symbol(name):] is seen. |
2071 void registerConstSymbol(String name) { | 1931 void registerConstSymbol(String name) { |
2072 symbolsUsed.add(name); | 1932 symbolsUsed.add(name); |
2073 if (name.endsWith('=')) { | 1933 if (name.endsWith('=')) { |
2074 symbolsUsed.add(name.substring(0, name.length - 1)); | 1934 symbolsUsed.add(name.substring(0, name.length - 1)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 ConstantValue constant = | 1966 ConstantValue constant = |
2107 constants.getConstantValueForMetadata(metadata); | 1967 constants.getConstantValueForMetadata(metadata); |
2108 constants.addCompileTimeConstantForEmission(constant); | 1968 constants.addCompileTimeConstantForEmission(constant); |
2109 } | 1969 } |
2110 return true; | 1970 return true; |
2111 } | 1971 } |
2112 return false; | 1972 return false; |
2113 } | 1973 } |
2114 | 1974 |
2115 void onLibraryCreated(LibraryElement library) { | 1975 void onLibraryCreated(LibraryElement library) { |
2116 Uri uri = library.canonicalUri; | 1976 helpers.onLibraryCreated(library); |
2117 if (uri == DART_JS_HELPER) { | |
2118 jsHelperLibrary = library; | |
2119 } else if (uri == Uris.dart_async) { | |
2120 asyncLibrary = library; | |
2121 } else if (uri == Uris.dart__internal) { | |
2122 internalLibrary = library; | |
2123 } else if (uri == DART_INTERCEPTORS) { | |
2124 interceptorsLibrary = library; | |
2125 } else if (uri == DART_FOREIGN_HELPER) { | |
2126 foreignLibrary = library; | |
2127 } else if (uri == DART_ISOLATE_HELPER) { | |
2128 isolateHelperLibrary = library; | |
2129 } | |
2130 } | |
2131 | |
2132 void initializeHelperClasses() { | |
2133 final List missingHelperClasses = []; | |
2134 ClassElement lookupHelperClass(String name) { | |
2135 ClassElement result = findHelper(name); | |
2136 if (result == null) { | |
2137 missingHelperClasses.add(name); | |
2138 } | |
2139 return result; | |
2140 } | |
2141 jsInvocationMirrorClass = lookupHelperClass('JSInvocationMirror'); | |
2142 boundClosureClass = lookupHelperClass('BoundClosure'); | |
2143 closureClass = lookupHelperClass('Closure'); | |
2144 if (!missingHelperClasses.isEmpty) { | |
2145 reporter.internalError(jsHelperLibrary, | |
2146 'dart:_js_helper library does not contain required classes: ' | |
2147 '$missingHelperClasses'); | |
2148 } | |
2149 } | 1977 } |
2150 | 1978 |
2151 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1979 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
2152 return super.onLibraryScanned(library, loader).then((_) { | 1980 return super.onLibraryScanned(library, loader).then((_) { |
2153 if (library.isPlatformLibrary && | 1981 if (library.isPlatformLibrary && |
2154 // Don't patch library currently disallowed. | 1982 // Don't patch library currently disallowed. |
2155 !library.isSynthesized && | 1983 !library.isSynthesized && |
2156 !library.isPatched) { | 1984 !library.isPatched) { |
2157 // Apply patch, if any. | 1985 // Apply patch, if any. |
2158 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); | 1986 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); |
2159 if (patchUri != null) { | 1987 if (patchUri != null) { |
2160 return compiler.patchParser.patchLibrary(loader, patchUri, library); | 1988 return compiler.patchParser.patchLibrary(loader, patchUri, library); |
2161 } | 1989 } |
2162 } | 1990 } |
2163 }).then((_) { | 1991 }).then((_) { |
| 1992 helpers.onLibraryScanned(library); |
2164 Uri uri = library.canonicalUri; | 1993 Uri uri = library.canonicalUri; |
2165 | 1994 if (uri == Uris.dart_html) { |
2166 FunctionElement findMethod(String name) { | |
2167 return find(library, name); | |
2168 } | |
2169 | |
2170 ClassElement findClass(String name) { | |
2171 return find(library, name); | |
2172 } | |
2173 | |
2174 if (uri == DART_INTERCEPTORS) { | |
2175 getInterceptorMethod = findMethod('getInterceptor'); | |
2176 getNativeInterceptorMethod = findMethod('getNativeInterceptor'); | |
2177 jsInterceptorClass = findClass('Interceptor'); | |
2178 jsStringClass = findClass('JSString'); | |
2179 jsArrayClass = findClass('JSArray'); | |
2180 // The int class must be before the double class, because the | |
2181 // emitter relies on this list for the order of type checks. | |
2182 jsIntClass = findClass('JSInt'); | |
2183 jsPositiveIntClass = findClass('JSPositiveInt'); | |
2184 jsUInt32Class = findClass('JSUInt32'); | |
2185 jsUInt31Class = findClass('JSUInt31'); | |
2186 jsDoubleClass = findClass('JSDouble'); | |
2187 jsNumberClass = findClass('JSNumber'); | |
2188 jsNullClass = findClass('JSNull'); | |
2189 jsBoolClass = findClass('JSBool'); | |
2190 jsMutableArrayClass = findClass('JSMutableArray'); | |
2191 jsFixedArrayClass = findClass('JSFixedArray'); | |
2192 jsExtendableArrayClass = findClass('JSExtendableArray'); | |
2193 jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray'); | |
2194 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'); | |
2195 jsJavaScriptObjectClass = findClass('JavaScriptObject'); | |
2196 jsJavaScriptFunctionClass = findClass('JavaScriptFunction'); | |
2197 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'); | |
2198 jsIndexableClass = findClass('JSIndexable'); | |
2199 jsMutableIndexableClass = findClass('JSMutableIndexable'); | |
2200 } else if (uri == DART_JS_HELPER) { | |
2201 initializeHelperClasses(); | |
2202 helpers.assertTest = findHelper('assertTest'); | |
2203 helpers.assertThrow = findHelper('assertThrow'); | |
2204 helpers.assertHelper = findHelper('assertHelper'); | |
2205 assertUnreachableMethod = findHelper('assertUnreachable'); | |
2206 | |
2207 typeLiteralClass = findClass('TypeImpl'); | |
2208 constMapLiteralClass = findClass('ConstantMap'); | |
2209 typeVariableClass = findClass('TypeVariable'); | |
2210 | |
2211 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); | |
2212 | |
2213 noSideEffectsClass = findClass('NoSideEffects'); | |
2214 noThrowsClass = findClass('NoThrows'); | |
2215 noInlineClass = findClass('NoInline'); | |
2216 forceInlineClass = findClass('ForceInline'); | |
2217 irRepresentationClass = findClass('IrRepresentation'); | |
2218 | |
2219 getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag'); | |
2220 | |
2221 requiresPreambleMarker = findMethod('requiresPreamble'); | |
2222 } else if (uri == DART_JS_MIRRORS) { | |
2223 disableTreeShakingMarker = find(library, 'disableTreeShaking'); | |
2224 preserveMetadataMarker = find(library, 'preserveMetadata'); | |
2225 preserveUrisMarker = find(library, 'preserveUris'); | |
2226 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); | |
2227 } else if (uri == DART_JS_NAMES) { | |
2228 preserveNamesMarker = find(library, 'preserveNames'); | |
2229 } else if (uri == DART_EMBEDDED_NAMES) { | |
2230 jsGetNameEnum = find(library, 'JsGetName'); | |
2231 jsBuiltinEnum = find(library, 'JsBuiltin'); | |
2232 } else if (uri == Uris.dart_html) { | |
2233 htmlLibraryIsLoaded = true; | 1995 htmlLibraryIsLoaded = true; |
2234 } else if (uri == PACKAGE_LOOKUP_MAP) { | 1996 } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) { |
2235 lookupMapAnalysis.init(library); | 1997 lookupMapAnalysis.init(library); |
2236 } else if (uri == Uris.dart__native_typed_data) { | |
2237 typedArrayClass = findClass('NativeTypedArray'); | |
2238 typedArrayOfIntClass = findClass('NativeTypedArrayOfInt'); | |
2239 } else if (uri == PACKAGE_JS) { | |
2240 jsAnnotationClass = find(library, 'JS'); | |
2241 } | 1998 } |
2242 annotations.onLibraryScanned(library); | 1999 annotations.onLibraryScanned(library); |
2243 }); | 2000 }); |
2244 } | 2001 } |
2245 | 2002 |
2246 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 2003 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
2247 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { | 2004 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { |
2248 return new Future.value(); | 2005 return new Future.value(); |
2249 } | 2006 } |
2250 | 2007 |
2251 assert(loadedLibraries.containsLibrary(Uris.dart_core)); | 2008 helpers.onLibrariesLoaded(loadedLibraries); |
2252 assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS)); | |
2253 assert(loadedLibraries.containsLibrary(DART_JS_HELPER)); | |
2254 | |
2255 if (jsInvocationMirrorClass != null) { | |
2256 jsInvocationMirrorClass.ensureResolved(resolution); | |
2257 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); | |
2258 } | |
2259 | |
2260 // [LinkedHashMap] is reexported from dart:collection and can therefore not | |
2261 // be loaded from dart:core in [onLibraryScanned]. | |
2262 mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); | |
2263 assert(invariant(compiler.coreLibrary, mapLiteralClass != null, | |
2264 message: "Element 'LinkedHashMap' not found in 'dart:core'.")); | |
2265 | 2009 |
2266 implementationClasses = <ClassElement, ClassElement>{}; | 2010 implementationClasses = <ClassElement, ClassElement>{}; |
2267 implementationClasses[coreClasses.intClass] = jsIntClass; | 2011 implementationClasses[coreClasses.intClass] = helpers.jsIntClass; |
2268 implementationClasses[coreClasses.boolClass] = jsBoolClass; | 2012 implementationClasses[coreClasses.boolClass] = helpers.jsBoolClass; |
2269 implementationClasses[coreClasses.numClass] = jsNumberClass; | 2013 implementationClasses[coreClasses.numClass] = helpers.jsNumberClass; |
2270 implementationClasses[coreClasses.doubleClass] = jsDoubleClass; | 2014 implementationClasses[coreClasses.doubleClass] = helpers.jsDoubleClass; |
2271 implementationClasses[coreClasses.stringClass] = jsStringClass; | 2015 implementationClasses[coreClasses.stringClass] = helpers.jsStringClass; |
2272 implementationClasses[coreClasses.listClass] = jsArrayClass; | 2016 implementationClasses[coreClasses.listClass] = helpers.jsArrayClass; |
2273 implementationClasses[coreClasses.nullClass] = jsNullClass; | 2017 implementationClasses[coreClasses.nullClass] = helpers.jsNullClass; |
2274 | 2018 |
2275 // These methods are overwritten with generated versions. | 2019 // These methods are overwritten with generated versions. |
2276 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); | 2020 inlineCache.markAsNonInlinable( |
2277 | 2021 helpers.getInterceptorMethod, insideLoop: true); |
2278 // TODO(kasperl): Some tests do not define the special JSArray | |
2279 // subclasses, so we check to see if they are defined before | |
2280 // trying to resolve them. | |
2281 if (jsFixedArrayClass != null) { | |
2282 jsFixedArrayClass.ensureResolved(resolution); | |
2283 } | |
2284 if (jsExtendableArrayClass != null) { | |
2285 jsExtendableArrayClass.ensureResolved(resolution); | |
2286 } | |
2287 if (jsUnmodifiableArrayClass != null) { | |
2288 jsUnmodifiableArrayClass.ensureResolved(resolution); | |
2289 } | |
2290 | |
2291 jsIndexableClass.ensureResolved(resolution); | |
2292 jsIndexableLength = compiler.lookupElementIn( | |
2293 jsIndexableClass, 'length'); | |
2294 if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { | |
2295 AbstractFieldElement element = jsIndexableLength; | |
2296 jsIndexableLength = element.getter; | |
2297 } | |
2298 | |
2299 jsArrayClass.ensureResolved(resolution); | |
2300 jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); | |
2301 jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); | |
2302 jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); | |
2303 | |
2304 jsStringClass.ensureResolved(resolution); | |
2305 jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split'); | |
2306 jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); | |
2307 jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); | |
2308 | |
2309 objectEquals = compiler.lookupElementIn(coreClasses.objectClass, '=='); | |
2310 | 2022 |
2311 specialOperatorEqClasses | 2023 specialOperatorEqClasses |
2312 ..add(coreClasses.objectClass) | 2024 ..add(coreClasses.objectClass) |
2313 ..add(jsInterceptorClass) | 2025 ..add(helpers.jsInterceptorClass) |
2314 ..add(jsNullClass); | 2026 ..add(helpers.jsNullClass); |
2315 | 2027 |
2316 validateInterceptorImplementsAllObjectMethods(jsInterceptorClass); | 2028 validateInterceptorImplementsAllObjectMethods(helpers.jsInterceptorClass); |
2317 // The null-interceptor must also implement *all* methods. | 2029 // The null-interceptor must also implement *all* methods. |
2318 validateInterceptorImplementsAllObjectMethods(jsNullClass); | 2030 validateInterceptorImplementsAllObjectMethods(helpers.jsNullClass); |
2319 | 2031 |
2320 return new Future.value(); | 2032 return new Future.value(); |
2321 } | 2033 } |
2322 | 2034 |
2323 void registerMirrorUsage(Set<String> symbols, | 2035 void registerMirrorUsage(Set<String> symbols, |
2324 Set<Element> targets, | 2036 Set<Element> targets, |
2325 Set<Element> metaTargets) { | 2037 Set<Element> metaTargets) { |
2326 if (symbols == null && targets == null && metaTargets == null) { | 2038 if (symbols == null && targets == null && metaTargets == null) { |
2327 // The user didn't specify anything, or there are imports of | 2039 // The user didn't specify anything, or there are imports of |
2328 // 'dart:mirrors' without @MirrorsUsed. | 2040 // 'dart:mirrors' without @MirrorsUsed. |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2521 for (Element closure in closureMap[null]) { | 2233 for (Element closure in closureMap[null]) { |
2522 if (referencedFromMirrorSystem(closure)) { | 2234 if (referencedFromMirrorSystem(closure)) { |
2523 reflectableMembers.add(closure); | 2235 reflectableMembers.add(closure); |
2524 foundClosure = true; | 2236 foundClosure = true; |
2525 } | 2237 } |
2526 } | 2238 } |
2527 } | 2239 } |
2528 // As we do not think about closures as classes, yet, we have to make sure | 2240 // As we do not think about closures as classes, yet, we have to make sure |
2529 // their superclasses are available for reflection manually. | 2241 // their superclasses are available for reflection manually. |
2530 if (foundClosure) { | 2242 if (foundClosure) { |
2531 reflectableMembers.add(closureClass); | 2243 reflectableMembers.add(helpers.closureClass); |
2532 } | 2244 } |
2533 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; | 2245 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; |
2534 if (closurizedMembers.any(reflectableMembers.contains)) { | 2246 if (closurizedMembers.any(reflectableMembers.contains)) { |
2535 reflectableMembers.add(boundClosureClass); | 2247 reflectableMembers.add(helpers.boundClosureClass); |
2536 } | 2248 } |
2537 // Add typedefs. | 2249 // Add typedefs. |
2538 reflectableMembers | 2250 reflectableMembers |
2539 .addAll(compiler.world.allTypedefs.where(referencedFromMirrorSystem)); | 2251 .addAll(compiler.world.allTypedefs.where(referencedFromMirrorSystem)); |
2540 // Register all symbols of reflectable elements | 2252 // Register all symbols of reflectable elements |
2541 for (Element element in reflectableMembers) { | 2253 for (Element element in reflectableMembers) { |
2542 symbolsUsed.add(element.name); | 2254 symbolsUsed.add(element.name); |
2543 } | 2255 } |
2544 _membersNeededForReflection = reflectableMembers; | 2256 _membersNeededForReflection = reflectableMembers; |
2545 } | 2257 } |
(...skipping 15 matching lines...) Expand all Loading... |
2561 jsAst.Expression dispatchProperty = | 2273 jsAst.Expression dispatchProperty = |
2562 emitter.generateEmbeddedGlobalAccess(dispatchPropertyName); | 2274 emitter.generateEmbeddedGlobalAccess(dispatchPropertyName); |
2563 | 2275 |
2564 // We pass the dispatch property record to the isJsIndexable | 2276 // We pass the dispatch property record to the isJsIndexable |
2565 // helper rather than reading it inside the helper to increase the | 2277 // helper rather than reading it inside the helper to increase the |
2566 // chance of making the dispatch record access monomorphic. | 2278 // chance of making the dispatch record access monomorphic. |
2567 jsAst.PropertyAccess record = | 2279 jsAst.PropertyAccess record = |
2568 new jsAst.PropertyAccess(use2, dispatchProperty); | 2280 new jsAst.PropertyAccess(use2, dispatchProperty); |
2569 | 2281 |
2570 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; | 2282 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; |
2571 FunctionElement helper = findHelper('isJsIndexable'); | 2283 FunctionElement helper = helpers.isJsIndexable; |
2572 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); | 2284 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); |
2573 return new jsAst.Call(helperExpression, arguments); | 2285 return new jsAst.Call(helperExpression, arguments); |
2574 } | 2286 } |
2575 | 2287 |
2576 bool isTypedArray(TypeMask mask) { | 2288 bool isTypedArray(TypeMask mask) { |
2577 // Just checking for [:TypedData:] is not sufficient, as it is an | 2289 // Just checking for [:TypedData:] is not sufficient, as it is an |
2578 // abstract class any user-defined class can implement. So we also | 2290 // abstract class any user-defined class can implement. So we also |
2579 // check for the interface [JavaScriptIndexingBehavior]. | 2291 // check for the interface [JavaScriptIndexingBehavior]. |
2580 return | 2292 return |
2581 compiler.typedDataClass != null && | 2293 compiler.typedDataClass != null && |
2582 compiler.world.isInstantiated(compiler.typedDataClass) && | 2294 compiler.world.isInstantiated(compiler.typedDataClass) && |
2583 mask.satisfies(compiler.typedDataClass, compiler.world) && | 2295 mask.satisfies(compiler.typedDataClass, compiler.world) && |
2584 mask.satisfies(jsIndexingBehaviorInterface, compiler.world); | 2296 mask.satisfies(helpers.jsIndexingBehaviorInterface, compiler.world); |
2585 } | 2297 } |
2586 | 2298 |
2587 bool couldBeTypedArray(TypeMask mask) { | 2299 bool couldBeTypedArray(TypeMask mask) { |
2588 bool intersects(TypeMask type1, TypeMask type2) => | 2300 bool intersects(TypeMask type1, TypeMask type2) => |
2589 !type1.intersection(type2, compiler.world).isEmpty; | 2301 !type1.intersection(type2, compiler.world).isEmpty; |
2590 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and | 2302 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and |
2591 // jsIndexingBehaviourInterface. | 2303 // jsIndexingBehaviourInterface. |
2592 return | 2304 return |
2593 compiler.typedDataClass != null && | 2305 compiler.typedDataClass != null && |
2594 compiler.world.isInstantiated(compiler.typedDataClass) && | 2306 compiler.world.isInstantiated(compiler.typedDataClass) && |
2595 intersects(mask, | 2307 intersects(mask, |
2596 new TypeMask.subtype(compiler.typedDataClass, compiler.world)) && | 2308 new TypeMask.subtype(compiler.typedDataClass, compiler.world)) && |
2597 intersects(mask, | 2309 intersects(mask, |
2598 new TypeMask.subtype(jsIndexingBehaviorInterface, compiler.world)); | 2310 new TypeMask.subtype(helpers.jsIndexingBehaviorInterface, compiler.w
orld)); |
2599 } | 2311 } |
2600 | 2312 |
2601 /// Returns all static fields that are referenced through [targetsUsed]. | 2313 /// Returns all static fields that are referenced through [targetsUsed]. |
2602 /// If the target is a library or class all nested static fields are | 2314 /// If the target is a library or class all nested static fields are |
2603 /// included too. | 2315 /// included too. |
2604 Iterable<Element> _findStaticFieldTargets() { | 2316 Iterable<Element> _findStaticFieldTargets() { |
2605 List staticFields = []; | 2317 List staticFields = []; |
2606 | 2318 |
2607 void addFieldsInContainer(ScopeContainerElement container) { | 2319 void addFieldsInContainer(ScopeContainerElement container) { |
2608 container.forEachLocalMember((Element member) { | 2320 container.forEachLocalMember((Element member) { |
(...skipping 26 matching lines...) Expand all Loading... |
2635 noSuchMethodRegistry.onQueueEmpty(); | 2347 noSuchMethodRegistry.onQueueEmpty(); |
2636 if (!enabledNoSuchMethod && | 2348 if (!enabledNoSuchMethod && |
2637 (noSuchMethodRegistry.hasThrowingNoSuchMethod || | 2349 (noSuchMethodRegistry.hasThrowingNoSuchMethod || |
2638 noSuchMethodRegistry.hasComplexNoSuchMethod)) { | 2350 noSuchMethodRegistry.hasComplexNoSuchMethod)) { |
2639 enableNoSuchMethod(enqueuer); | 2351 enableNoSuchMethod(enqueuer); |
2640 enabledNoSuchMethod = true; | 2352 enabledNoSuchMethod = true; |
2641 } | 2353 } |
2642 | 2354 |
2643 if (compiler.hasIncrementalSupport) { | 2355 if (compiler.hasIncrementalSupport) { |
2644 // Always enable tear-off closures during incremental compilation. | 2356 // Always enable tear-off closures during incremental compilation. |
2645 Element e = findHelper('closureFromTearOff'); | 2357 Element e = helpers.closureFromTearOff; |
2646 if (e != null && !enqueuer.isProcessed(e)) { | 2358 if (e != null && !enqueuer.isProcessed(e)) { |
2647 registerBackendUse(e); | 2359 registerBackendUse(e); |
2648 enqueuer.addToWorkList(e); | 2360 enqueuer.addToWorkList(e); |
2649 } | 2361 } |
2650 } | 2362 } |
2651 | 2363 |
2652 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { | 2364 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { |
2653 preMirrorsMethodCount = generatedCode.length; | 2365 preMirrorsMethodCount = generatedCode.length; |
2654 } | 2366 } |
2655 | 2367 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2709 bool hasForceInline = false; | 2421 bool hasForceInline = false; |
2710 bool hasNoThrows = false; | 2422 bool hasNoThrows = false; |
2711 bool hasNoSideEffects = false; | 2423 bool hasNoSideEffects = false; |
2712 for (MetadataAnnotation metadata in element.implementation.metadata) { | 2424 for (MetadataAnnotation metadata in element.implementation.metadata) { |
2713 metadata.ensureResolved(resolution); | 2425 metadata.ensureResolved(resolution); |
2714 ConstantValue constantValue = | 2426 ConstantValue constantValue = |
2715 compiler.constants.getConstantValue(metadata.constant); | 2427 compiler.constants.getConstantValue(metadata.constant); |
2716 if (!constantValue.isConstructedObject) continue; | 2428 if (!constantValue.isConstructedObject) continue; |
2717 ObjectConstantValue value = constantValue; | 2429 ObjectConstantValue value = constantValue; |
2718 ClassElement cls = value.type.element; | 2430 ClassElement cls = value.type.element; |
2719 if (cls == forceInlineClass) { | 2431 if (cls == helpers.forceInlineClass) { |
2720 hasForceInline = true; | 2432 hasForceInline = true; |
2721 if (VERBOSE_OPTIMIZER_HINTS) { | 2433 if (VERBOSE_OPTIMIZER_HINTS) { |
2722 reporter.reportHintMessage( | 2434 reporter.reportHintMessage( |
2723 element, | 2435 element, |
2724 MessageKind.GENERIC, | 2436 MessageKind.GENERIC, |
2725 {'text': "Must inline"}); | 2437 {'text': "Must inline"}); |
2726 } | 2438 } |
2727 inlineCache.markAsMustInline(element); | 2439 inlineCache.markAsMustInline(element); |
2728 } else if (cls == noInlineClass) { | 2440 } else if (cls == helpers.noInlineClass) { |
2729 hasNoInline = true; | 2441 hasNoInline = true; |
2730 if (VERBOSE_OPTIMIZER_HINTS) { | 2442 if (VERBOSE_OPTIMIZER_HINTS) { |
2731 reporter.reportHintMessage( | 2443 reporter.reportHintMessage( |
2732 element, | 2444 element, |
2733 MessageKind.GENERIC, | 2445 MessageKind.GENERIC, |
2734 {'text': "Cannot inline"}); | 2446 {'text': "Cannot inline"}); |
2735 } | 2447 } |
2736 inlineCache.markAsNonInlinable(element); | 2448 inlineCache.markAsNonInlinable(element); |
2737 } else if (cls == noThrowsClass) { | 2449 } else if (cls == helpers.noThrowsClass) { |
2738 hasNoThrows = true; | 2450 hasNoThrows = true; |
2739 if (!Elements.isStaticOrTopLevelFunction(element) && | 2451 if (!Elements.isStaticOrTopLevelFunction(element) && |
2740 !element.isFactoryConstructor) { | 2452 !element.isFactoryConstructor) { |
2741 reporter.internalError(element, | 2453 reporter.internalError(element, |
2742 "@NoThrows() is currently limited to top-level" | 2454 "@NoThrows() is currently limited to top-level" |
2743 " or static functions and factory constructors."); | 2455 " or static functions and factory constructors."); |
2744 } | 2456 } |
2745 if (VERBOSE_OPTIMIZER_HINTS) { | 2457 if (VERBOSE_OPTIMIZER_HINTS) { |
2746 reporter.reportHintMessage( | 2458 reporter.reportHintMessage( |
2747 element, | 2459 element, |
2748 MessageKind.GENERIC, | 2460 MessageKind.GENERIC, |
2749 {'text': "Cannot throw"}); | 2461 {'text': "Cannot throw"}); |
2750 } | 2462 } |
2751 compiler.world.registerCannotThrow(element); | 2463 compiler.world.registerCannotThrow(element); |
2752 } else if (cls == noSideEffectsClass) { | 2464 } else if (cls == helpers.noSideEffectsClass) { |
2753 hasNoSideEffects = true; | 2465 hasNoSideEffects = true; |
2754 if (VERBOSE_OPTIMIZER_HINTS) { | 2466 if (VERBOSE_OPTIMIZER_HINTS) { |
2755 reporter.reportHintMessage( | 2467 reporter.reportHintMessage( |
2756 element, | 2468 element, |
2757 MessageKind.GENERIC, | 2469 MessageKind.GENERIC, |
2758 {'text': "Has no side effects"}); | 2470 {'text': "Has no side effects"}); |
2759 } | 2471 } |
2760 compiler.world.registerSideEffectsFree(element); | 2472 compiler.world.registerSideEffectsFree(element); |
2761 } | 2473 } |
2762 } | 2474 } |
2763 if (hasForceInline && hasNoInline) { | 2475 if (hasForceInline && hasNoInline) { |
2764 reporter.internalError(element, | 2476 reporter.internalError(element, |
2765 "@ForceInline() must not be used with @NoInline."); | 2477 "@ForceInline() must not be used with @NoInline."); |
2766 } | 2478 } |
2767 if (hasNoThrows && !hasNoInline) { | 2479 if (hasNoThrows && !hasNoInline) { |
2768 reporter.internalError(element, | 2480 reporter.internalError(element, |
2769 "@NoThrows() should always be combined with @NoInline."); | 2481 "@NoThrows() should always be combined with @NoInline."); |
2770 } | 2482 } |
2771 if (hasNoSideEffects && !hasNoInline) { | 2483 if (hasNoSideEffects && !hasNoInline) { |
2772 reporter.internalError(element, | 2484 reporter.internalError(element, |
2773 "@NoSideEffects() should always be combined with @NoInline."); | 2485 "@NoSideEffects() should always be combined with @NoInline."); |
2774 } | 2486 } |
2775 if (element == invokeOnMethod) { | 2487 if (element == helpers.invokeOnMethod) { |
2776 compiler.enabledInvokeOn = true; | 2488 compiler.enabledInvokeOn = true; |
2777 } | 2489 } |
2778 } | 2490 } |
2779 | 2491 |
2780 CodeBuffer codeOf(Element element) { | 2492 CodeBuffer codeOf(Element element) { |
2781 return generatedCode.containsKey(element) | 2493 return generatedCode.containsKey(element) |
2782 ? jsAst.prettyPrint(generatedCode[element], compiler) | 2494 ? jsAst.prettyPrint(generatedCode[element], compiler) |
2783 : null; | 2495 : null; |
2784 } | 2496 } |
2785 | 2497 |
2786 FunctionElement helperForBadMain() => findHelper('badMain'); | 2498 FunctionElement helperForBadMain() => helpers.badMain; |
2787 | 2499 |
2788 FunctionElement helperForMissingMain() => findHelper('missingMain'); | 2500 FunctionElement helperForMissingMain() => helpers.missingMain; |
2789 | 2501 |
2790 FunctionElement helperForMainArity() { | 2502 FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters; |
2791 return findHelper('mainHasTooManyParameters'); | |
2792 } | |
2793 | 2503 |
2794 void forgetElement(Element element) { | 2504 void forgetElement(Element element) { |
2795 constants.forgetElement(element); | 2505 constants.forgetElement(element); |
2796 constantCompilerTask.dartConstantCompiler.forgetElement(element); | 2506 constantCompilerTask.dartConstantCompiler.forgetElement(element); |
2797 aliasedSuperMembers.remove(element); | 2507 aliasedSuperMembers.remove(element); |
2798 } | 2508 } |
2799 | 2509 |
2800 void registerMainHasArguments(Enqueuer enqueuer) { | 2510 void registerMainHasArguments(Enqueuer enqueuer) { |
2801 // If the main method takes arguments, this compilation could be the target | 2511 // If the main method takes arguments, this compilation could be the target |
2802 // of Isolate.spawnUri. Strictly speaking, that can happen also if main | 2512 // of Isolate.spawnUri. Strictly speaking, that can happen also if main |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2957 } | 2667 } |
2958 } | 2668 } |
2959 } | 2669 } |
2960 | 2670 |
2961 /// Returns `true` if inlining is disabled for [element]. | 2671 /// Returns `true` if inlining is disabled for [element]. |
2962 bool noInline(Element element) { | 2672 bool noInline(Element element) { |
2963 if (_hasAnnotation(element, expectNoInlineClass)) { | 2673 if (_hasAnnotation(element, expectNoInlineClass)) { |
2964 // TODO(floitsch): restrict to elements from the test directory. | 2674 // TODO(floitsch): restrict to elements from the test directory. |
2965 return true; | 2675 return true; |
2966 } | 2676 } |
2967 return _hasAnnotation(element, backend.noInlineClass); | 2677 return _hasAnnotation(element, backend.helpers.noInlineClass); |
2968 } | 2678 } |
2969 | 2679 |
2970 /// Returns `true` if parameter and returns types should be trusted for | 2680 /// Returns `true` if parameter and returns types should be trusted for |
2971 /// [element]. | 2681 /// [element]. |
2972 bool trustTypeAnnotations(Element element) { | 2682 bool trustTypeAnnotations(Element element) { |
2973 return _hasAnnotation(element, expectTrustTypeAnnotationsClass); | 2683 return _hasAnnotation(element, expectTrustTypeAnnotationsClass); |
2974 } | 2684 } |
2975 | 2685 |
2976 /// Returns `true` if inference of parameter types is disabled for [element]. | 2686 /// Returns `true` if inference of parameter types is disabled for [element]. |
2977 bool assumeDynamic(Element element) { | 2687 bool assumeDynamic(Element element) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3232 } | 2942 } |
3233 | 2943 |
3234 /// Records that [constant] is used by the element behind [registry]. | 2944 /// Records that [constant] is used by the element behind [registry]. |
3235 class Dependency { | 2945 class Dependency { |
3236 final ConstantValue constant; | 2946 final ConstantValue constant; |
3237 final Element annotatedElement; | 2947 final Element annotatedElement; |
3238 | 2948 |
3239 const Dependency(this.constant, this.annotatedElement); | 2949 const Dependency(this.constant, this.annotatedElement); |
3240 } | 2950 } |
3241 | 2951 |
OLD | NEW |