| 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 library js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 // but may be inlined in a loop. | 107 // but may be inlined in a loop. |
| 108 static const int _mayInlineInLoopMustNotOutside = 1; | 108 static const int _mayInlineInLoopMustNotOutside = 1; |
| 109 // The function can be inlined in a loop, but not outside. | 109 // The function can be inlined in a loop, but not outside. |
| 110 static const int _canInlineInLoopMustNotOutside = 2; | 110 static const int _canInlineInLoopMustNotOutside = 2; |
| 111 // May-inline means that we know that it can be inlined inside a loop, but | 111 // May-inline means that we know that it can be inlined inside a loop, but |
| 112 // don't know about the general case yet. | 112 // don't know about the general case yet. |
| 113 static const int _canInlineInLoopMayInlineOutside = 3; | 113 static const int _canInlineInLoopMayInlineOutside = 3; |
| 114 static const int _canInline = 4; | 114 static const int _canInline = 4; |
| 115 static const int _mustInline = 5; | 115 static const int _mustInline = 5; |
| 116 | 116 |
| 117 final Map<FunctionElement, int> _cachedDecisions = | 117 final Map<MethodElement, int> _cachedDecisions = |
| 118 new Map<FunctionElement, int>(); | 118 new Map<MethodElement, int>(); |
| 119 | 119 |
| 120 /// Returns the current cache decision. This should only be used for testing. | 120 /// Returns the current cache decision. This should only be used for testing. |
| 121 int getCurrentCacheDecisionForTesting(Element element) { | 121 int getCurrentCacheDecisionForTesting(Element element) { |
| 122 return _cachedDecisions[element]; | 122 return _cachedDecisions[element]; |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Returns `true`/`false` if we have a cached decision. | 125 // Returns `true`/`false` if we have a cached decision. |
| 126 // Returns `null` otherwise. | 126 // Returns `null` otherwise. |
| 127 bool canInline(FunctionElement element, {bool insideLoop}) { | 127 bool canInline(MethodElement element, {bool insideLoop}) { |
| 128 int decision = _cachedDecisions[element]; | 128 int decision = _cachedDecisions[element]; |
| 129 | 129 |
| 130 if (decision == null) { | 130 if (decision == null) { |
| 131 // These synthetic elements are not yet present when we initially compute | 131 // These synthetic elements are not yet present when we initially compute |
| 132 // this cache from metadata annotations, so look for their parent. | 132 // this cache from metadata annotations, so look for their parent. |
| 133 if (element is ConstructorBodyElement) { | 133 if (element is ConstructorBodyElement) { |
| 134 ConstructorBodyElement body = element; | 134 ConstructorBodyElement body = element; |
| 135 decision = _cachedDecisions[body.constructor]; | 135 decision = _cachedDecisions[body.constructor]; |
| 136 } | 136 } |
| 137 if (decision == null) { | 137 if (decision == null) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 case _canInline: | 172 case _canInline: |
| 173 case _mustInline: | 173 case _mustInline: |
| 174 return true; | 174 return true; |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 // Quiet static checker. | 178 // Quiet static checker. |
| 179 return null; | 179 return null; |
| 180 } | 180 } |
| 181 | 181 |
| 182 void markAsInlinable(FunctionElement element, {bool insideLoop}) { | 182 void markAsInlinable(MethodElement element, {bool insideLoop}) { |
| 183 int oldDecision = _cachedDecisions[element]; | 183 int oldDecision = _cachedDecisions[element]; |
| 184 | 184 |
| 185 if (oldDecision == null) { | 185 if (oldDecision == null) { |
| 186 oldDecision = _unknown; | 186 oldDecision = _unknown; |
| 187 } | 187 } |
| 188 | 188 |
| 189 if (insideLoop) { | 189 if (insideLoop) { |
| 190 switch (oldDecision) { | 190 switch (oldDecision) { |
| 191 case _mustNotInline: | 191 case _mustNotInline: |
| 192 throw new SpannableAssertionFailure( | 192 throw new SpannableAssertionFailure( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 break; | 227 break; |
| 228 | 228 |
| 229 case _canInline: | 229 case _canInline: |
| 230 case _mustInline: | 230 case _mustInline: |
| 231 // Do nothing. | 231 // Do nothing. |
| 232 break; | 232 break; |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 } | 235 } |
| 236 | 236 |
| 237 void markAsNonInlinable(FunctionElement element, {bool insideLoop: true}) { | 237 void markAsNonInlinable(MethodElement element, {bool insideLoop: true}) { |
| 238 int oldDecision = _cachedDecisions[element]; | 238 int oldDecision = _cachedDecisions[element]; |
| 239 | 239 |
| 240 if (oldDecision == null) { | 240 if (oldDecision == null) { |
| 241 oldDecision = _unknown; | 241 oldDecision = _unknown; |
| 242 } | 242 } |
| 243 | 243 |
| 244 if (insideLoop) { | 244 if (insideLoop) { |
| 245 switch (oldDecision) { | 245 switch (oldDecision) { |
| 246 case _canInlineInLoopMustNotOutside: | 246 case _canInlineInLoopMustNotOutside: |
| 247 case _canInlineInLoopMayInlineOutside: | 247 case _canInlineInLoopMayInlineOutside: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 285 |
| 286 case _mayInlineInLoopMustNotOutside: | 286 case _mayInlineInLoopMustNotOutside: |
| 287 case _canInlineInLoopMustNotOutside: | 287 case _canInlineInLoopMustNotOutside: |
| 288 case _mustNotInline: | 288 case _mustNotInline: |
| 289 // Do nothing. | 289 // Do nothing. |
| 290 break; | 290 break; |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 } | 293 } |
| 294 | 294 |
| 295 void markAsMustInline(FunctionElement element) { | 295 void markAsMustInline(MethodElement element) { |
| 296 _cachedDecisions[element] = _mustInline; | 296 _cachedDecisions[element] = _mustInline; |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| 300 enum SyntheticConstantKind { | 300 enum SyntheticConstantKind { |
| 301 DUMMY_INTERCEPTOR, | 301 DUMMY_INTERCEPTOR, |
| 302 EMPTY_VALUE, | 302 EMPTY_VALUE, |
| 303 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. | 303 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. |
| 304 NAME | 304 NAME |
| 305 } | 305 } |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 JavaScriptBackendSerialization serialization; | 544 JavaScriptBackendSerialization serialization; |
| 545 | 545 |
| 546 StagedWorldImpactBuilder constantImpactsForResolution = | 546 StagedWorldImpactBuilder constantImpactsForResolution = |
| 547 new StagedWorldImpactBuilder(); | 547 new StagedWorldImpactBuilder(); |
| 548 | 548 |
| 549 StagedWorldImpactBuilder constantImpactsForCodegen = | 549 StagedWorldImpactBuilder constantImpactsForCodegen = |
| 550 new StagedWorldImpactBuilder(); | 550 new StagedWorldImpactBuilder(); |
| 551 | 551 |
| 552 final NativeData nativeData = new NativeData(); | 552 final NativeData nativeData = new NativeData(); |
| 553 | 553 |
| 554 final BackendHelpers helpers; | 554 BackendHelpers helpers; |
| 555 final BackendImpacts impacts; | 555 final BackendImpacts impacts; |
| 556 BackendClasses backendClasses; | 556 BackendClasses backendClasses; |
| 557 | 557 |
| 558 final JSFrontendAccess frontend; | 558 final JSFrontendAccess frontend; |
| 559 | 559 |
| 560 Tracer tracer; | 560 Tracer tracer; |
| 561 | 561 |
| 562 JavaScriptBackend(Compiler compiler, | 562 JavaScriptBackend(Compiler compiler, |
| 563 {bool generateSourceMap: true, | 563 {bool generateSourceMap: true, |
| 564 bool useStartupEmitter: false, | 564 bool useStartupEmitter: false, |
| 565 bool useNewSourceInfo: false, | 565 bool useNewSourceInfo: false, |
| 566 bool useKernel: false}) | 566 bool useKernel: false}) |
| 567 : oneShotInterceptors = new Map<jsAst.Name, Selector>(), | 567 : oneShotInterceptors = new Map<jsAst.Name, Selector>(), |
| 568 interceptedElements = new Map<String, Set<Element>>(), | 568 interceptedElements = new Map<String, Set<Element>>(), |
| 569 rti = new _RuntimeTypes(compiler), | 569 rti = new _RuntimeTypes(compiler), |
| 570 rtiEncoder = new _RuntimeTypesEncoder(compiler), | 570 rtiEncoder = new _RuntimeTypesEncoder(compiler), |
| 571 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), | 571 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), |
| 572 annotations = new Annotations(compiler), | 572 annotations = new Annotations(compiler), |
| 573 this.sourceInformationStrategy = generateSourceMap | 573 this.sourceInformationStrategy = generateSourceMap |
| 574 ? (useNewSourceInfo | 574 ? (useNewSourceInfo |
| 575 ? new PositionSourceInformationStrategy() | 575 ? new PositionSourceInformationStrategy() |
| 576 : const StartEndSourceInformationStrategy()) | 576 : const StartEndSourceInformationStrategy()) |
| 577 : const JavaScriptSourceInformationStrategy(), | 577 : const JavaScriptSourceInformationStrategy(), |
| 578 helpers = new BackendHelpers(compiler), | |
| 579 impacts = new BackendImpacts(compiler), | 578 impacts = new BackendImpacts(compiler), |
| 580 frontend = new JSFrontendAccess(compiler), | 579 frontend = new JSFrontendAccess(compiler), |
| 581 super(compiler) { | 580 super(compiler) { |
| 581 helpers = |
| 582 new BackendHelpers(compiler.elementEnvironment, this, commonElements); |
| 582 emitter = | 583 emitter = |
| 583 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); | 584 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); |
| 584 typeVariableHandler = new TypeVariableHandler(compiler); | 585 typeVariableHandler = new TypeVariableHandler(compiler); |
| 585 customElementsAnalysis = new CustomElementsAnalysis(this); | 586 customElementsAnalysis = new CustomElementsAnalysis(this); |
| 586 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); | 587 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); |
| 587 jsInteropAnalysis = new JsInteropAnalysis(this); | 588 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 588 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); | 589 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
| 589 | 590 |
| 590 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 591 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 591 kernelTask = new KernelTask(compiler); | 592 kernelTask = new KernelTask(compiler); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 if (element.isClass && element.isPatched) { | 666 if (element.isClass && element.isPatched) { |
| 666 // Both declaration and implementation may declare fields, so we | 667 // Both declaration and implementation may declare fields, so we |
| 667 // add both to the list of helpers. | 668 // add both to the list of helpers. |
| 668 helpersUsed.add(element.implementation); | 669 helpersUsed.add(element.implementation); |
| 669 } | 670 } |
| 670 return element; | 671 return element; |
| 671 } | 672 } |
| 672 | 673 |
| 673 bool _isValidBackendUse(Element element) { | 674 bool _isValidBackendUse(Element element) { |
| 674 assert(invariant(element, element.isDeclaration, message: "")); | 675 assert(invariant(element, element.isDeclaration, message: "")); |
| 675 if (element == helpers.streamIteratorConstructor || | 676 if (element is ConstructorElement && |
| 677 (element == helpers.streamIteratorConstructor || |
| 676 compiler.commonElements.isSymbolConstructor(element) || | 678 compiler.commonElements.isSymbolConstructor(element) || |
| 677 helpers.isSymbolValidatedConstructor(element) || | 679 helpers.isSymbolValidatedConstructor(element) || |
| 678 element == helpers.syncCompleterConstructor || | 680 element == helpers.syncCompleterConstructor)) { |
| 679 element == commonElements.symbolClass || | 681 // TODO(johnniwinther): These are valid but we could be more precise. |
| 682 return true; |
| 683 } else if (element == commonElements.symbolClass || |
| 680 element == helpers.objectNoSuchMethod) { | 684 element == helpers.objectNoSuchMethod) { |
| 681 // TODO(johnniwinther): These are valid but we could be more precise. | 685 // TODO(johnniwinther): These are valid but we could be more precise. |
| 682 return true; | 686 return true; |
| 683 } else if (element.implementationLibrary.isPatch || | 687 } else if (element.implementationLibrary.isPatch || |
| 684 // Needed to detect deserialized injected elements, that is | 688 // Needed to detect deserialized injected elements, that is |
| 685 // element declared in patch files. | 689 // element declared in patch files. |
| 686 (element.library.isPlatformLibrary && | 690 (element.library.isPlatformLibrary && |
| 687 element.sourcePosition.uri.path | 691 element.sourcePosition.uri.path |
| 688 .contains('_internal/js_runtime/lib/')) || | 692 .contains('_internal/js_runtime/lib/')) || |
| 689 element.library == helpers.jsHelperLibrary || | 693 element.library == helpers.jsHelperLibrary || |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 FunctionConstantValue function = constant; | 1086 FunctionConstantValue function = constant; |
| 1083 impactBuilder | 1087 impactBuilder |
| 1084 .registerStaticUse(new StaticUse.staticTearOff(function.element)); | 1088 .registerStaticUse(new StaticUse.staticTearOff(function.element)); |
| 1085 } else if (constant.isInterceptor) { | 1089 } else if (constant.isInterceptor) { |
| 1086 // An interceptor constant references the class's prototype chain. | 1090 // An interceptor constant references the class's prototype chain. |
| 1087 InterceptorConstantValue interceptor = constant; | 1091 InterceptorConstantValue interceptor = constant; |
| 1088 ClassElement cls = interceptor.cls; | 1092 ClassElement cls = interceptor.cls; |
| 1089 computeImpactForInstantiatedConstantType(cls.thisType, impactBuilder); | 1093 computeImpactForInstantiatedConstantType(cls.thisType, impactBuilder); |
| 1090 } else if (constant.isType) { | 1094 } else if (constant.isType) { |
| 1091 if (isForResolution) { | 1095 if (isForResolution) { |
| 1096 MethodElement helper = helpers.createRuntimeType; |
| 1092 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1097 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 1093 // TODO(johnniwinther): Find the right [CallStructure]. | 1098 // TODO(johnniwinther): Find the right [CallStructure]. |
| 1094 helpers.createRuntimeType, | 1099 helper, |
| 1095 null)); | 1100 null)); |
| 1096 registerBackendUse(helpers.createRuntimeType); | 1101 registerBackendUse(helper); |
| 1097 } | 1102 } |
| 1098 impactBuilder | 1103 impactBuilder |
| 1099 .registerTypeUse(new TypeUse.instantiation(backendClasses.typeType)); | 1104 .registerTypeUse(new TypeUse.instantiation(backendClasses.typeType)); |
| 1100 } | 1105 } |
| 1101 lookupMapAnalysis.registerConstantKey(constant); | 1106 lookupMapAnalysis.registerConstantKey(constant); |
| 1102 } | 1107 } |
| 1103 | 1108 |
| 1104 void computeImpactForInstantiatedConstantType( | 1109 void computeImpactForInstantiatedConstantType( |
| 1105 DartType type, WorldImpactBuilder impactBuilder) { | 1110 DartType type, WorldImpactBuilder impactBuilder) { |
| 1106 if (type is ResolutionInterfaceType) { | 1111 if (type is ResolutionInterfaceType) { |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1880 metadata.ensureResolved(resolution); | 1885 metadata.ensureResolved(resolution); |
| 1881 ConstantValue constant = | 1886 ConstantValue constant = |
| 1882 constants.getConstantValueForMetadata(metadata); | 1887 constants.getConstantValueForMetadata(metadata); |
| 1883 constants.addCompileTimeConstantForEmission(constant); | 1888 constants.addCompileTimeConstantForEmission(constant); |
| 1884 } | 1889 } |
| 1885 return true; | 1890 return true; |
| 1886 } | 1891 } |
| 1887 return false; | 1892 return false; |
| 1888 } | 1893 } |
| 1889 | 1894 |
| 1890 void onLibraryCreated(LibraryElement library) { | |
| 1891 helpers.onLibraryCreated(library); | |
| 1892 } | |
| 1893 | |
| 1894 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1895 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
| 1895 return super.onLibraryScanned(library, loader).then((_) { | 1896 return super.onLibraryScanned(library, loader).then((_) { |
| 1896 if (library.isPlatformLibrary && | 1897 if (library.isPlatformLibrary && |
| 1897 // Don't patch library currently disallowed. | 1898 // Don't patch library currently disallowed. |
| 1898 !library.isSynthesized && | 1899 !library.isSynthesized && |
| 1899 !library.isPatched && | 1900 !library.isPatched && |
| 1900 // Don't patch deserialized libraries. | 1901 // Don't patch deserialized libraries. |
| 1901 !compiler.serialization.isDeserialized(library)) { | 1902 !compiler.serialization.isDeserialized(library)) { |
| 1902 // Apply patch, if any. | 1903 // Apply patch, if any. |
| 1903 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); | 1904 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); |
| 1904 if (patchUri != null) { | 1905 if (patchUri != null) { |
| 1905 return compiler.patchParser.patchLibrary(loader, patchUri, library); | 1906 return compiler.patchParser.patchLibrary(loader, patchUri, library); |
| 1906 } | 1907 } |
| 1907 } | 1908 } |
| 1908 }).then((_) { | 1909 }).then((_) { |
| 1909 helpers.onLibraryScanned(library); | |
| 1910 Uri uri = library.canonicalUri; | 1910 Uri uri = library.canonicalUri; |
| 1911 if (uri == Uris.dart_html) { | 1911 if (uri == Uris.dart_html) { |
| 1912 htmlLibraryIsLoaded = true; | 1912 htmlLibraryIsLoaded = true; |
| 1913 } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) { | 1913 } else if (uri == LookupMapAnalysis.PACKAGE_LOOKUP_MAP) { |
| 1914 lookupMapAnalysis.init(library); | 1914 lookupMapAnalysis.init(library); |
| 1915 } | 1915 } |
| 1916 annotations.onLibraryScanned(library); | 1916 annotations.onLibraryScanned(library); |
| 1917 }); | 1917 }); |
| 1918 } | 1918 } |
| 1919 | 1919 |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2162 for (Element closure in closureMap[null]) { | 2162 for (Element closure in closureMap[null]) { |
| 2163 if (referencedFromMirrorSystem(closure)) { | 2163 if (referencedFromMirrorSystem(closure)) { |
| 2164 reflectableMembers.add(closure); | 2164 reflectableMembers.add(closure); |
| 2165 foundClosure = true; | 2165 foundClosure = true; |
| 2166 } | 2166 } |
| 2167 } | 2167 } |
| 2168 } | 2168 } |
| 2169 // As we do not think about closures as classes, yet, we have to make sure | 2169 // As we do not think about closures as classes, yet, we have to make sure |
| 2170 // their superclasses are available for reflection manually. | 2170 // their superclasses are available for reflection manually. |
| 2171 if (foundClosure) { | 2171 if (foundClosure) { |
| 2172 reflectableMembers.add(helpers.closureClass); | 2172 ClassElement cls = helpers.closureClass; |
| 2173 reflectableMembers.add(cls); |
| 2173 } | 2174 } |
| 2174 Set<Element> closurizedMembers = | 2175 Set<Element> closurizedMembers = |
| 2175 compiler.resolutionWorldBuilder.closurizedMembers; | 2176 compiler.resolutionWorldBuilder.closurizedMembers; |
| 2176 if (closurizedMembers.any(reflectableMembers.contains)) { | 2177 if (closurizedMembers.any(reflectableMembers.contains)) { |
| 2177 reflectableMembers.add(helpers.boundClosureClass); | 2178 ClassElement cls = helpers.boundClosureClass; |
| 2179 reflectableMembers.add(cls); |
| 2178 } | 2180 } |
| 2179 // Add typedefs. | 2181 // Add typedefs. |
| 2180 reflectableMembers | 2182 reflectableMembers |
| 2181 .addAll(closedWorld.allTypedefs.where(referencedFromMirrorSystem)); | 2183 .addAll(closedWorld.allTypedefs.where(referencedFromMirrorSystem)); |
| 2182 // Register all symbols of reflectable elements | 2184 // Register all symbols of reflectable elements |
| 2183 for (Element element in reflectableMembers) { | 2185 for (Element element in reflectableMembers) { |
| 2184 symbolsUsed.add(element.name); | 2186 symbolsUsed.add(element.name); |
| 2185 } | 2187 } |
| 2186 _membersNeededForReflection = reflectableMembers; | 2188 _membersNeededForReflection = reflectableMembers; |
| 2187 } | 2189 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2491 if (hasNoThrows && !hasNoInline) { | 2493 if (hasNoThrows && !hasNoInline) { |
| 2492 reporter.internalError( | 2494 reporter.internalError( |
| 2493 element, "@NoThrows() should always be combined with @NoInline."); | 2495 element, "@NoThrows() should always be combined with @NoInline."); |
| 2494 } | 2496 } |
| 2495 if (hasNoSideEffects && !hasNoInline) { | 2497 if (hasNoSideEffects && !hasNoInline) { |
| 2496 reporter.internalError(element, | 2498 reporter.internalError(element, |
| 2497 "@NoSideEffects() should always be combined with @NoInline."); | 2499 "@NoSideEffects() should always be combined with @NoInline."); |
| 2498 } | 2500 } |
| 2499 } | 2501 } |
| 2500 | 2502 |
| 2501 FunctionElement helperForBadMain() => helpers.badMain; | 2503 MethodElement helperForBadMain() => helpers.badMain; |
| 2502 | 2504 |
| 2503 FunctionElement helperForMissingMain() => helpers.missingMain; | 2505 MethodElement helperForMissingMain() => helpers.missingMain; |
| 2504 | 2506 |
| 2505 FunctionElement helperForMainArity() => helpers.mainHasTooManyParameters; | 2507 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; |
| 2506 | 2508 |
| 2507 @override | 2509 @override |
| 2508 WorldImpact computeMainImpact(MethodElement mainMethod, | 2510 WorldImpact computeMainImpact(MethodElement mainMethod, |
| 2509 {bool forResolution}) { | 2511 {bool forResolution}) { |
| 2510 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | 2512 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
| 2511 if (mainMethod.parameters.isNotEmpty) { | 2513 if (mainMethod.parameters.isNotEmpty) { |
| 2512 impactTransformer.registerBackendImpact( | 2514 impactTransformer.registerBackendImpact( |
| 2513 mainImpact, impacts.mainWithArguments); | 2515 mainImpact, impacts.mainWithArguments); |
| 2514 mainImpact.registerStaticUse( | 2516 mainImpact.registerStaticUse( |
| 2515 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); | 2517 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 break; | 2999 break; |
| 2998 case BackendFeature.needToInitializeIsolateAffinityTag: | 3000 case BackendFeature.needToInitializeIsolateAffinityTag: |
| 2999 backend.needToInitializeIsolateAffinityTag = true; | 3001 backend.needToInitializeIsolateAffinityTag = true; |
| 3000 break; | 3002 break; |
| 3001 } | 3003 } |
| 3002 } | 3004 } |
| 3003 } | 3005 } |
| 3004 | 3006 |
| 3005 /// Register [type] as required for the runtime type information system. | 3007 /// Register [type] as required for the runtime type information system. |
| 3006 void registerRequiredType(ResolutionDartType type) { | 3008 void registerRequiredType(ResolutionDartType type) { |
| 3009 if (!type.isInterfaceType) return; |
| 3007 // If [argument] has type variables or is a type variable, this method | 3010 // If [argument] has type variables or is a type variable, this method |
| 3008 // registers a RTI dependency between the class where the type variable is | 3011 // registers a RTI dependency between the class where the type variable is |
| 3009 // defined (that is the enclosing class of the current element being | 3012 // defined (that is the enclosing class of the current element being |
| 3010 // resolved) and the class of [type]. If the class of [type] requires RTI, | 3013 // resolved) and the class of [type]. If the class of [type] requires RTI, |
| 3011 // then the class of the type variable does too. | 3014 // then the class of the type variable does too. |
| 3012 ClassElement contextClass = Types.getClassContext(type); | 3015 ClassElement contextClass = Types.getClassContext(type); |
| 3013 if (contextClass != null) { | 3016 if (contextClass != null) { |
| 3014 backend.rti.registerRtiDependency(type.element, contextClass); | 3017 backend.rti.registerRtiDependency(type.element, contextClass); |
| 3015 } | 3018 } |
| 3016 } | 3019 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3278 @override | 3281 @override |
| 3279 bool isNativeClass(ClassElement element) { | 3282 bool isNativeClass(ClassElement element) { |
| 3280 return helpers.backend.isNative(element); | 3283 return helpers.backend.isNative(element); |
| 3281 } | 3284 } |
| 3282 | 3285 |
| 3283 @override | 3286 @override |
| 3284 bool isNativeMember(MemberElement element) { | 3287 bool isNativeMember(MemberElement element) { |
| 3285 return helpers.backend.isNative(element); | 3288 return helpers.backend.isNative(element); |
| 3286 } | 3289 } |
| 3287 } | 3290 } |
| OLD | NEW |