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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/lib/native_helper.dart ('k') | frog/leg/native_handler.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class NativeEmitter { 5 class NativeEmitter {
6 6
7 Compiler compiler; 7 Compiler compiler;
8 StringBuffer buffer; 8 StringBuffer buffer;
9 9
10 // Classes that participate in dynamic dispatch. These are the 10 // Classes that participate in dynamic dispatch. These are the
(...skipping 30 matching lines...) Expand all
41 const SourceString('dynamicSetMetadata')); 41 const SourceString('dynamicSetMetadata'));
42 return compiler.namer.isolateAccess(element); 42 return compiler.namer.isolateAccess(element);
43 } 43 }
44 44
45 String get typeNameOfName() { 45 String get typeNameOfName() {
46 Element element = compiler.findHelper( 46 Element element = compiler.findHelper(
47 const SourceString('getTypeNameOf')); 47 const SourceString('getTypeNameOf'));
48 return compiler.namer.isolateAccess(element); 48 return compiler.namer.isolateAccess(element);
49 } 49 }
50 50
51 String get dynamicIsCheckName() { 51 String get defPropName() {
52 Element element = compiler.findHelper( 52 Element element = compiler.findHelper(
53 const SourceString('dynamicIsCheck')); 53 const SourceString('defineProperty'));
54 return compiler.namer.isolateAccess(element);
55 }
56
57 String get isChecksHelperName() {
58 Element element = compiler.findHelper(
59 const SourceString('isChecksHelper'));
60 if (element === null) return null;
61 return compiler.namer.isolateAccess(element); 54 return compiler.namer.isolateAccess(element);
62 } 55 }
63 56
64 void generateNativeLiteral(ClassElement classElement) { 57 void generateNativeLiteral(ClassElement classElement) {
65 String quotedNative = classElement.nativeName.slowToString(); 58 String quotedNative = classElement.nativeName.slowToString();
66 String nativeCode = quotedNative.substring(2, quotedNative.length - 1); 59 String nativeCode = quotedNative.substring(2, quotedNative.length - 1);
67 String className = compiler.namer.getName(classElement); 60 String className = compiler.namer.getName(classElement);
68 buffer.add(className); 61 buffer.add(className);
69 buffer.add(' = '); 62 buffer.add(' = ');
70 buffer.add(nativeCode); 63 buffer.add(nativeCode);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 return "$dynamicName('$name').$nativeName"; 111 return "$dynamicName('$name').$nativeName";
119 } 112 }
120 113
121 for (Element member in classElement.members) { 114 for (Element member in classElement.members) {
122 if (member.isInstanceMember()) { 115 if (member.isInstanceMember()) {
123 compiler.emitter.addInstanceMember( 116 compiler.emitter.addInstanceMember(
124 member, attachTo, buffer, isNative: true); 117 member, attachTo, buffer, isNative: true);
125 } 118 }
126 } 119 }
127 120
128 // Create an object that contains the is checks properties. 121 compiler.emitter.generateTypeTests(classElement, (Element other) {
129 buffer.add('$isChecksHelperName.$nativeName = { '); 122 assert(requiresNativeIsCheck(other));
130 List<String> tests = <String>[]; 123 buffer.add('${attachTo(compiler.namer.operatorIs(other))} = ');
131 124 buffer.add('function() { return true; };\n');
132 ClassElement objectClass = 125 });
133 compiler.coreLibrary.find(const SourceString('Object'));
134 ClassElement element = classElement;
135 // We need to put the super class is checks too, since a check on
136 // the subclass can happen before a check on the super class
137 // (which does the patching on the prototype).
138 do {
139 compiler.emitter.generateTypeTests(element, (Element other) {
140 tests.add("${compiler.namer.operatorIs(other)}:true");
141 });
142 element = element.superclass;
143 } while (element !== objectClass);
144
145 buffer.add('${Strings.join(tests, ",")}');
146 buffer.add('};\n');
147 126
148 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement); 127 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement);
149 } 128 }
150 129
151 List<ClassElement> getDirectSubclasses(ClassElement cls) { 130 List<ClassElement> getDirectSubclasses(ClassElement cls) {
152 List<ClassElement> result = subtypes[cls]; 131 List<ClassElement> result = subtypes[cls];
153 if (result === null) result = const<ClassElement>[]; 132 if (result === null) result = const<ClassElement>[];
154 return result; 133 return result;
155 } 134 }
156 135
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 entries.add("\n ['$clsName', ${tagDefns[cls]}]"); 287 entries.add("\n ['$clsName', ${tagDefns[cls]}]");
309 } 288 }
310 buffer.add(Strings.join(entries, ',')); 289 buffer.add(Strings.join(entries, ','));
311 buffer.add('];\n'); 290 buffer.add('];\n');
312 buffer.add('$dynamicSetMetadataName(table);\n'); 291 buffer.add('$dynamicSetMetadataName(table);\n');
313 292
314 buffer.add('})();\n'); 293 buffer.add('})();\n');
315 } 294 }
316 } 295 }
317 296
297 bool isSupertypeOfNativeClass(Element element) {
298 if (element.isTypeVariable()) {
299 compiler.cancel("Is check for type variable", element: work.element);
300 return false;
301 }
302 if (element.computeType(compiler) is FunctionType) return false;
303
304 if (!element.isClass()) {
305 compiler.cancel("Is check does not handle element", element: element);
306 return false;
307 }
308
309 return subtypes[element] !== null;
310 }
311
312 bool requiresNativeIsCheck(Element element) {
313 if (!element.isClass()) return false;
314 ClassElement cls = element;
315 if (cls.isNative()) return true;
316 return isSupertypeOfNativeClass(element);
317 }
318
319 void emitIsChecks(StringBuffer buffer) {
320 for (Element type in compiler.universe.isChecks) {
321 if (!requiresNativeIsCheck(type)) continue;
322 String name = compiler.namer.operatorIs(type);
323 buffer.add("$defPropName(Object.prototype, '$name', ");
324 buffer.add('function() { return false; });\n');
325 }
326 }
327
318 void assembleCode(StringBuffer other) { 328 void assembleCode(StringBuffer other) {
319 if (isChecksHelperName === null) return; 329 StringBuffer isChecks = new StringBuffer();
320 other.add('(function() { $isChecksHelperName = {};\n$buffer\n })();\n'); 330 emitIsChecks(isChecks);
331 other.add('(function() {\n$isChecks$buffer\n})();\n');
321 } 332 }
322 } 333 }
OLDNEW
« no previous file with comments | « frog/leg/lib/native_helper.dart ('k') | frog/leg/native_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698