Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| index 95ac063aa841d0ebc52b1b863e4475e12726c22d..f9d53d363727ede758ca2af63835bad9440a0c09 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart |
| @@ -44,6 +44,8 @@ class CodeEmitterTask extends CompilerTask { |
| well as in the generated code. */ |
| String isolateProperties; |
| String classesCollector; |
| + Set<ClassElement> cachedNeededClasses; |
| + Set<ClassElement> cachedInstantiatedClasses; |
| /** |
| * A cache of closures that are used to closurize instance methods. |
| @@ -753,6 +755,49 @@ $lazyInitializerLogic |
| } |
| } |
| + void emitRuntimeClassesAndTests(CodeBuffer buffer) { |
| + JavaScriptBackend backend = compiler.backend; |
| + RuntimeTypeInformation rti = backend.rti; |
| + |
| + TypeChecks typeChecks = rti.computeRequiredChecks(); |
| + |
| + bool needsHolder(ClassElement cls) { |
| + return !neededClasses.contains(cls) || cls.isNative() || |
| + rti.isJsNative(cls); |
| + } |
| + |
| + void maybeGenerateHolder(ClassElement cls) { |
| + if (!needsHolder(cls)) return; |
| + |
| + String holder = namer.isolateAccess(cls); |
| + String name = namer.getName(cls); |
| + buffer.add("$holder = {builtin\$cls: '$name'"); |
|
kasperl
2012/12/13 09:48:55
You should be able to use Erik's new whitespace sa
karlklose
2012/12/13 12:55:46
Done.
|
| + for (ClassElement check in typeChecks[cls]) { |
| + buffer.add(', is\$${namer.getName(check)}: true'); |
| + }; |
| + buffer.add('};\n'); |
| + } |
| + |
| + // Create representation objects for classes that we do not need a class |
| + // definition for (because they are uninstantiated or native). |
| + for (ClassElement cls in rti.allArguments) { |
| + maybeGenerateHolder(cls); |
| + } |
| + |
| + // Add checks to the constructors of instantiated classes. |
| + for (ClassElement cls in typeChecks) { |
| + if (needsHolder(cls)) { |
| + // We already emitted the is-checks in the object definition for this |
| + // class. |
| + continue; |
| + } |
| + String holder = namer.isolateAccess(cls); |
| + for (ClassElement check in typeChecks[cls]) { |
| + buffer.add('$holder.is\$${namer.getName(check)} = true;\n'); |
| + }; |
| + } |
| + } |
| + |
| /** |
| * Documentation wanted -- johnniwinther |
| * |
| @@ -1146,16 +1191,18 @@ $lazyInitializerLogic |
| return (ClassElement cls) => !unneededClasses.contains(cls); |
| } |
| - void emitClasses(CodeBuffer buffer) { |
| - // Compute the required type checks to know which classes need a |
| - // 'is$' method. |
| - computeRequiredTypeChecks(); |
| - |
| - Set<ClassElement> instantiatedClasses = |
| + Set<ClassElement> get instantiatedClasses { |
| + if (cachedInstantiatedClasses != null) return cachedInstantiatedClasses; |
| + cachedInstantiatedClasses = |
| compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter()); |
| + return cachedInstantiatedClasses; |
| + } |
| + |
| + /// Get or Compute the classes that we need to emit. |
|
kasperl
2012/12/13 09:48:55
Compute -> compute
karlklose
2012/12/13 12:55:46
Done.
|
| + Set<ClassElement> get neededClasses { |
| + if (cachedNeededClasses != null) return cachedNeededClasses; |
| - Set<ClassElement> neededClasses = |
| - new Set<ClassElement>.from(instantiatedClasses); |
| + cachedNeededClasses = new Set<ClassElement>.from(instantiatedClasses); |
| for (ClassElement element in instantiatedClasses) { |
| for (ClassElement superclass = element.superclass; |
| @@ -1165,6 +1212,14 @@ $lazyInitializerLogic |
| neededClasses.add(superclass); |
| } |
| } |
| + |
| + return cachedNeededClasses; |
| + } |
| + |
| + void emitClasses(CodeBuffer buffer) { |
| + // Compute the required type checks to know which classes need a |
| + // 'is$' method. |
| + computeRequiredTypeChecks(); |
| List<ClassElement> sortedClasses = |
| new List<ClassElement>.from(neededClasses); |
| sortedClasses.sort((ClassElement class1, ClassElement class2) { |
| @@ -1918,6 +1973,7 @@ if (typeof document !== 'undefined' && document.readyState !== 'complete') { |
| // We need to finish the classes before we construct compile time |
| // constants. |
| emitFinishClassesInvocationIfNecessary(mainBuffer); |
| + emitRuntimeClassesAndTests(mainBuffer); |
| emitCompileTimeConstants(mainBuffer); |
| // Static field initializations require the classes and compile-time |
| // constants to be set up. |