Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
index d599057ff83e0311cf392c7acd52140a44301d74..ad2dfea84dc918125b62b93259fd1aa7af0928fb 100644 |
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
@@ -53,6 +53,11 @@ class FunctionInlineCache { |
} |
class JavaScriptBackend extends Backend { |
+ static final Uri DART_JS_MIRRORS = |
+ new Uri(scheme: 'dart', path: '_js_mirrors'); |
+ static final Uri DART_JS_NAMES = |
+ new Uri(scheme: 'dart', path: '_js_names'); |
+ |
SsaBuilderTask builder; |
SsaOptimizerTask optimizer; |
SsaCodeGeneratorTask generator; |
@@ -469,113 +474,6 @@ class JavaScriptBackend extends Backend { |
operatorEqfunction.enclosingClass); |
} |
- void initializeHelperClasses() { |
- getInterceptorMethod = compiler.findInterceptor('getInterceptor'); |
- interceptedNames = compiler.findInterceptor('interceptedNames'); |
- mapTypeToInterceptor = compiler.findInterceptor('mapTypeToInterceptor'); |
- getNativeInterceptorMethod = |
- compiler.findInterceptor('getNativeInterceptor'); |
- |
- // These methods are overwritten with generated versions. |
- inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); |
- |
- List<ClassElement> classes = [ |
- jsInterceptorClass = |
- compiler.findInterceptor('Interceptor'), |
- jsStringClass = compiler.findInterceptor('JSString'), |
- jsArrayClass = compiler.findInterceptor('JSArray'), |
- // The int class must be before the double class, because the |
- // emitter relies on this list for the order of type checks. |
- jsIntClass = compiler.findInterceptor('JSInt'), |
- jsPositiveIntClass = compiler.findInterceptor('JSPositiveInt'), |
- jsUInt32Class = compiler.findInterceptor('JSUInt32'), |
- jsUInt31Class = compiler.findInterceptor('JSUInt31'), |
- jsDoubleClass = compiler.findInterceptor('JSDouble'), |
- jsNumberClass = compiler.findInterceptor('JSNumber'), |
- jsNullClass = compiler.findInterceptor('JSNull'), |
- jsBoolClass = compiler.findInterceptor('JSBool'), |
- jsMutableArrayClass = compiler.findInterceptor('JSMutableArray'), |
- jsFixedArrayClass = compiler.findInterceptor('JSFixedArray'), |
- jsExtendableArrayClass = compiler.findInterceptor('JSExtendableArray'), |
- jsPlainJavaScriptObjectClass = |
- compiler.findInterceptor('PlainJavaScriptObject'), |
- jsUnknownJavaScriptObjectClass = |
- compiler.findInterceptor('UnknownJavaScriptObject'), |
- ]; |
- |
- implementationClasses = <ClassElement, ClassElement>{}; |
- implementationClasses[compiler.intClass] = jsIntClass; |
- implementationClasses[compiler.boolClass] = jsBoolClass; |
- implementationClasses[compiler.numClass] = jsNumberClass; |
- implementationClasses[compiler.doubleClass] = jsDoubleClass; |
- implementationClasses[compiler.stringClass] = jsStringClass; |
- implementationClasses[compiler.listClass] = jsArrayClass; |
- implementationClasses[compiler.nullClass] = jsNullClass; |
- |
- jsIndexableClass = compiler.findInterceptor('JSIndexable'); |
- jsMutableIndexableClass = compiler.findInterceptor('JSMutableIndexable'); |
- |
- // TODO(kasperl): Some tests do not define the special JSArray |
- // subclasses, so we check to see if they are defined before |
- // trying to resolve them. |
- if (jsFixedArrayClass != null) { |
- jsFixedArrayClass.ensureResolved(compiler); |
- } |
- if (jsExtendableArrayClass != null) { |
- jsExtendableArrayClass.ensureResolved(compiler); |
- } |
- |
- jsIndexableClass.ensureResolved(compiler); |
- jsIndexableLength = compiler.lookupElementIn( |
- jsIndexableClass, 'length'); |
- if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { |
- AbstractFieldElement element = jsIndexableLength; |
- jsIndexableLength = element.getter; |
- } |
- |
- jsArrayClass.ensureResolved(compiler); |
- jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); |
- jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); |
- jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); |
- |
- jsStringClass.ensureResolved(compiler); |
- jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split'); |
- jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); |
- jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); |
- |
- typeLiteralClass = compiler.findHelper('TypeImpl'); |
- mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); |
- constMapLiteralClass = compiler.findHelper('ConstantMap'); |
- |
- objectEquals = compiler.lookupElementIn(compiler.objectClass, '=='); |
- |
- jsIndexingBehaviorInterface = |
- compiler.findHelper('JavaScriptIndexingBehavior'); |
- |
- specialOperatorEqClasses |
- ..add(compiler.objectClass) |
- ..add(jsInterceptorClass) |
- ..add(jsNullClass); |
- |
- validateInterceptorImplementsAllObjectMethods(jsInterceptorClass); |
- // The null-interceptor must also implement *all* methods. |
- validateInterceptorImplementsAllObjectMethods(jsNullClass); |
- |
- typeVariableClass = compiler.findHelper('TypeVariable'); |
- |
- indexablePrimitiveType = new TypeMask.nonNullSubtype(jsIndexableClass); |
- readableArrayType = new TypeMask.nonNullSubclass(jsArrayClass); |
- mutableArrayType = new TypeMask.nonNullSubclass(jsMutableArrayClass); |
- fixedArrayType = new TypeMask.nonNullExact(jsFixedArrayClass); |
- extendableArrayType = new TypeMask.nonNullExact(jsExtendableArrayClass); |
- nonNullType = compiler.typesTask.dynamicType.nonNullable(); |
- |
- noSideEffectsClass = compiler.findHelper('NoSideEffects'); |
- noThrowsClass = compiler.findHelper('NoThrows'); |
- noInlineClass = compiler.findHelper('NoInline'); |
- irRepresentationClass = compiler.findHelper('IrRepresentation'); |
- } |
- |
void validateInterceptorImplementsAllObjectMethods( |
ClassElement interceptorClass) { |
if (interceptorClass == null) return; |
@@ -848,6 +746,7 @@ class JavaScriptBackend extends Backend { |
} |
void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { |
+ assert(compiler.interceptorsLibrary != null); |
// TODO(ngeoffray): Not enqueuing those two classes currently make |
// the compiler potentially crash. However, any reasonable program |
// will instantiate those two classes. |
@@ -1691,19 +1590,141 @@ class JavaScriptBackend extends Backend { |
return false; |
} |
- Future onLibraryLoaded(LibraryElement library, Uri uri) { |
- if (uri == Uri.parse('dart:_js_mirrors')) { |
- disableTreeShakingMarker = |
- library.find('disableTreeShaking'); |
- preserveMetadataMarker = |
- library.find('preserveMetadata'); |
- } else if (uri == Uri.parse('dart:_js_names')) { |
- preserveNamesMarker = |
- library.find('preserveNames'); |
- } else if (uri == Uri.parse('dart:_js_helper')) { |
- getIsolateAffinityTagMarker = |
- library.find('getIsolateAffinityTag'); |
+ void onLibraryScanned(LibraryElement library) { |
+ Uri uri = library.canonicalUri; |
+ |
+ // TODO(johnniwinther): Assert that the elements are found. |
+ VariableElement findVariable(String name) { |
+ return library.find(name); |
+ } |
+ |
+ FunctionElement findMethod(String name) { |
+ return library.find(name); |
+ } |
+ |
+ ClassElement findClass(String name) { |
+ return library.find(name); |
+ } |
+ |
+ if (uri == Compiler.DART_INTERCEPTORS) { |
+ getInterceptorMethod = findMethod('getInterceptor'); |
+ interceptedNames = findVariable('interceptedNames'); |
+ mapTypeToInterceptor = findVariable('mapTypeToInterceptor'); |
+ getNativeInterceptorMethod = findMethod('getNativeInterceptor'); |
+ |
+ List<ClassElement> classes = [ |
+ jsInterceptorClass = findClass('Interceptor'), |
+ jsStringClass = findClass('JSString'), |
+ jsArrayClass = findClass('JSArray'), |
+ // The int class must be before the double class, because the |
+ // emitter relies on this list for the order of type checks. |
+ jsIntClass = findClass('JSInt'), |
+ jsPositiveIntClass = findClass('JSPositiveInt'), |
+ jsUInt32Class = findClass('JSUInt32'), |
+ jsUInt31Class = findClass('JSUInt31'), |
+ jsDoubleClass = findClass('JSDouble'), |
+ jsNumberClass = findClass('JSNumber'), |
+ jsNullClass = findClass('JSNull'), |
+ jsBoolClass = findClass('JSBool'), |
+ jsMutableArrayClass = findClass('JSMutableArray'), |
+ jsFixedArrayClass = findClass('JSFixedArray'), |
+ jsExtendableArrayClass = findClass('JSExtendableArray'), |
+ jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'), |
+ jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'), |
+ ]; |
+ |
+ jsIndexableClass = findClass('JSIndexable'); |
+ jsMutableIndexableClass = findClass('JSMutableIndexable'); |
+ } else if (uri == Compiler.DART_JS_HELPER) { |
+ typeLiteralClass = findClass('TypeImpl'); |
+ constMapLiteralClass = findClass('ConstantMap'); |
+ typeVariableClass = findClass('TypeVariable'); |
+ |
+ jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); |
+ |
+ noSideEffectsClass = findClass('NoSideEffects'); |
+ noThrowsClass = findClass('NoThrows'); |
+ noInlineClass = findClass('NoInline'); |
+ irRepresentationClass = findClass('IrRepresentation'); |
+ } else if (uri == DART_JS_MIRRORS) { |
+ disableTreeShakingMarker = library.find('disableTreeShaking'); |
+ preserveMetadataMarker = library.find('preserveMetadata'); |
+ } else if (uri == DART_JS_NAMES) { |
+ preserveNamesMarker = library.find('preserveNames'); |
+ } else if (uri == Compiler.DART_JS_HELPER) { |
+ getIsolateAffinityTagMarker = library.find('getIsolateAffinityTag'); |
+ } |
+ } |
+ |
+ Future onLibrariesLoaded(Map<Uri, LibraryElement> loadedLibraries) { |
+ if (!loadedLibraries.containsKey(Compiler.DART_CORE)) { |
+ return new Future.value(); |
+ } |
+ assert(loadedLibraries.containsKey(Compiler.DART_CORE)); |
+ assert(loadedLibraries.containsKey(Compiler.DART_INTERCEPTORS)); |
+ assert(loadedLibraries.containsKey(Compiler.DART_JS_HELPER)); |
+ |
+ // [LinkedHashMap] is reexported from dart:collection and can therefore not |
+ // be loaded from dart:core in [onLibraryScanned]. |
+ mapLiteralClass = compiler.coreLibrary.find('LinkedHashMap'); |
+ |
+ implementationClasses = <ClassElement, ClassElement>{}; |
+ implementationClasses[compiler.intClass] = jsIntClass; |
+ implementationClasses[compiler.boolClass] = jsBoolClass; |
+ implementationClasses[compiler.numClass] = jsNumberClass; |
+ implementationClasses[compiler.doubleClass] = jsDoubleClass; |
+ implementationClasses[compiler.stringClass] = jsStringClass; |
+ implementationClasses[compiler.listClass] = jsArrayClass; |
+ implementationClasses[compiler.nullClass] = jsNullClass; |
+ |
+ // These methods are overwritten with generated versions. |
+ inlineCache.markAsNonInlinable(getInterceptorMethod, insideLoop: true); |
+ |
+ // TODO(kasperl): Some tests do not define the special JSArray |
+ // subclasses, so we check to see if they are defined before |
+ // trying to resolve them. |
+ if (jsFixedArrayClass != null) { |
+ jsFixedArrayClass.ensureResolved(compiler); |
} |
+ if (jsExtendableArrayClass != null) { |
+ jsExtendableArrayClass.ensureResolved(compiler); |
+ } |
+ |
+ jsIndexableClass.ensureResolved(compiler); |
+ jsIndexableLength = compiler.lookupElementIn( |
+ jsIndexableClass, 'length'); |
+ if (jsIndexableLength != null && jsIndexableLength.isAbstractField) { |
+ AbstractFieldElement element = jsIndexableLength; |
+ jsIndexableLength = element.getter; |
+ } |
+ |
+ jsArrayClass.ensureResolved(compiler); |
+ jsArrayTypedConstructor = compiler.lookupElementIn(jsArrayClass, 'typed'); |
+ jsArrayRemoveLast = compiler.lookupElementIn(jsArrayClass, 'removeLast'); |
+ jsArrayAdd = compiler.lookupElementIn(jsArrayClass, 'add'); |
+ |
+ jsStringClass.ensureResolved(compiler); |
+ jsStringSplit = compiler.lookupElementIn(jsStringClass, 'split'); |
+ jsStringOperatorAdd = compiler.lookupElementIn(jsStringClass, '+'); |
+ jsStringToString = compiler.lookupElementIn(jsStringClass, 'toString'); |
+ |
+ objectEquals = compiler.lookupElementIn(compiler.objectClass, '=='); |
+ |
+ specialOperatorEqClasses |
+ ..add(compiler.objectClass) |
+ ..add(jsInterceptorClass) |
+ ..add(jsNullClass); |
+ |
+ indexablePrimitiveType = new TypeMask.nonNullSubtype(jsIndexableClass); |
+ readableArrayType = new TypeMask.nonNullSubclass(jsArrayClass); |
+ mutableArrayType = new TypeMask.nonNullSubclass(jsMutableArrayClass); |
+ fixedArrayType = new TypeMask.nonNullExact(jsFixedArrayClass); |
+ extendableArrayType = new TypeMask.nonNullExact(jsExtendableArrayClass); |
+ nonNullType = compiler.typesTask.dynamicType.nonNullable(); |
+ |
+ validateInterceptorImplementsAllObjectMethods(jsInterceptorClass); |
+ // The null-interceptor must also implement *all* methods. |
+ validateInterceptorImplementsAllObjectMethods(jsNullClass); |
return new Future.value(); |
} |