Chromium Code Reviews| Index: frog/leg/native_emitter.dart |
| =================================================================== |
| --- frog/leg/native_emitter.dart (revision 5830) |
| +++ frog/leg/native_emitter.dart (working copy) |
| @@ -175,30 +175,7 @@ |
| String buildDynamicMetadataCode() => ''' |
| if (typeof $dynamicMetadataName == 'undefined') $dynamicMetadataName = [];'''; |
| - // This method will be called for 'is' checks on native types. |
| - // It takes the object on which the 'is' check is being done, and the |
| - // property name for the type check. The method patches the real |
| - // prototype of the object with the value from the Dart object |
| - // (see [generateNativeClass]). |
| - String buildDynamicIsCheckCode() { |
| - ClassElement objectClass = |
| - compiler.coreLibrary.find(const SourceString('Object')); |
| - return ''' |
| -function(obj, isCheck) { |
| - if (obj.constructor === Array) return false; |
| - var proto = Object.getPrototypeOf(obj); |
| - // Check if the Dart object corresponding to this class has the property. |
| - var res = |
| - !!${compiler.namer.CURRENT_ISOLATE}.native[$typeNameOfName(obj)][isCheck]; |
| - res = res || false; |
| - $defPropName(proto, isCheck, res); |
| - return res; |
| -}'''; |
| - } |
| - String buildNativePropertyCode() => ''' |
| -${compiler.namer.ISOLATE}.prototype.native = {};'''; |
| - |
| String buildDynamicSetMetadataCode() => """ |
| function(inputTable) { |
| // TODO: Deal with light isolates. |
| @@ -222,8 +199,6 @@ |
| String get typeNameOfName() => '${compiler.namer.ISOLATE}.\$typeNameOf'; |
| String get dynamicMetadataName() => |
| '${compiler.namer.ISOLATE}.\$dynamicMetatada'; |
| - String get dynamicIsCheckName() => |
| - '${compiler.namer.ISOLATE}.\$dynamicIsCheck'; |
| String get dynamicSetMetadataName() => |
| '${compiler.namer.ISOLATE}.\$dynamicSetMetatada'; |
| @@ -255,13 +230,6 @@ |
| buffer.add('\n'); |
| } |
| - void addNativePropertyIfNecessary(StringBuffer buffer) { |
| - if (addedNativeProperty) return; |
| - addedNativeProperty = true; |
| - buffer.add(buildNativePropertyCode()); |
| - buffer.add('\n'); |
| - } |
| - |
| void generateNativeLiteral(ClassElement classElement, StringBuffer buffer) { |
| String quotedNative = classElement.nativeName.slowToString(); |
| String nativeCode = quotedNative.substring(2, quotedNative.length - 1); |
| @@ -327,28 +295,15 @@ |
| } |
| } |
| - addNativePropertyIfNecessary(buffer); |
| - // Create an object that contains the is checks properties. The |
| - // object will be used when entering [buildDynamicIsCheckCode]. |
| - buffer.add('${compiler.namer.ISOLATE}.prototype.native.$nativeName = { '); |
| - List<String> tests = <String>[]; |
| - |
| - ClassElement objectClass = |
| - compiler.coreLibrary.find(const SourceString('Object')); |
| - ClassElement element = classElement; |
| // We need to put the super class is checks too, since a check on |
|
floitsch
2012/03/26 20:32:59
Remove comment.
ngeoffray
2012/03/27 10:48:53
Done.
|
| // the subclass can happen before a check on the super class |
| // (which does the patching on the prototype). |
| - do { |
| - compiler.emitter.generateTypeTests(element, (Element other) { |
| - tests.add("${compiler.namer.operatorIs(other)}:true"); |
| - }); |
| - element = element.superclass; |
| - } while (element !== objectClass); |
| + compiler.emitter.generateTypeTests(classElement, (Element other) { |
| + assert(requiresNativeIsCheck(other)); |
| + buffer.add('${attachTo(compiler.namer.operatorIs(other))} = '); |
| + buffer.add('function() { return true; }\n'); |
| + }); |
| - buffer.add('${Strings.join(tests, ",")}'); |
| - buffer.add('};\n'); |
| - |
| if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement); |
| } |
| @@ -405,12 +360,6 @@ |
| } |
| void emitDynamicDispatchMetadata(StringBuffer buffer) { |
| - // TODO(ngeoffray): emit this conditionally. |
| - addTypeNameOfFunctionIfNecessary(buffer); |
| - buffer.add('$dynamicIsCheckName = '); |
| - buffer.add(buildDynamicIsCheckCode()); |
| - buffer.add('\n'); |
| - |
| if (classesWithDynamicDispatch.isEmpty()) return; |
| buffer.add('// ${classesWithDynamicDispatch.length} dynamic classes.\n'); |
| @@ -529,4 +478,36 @@ |
| buffer.add('})();\n'); |
| } |
| } |
| + |
| + bool isSupertypeOfNativeClass(Element element) { |
| + if (element.isTypeVariable()) { |
| + compiler.cancel("Is check for type variable", element: work.element); |
| + return false; |
| + } |
| + if (element.computeType(compiler) is FunctionType) return false; |
| + |
| + if (!element.isClass()) { |
| + compiler.cancel("Is check does not handle element", element: element); |
| + return false; |
| + } |
| + |
| + return subtypes[element] !== null; |
| + } |
| + |
| + bool requiresNativeIsCheck(Element element) { |
| + if (!element.isClass()) return false; |
| + ClassElement cls = element; |
| + if (cls.isNative()) return true; |
| + return isSupertypeOfNativeClass(element); |
| + } |
| + |
| + void emitIsChecks(StringBuffer buffer) { |
| + for (Element type in compiler.universe.isChecks) { |
| + if (!requiresNativeIsCheck(type)) continue; |
| + addDefPropFunctionIfNecessary(buffer); |
| + String name = compiler.namer.operatorIs(type); |
| + buffer.add("$defPropName(Object.prototype, '$name', "); |
| + buffer.add('function() { return false; });\n'); |
| + } |
| + } |
| } |