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 b9b44ef4b1ada1c78afb8033cbfe2a3bf584bf33..10611355110e986b407562e7c100899982660d31 100644 |
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
@@ -1085,33 +1085,51 @@ class JavaScriptBackend extends Backend { |
enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
} |
- void registerRuntimeType(TreeElements elements) { |
+ void registerGenericCallMethod(Element callMethod, |
+ Enqueuer enqueuer, TreeElements elements) { |
+ if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { |
+ registerApplySignature(enqueuer, elements); |
+ } |
+ } |
+ |
+ void registerGenericClosure(Element closure, |
+ Enqueuer enqueuer, TreeElements elements) { |
+ if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { |
+ registerApplySignature(enqueuer, elements); |
+ } |
+ } |
+ |
+ void registerApplySignature(Enqueuer enqueuer, TreeElements elements) { |
+ // Calls to [:applySignature:] are generated by the emitter and we therefore |
+ // need to enqueue the used elements in the codegen enqueuer as well as in |
+ // the resolution enqueuer. |
+ enqueue(enqueuer, getSetRuntimeTypeInfo(), elements); |
+ enqueue(enqueuer, getGetRuntimeTypeInfo(), elements); |
+ enqueue(enqueuer, getApplySignature(), elements); |
+ enqueue(enqueuer, getGetRuntimeTypeArguments(), elements); |
+ enqueuer.registerInstantiatedClass(compiler.listClass, elements); |
+ } |
+ |
+ void registerRuntimeType(Enqueuer enqueuer, TreeElements elements) { |
+ registerApplySignature(enqueuer, elements); |
enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
- enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
+ registerGetRuntimeTypeArgument(elements); |
compiler.enqueuer.resolution.registerInstantiatedClass( |
compiler.listClass, elements); |
} |
void registerTypeVariableExpression(TreeElements elements) { |
- registerRuntimeType(elements); |
+ enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
+ enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
+ registerGetRuntimeTypeArgument(elements); |
+ compiler.enqueuer.resolution.registerInstantiatedClass( |
+ compiler.listClass, elements); |
enqueueInResolution(getRuntimeTypeToString(), elements); |
enqueueInResolution(getCreateRuntimeType(), elements); |
} |
void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { |
- world.registerInstantiatedClass(compiler.boolClass, elements); |
- bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
- if (!type.isRaw || isTypeVariable) { |
- enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
- enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
- enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
- enqueueInResolution(getCheckSubtype(), elements); |
- if (isTypeVariable) { |
- enqueueInResolution(getGetObjectIsSubtype(), elements); |
- } |
- world.registerInstantiatedClass(compiler.listClass, elements); |
- } |
// [registerIsCheck] is also called for checked mode checks, so we |
// need to register checked mode helpers. |
if (compiler.enableTypeAssertions) { |
@@ -1120,6 +1138,11 @@ class JavaScriptBackend extends Backend { |
// We also need the native variant of the check (for DOM types). |
e = getNativeCheckedModeHelper(type, typeCast: false); |
if (e != null) world.addToWorkList(e); |
+ } else { |
+ if (type.isMalformed) { |
+ registerThrowRuntimeError(elements); |
+ return; |
+ } |
} |
if (type.element.isNative()) { |
// We will neeed to add the "$is" and "$as" properties on the |
@@ -1128,6 +1151,21 @@ class JavaScriptBackend extends Backend { |
world.addToWorkList( |
compiler.findHelper(const SourceString('defineProperty'))); |
} |
+ world.registerInstantiatedClass(compiler.boolClass, elements); |
+ bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
+ if (!type.isRaw || type.containsTypeVariables) { |
+ enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
+ enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
+ enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
+ enqueueInResolution(getCheckSubtype(), elements); |
+ if (isTypeVariable) { |
+ enqueueInResolution(getGetObjectIsSubtype(), elements); |
+ } |
+ world.registerInstantiatedClass(compiler.listClass, elements); |
+ } |
+ if (type is FunctionType) { |
+ enqueueInResolution(getCheckFunctionSubtype(), elements); |
+ } |
} |
void registerAsCheck(DartType type, TreeElements elements) { |
@@ -1203,11 +1241,19 @@ class JavaScriptBackend extends Backend { |
return rti.classesNeedingRti.contains(cls) || compiler.enabledRuntimeType; |
} |
+ bool methodNeedsRti(Element cls) { |
+ return rti.methodsNeedingRti.contains(cls) || compiler.enabledRuntimeType; |
+ } |
+ |
+ void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) { |
+ enqueuer.addToWorkList(e); |
+ elements.registerDependency(e); |
+ } |
+ |
void enqueueInResolution(Element e, TreeElements elements) { |
if (e == null) return; |
ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; |
- enqueuer.addToWorkList(e); |
- elements.registerDependency(e); |
+ enqueue(enqueuer, e, elements); |
} |
void registerConstantMap(TreeElements elements) { |
@@ -1606,6 +1652,14 @@ class JavaScriptBackend extends Backend { |
return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); |
} |
+ Element getApplySignature() { |
+ return compiler.findHelper(const SourceString('applySignature')); |
+ } |
+ |
+ Element getGetRuntimeTypeArguments() { |
+ return compiler.findHelper(const SourceString('getRuntimeTypeArguments')); |
+ } |
+ |
Element getGetRuntimeTypeArgument() { |
return compiler.findHelper(const SourceString('getRuntimeTypeArgument')); |
} |
@@ -1622,6 +1676,10 @@ class JavaScriptBackend extends Backend { |
return compiler.findHelper(const SourceString('objectIsSubtype')); |
} |
+ Element getCheckFunctionSubtype() { |
+ return compiler.findHelper(const SourceString('checkFunctionSubtype')); |
+ } |
+ |
Element getThrowNoSuchMethod() { |
return compiler.findHelper(const SourceString('throwNoSuchMethod')); |
} |