| 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 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); | 658 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); |
| 659 patchResolverTask = new PatchResolverTask(compiler); | 659 patchResolverTask = new PatchResolverTask(compiler); |
| 660 functionCompiler = compiler.useCpsIr | 660 functionCompiler = compiler.useCpsIr |
| 661 ? new CpsFunctionCompiler( | 661 ? new CpsFunctionCompiler( |
| 662 compiler, this, sourceInformationStrategy) | 662 compiler, this, sourceInformationStrategy) |
| 663 : new SsaFunctionCompiler(this, sourceInformationStrategy); | 663 : new SsaFunctionCompiler(this, sourceInformationStrategy); |
| 664 } | 664 } |
| 665 | 665 |
| 666 ConstantSystem get constantSystem => constants.constantSystem; | 666 ConstantSystem get constantSystem => constants.constantSystem; |
| 667 | 667 |
| 668 Resolution get resolution => compiler.resolution; |
| 669 |
| 668 /// Returns constant environment for the JavaScript interpretation of the | 670 /// Returns constant environment for the JavaScript interpretation of the |
| 669 /// constants. | 671 /// constants. |
| 670 JavaScriptConstantCompiler get constants { | 672 JavaScriptConstantCompiler get constants { |
| 671 return constantCompilerTask.jsConstantCompiler; | 673 return constantCompilerTask.jsConstantCompiler; |
| 672 } | 674 } |
| 673 | 675 |
| 674 FunctionElement resolveExternalFunction(FunctionElement element) { | 676 FunctionElement resolveExternalFunction(FunctionElement element) { |
| 675 if (isForeign(element)) return element; | 677 if (isForeign(element)) return element; |
| 676 return patchResolverTask.measure(() { | 678 return patchResolverTask.measure(() { |
| 677 return patchResolverTask.resolveExternalFunction(element); | 679 return patchResolverTask.resolveExternalFunction(element); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 } | 881 } |
| 880 | 882 |
| 881 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { | 883 bool operatorEqHandlesNullArgument(FunctionElement operatorEqfunction) { |
| 882 return specialOperatorEqClasses.contains( | 884 return specialOperatorEqClasses.contains( |
| 883 operatorEqfunction.enclosingClass); | 885 operatorEqfunction.enclosingClass); |
| 884 } | 886 } |
| 885 | 887 |
| 886 void validateInterceptorImplementsAllObjectMethods( | 888 void validateInterceptorImplementsAllObjectMethods( |
| 887 ClassElement interceptorClass) { | 889 ClassElement interceptorClass) { |
| 888 if (interceptorClass == null) return; | 890 if (interceptorClass == null) return; |
| 889 interceptorClass.ensureResolved(compiler); | 891 interceptorClass.ensureResolved(resolution); |
| 890 compiler.objectClass.forEachMember((_, Element member) { | 892 compiler.objectClass.forEachMember((_, Element member) { |
| 891 if (member.isGenerativeConstructor) return; | 893 if (member.isGenerativeConstructor) return; |
| 892 Element interceptorMember = interceptorClass.lookupMember(member.name); | 894 Element interceptorMember = interceptorClass.lookupMember(member.name); |
| 893 // Interceptors must override all Object methods due to calling convention | 895 // Interceptors must override all Object methods due to calling convention |
| 894 // differences. | 896 // differences. |
| 895 assert(interceptorMember.enclosingClass == interceptorClass); | 897 assert(interceptorMember.enclosingClass == interceptorClass); |
| 896 }); | 898 }); |
| 897 } | 899 } |
| 898 | 900 |
| 899 void addInterceptorsForNativeClassMembers( | 901 void addInterceptorsForNativeClassMembers( |
| 900 ClassElement cls, Enqueuer enqueuer) { | 902 ClassElement cls, Enqueuer enqueuer) { |
| 901 if (enqueuer.isResolutionQueue) { | 903 if (enqueuer.isResolutionQueue) { |
| 902 cls.ensureResolved(compiler); | 904 cls.ensureResolved(resolution); |
| 903 cls.forEachMember((ClassElement classElement, Element member) { | 905 cls.forEachMember((ClassElement classElement, Element member) { |
| 904 if (member.name == Identifiers.call) { | 906 if (member.name == Identifiers.call) { |
| 905 compiler.reportErrorMessage( | 907 compiler.reportErrorMessage( |
| 906 member, | 908 member, |
| 907 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS); | 909 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS); |
| 908 return; | 910 return; |
| 909 } | 911 } |
| 910 if (member.isSynthesized) return; | 912 if (member.isSynthesized) return; |
| 911 // All methods on [Object] are shadowed by [Interceptor]. | 913 // All methods on [Object] are shadowed by [Interceptor]. |
| 912 if (classElement == compiler.objectClass) return; | 914 if (classElement == compiler.objectClass) return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 925 } | 927 } |
| 926 } | 928 } |
| 927 } | 929 } |
| 928 | 930 |
| 929 void addInterceptors(ClassElement cls, | 931 void addInterceptors(ClassElement cls, |
| 930 Enqueuer enqueuer, | 932 Enqueuer enqueuer, |
| 931 Registry registry) { | 933 Registry registry) { |
| 932 if (enqueuer.isResolutionQueue) { | 934 if (enqueuer.isResolutionQueue) { |
| 933 _interceptedClasses.add(jsInterceptorClass); | 935 _interceptedClasses.add(jsInterceptorClass); |
| 934 _interceptedClasses.add(cls); | 936 _interceptedClasses.add(cls); |
| 935 cls.ensureResolved(compiler); | 937 cls.ensureResolved(resolution); |
| 936 cls.forEachMember((ClassElement classElement, Element member) { | 938 cls.forEachMember((ClassElement classElement, Element member) { |
| 937 // All methods on [Object] are shadowed by [Interceptor]. | 939 // All methods on [Object] are shadowed by [Interceptor]. |
| 938 if (classElement == compiler.objectClass) return; | 940 if (classElement == compiler.objectClass) return; |
| 939 Set<Element> set = interceptedElements.putIfAbsent( | 941 Set<Element> set = interceptedElements.putIfAbsent( |
| 940 member.name, () => new Set<Element>()); | 942 member.name, () => new Set<Element>()); |
| 941 set.add(member); | 943 set.add(member); |
| 942 }, | 944 }, |
| 943 includeSuperAndInjectedMembers: true); | 945 includeSuperAndInjectedMembers: true); |
| 944 } | 946 } |
| 945 enqueueClass(enqueuer, cls, registry); | 947 enqueueClass(enqueuer, cls, registry); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 | 1259 |
| 1258 /// Call during codegen if an instance of [closure] is being created. | 1260 /// Call during codegen if an instance of [closure] is being created. |
| 1259 void registerInstantiatedClosure(LocalFunctionElement closure, | 1261 void registerInstantiatedClosure(LocalFunctionElement closure, |
| 1260 CodegenRegistry registry) { | 1262 CodegenRegistry registry) { |
| 1261 if (methodNeedsRti(closure)) { | 1263 if (methodNeedsRti(closure)) { |
| 1262 registerComputeSignature(compiler.enqueuer.codegen, registry); | 1264 registerComputeSignature(compiler.enqueuer.codegen, registry); |
| 1263 } | 1265 } |
| 1264 } | 1266 } |
| 1265 | 1267 |
| 1266 void registerBoundClosure(Enqueuer enqueuer) { | 1268 void registerBoundClosure(Enqueuer enqueuer) { |
| 1267 boundClosureClass.ensureResolved(compiler); | 1269 boundClosureClass.ensureResolved(resolution); |
| 1268 registerInstantiatedType( | 1270 registerInstantiatedType( |
| 1269 boundClosureClass.rawType, | 1271 boundClosureClass.rawType, |
| 1270 enqueuer, | 1272 enqueuer, |
| 1271 // Precise dependency is not important here. | 1273 // Precise dependency is not important here. |
| 1272 compiler.globalDependencies); | 1274 compiler.globalDependencies); |
| 1273 } | 1275 } |
| 1274 | 1276 |
| 1275 void registerGetOfStaticFunction(Enqueuer enqueuer) { | 1277 void registerGetOfStaticFunction(Enqueuer enqueuer) { |
| 1276 closureClass.ensureResolved(compiler); | 1278 closureClass.ensureResolved(resolution); |
| 1277 registerInstantiatedType( | 1279 registerInstantiatedType( |
| 1278 closureClass.rawType, | 1280 closureClass.rawType, |
| 1279 enqueuer, | 1281 enqueuer, |
| 1280 compiler.globalDependencies); | 1282 compiler.globalDependencies); |
| 1281 } | 1283 } |
| 1282 | 1284 |
| 1283 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { | 1285 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { |
| 1284 // Calls to [:computeSignature:] are generated by the emitter and we | 1286 // Calls to [:computeSignature:] are generated by the emitter and we |
| 1285 // therefore need to enqueue the used elements in the codegen enqueuer as | 1287 // therefore need to enqueue the used elements in the codegen enqueuer as |
| 1286 // well as in the resolution enqueuer. | 1288 // well as in the resolution enqueuer. |
| 1287 enqueue(enqueuer, getSetRuntimeTypeInfo(), registry); | 1289 enqueue(enqueuer, getSetRuntimeTypeInfo(), registry); |
| 1288 enqueue(enqueuer, getGetRuntimeTypeInfo(), registry); | 1290 enqueue(enqueuer, getGetRuntimeTypeInfo(), registry); |
| 1289 enqueue(enqueuer, getComputeSignature(), registry); | 1291 enqueue(enqueuer, getComputeSignature(), registry); |
| 1290 enqueue(enqueuer, getGetRuntimeTypeArguments(), registry); | 1292 enqueue(enqueuer, getGetRuntimeTypeArguments(), registry); |
| 1291 enqueueClass(enqueuer, compiler.listClass, registry); | 1293 enqueueClass(enqueuer, compiler.listClass, registry); |
| 1292 } | 1294 } |
| 1293 | 1295 |
| 1294 void registerRuntimeType(Enqueuer enqueuer, Registry registry) { | 1296 void registerRuntimeType(Enqueuer enqueuer, Registry registry) { |
| 1295 registerComputeSignature(enqueuer, registry); | 1297 registerComputeSignature(enqueuer, registry); |
| 1296 enqueueInResolution(getSetRuntimeTypeInfo(), registry); | 1298 enqueueInResolution(getSetRuntimeTypeInfo(), registry); |
| 1297 enqueueInResolution(getGetRuntimeTypeInfo(), registry); | 1299 enqueueInResolution(getGetRuntimeTypeInfo(), registry); |
| 1298 registerGetRuntimeTypeArgument(registry); | 1300 registerGetRuntimeTypeArgument(registry); |
| 1299 enqueueClass(enqueuer, compiler.listClass, registry); | 1301 enqueueClass(enqueuer, compiler.listClass, registry); |
| 1300 } | 1302 } |
| 1301 | 1303 |
| 1302 void registerIsCheckForCodegen(DartType type, | 1304 void registerIsCheckForCodegen(DartType type, |
| 1303 Enqueuer world, | 1305 Enqueuer world, |
| 1304 Registry registry) { | 1306 Registry registry) { |
| 1305 assert(!registry.isForResolution); | 1307 assert(!registry.isForResolution); |
| 1306 type = type.unalias(compiler); | 1308 type = type.unalias(resolution); |
| 1307 enqueueClass(world, compiler.boolClass, registry); | 1309 enqueueClass(world, compiler.boolClass, registry); |
| 1308 bool inCheckedMode = compiler.enableTypeAssertions; | 1310 bool inCheckedMode = compiler.enableTypeAssertions; |
| 1309 // [registerIsCheck] is also called for checked mode checks, so we | 1311 // [registerIsCheck] is also called for checked mode checks, so we |
| 1310 // need to register checked mode helpers. | 1312 // need to register checked mode helpers. |
| 1311 if (inCheckedMode) { | 1313 if (inCheckedMode) { |
| 1312 // All helpers are added to resolution queue in enqueueHelpers. These | 1314 // All helpers are added to resolution queue in enqueueHelpers. These |
| 1313 // calls to enqueueInResolution serve as assertions that the helper was | 1315 // calls to enqueueInResolution serve as assertions that the helper was |
| 1314 // in fact added. | 1316 // in fact added. |
| 1315 // TODO(13155): Find a way to enqueue helpers lazily. | 1317 // TODO(13155): Find a way to enqueue helpers lazily. |
| 1316 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); | 1318 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1455 /// Register instantiation of [cls] in [enqueuer]. | 1457 /// Register instantiation of [cls] in [enqueuer]. |
| 1456 /// | 1458 /// |
| 1457 /// This method calls [registerBackendUse]. | 1459 /// This method calls [registerBackendUse]. |
| 1458 void enqueueClass(Enqueuer enqueuer, ClassElement cls, Registry registry) { | 1460 void enqueueClass(Enqueuer enqueuer, ClassElement cls, Registry registry) { |
| 1459 if (cls == null) return; | 1461 if (cls == null) return; |
| 1460 registerBackendUse(cls); | 1462 registerBackendUse(cls); |
| 1461 helpersUsed.add(cls.declaration); | 1463 helpersUsed.add(cls.declaration); |
| 1462 if (cls.declaration != cls.implementation) { | 1464 if (cls.declaration != cls.implementation) { |
| 1463 helpersUsed.add(cls.implementation); | 1465 helpersUsed.add(cls.implementation); |
| 1464 } | 1466 } |
| 1465 cls.ensureResolved(compiler); | 1467 cls.ensureResolved(resolution); |
| 1466 registerInstantiatedType(cls.rawType, enqueuer, registry); | 1468 registerInstantiatedType(cls.rawType, enqueuer, registry); |
| 1467 } | 1469 } |
| 1468 | 1470 |
| 1469 WorldImpact codegen(CodegenWorkItem work) { | 1471 WorldImpact codegen(CodegenWorkItem work) { |
| 1470 Element element = work.element; | 1472 Element element = work.element; |
| 1471 if (compiler.elementHasCompileTimeError(element)) { | 1473 if (compiler.elementHasCompileTimeError(element)) { |
| 1472 generatedCode[element] = jsAst.js( | 1474 generatedCode[element] = jsAst.js( |
| 1473 "function () { throw new Error('Compile time error in $element') }"); | 1475 "function () { throw new Error('Compile time error in $element') }"); |
| 1474 return const WorldImpact(); | 1476 return const WorldImpact(); |
| 1475 } | 1477 } |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 Element getAsyncHelper() { | 1897 Element getAsyncHelper() { |
| 1896 return findAsyncHelper("_asyncHelper"); | 1898 return findAsyncHelper("_asyncHelper"); |
| 1897 } | 1899 } |
| 1898 | 1900 |
| 1899 Element getWrapBody() { | 1901 Element getWrapBody() { |
| 1900 return findAsyncHelper("_wrapJsFunctionForAsync"); | 1902 return findAsyncHelper("_wrapJsFunctionForAsync"); |
| 1901 } | 1903 } |
| 1902 | 1904 |
| 1903 Element getYieldStar() { | 1905 Element getYieldStar() { |
| 1904 ClassElement classElement = findAsyncHelper("_IterationMarker"); | 1906 ClassElement classElement = findAsyncHelper("_IterationMarker"); |
| 1905 classElement.ensureResolved(compiler); | 1907 classElement.ensureResolved(resolution); |
| 1906 return classElement.lookupLocalMember("yieldStar"); | 1908 return classElement.lookupLocalMember("yieldStar"); |
| 1907 } | 1909 } |
| 1908 | 1910 |
| 1909 Element getYieldSingle() { | 1911 Element getYieldSingle() { |
| 1910 ClassElement classElement = findAsyncHelper("_IterationMarker"); | 1912 ClassElement classElement = findAsyncHelper("_IterationMarker"); |
| 1911 classElement.ensureResolved(compiler); | 1913 classElement.ensureResolved(resolution); |
| 1912 return classElement.lookupLocalMember("yieldSingle"); | 1914 return classElement.lookupLocalMember("yieldSingle"); |
| 1913 } | 1915 } |
| 1914 | 1916 |
| 1915 Element getSyncStarUncaughtError() { | 1917 Element getSyncStarUncaughtError() { |
| 1916 ClassElement classElement = findAsyncHelper("_IterationMarker"); | 1918 ClassElement classElement = findAsyncHelper("_IterationMarker"); |
| 1917 classElement.ensureResolved(compiler); | 1919 classElement.ensureResolved(resolution); |
| 1918 return classElement.lookupLocalMember("uncaughtError"); | 1920 return classElement.lookupLocalMember("uncaughtError"); |
| 1919 } | 1921 } |
| 1920 | 1922 |
| 1921 Element getAsyncStarHelper() { | 1923 Element getAsyncStarHelper() { |
| 1922 return findAsyncHelper("_asyncStarHelper"); | 1924 return findAsyncHelper("_asyncStarHelper"); |
| 1923 } | 1925 } |
| 1924 | 1926 |
| 1925 Element getStreamOfController() { | 1927 Element getStreamOfController() { |
| 1926 return findAsyncHelper("_streamOfController"); | 1928 return findAsyncHelper("_streamOfController"); |
| 1927 } | 1929 } |
| 1928 | 1930 |
| 1929 Element getEndOfIteration() { | 1931 Element getEndOfIteration() { |
| 1930 ClassElement classElement = findAsyncHelper("_IterationMarker"); | 1932 ClassElement classElement = findAsyncHelper("_IterationMarker"); |
| 1931 classElement.ensureResolved(compiler); | 1933 classElement.ensureResolved(resolution); |
| 1932 return classElement.lookupLocalMember("endOfIteration"); | 1934 return classElement.lookupLocalMember("endOfIteration"); |
| 1933 } | 1935 } |
| 1934 | 1936 |
| 1935 Element getSyncStarIterable() { | 1937 Element getSyncStarIterable() { |
| 1936 ClassElement classElement = findAsyncHelper("_SyncStarIterable"); | 1938 ClassElement classElement = findAsyncHelper("_SyncStarIterable"); |
| 1937 classElement.ensureResolved(compiler); | 1939 classElement.ensureResolved(resolution); |
| 1938 return classElement; | 1940 return classElement; |
| 1939 } | 1941 } |
| 1940 | 1942 |
| 1941 Element getSyncStarIterableConstructor() { | 1943 Element getSyncStarIterableConstructor() { |
| 1942 ClassElement classElement = getSyncStarIterable(); | 1944 ClassElement classElement = getSyncStarIterable(); |
| 1943 classElement.ensureResolved(compiler); | 1945 classElement.ensureResolved(resolution); |
| 1944 return classElement.lookupConstructor(""); | 1946 return classElement.lookupConstructor(""); |
| 1945 } | 1947 } |
| 1946 | 1948 |
| 1947 Element getSyncCompleterConstructor() { | 1949 Element getSyncCompleterConstructor() { |
| 1948 ClassElement classElement = find(compiler.asyncLibrary, "Completer"); | 1950 ClassElement classElement = find(compiler.asyncLibrary, "Completer"); |
| 1949 classElement.ensureResolved(compiler); | 1951 classElement.ensureResolved(resolution); |
| 1950 return classElement.lookupConstructor("sync"); | 1952 return classElement.lookupConstructor("sync"); |
| 1951 } | 1953 } |
| 1952 | 1954 |
| 1953 Element getASyncStarController() { | 1955 Element getASyncStarController() { |
| 1954 ClassElement classElement = | 1956 ClassElement classElement = |
| 1955 findAsyncHelper("_AsyncStarStreamController"); | 1957 findAsyncHelper("_AsyncStarStreamController"); |
| 1956 classElement.ensureResolved(compiler); | 1958 classElement.ensureResolved(resolution); |
| 1957 return classElement; | 1959 return classElement; |
| 1958 } | 1960 } |
| 1959 | 1961 |
| 1960 Element getASyncStarControllerConstructor() { | 1962 Element getASyncStarControllerConstructor() { |
| 1961 ClassElement classElement = getASyncStarController(); | 1963 ClassElement classElement = getASyncStarController(); |
| 1962 return classElement.lookupConstructor(""); | 1964 return classElement.lookupConstructor(""); |
| 1963 } | 1965 } |
| 1964 | 1966 |
| 1965 Element getStreamIteratorConstructor() { | 1967 Element getStreamIteratorConstructor() { |
| 1966 ClassElement classElement = find(compiler.asyncLibrary, "StreamIterator"); | 1968 ClassElement classElement = find(compiler.asyncLibrary, "StreamIterator"); |
| 1967 classElement.ensureResolved(compiler); | 1969 classElement.ensureResolved(resolution); |
| 1968 return classElement.lookupConstructor(""); | 1970 return classElement.lookupConstructor(""); |
| 1969 } | 1971 } |
| 1970 | 1972 |
| 1971 bool isNullImplementation(ClassElement cls) { | 1973 bool isNullImplementation(ClassElement cls) { |
| 1972 return cls == jsNullClass; | 1974 return cls == jsNullClass; |
| 1973 } | 1975 } |
| 1974 | 1976 |
| 1975 ClassElement get intImplementation => jsIntClass; | 1977 ClassElement get intImplementation => jsIntClass; |
| 1976 ClassElement get uint32Implementation => jsUInt32Class; | 1978 ClassElement get uint32Implementation => jsUInt32Class; |
| 1977 ClassElement get uint31Implementation => jsUInt31Class; | 1979 ClassElement get uint31Implementation => jsUInt31Class; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2045 bool shouldRetainName(String name) { | 2047 bool shouldRetainName(String name) { |
| 2046 if (hasInsufficientMirrorsUsed) return mustPreserveNames; | 2048 if (hasInsufficientMirrorsUsed) return mustPreserveNames; |
| 2047 if (name == '') return false; | 2049 if (name == '') return false; |
| 2048 return symbolsUsed.contains(name); | 2050 return symbolsUsed.contains(name); |
| 2049 } | 2051 } |
| 2050 | 2052 |
| 2051 bool retainMetadataOf(Element element) { | 2053 bool retainMetadataOf(Element element) { |
| 2052 if (mustRetainMetadata) hasRetainedMetadata = true; | 2054 if (mustRetainMetadata) hasRetainedMetadata = true; |
| 2053 if (mustRetainMetadata && referencedFromMirrorSystem(element)) { | 2055 if (mustRetainMetadata && referencedFromMirrorSystem(element)) { |
| 2054 for (MetadataAnnotation metadata in element.metadata) { | 2056 for (MetadataAnnotation metadata in element.metadata) { |
| 2055 metadata.ensureResolved(compiler); | 2057 metadata.ensureResolved(resolution); |
| 2056 ConstantValue constant = | 2058 ConstantValue constant = |
| 2057 constants.getConstantValueForMetadata(metadata); | 2059 constants.getConstantValueForMetadata(metadata); |
| 2058 constants.addCompileTimeConstantForEmission(constant); | 2060 constants.addCompileTimeConstantForEmission(constant); |
| 2059 } | 2061 } |
| 2060 return true; | 2062 return true; |
| 2061 } | 2063 } |
| 2062 return false; | 2064 return false; |
| 2063 } | 2065 } |
| 2064 | 2066 |
| 2065 void onLibraryCreated(LibraryElement library) { | 2067 void onLibraryCreated(LibraryElement library) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2192 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 2194 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
| 2193 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { | 2195 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { |
| 2194 return new Future.value(); | 2196 return new Future.value(); |
| 2195 } | 2197 } |
| 2196 | 2198 |
| 2197 assert(loadedLibraries.containsLibrary(Uris.dart_core)); | 2199 assert(loadedLibraries.containsLibrary(Uris.dart_core)); |
| 2198 assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS)); | 2200 assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS)); |
| 2199 assert(loadedLibraries.containsLibrary(DART_JS_HELPER)); | 2201 assert(loadedLibraries.containsLibrary(DART_JS_HELPER)); |
| 2200 | 2202 |
| 2201 if (jsInvocationMirrorClass != null) { | 2203 if (jsInvocationMirrorClass != null) { |
| 2202 jsInvocationMirrorClass.ensureResolved(compiler); | 2204 jsInvocationMirrorClass.ensureResolved(resolution); |
| 2203 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); | 2205 invokeOnMethod = jsInvocationMirrorClass.lookupLocalMember(INVOKE_ON); |
| 2204 } | 2206 } |
| 2205 | 2207 |
| 2206 // [LinkedHashMap] is reexported from dart:collection and can therefore not | 2208 // [LinkedHashMap] is reexported from dart:collection and can therefore not |
| 2207 // be loaded from dart:core in [onLibraryScanned]. | 2209 // be loaded from dart:core in [onLibraryScanned]. |
| 2208 mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); | 2210 mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); |
| 2209 assert(invariant(compiler.coreLibrary, mapLiteralClass != null, | 2211 assert(invariant(compiler.coreLibrary, mapLiteralClass != null, |
| 2210 message: "Element 'LinkedHashMap' not found in 'dart:core'.")); | 2212 message: "Element 'LinkedHashMap' not found in 'dart:core'.")); |
| 2211 | 2213 |
| 2212 implementationClasses = <ClassElement, ClassElement>{}; | 2214 implementationClasses = <ClassElement, ClassElement>{}; |
| 2213 implementationClasses[compiler.intClass] = jsIntClass; | 2215 implementationClasses[compiler.intClass] = jsIntClass; |
| 2214 implementationClasses[compiler.boolClass] = jsBoolClass; | 2216 implementationClasses[compiler.boolClass] = jsBoolClass; |
| 2215 implementationClasses[compiler.numClass] = jsNumberClass; | 2217 implementationClasses[compiler.numClass] = jsNumberClass; |
| 2216 implementationClasses[compiler.doubleClass] = jsDoubleClass; | 2218 implementationClasses[compiler.doubleClass] = jsDoubleClass; |
| 2217 implementationClasses[compiler.stringClass] = jsStringClass; | 2219 implementationClasses[compiler.stringClass] = jsStringClass; |
| 2218 implementationClasses[compiler.listClass] = jsArrayClass; | 2220 implementationClasses[compiler.listClass] = jsArrayClass; |
| 2219 implementationClasses[compiler.nullClass] = jsNullClass; | 2221 implementationClasses[compiler.nullClass] = jsNullClass; |
| 2220 | 2222 |
| 2221 // These methods are overwritten with generated versions. | 2223 // These methods are overwritten with generated versions. |
| 2222 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); | 2224 inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); |
| 2223 | 2225 |
| 2224 // TODO(kasperl): Some tests do not define the special JSArray | 2226 // TODO(kasperl): Some tests do not define the special JSArray |
| 2225 // subclasses, so we check to see if they are defined before | 2227 // subclasses, so we check to see if they are defined before |
| 2226 // trying to resolve them. | 2228 // trying to resolve them. |
| 2227 if (jsFixedArrayClass != null) { | 2229 if (jsFixedArrayClass != null) { |
| 2228 jsFixedArrayClass.ensureResolved(compiler); | 2230 jsFixedArrayClass.ensureResolved(resolution); |
| 2229 } | 2231 } |
| 2230 if (jsExtendableArrayClass != null) { | 2232 if (jsExtendableArrayClass != null) { |
| 2231 jsExtendableArrayClass.ensureResolved(compiler); | 2233 jsExtendableArrayClass.ensureResolved(resolution); |
| 2232 } | 2234 } |
| 2233 if (jsUnmodifiableArrayClass != null) { | 2235 if (jsUnmodifiableArrayClass != null) { |
| 2234 jsUnmodifiableArrayClass.ensureResolved(compiler); | 2236 jsUnmodifiableArrayClass.ensureResolved(resolution); |
| 2235 } | 2237 } |
| 2236 | 2238 |
| 2237 jsIndexableClass.ensureResolved(compiler); | 2239 jsIndexableClass.ensureResolved(resolution); |
| 2238 jsIndexableLength = compiler.lookupElementIn( | 2240 jsIndexableLength = compiler.lookupElementIn( |
| 2239 jsIndexableClass, 'length'); | 2241 jsIndexableClass, 'length'); |
| 2240 if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { | 2242 if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { |
| 2241 AbstractFieldElement element = jsIndexableLength; | 2243 AbstractFieldElement element = jsIndexableLength; |
| 2242 jsIndexableLength = element.getter; | 2244 jsIndexableLength = element.getter; |
| 2243 } | 2245 } |
| 2244 | 2246 |
| 2245 jsArrayClass.ensureResolved(compiler); | 2247 jsArrayClass.ensureResolved(resolution); |
| 2246 jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); | 2248 jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); |
| 2247 jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); | 2249 jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); |
| 2248 jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); | 2250 jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); |
| 2249 | 2251 |
| 2250 jsStringClass.ensureResolved(compiler); | 2252 jsStringClass.ensureResolved(resolution); |
| 2251 jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split'); | 2253 jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split'); |
| 2252 jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); | 2254 jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); |
| 2253 jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); | 2255 jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); |
| 2254 | 2256 |
| 2255 objectEquals = compiler.lookupElementIn(compiler.objectClass, '=='); | 2257 objectEquals = compiler.lookupElementIn(compiler.objectClass, '=='); |
| 2256 | 2258 |
| 2257 specialOperatorEqClasses | 2259 specialOperatorEqClasses |
| 2258 ..add(compiler.objectClass) | 2260 ..add(compiler.objectClass) |
| 2259 ..add(jsInterceptorClass) | 2261 ..add(jsInterceptorClass) |
| 2260 ..add(jsNullClass); | 2262 ..add(jsNullClass); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2334 /** | 2336 /** |
| 2335 * Returns `true` if the element is needed because it has an annotation | 2337 * Returns `true` if the element is needed because it has an annotation |
| 2336 * of a type that is used as a meta target for reflection. | 2338 * of a type that is used as a meta target for reflection. |
| 2337 */ | 2339 */ |
| 2338 bool matchesMirrorsMetaTarget(Element element) { | 2340 bool matchesMirrorsMetaTarget(Element element) { |
| 2339 if (metaTargetsUsed.isEmpty) return false; | 2341 if (metaTargetsUsed.isEmpty) return false; |
| 2340 for (MetadataAnnotation metadata in element.metadata) { | 2342 for (MetadataAnnotation metadata in element.metadata) { |
| 2341 // TODO(kasperl): It would be nice if we didn't have to resolve | 2343 // TODO(kasperl): It would be nice if we didn't have to resolve |
| 2342 // all metadata but only stuff that potentially would match one | 2344 // all metadata but only stuff that potentially would match one |
| 2343 // of the used meta targets. | 2345 // of the used meta targets. |
| 2344 metadata.ensureResolved(compiler); | 2346 metadata.ensureResolved(resolution); |
| 2345 ConstantValue value = | 2347 ConstantValue value = |
| 2346 compiler.constants.getConstantValue(metadata.constant); | 2348 compiler.constants.getConstantValue(metadata.constant); |
| 2347 if (value == null) continue; | 2349 if (value == null) continue; |
| 2348 DartType type = value.getType(compiler.coreTypes); | 2350 DartType type = value.getType(compiler.coreTypes); |
| 2349 if (metaTargetsUsed.contains(type.element)) return true; | 2351 if (metaTargetsUsed.contains(type.element)) return true; |
| 2350 } | 2352 } |
| 2351 return false; | 2353 return false; |
| 2352 } | 2354 } |
| 2353 | 2355 |
| 2354 /** | 2356 /** |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2642 inlineCache.markAsNonInlinable(element); | 2644 inlineCache.markAsNonInlinable(element); |
| 2643 } | 2645 } |
| 2644 | 2646 |
| 2645 LibraryElement library = element.library; | 2647 LibraryElement library = element.library; |
| 2646 if (!library.isPlatformLibrary && !library.canUseNative) return; | 2648 if (!library.isPlatformLibrary && !library.canUseNative) return; |
| 2647 bool hasNoInline = false; | 2649 bool hasNoInline = false; |
| 2648 bool hasForceInline = false; | 2650 bool hasForceInline = false; |
| 2649 bool hasNoThrows = false; | 2651 bool hasNoThrows = false; |
| 2650 bool hasNoSideEffects = false; | 2652 bool hasNoSideEffects = false; |
| 2651 for (MetadataAnnotation metadata in element.implementation.metadata) { | 2653 for (MetadataAnnotation metadata in element.implementation.metadata) { |
| 2652 metadata.ensureResolved(compiler); | 2654 metadata.ensureResolved(resolution); |
| 2653 ConstantValue constantValue = | 2655 ConstantValue constantValue = |
| 2654 compiler.constants.getConstantValue(metadata.constant); | 2656 compiler.constants.getConstantValue(metadata.constant); |
| 2655 if (!constantValue.isConstructedObject) continue; | 2657 if (!constantValue.isConstructedObject) continue; |
| 2656 ObjectConstantValue value = constantValue; | 2658 ObjectConstantValue value = constantValue; |
| 2657 ClassElement cls = value.type.element; | 2659 ClassElement cls = value.type.element; |
| 2658 if (cls == forceInlineClass) { | 2660 if (cls == forceInlineClass) { |
| 2659 hasForceInline = true; | 2661 hasForceInline = true; |
| 2660 if (VERBOSE_OPTIMIZER_HINTS) { | 2662 if (VERBOSE_OPTIMIZER_HINTS) { |
| 2661 compiler.reportHintMessage( | 2663 compiler.reportHintMessage( |
| 2662 element, | 2664 element, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2760 void registerAsyncMarker(FunctionElement element, | 2762 void registerAsyncMarker(FunctionElement element, |
| 2761 Enqueuer enqueuer, | 2763 Enqueuer enqueuer, |
| 2762 Registry registry) { | 2764 Registry registry) { |
| 2763 if (element.asyncMarker == AsyncMarker.ASYNC) { | 2765 if (element.asyncMarker == AsyncMarker.ASYNC) { |
| 2764 enqueue(enqueuer, getAsyncHelper(), registry); | 2766 enqueue(enqueuer, getAsyncHelper(), registry); |
| 2765 enqueue(enqueuer, getSyncCompleterConstructor(), registry); | 2767 enqueue(enqueuer, getSyncCompleterConstructor(), registry); |
| 2766 enqueue(enqueuer, getStreamIteratorConstructor(), registry); | 2768 enqueue(enqueuer, getStreamIteratorConstructor(), registry); |
| 2767 enqueue(enqueuer, getWrapBody(), registry); | 2769 enqueue(enqueuer, getWrapBody(), registry); |
| 2768 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) { | 2770 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) { |
| 2769 ClassElement clsSyncStarIterable = getSyncStarIterable(); | 2771 ClassElement clsSyncStarIterable = getSyncStarIterable(); |
| 2770 clsSyncStarIterable.ensureResolved(compiler); | 2772 clsSyncStarIterable.ensureResolved(resolution); |
| 2771 registerInstantiatedType(clsSyncStarIterable.rawType, enqueuer, registry); | 2773 registerInstantiatedType(clsSyncStarIterable.rawType, enqueuer, registry); |
| 2772 enqueue(enqueuer, getSyncStarIterableConstructor(), registry); | 2774 enqueue(enqueuer, getSyncStarIterableConstructor(), registry); |
| 2773 enqueue(enqueuer, getEndOfIteration(), registry); | 2775 enqueue(enqueuer, getEndOfIteration(), registry); |
| 2774 enqueue(enqueuer, getYieldStar(), registry); | 2776 enqueue(enqueuer, getYieldStar(), registry); |
| 2775 enqueue(enqueuer, getSyncStarUncaughtError(), registry); | 2777 enqueue(enqueuer, getSyncStarUncaughtError(), registry); |
| 2776 } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) { | 2778 } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) { |
| 2777 ClassElement clsASyncStarController = getASyncStarController(); | 2779 ClassElement clsASyncStarController = getASyncStarController(); |
| 2778 clsASyncStarController.ensureResolved(compiler); | 2780 clsASyncStarController.ensureResolved(resolution); |
| 2779 registerInstantiatedType( | 2781 registerInstantiatedType( |
| 2780 clsASyncStarController.rawType, enqueuer, registry); | 2782 clsASyncStarController.rawType, enqueuer, registry); |
| 2781 enqueue(enqueuer, getAsyncStarHelper(), registry); | 2783 enqueue(enqueuer, getAsyncStarHelper(), registry); |
| 2782 enqueue(enqueuer, getStreamOfController(), registry); | 2784 enqueue(enqueuer, getStreamOfController(), registry); |
| 2783 enqueue(enqueuer, getYieldSingle(), registry); | 2785 enqueue(enqueuer, getYieldSingle(), registry); |
| 2784 enqueue(enqueuer, getYieldStar(), registry); | 2786 enqueue(enqueuer, getYieldStar(), registry); |
| 2785 enqueue(enqueuer, getASyncStarControllerConstructor(), registry); | 2787 enqueue(enqueuer, getASyncStarControllerConstructor(), registry); |
| 2786 enqueue(enqueuer, getStreamIteratorConstructor(), registry); | 2788 enqueue(enqueuer, getStreamIteratorConstructor(), registry); |
| 2787 enqueue(enqueuer, getWrapBody(), registry); | 2789 enqueue(enqueuer, getWrapBody(), registry); |
| 2788 } | 2790 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2943 final JavaScriptBackend backend; | 2945 final JavaScriptBackend backend; |
| 2944 | 2946 |
| 2945 JavaScriptResolutionCallbacks(this.backend); | 2947 JavaScriptResolutionCallbacks(this.backend); |
| 2946 | 2948 |
| 2947 void registerBackendStaticInvocation(Element element, Registry registry) { | 2949 void registerBackendStaticInvocation(Element element, Registry registry) { |
| 2948 registry.registerStaticInvocation(backend.registerBackendUse(element)); | 2950 registry.registerStaticInvocation(backend.registerBackendUse(element)); |
| 2949 } | 2951 } |
| 2950 | 2952 |
| 2951 void registerBackendInstantiation(ClassElement element, Registry registry) { | 2953 void registerBackendInstantiation(ClassElement element, Registry registry) { |
| 2952 backend.registerBackendUse(element); | 2954 backend.registerBackendUse(element); |
| 2953 element.ensureResolved(backend.compiler); | 2955 element.ensureResolved(backend.resolution); |
| 2954 registry.registerInstantiation(element.rawType); | 2956 registry.registerInstantiation(element.rawType); |
| 2955 } | 2957 } |
| 2956 | 2958 |
| 2957 void onAssert(bool hasMessage, Registry registry) { | 2959 void onAssert(bool hasMessage, Registry registry) { |
| 2958 if (hasMessage) { | 2960 if (hasMessage) { |
| 2959 registerBackendStaticInvocation(backend.assertTestMethod, registry); | 2961 registerBackendStaticInvocation(backend.assertTestMethod, registry); |
| 2960 registerBackendStaticInvocation(backend.assertThrowMethod, registry); | 2962 registerBackendStaticInvocation(backend.assertThrowMethod, registry); |
| 2961 } else { | 2963 } else { |
| 2962 registerBackendStaticInvocation(backend.assertHelperMethod, registry); | 2964 registerBackendStaticInvocation(backend.assertHelperMethod, registry); |
| 2963 } | 2965 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3034 registerBackendStaticInvocation(backend.getRuntimeTypeToString(), registry); | 3036 registerBackendStaticInvocation(backend.getRuntimeTypeToString(), registry); |
| 3035 registerBackendStaticInvocation(backend.getCreateRuntimeType(), registry); | 3037 registerBackendStaticInvocation(backend.getCreateRuntimeType(), registry); |
| 3036 needsInt(registry, 'Needed for accessing a type variable literal on this.'); | 3038 needsInt(registry, 'Needed for accessing a type variable literal on this.'); |
| 3037 ClassElement cls = variable.enclosingClass; | 3039 ClassElement cls = variable.enclosingClass; |
| 3038 backend.rti.classesUsingTypeVariableExpression.add(cls); | 3040 backend.rti.classesUsingTypeVariableExpression.add(cls); |
| 3039 } | 3041 } |
| 3040 | 3042 |
| 3041 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. | 3043 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. |
| 3042 void onIsCheck(DartType type, Registry registry) { | 3044 void onIsCheck(DartType type, Registry registry) { |
| 3043 assert(registry.isForResolution); | 3045 assert(registry.isForResolution); |
| 3044 type = type.unalias(backend.compiler); | 3046 type = type.unalias(backend.resolution); |
| 3045 registerBackendInstantiation(backend.compiler.boolClass, registry); | 3047 registerBackendInstantiation(backend.compiler.boolClass, registry); |
| 3046 bool inCheckedMode = backend.compiler.enableTypeAssertions; | 3048 bool inCheckedMode = backend.compiler.enableTypeAssertions; |
| 3047 if (inCheckedMode) { | 3049 if (inCheckedMode) { |
| 3048 registerBackendStaticInvocation(backend.getThrowRuntimeError(), registry); | 3050 registerBackendStaticInvocation(backend.getThrowRuntimeError(), registry); |
| 3049 } | 3051 } |
| 3050 if (type.isMalformed) { | 3052 if (type.isMalformed) { |
| 3051 registerBackendStaticInvocation(backend.getThrowTypeError(), registry); | 3053 registerBackendStaticInvocation(backend.getThrowTypeError(), registry); |
| 3052 } | 3054 } |
| 3053 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { | 3055 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { |
| 3054 // TODO(johnniwinther): Investigate why this is needed. | 3056 // TODO(johnniwinther): Investigate why this is needed. |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3201 } | 3203 } |
| 3202 } | 3204 } |
| 3203 | 3205 |
| 3204 /// Records that [constant] is used by the element behind [registry]. | 3206 /// Records that [constant] is used by the element behind [registry]. |
| 3205 class Dependency { | 3207 class Dependency { |
| 3206 final ConstantValue constant; | 3208 final ConstantValue constant; |
| 3207 final Element annotatedElement; | 3209 final Element annotatedElement; |
| 3208 | 3210 |
| 3209 const Dependency(this.constant, this.annotatedElement); | 3211 const Dependency(this.constant, this.annotatedElement); |
| 3210 } | 3212 } |
| OLD | NEW |