Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Unified Diff: frog/leg/native_emitter.dart

Issue 9773026: Add a method on native classes for is checks. Reduces the code for generating is checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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');
+ }
+ }
}
« no previous file with comments | « frog/leg/emitter.dart ('k') | frog/leg/ssa/codegen.dart » ('j') | frog/leg/ssa/codegen.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698