Index: sdk/lib/_internal/compiler/js_lib/js_rti.dart |
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/compiler/js_lib/js_rti.dart |
index 2cf4b4826b467721cc46084a6e12aec4f6340ca3..c8981cb629f71de520e9805c37b9757a3e400f62 100644 |
--- a/sdk/lib/_internal/compiler/js_lib/js_rti.dart |
+++ b/sdk/lib/_internal/compiler/js_lib/js_rti.dart |
@@ -390,18 +390,19 @@ bool checkSubtypeOfRuntimeType(o, t) { |
// overwrite o with the interceptor below. |
var rti = getRuntimeTypeInfo(o); |
o = getInterceptor(o); |
- // We can use the object as its own type representation because we install |
- // the subtype flags and the substitution on the prototype, so they are |
- // properties of the object in JS. |
- var type; |
+ var type = JS('', '#.constructor', o); |
if (isNotNull(rti)) { |
// If the type has type variables (that is, [:rti != null:]), make a copy of |
// the type arguments and insert [o] in the first position to create a |
// compound type representation. |
- type = JS('JSExtendableArray', '#.slice()', rti); |
- JS('', '#.splice(0, 0, #)', type, o); |
- } else { |
- // Use the object as representation of the raw type. |
+ rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy. |
+ JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0. |
+ type = rti; |
+ } else if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}') || |
karlklose
2014/12/15 13:12:21
One of them should be 'hasField(o, ...'.
floitsch
2014/12/15 16:04:35
argh.
In fact o can never have a function-type-tag
|
+ hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) { |
+ // Functions are treated specially. If either `o` is a function or if t is |
+ // a function type, take o as the type-object. If o isn't a function the |
+ // test will fail, because `o` doesn't have the necessary fields. |
type = o; |
} |
return isSubtype(type, t); |
@@ -436,6 +437,13 @@ getArguments(var type) { |
* |
* See the comment in the beginning of this file for a description of type |
* representations. |
+ * |
+ * [t] must be a type, usually represented by the constructor of the class, or |
+ * an array (for generic types). |
+ * |
+ * If [t] is a function type, then [s] may be any object (and the test will |
+ * look for closure properties on the object). if [t] is not a function type |
karlklose
2014/12/15 13:12:21
'closure properties' -> 'function type tag'?
floitsch
2014/12/15 16:04:34
Changed.
Not true anymore.
|
+ * [s] must be a type too. |
*/ |
bool isSubtype(var s, var t) { |
// Subtyping is reflexive. |
@@ -454,10 +462,10 @@ bool isSubtype(var s, var t) { |
return isFunctionSubtype(s, t); |
} |
// Check function types against the Function class. |
- if (getConstructorName(t) == JS_FUNCTION_CLASS_NAME() && |
- hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) { |
- return true; |
+ if (hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) { |
+ return getConstructorName(t) == JS_FUNCTION_CLASS_NAME(); |
} |
+ |
// Get the object describing the class and check for the subtyping flag |
// constructed from the type of [t]. |
var typeOfS = isJsArray(s) ? getIndex(s, 0) : s; |
@@ -468,9 +476,10 @@ bool isSubtype(var s, var t) { |
var substitution; |
if (isNotIdentical(typeOfT, typeOfS)) { |
var test = '${JS_OPERATOR_IS_PREFIX()}${name}'; |
- if (hasNoField(typeOfS, test)) return false; |
+ var typeOfSPrototype = JS('', '#.prototype', typeOfS); |
+ if (hasNoField(typeOfSPrototype, test)) return false; |
var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}'; |
- substitution = getField(typeOfS, field); |
+ substitution = getField(typeOfSPrototype, field); |
} |
// The class of [s] is a subclass of the class of [t]. If [s] has no type |
// arguments and no substitution, it is used as raw type. If [t] has no |