OLD | NEW |
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 |
11 // classes that contain used members. | 11 // classes that contain used members. |
12 Set<ClassElement> classesWithDynamicDispatch; | 12 Set<ClassElement> classesWithDynamicDispatch; |
13 | 13 |
14 // Native classes found in the application. | 14 // Native classes found in the application. |
15 Set<ClassElement> nativeClasses; | 15 Set<ClassElement> nativeClasses; |
16 | 16 |
| 17 // Caches the native subtypes of a native class. |
| 18 Map<ClassElement, List<ClassElement>> subtypes; |
| 19 |
17 // Caches the direct native subtypes of a native class. | 20 // Caches the direct native subtypes of a native class. |
18 Map<ClassElement, List<ClassElement>> subtypes; | 21 Map<ClassElement, List<ClassElement>> directSubtypes; |
19 | 22 |
20 // Caches the native methods that are overridden by a native class. | 23 // Caches the native methods that are overridden by a native class. |
21 // Note that the method that overrides does not have to be native: | 24 // Note that the method that overrides does not have to be native: |
22 // it's the overridden method that must make sure it will dispatch | 25 // it's the overridden method that must make sure it will dispatch |
23 // to its subclass if it sees an instance whose class is a subclass. | 26 // to its subclass if it sees an instance whose class is a subclass. |
24 Set<FunctionElement> overriddenMethods; | 27 Set<FunctionElement> overriddenMethods; |
25 | 28 |
26 NativeEmitter(this.compiler) | 29 NativeEmitter(this.compiler) |
27 : classesWithDynamicDispatch = new Set<ClassElement>(), | 30 : classesWithDynamicDispatch = new Set<ClassElement>(), |
28 nativeClasses = new Set<ClassElement>(), | 31 nativeClasses = new Set<ClassElement>(), |
29 subtypes = new Map<ClassElement, List<ClassElement>>(), | 32 subtypes = new Map<ClassElement, List<ClassElement>>(), |
| 33 directSubtypes = new Map<ClassElement, List<ClassElement>>(), |
30 overriddenMethods = new Set<FunctionElement>(), | 34 overriddenMethods = new Set<FunctionElement>(), |
31 buffer = new StringBuffer(); | 35 buffer = new StringBuffer(); |
32 | 36 |
33 String get dynamicName() { | 37 String get dynamicName() { |
34 Element element = compiler.findHelper( | 38 Element element = compiler.findHelper( |
35 const SourceString('dynamicFunction')); | 39 const SourceString('dynamicFunction')); |
36 return compiler.namer.isolateAccess(element); | 40 return compiler.namer.isolateAccess(element); |
37 } | 41 } |
38 | 42 |
39 String get dynamicSetMetadataName() { | 43 String get dynamicSetMetadataName() { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 compiler.emitter.generateTypeTests(classElement, (Element other) { | 129 compiler.emitter.generateTypeTests(classElement, (Element other) { |
126 assert(requiresNativeIsCheck(other)); | 130 assert(requiresNativeIsCheck(other)); |
127 buffer.add('${attachTo(compiler.namer.operatorIs(other))} = '); | 131 buffer.add('${attachTo(compiler.namer.operatorIs(other))} = '); |
128 buffer.add('function() { return true; };\n'); | 132 buffer.add('function() { return true; };\n'); |
129 }); | 133 }); |
130 | 134 |
131 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement); | 135 if (hasUsedSelectors) classesWithDynamicDispatch.add(classElement); |
132 } | 136 } |
133 | 137 |
134 List<ClassElement> getDirectSubclasses(ClassElement cls) { | 138 List<ClassElement> getDirectSubclasses(ClassElement cls) { |
135 List<ClassElement> result = subtypes[cls]; | 139 List<ClassElement> result = directSubtypes[cls]; |
136 if (result === null) result = const<ClassElement>[]; | 140 return result === null ? const<ClassElement>[] : result; |
137 return result; | |
138 } | 141 } |
139 | 142 |
140 void potentiallyConvertDartClosuresToJs(StringBuffer code, | 143 void potentiallyConvertDartClosuresToJs(StringBuffer code, |
141 FunctionElement member) { | 144 FunctionElement member) { |
142 FunctionParameters parameters = member.computeParameters(compiler); | 145 FunctionParameters parameters = member.computeParameters(compiler); |
143 Element converter = | 146 Element converter = |
144 compiler.findHelper(const SourceString('convertDartClosureToJS')); | 147 compiler.findHelper(const SourceString('convertDartClosureToJS')); |
145 String closureConverter = compiler.namer.isolateAccess(converter); | 148 String closureConverter = compiler.namer.isolateAccess(converter); |
146 parameters.forEachParameter((Element parameter) { | 149 parameters.forEachParameter((Element parameter) { |
147 Type type = parameter.computeType(compiler); | 150 Type type = parameter.computeType(compiler); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 String toStringName = compiler.namer.instanceMethodName( | 354 String toStringName = compiler.namer.instanceMethodName( |
352 null, const SourceString('toString'), 0); | 355 null, const SourceString('toString'), 0); |
353 objectProperties.add("$defPropName(Object.prototype, '$toStringName', "); | 356 objectProperties.add("$defPropName(Object.prototype, '$toStringName', "); |
354 objectProperties.add( | 357 objectProperties.add( |
355 'function() { return $toStringHelperName(this); });\n'); | 358 'function() { return $toStringHelperName(this); });\n'); |
356 | 359 |
357 // Finally, emit the code in the main buffer. | 360 // Finally, emit the code in the main buffer. |
358 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n'); | 361 targetBuffer.add('(function() {\n$objectProperties$buffer\n})();\n'); |
359 } | 362 } |
360 } | 363 } |
OLD | NEW |