Chromium Code Reviews| 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 |