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 b70c32c2aaa78bac336c88971e1f1c5153986a08..2afab9f8b7cda1506160a0a3717e027f782800f3 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; |
| String get _ => compiler.enableMinification ? "" : " "; |
| String get n => compiler.enableMinification ? "" : "\n"; |
| @@ -757,6 +759,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'"); |
|
ngeoffray
2012/12/13 13:34:58
I think you can share the following code with the
karlklose
2012/12/13 14:37:34
I want to generate the checks for the synthetic ho
|
| + for (ClassElement check in typeChecks[cls]) { |
| + buffer.add(',${_}is\$${namer.getName(check)}:${_}true'); |
|
ngeoffray
2012/12/13 13:34:58
Please use namer.operatorIs.
karlklose
2012/12/13 14:37:34
Done.
|
| + }; |
| + buffer.add('}$N'); |
| + } |
| + |
| + // Create representation objects for classes that we do not need a class |
|
ngeoffray
2012/12/13 13:34:58
do not need -> do not have
karlklose
2012/12/13 14:37:34
Done.
|
| + // 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'); |
|
ngeoffray
2012/12/13 13:34:58
namer.operatorIs.
karlklose
2012/12/13 14:37:34
Done.
|
| + }; |
| + } |
| + } |
| + |
| /** |
| * Documentation wanted -- johnniwinther |
| * |
| @@ -1177,16 +1222,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 { |
|
ngeoffray
2012/12/13 13:34:58
Do you need this? If it's only used by the neededC
karlklose
2012/12/13 14:37:34
It is also needed in emitClasses.
|
| + if (cachedInstantiatedClasses != null) return cachedInstantiatedClasses; |
| + cachedInstantiatedClasses = |
| compiler.codegenWorld.instantiatedClasses.filter(computeClassFilter()); |
| + return cachedInstantiatedClasses; |
| + } |
| + |
| + /// Get or compute the classes that we need to emit. |
| + Set<ClassElement> get neededClasses { |
|
ngeoffray
2012/12/13 13:34:58
Instead of doing this lazily I would definitely pr
karlklose
2012/12/13 14:37:34
Done.
|
| + 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; |
| @@ -1196,6 +1243,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) { |
| @@ -1961,6 +2016,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. |