| 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 f805355f634bccc366b0574aedde8def7f8eedd6..e8750f8c28f6b169734df7e97e75b5a283d1e143 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
|
| @@ -107,6 +107,18 @@ class CodeEmitterTask extends CompilerTask {
|
|
|
| final bool generateSourceMap;
|
|
|
| + Iterable<ClassElement> cachedClassesUsingTypeVariableTests;
|
| +
|
| + Iterable<ClassElement> get classesUsingTypeVariableTests {
|
| + if (cachedClassesUsingTypeVariableTests == null) {
|
| + cachedClassesUsingTypeVariableTests = compiler.codegenWorld.isChecks
|
| + .where((DartType t) => t is TypeVariableType)
|
| + .map((TypeVariableType v) => v.element.getEnclosingClass())
|
| + .toList();
|
| + }
|
| + return cachedClassesUsingTypeVariableTests;
|
| + }
|
| +
|
| CodeEmitterTask(Compiler compiler, Namer namer, this.generateSourceMap)
|
| : boundClosureBuffer = new CodeBuffer(),
|
| mainBuffer = new CodeBuffer(),
|
| @@ -119,7 +131,10 @@ class CodeEmitterTask extends CompilerTask {
|
| }
|
|
|
| void computeRequiredTypeChecks() {
|
| - assert(checkedClasses == null);
|
| + assert(checkedClasses == null && checkedTypedefs == null);
|
| +
|
| + compiler.codegenWorld.addImplicitChecks(classesUsingTypeVariableTests);
|
| +
|
| checkedClasses = new Set<ClassElement>();
|
| checkedTypedefs = new Set<TypedefElement>();
|
| compiler.codegenWorld.isChecks.forEach((DartType t) {
|
| @@ -1075,7 +1090,10 @@ class CodeEmitterTask extends CompilerTask {
|
|
|
| void generateIsTest(Element other) {
|
| jsAst.Expression code;
|
| - if (compiler.objectClass == other) return;
|
| + if (other == compiler.objectClass && other != classElement) {
|
| + // Avoid emitting [:$isObject:] on all classes but [Object].
|
| + return;
|
| + }
|
| if (nativeEmitter.requiresNativeIsCheck(other)) {
|
| code = js.fun([], [js.return_(true)]);
|
| } else {
|
| @@ -1136,13 +1154,15 @@ class CodeEmitterTask extends CompilerTask {
|
| }
|
| }
|
|
|
| - void emitRuntimeClassesAndTests(CodeBuffer buffer) {
|
| + void emitRuntimeTypeSupport(CodeBuffer buffer) {
|
| RuntimeTypeInformation rti = backend.rti;
|
| TypeChecks typeChecks = rti.getRequiredChecks();
|
|
|
| + /// Classes that are not instantiated and native classes need a holder
|
| + /// object for their checks, because there will be no class defined for
|
| + /// them.
|
| bool needsHolder(ClassElement cls) {
|
| - return !neededClasses.contains(cls) || cls.isNative() ||
|
| - rti.isJsNative(cls);
|
| + return !neededClasses.contains(cls) || cls.isNative();
|
| }
|
|
|
| /**
|
| @@ -1565,6 +1585,11 @@ class CodeEmitterTask extends CompilerTask {
|
| emitted.add(superclass);
|
| }
|
| for (DartType supertype in cls.allSupertypes) {
|
| + ClassElement superclass = supertype.element;
|
| + if (classesUsingTypeVariableTests.contains(superclass)) {
|
| + emitSubstitution(superclass, emitNull: true);
|
| + emitted.add(superclass);
|
| + }
|
| for (ClassElement check in checkedClasses) {
|
| if (supertype.element == check && !emitted.contains(check)) {
|
| // Generate substitution. If no substitution is necessary, emit
|
| @@ -2582,7 +2607,6 @@ if (typeof document !== 'undefined' && document.readyState !== 'complete') {
|
| String assembleProgram() {
|
| measure(() {
|
| computeNeededClasses();
|
| -
|
| mainBuffer.add(GENERATED_BY);
|
| if (!compiler.enableMinification) mainBuffer.add(HOOKS_API_USAGE);
|
| mainBuffer.add('function ${namer.isolateName}()$_{}\n');
|
| @@ -2603,7 +2627,7 @@ if (typeof document !== 'undefined' && document.readyState !== 'complete') {
|
| // We need to finish the classes before we construct compile time
|
| // constants.
|
| emitFinishClassesInvocationIfNecessary(mainBuffer);
|
| - emitRuntimeClassesAndTests(mainBuffer);
|
| + emitRuntimeTypeSupport(mainBuffer);
|
| emitCompileTimeConstants(mainBuffer);
|
| // Static field initializations require the classes and compile-time
|
| // constants to be set up.
|
|
|