| 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 7c09021b4636681a39c466c9ffa19bc5a277519a..c25a335ce8c54ed34d04910912117b1dc10d6ff3 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
|
| @@ -775,7 +775,7 @@ $lazyInitializerLogic
|
| includeBackendMembers: true,
|
| includeSuperMembers: false);
|
|
|
| - void generateIsTest(Element other) {
|
| + generateIsTestsOn(classElement, (Element other) {
|
| js.Expression code;
|
| if (compiler.objectClass == other) return;
|
| if (nativeEmitter.requiresNativeIsCheck(other)) {
|
| @@ -784,25 +784,7 @@ $lazyInitializerLogic
|
| code = new js.LiteralBool(true);
|
| }
|
| builder.addProperty(namer.operatorIs(other), code);
|
| - }
|
| -
|
| - void generateSubstitution(Element other, {bool emitNull: false}) {
|
| - RuntimeTypeInformation rti = backend.rti;
|
| - // TODO(karlklose): support typedefs with variables.
|
| - if (other.kind == ElementKind.CLASS) {
|
| - String substitution = rti.getSupertypeSubstitution(classElement, other,
|
| - alwaysGenerateFunction: true);
|
| - if (substitution != null) {
|
| - builder.addProperty(namer.substitutionName(other),
|
| - new js.LiteralExpression(substitution));
|
| - } else if (emitNull) {
|
| - builder.addProperty(namer.substitutionName(other),
|
| - new js.LiteralNull());
|
| - }
|
| - }
|
| - }
|
| -
|
| - generateIsTestsOn(classElement, generateIsTest, generateSubstitution);
|
| + });
|
|
|
| if (identical(classElement, compiler.objectClass)
|
| && compiler.enabledNoSuchMethod) {
|
| @@ -835,24 +817,23 @@ $lazyInitializerLogic
|
| void emitRuntimeClassesAndTests(CodeBuffer buffer) {
|
| JavaScriptBackend backend = compiler.backend;
|
| RuntimeTypeInformation rti = backend.rti;
|
| - TypeChecks typeChecks = rti.getRequiredChecks();
|
| +
|
| + TypeChecks typeChecks = rti.computeRequiredChecks();
|
|
|
| bool needsHolder(ClassElement cls) {
|
| return !neededClasses.contains(cls) || cls.isNative() ||
|
| rti.isJsNative(cls);
|
| }
|
|
|
| - /**
|
| - * Generates a holder object if it is needed. A holder is a JavaScript
|
| - * object literal with a field [builtin$cls] that contains the name of the
|
| - * class as a string (just like object constructors do). The is-checks for
|
| - * the class are are added to the holder object later.
|
| - */
|
| void maybeGenerateHolder(ClassElement cls) {
|
| if (!needsHolder(cls)) return;
|
| +
|
| String holder = namer.isolateAccess(cls);
|
| String name = namer.getName(cls);
|
| buffer.add("$holder$_=$_{builtin\$cls:$_'$name'");
|
| + for (ClassElement check in typeChecks[cls]) {
|
| + buffer.add(',$_${namer.operatorIs(check)}:${_}true');
|
| + };
|
| buffer.add('}$N');
|
| }
|
|
|
| @@ -862,16 +843,16 @@ $lazyInitializerLogic
|
| maybeGenerateHolder(cls);
|
| }
|
|
|
| - // Add checks to the constructors of instantiated classes or to the created
|
| - // holder object.
|
| + // 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.${namer.operatorIs(check)}$_=${_}true$N');
|
| - String body = rti.getSupertypeSubstitution(cls, check);
|
| - if (body != null) {
|
| - buffer.add('$holder.${namer.substitutionName(check)}$_=${_}$body$N');
|
| - }
|
| };
|
| }
|
| }
|
| @@ -1243,46 +1224,13 @@ $lazyInitializerLogic
|
|
|
| /**
|
| * Generate "is tests" for [cls]: itself, and the "is tests" for the
|
| - * classes it implements and type argument substitution functions for these
|
| - * tests. We don't need to add the "is tests" of the super class because
|
| - * they will be inherited at runtime, but we may need to generate the
|
| - * substitutions, because they may have changed.
|
| + * classes it implements. We don't need to add the "is tests" of the
|
| + * super class because they will be inherited at runtime.
|
| */
|
| void generateIsTestsOn(ClassElement cls,
|
| - void emitIsTest(Element element),
|
| - void emitSubstitution(Element element, {emitNull})) {
|
| + void emitIsTest(Element element)) {
|
| if (checkedClasses.contains(cls)) {
|
| emitIsTest(cls);
|
| - emitSubstitution(cls);
|
| - }
|
| -
|
| - JavaScriptBackend jsBackend = compiler.backend;
|
| - RuntimeTypeInformation rti = jsBackend.rti;
|
| - ClassElement superclass = cls.superclass;
|
| -
|
| - bool haveSameTypeVariables(ClassElement a, ClassElement b) {
|
| - if (a.isClosure()) return true;
|
| - return a.typeVariables == b.typeVariables;
|
| - }
|
| -
|
| - if (superclass != null && superclass != compiler.objectClass &&
|
| - !haveSameTypeVariables(cls, superclass)) {
|
| - // We cannot inherit the generated substitutions, because the type
|
| - // variable layout for this class is different. Instead we generate
|
| - // substitutions for all checks and make emitSubstitution a NOP for the
|
| - // rest of this function.
|
| - for (ClassElement check in checkedClasses) {
|
| - for (DartType supertype in cls.allSupertypes) {
|
| - if (supertype.element == check) {
|
| - // Generate substitution. If no substitution is necessary, emit
|
| - // [:null:] to overwrite a (possibly) existing substitution from the
|
| - // super classes.
|
| - emitSubstitution(check, emitNull: true);
|
| - }
|
| - }
|
| - }
|
| - void emitNothing(_, {emitNull}) {};
|
| - emitSubstitution = emitNothing;
|
| }
|
|
|
| Set<Element> generated = new Set<Element>();
|
| @@ -1298,15 +1246,13 @@ $lazyInitializerLogic
|
| if (call != null) {
|
| generateInterfacesIsTests(compiler.functionClass,
|
| emitIsTest,
|
| - emitSubstitution,
|
| generated);
|
| getTypedefChecksOn(call.computeType(compiler)).forEach(emitIsTest);
|
| }
|
| }
|
|
|
| for (DartType interfaceType in cls.interfaces) {
|
| - generateInterfacesIsTests(interfaceType.element, emitIsTest,
|
| - emitSubstitution, generated);
|
| + generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
|
| }
|
|
|
| // For native classes, we also have to run through their mixin
|
| @@ -1315,8 +1261,7 @@ $lazyInitializerLogic
|
| visitNativeMixins(cls, (MixinApplicationElement mixin) {
|
| for (DartType interfaceType in mixin.interfaces) {
|
| ClassElement interfaceElement = interfaceType.element;
|
| - generateInterfacesIsTests(interfaceType.element, emitIsTest,
|
| - emitSubstitution, generated);
|
| + generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);
|
| }
|
| });
|
| }
|
| @@ -1326,13 +1271,11 @@ $lazyInitializerLogic
|
| */
|
| void generateInterfacesIsTests(ClassElement cls,
|
| void emitIsTest(ClassElement element),
|
| - void emitSubstitution(ClassElement element),
|
| Set<Element> alreadyGenerated) {
|
| - void tryEmitTest(ClassElement check) {
|
| - if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
|
| - alreadyGenerated.add(check);
|
| - emitIsTest(check);
|
| - emitSubstitution(check);
|
| + void tryEmitTest(ClassElement cls) {
|
| + if (!alreadyGenerated.contains(cls) && checkedClasses.contains(cls)) {
|
| + alreadyGenerated.add(cls);
|
| + emitIsTest(cls);
|
| }
|
| };
|
|
|
| @@ -1341,16 +1284,14 @@ $lazyInitializerLogic
|
| for (DartType interfaceType in cls.interfaces) {
|
| Element element = interfaceType.element;
|
| tryEmitTest(element);
|
| - generateInterfacesIsTests(element, emitIsTest, emitSubstitution,
|
| - alreadyGenerated);
|
| + generateInterfacesIsTests(element, emitIsTest, alreadyGenerated);
|
| }
|
|
|
| // We need to also emit "is checks" for the superclass and its supertypes.
|
| ClassElement superclass = cls.superclass;
|
| if (superclass != null) {
|
| tryEmitTest(superclass);
|
| - generateInterfacesIsTests(superclass, emitIsTest, emitSubstitution,
|
| - alreadyGenerated);
|
| + generateInterfacesIsTests(superclass, emitIsTest, alreadyGenerated);
|
| }
|
| }
|
|
|
|
|