| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class NativeEmitter { | 7 class NativeEmitter { |
| 8 | 8 |
| 9 final Map<Element, ClassBuilder> cachedBuilders; | 9 final Map<Element, ClassBuilder> cachedBuilders; |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 Compiler get compiler => emitterTask.compiler; | 37 Compiler get compiler => emitterTask.compiler; |
| 38 JavaScriptBackend get backend => compiler.backend; | 38 JavaScriptBackend get backend => compiler.backend; |
| 39 | 39 |
| 40 jsAst.Expression get defPropFunction { | 40 jsAst.Expression get defPropFunction { |
| 41 Element element = backend.findHelper('defineProperty'); | 41 Element element = backend.findHelper('defineProperty'); |
| 42 return emitterTask.staticFunctionAccess(element); | 42 return emitterTask.staticFunctionAccess(element); |
| 43 } | 43 } |
| 44 | 44 |
| 45 /** | 45 /** |
| 46 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. | 46 * Prepares native classes for emission. Returns the reduced list of classes. |
| 47 * |
| 48 * Removes trivial classes (that can be represented by a super type) and |
| 49 * generates properties that have to be added to classes (native or not). |
| 47 * | 50 * |
| 48 * The interceptors are filtered to avoid emitting trivial interceptors. For | 51 * The interceptors are filtered to avoid emitting trivial interceptors. For |
| 49 * example, if the program contains no code that can distinguish between the | 52 * example, if the program contains no code that can distinguish between the |
| 50 * numerous subclasses of `Element` then we can pretend that `Element` is a | 53 * numerous subclasses of `Element` then we can pretend that `Element` is a |
| 51 * leaf class, and all instances of subclasses of `Element` are instances of | 54 * leaf class, and all instances of subclasses of `Element` are instances of |
| 52 * `Element`. | 55 * `Element`. |
| 53 * | 56 * |
| 54 * There is also a performance benefit (in addition to the obvious code size | 57 * There is also a performance benefit (in addition to the obvious code size |
| 55 * benefit), due to how [getNativeInterceptor] works. Finding the interceptor | 58 * benefit), due to how [getNativeInterceptor] works. Finding the interceptor |
| 56 * of a leaf class in the hierarchy is more efficient that a non-leaf, so it | 59 * of a leaf class in the hierarchy is more efficient that a non-leaf, so it |
| 57 * improves performance when more classes can be treated as leaves. | 60 * improves performance when more classes can be treated as leaves. |
| 58 * | 61 * |
| 59 * [classes] contains native classes, mixin applications, and user subclasses | 62 * [classes] contains native classes, mixin applications, and user subclasses |
| 60 * of native classes. ONLY the native classes are generated here. [classes] | 63 * of native classes. *Only* the native classes are returned. The order of |
| 61 * is sorted in desired output order. | 64 * the returned classes is unchanged. (That is, the returned output might |
| 65 * just have classes removed). |
| 62 * | 66 * |
| 63 * [allAdditionalProperties] is used to collect properties that are pushed up | 67 * [allAdditionalProperties] is used to collect properties that are pushed up |
| 64 * from the above optimizations onto a non-native class, e.g, `Interceptor`. | 68 * from the above optimizations onto a non-native class, e.g, `Interceptor`. |
| 65 */ | 69 */ |
| 66 void generateNativeClasses( | 70 List<Class> prepareNativeClasses( |
| 67 List<Class> classes, | 71 List<Class> classes, |
| 68 Map<Class, Map<String, jsAst.Expression>> allAdditionalProperties) { | 72 Map<Class, Map<String, jsAst.Expression>> allAdditionalProperties) { |
| 69 // Compute a pre-order traversal of the subclass forest. We actually want a | 73 // Compute a pre-order traversal of the subclass forest. We actually want a |
| 70 // post-order traversal but it is easier to compute the pre-order and use it | 74 // post-order traversal but it is easier to compute the pre-order and use it |
| 71 // in reverse. | 75 // in reverse. |
| 72 | 76 |
| 73 if (classes.isNotEmpty) { | 77 hasNativeClasses = classes.isNotEmpty; |
| 74 hasNativeClasses = true; | |
| 75 } | |
| 76 | 78 |
| 77 List<Class> preOrder = <Class>[]; | 79 List<Class> preOrder = <Class>[]; |
| 78 Set<Class> seen = new Set<Class>(); | 80 Set<Class> seen = new Set<Class>(); |
| 79 | 81 |
| 80 Class objectClass = null; | 82 Class objectClass = null; |
| 81 Class jsInterceptorClass = null; | 83 Class jsInterceptorClass = null; |
| 82 void walk(Class cls) { | 84 void walk(Class cls) { |
| 83 if (cls.element == compiler.objectClass) { | 85 if (cls.element == compiler.objectClass) { |
| 84 objectClass = cls; | 86 objectClass = cls; |
| 85 return; | 87 return; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 generateClassInfo(jsInterceptorClass); | 218 generateClassInfo(jsInterceptorClass); |
| 217 for (Class cls in classes) { | 219 for (Class cls in classes) { |
| 218 if (!cls.isNative || neededClasses.contains(cls)) { | 220 if (!cls.isNative || neededClasses.contains(cls)) { |
| 219 generateClassInfo(cls); | 221 generateClassInfo(cls); |
| 220 } | 222 } |
| 221 } | 223 } |
| 222 } | 224 } |
| 223 | 225 |
| 224 // Emit the native class interceptors that were actually used. | 226 // TODO(sra): Issue #13731- this is commented out as part of custom |
| 225 for (Class cls in classes) { | 227 // element constructor work. |
| 226 assert(!cls.onlyForRti); | 228 // (floitsch: was run on every native class.) |
| 227 ClassElement classElement = cls.element; | 229 //assert(!classElement.hasBackendMembers); |
| 228 if (!cls.isNative) continue; | |
| 229 if (neededClasses.contains(cls)) { | |
| 230 // TODO(sra): Issue #13731- this is commented out as part of custom | |
| 231 // element constructor work. | |
| 232 //assert(!classElement.hasBackendMembers); | |
| 233 | 230 |
| 234 ClassBuilder enclosingBuilder = | 231 return classes |
| 235 emitterTask.oldEmitter.getElementDescriptor(classElement); | 232 .where((Class cls) => cls.isNative && neededClasses.contains(cls)) |
| 236 emitterTask.oldEmitter.emitClass(cls, enclosingBuilder); | 233 .toList(); |
| 237 } | |
| 238 } | |
| 239 } | 234 } |
| 240 | 235 |
| 241 /** | 236 /** |
| 242 * Computes the native classes that are extended (subclassed) by non-native | 237 * Computes the native classes that are extended (subclassed) by non-native |
| 243 * classes and the set non-mative classes that extend them. (A List is used | 238 * classes and the set non-mative classes that extend them. (A List is used |
| 244 * instead of a Set for out stability). | 239 * instead of a Set for out stability). |
| 245 */ | 240 */ |
| 246 Map<Class, List<Class>> computeExtensionPoints(List<Class> classes) { | 241 Map<Class, List<Class>> computeExtensionPoints(List<Class> classes) { |
| 247 Class nativeSuperclassOf(Class cls) { | 242 Class nativeSuperclassOf(Class cls) { |
| 248 if (cls == null) return null; | 243 if (cls == null) return null; |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 targetOutput.add(';'); | 427 targetOutput.add(';'); |
| 433 } | 428 } |
| 434 targetOutput.addBuffer(jsAst.prettyPrint( | 429 targetOutput.addBuffer(jsAst.prettyPrint( |
| 435 new jsAst.ExpressionStatement(init), compiler)); | 430 new jsAst.ExpressionStatement(init), compiler)); |
| 436 targetOutput.add('\n'); | 431 targetOutput.add('\n'); |
| 437 } | 432 } |
| 438 | 433 |
| 439 targetOutput.add('\n'); | 434 targetOutput.add('\n'); |
| 440 } | 435 } |
| 441 } | 436 } |
| OLD | NEW |