Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| index 746df0e8314b54715af2dd13d17c024902cec9ad..65ca9995c867b8d751f9b8b00e5c665100b9f992 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart |
| @@ -21,13 +21,69 @@ class RuntimeTypeInformation { |
| /// instantiations and checks. |
| Set<ClassElement> allArguments; |
| - bool isJsNative(Element element) { |
| - return (element == compiler.intClass || |
| - element == compiler.boolClass || |
| - element == compiler.numClass || |
| - element == compiler.doubleClass || |
| - element == compiler.stringClass || |
| - element == compiler.listClass); |
| + /** |
| + * Contains the classes for which we use builtin JavaScript datatypes on which |
|
ngeoffray
2013/02/21 10:26:18
on which we -> and therefore cannot
karlklose
2013/02/21 14:48:44
Done.
|
| + * we cannot install subtyping flags and substitutions. |
| + */ |
| + Collection<ClassElement> get jsNatives { |
| + if (cachedJsNatives == null) { |
| + cachedJsNatives = <ClassElement>[compiler.intClass, |
| + compiler.boolClass, |
| + compiler.numClass, |
| + compiler.doubleClass, |
| + compiler.stringClass]; |
|
ngeoffray
2013/02/21 10:26:18
Could you add a comment on why you don't put list
karlklose
2013/02/21 14:48:44
Done.
|
| + } |
| + return cachedJsNatives; |
| + } |
| + Collection<ClassElement> cachedJsNatives; |
| + |
| + bool isJsNative(Element element) => jsNatives.contains(element); |
| + |
| + bool needsNativeCheck(Element element) { |
| + return element == compiler.objectClass || isJsNative(element); |
|
ngeoffray
2013/02/21 10:26:18
How about super types of string?
karlklose
2013/02/21 14:48:44
Which do we have?
ngeoffray
2013/02/21 16:31:55
Comparable<String>, Pattern.
|
| + } |
| + |
| + /** |
| + * Constructs the native check function for the class [element]. |
| + * |
| + * This function will be put on the type representation for native classes |
| + * (and Object) and is called by the helper function [:objectIsSubtype:], if |
| + * it is on the object that represents the type to test against. We have to |
| + * put a trivial native check on object when it is used as a type argument in |
| + * a check because the native objects cannot have [:$isObject:] bits set on |
| + * them. |
| + * |
| + * TODO(karlklose): use the interceptors instead of holders for native classes |
| + * and implement the native checks on them. |
| + */ |
| + jsAst.Expression getNativeCheck(Element element) { |
| + final String parameterName = 'object'; |
| + final jsAst.VariableUse variable = new jsAst.VariableUse(parameterName); |
| + |
| + jsAst.Expression typeTest(String typeName) { |
| + return js.strictEquals( |
| + new jsAst.LiteralExpression.withData('typeof #', [variable]), |
| + new jsAst.LiteralString("'$typeName'")); |
| + } |
| + |
| + jsAst.Expression test; |
| + if (element == compiler.objectClass) { |
| + test = new jsAst.LiteralBool(true); |
| + } else if (element == compiler.intClass) { |
| + final jsAst.Expression zero = new jsAst.LiteralNumber('0'); |
| + test = js.strictEquals(variable, new jsAst.Binary('|', variable, zero)); |
|
ngeoffray
2013/02/21 10:26:18
Our int check is Math.floor(a) === a
karlklose
2013/02/21 14:48:44
Done.
|
| + } else if (element == compiler.boolClass) { |
| + test = typeTest('boolean'); |
| + } else if (element == compiler.numClass) { |
| + test = typeTest('number'); |
| + } else if (element == compiler.doubleClass) { |
| + test = typeTest('number'); |
| + } else if (element == compiler.stringClass) { |
| + test = typeTest('string'); |
| + } else { |
| + return null; |
| + } |
| + return js.fun([parameterName], js.block(js.return_(test))); |
| } |
| TypeChecks cachedRequiredChecks; |
| @@ -294,4 +350,14 @@ class TypeCheckMapping implements TypeChecks { |
| } |
| Iterator<ClassElement> get iterator => map.keys.iterator; |
| + |
| + String toString() { |
| + StringBuffer sb = new StringBuffer(); |
| + for (ClassElement holder in this) { |
| + for (ClassElement check in [holder]) { |
| + sb.add('${holder.name.slowToString()}.${check.name.slowToString()}, '); |
| + } |
| + } |
| + return '[$sb]'; |
| + } |
| } |