| 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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class NativeEmitter { | 7 class NativeEmitter { |
| 8 | 8 |
| 9 CodeEmitterTask emitter; | 9 CodeEmitterTask emitter; |
| 10 CodeBuffer nativeBuffer; | 10 CodeBuffer nativeBuffer; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 String get hashCodeHelperName { | 67 String get hashCodeHelperName { |
| 68 Element element = compiler.findHelper('hashCodeForNativeObject'); | 68 Element element = compiler.findHelper('hashCodeForNativeObject'); |
| 69 return backend.namer.isolateAccess(element); | 69 return backend.namer.isolateAccess(element); |
| 70 } | 70 } |
| 71 | 71 |
| 72 String get dispatchPropertyNameVariable { | 72 String get dispatchPropertyNameVariable { |
| 73 Element element = compiler.findInterceptor('dispatchPropertyName'); | 73 Element element = compiler.findInterceptor('dispatchPropertyName'); |
| 74 return backend.namer.isolateAccess(element); | 74 return backend.namer.isolateAccess(element); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // The tags string contains comma-separated 'words' which are either dispatch | |
| 78 // tags (having JavaScript identifier syntax) and directives that begin with | |
| 79 // `!`. | |
| 80 List<String> nativeTagsOfClassRaw(ClassElement cls) { | |
| 81 String quotedName = cls.nativeTagInfo; | |
| 82 return quotedName.substring(1, quotedName.length - 1).split(','); | |
| 83 } | |
| 84 | |
| 85 List<String> nativeTagsOfClass(ClassElement cls) { | |
| 86 return nativeTagsOfClassRaw(cls).where((s) => !s.startsWith('!')).toList(); | |
| 87 } | |
| 88 | |
| 89 bool nativeHasTagsMarker(ClassElement cls, String marker) { | |
| 90 return nativeTagsOfClassRaw(cls).contains(marker); | |
| 91 } | |
| 92 | |
| 93 bool nativeForcedNonLeaf(ClassElement cls) => | |
| 94 nativeHasTagsMarker(cls, '!nonleaf'); | |
| 95 | |
| 96 /** | 77 /** |
| 97 * Writes the class definitions for the interceptors to [mainBuffer]. | 78 * Writes the class definitions for the interceptors to [mainBuffer]. |
| 98 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. | 79 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. |
| 99 * | 80 * |
| 100 * The interceptors are filtered to avoid emitting trivial interceptors. For | 81 * The interceptors are filtered to avoid emitting trivial interceptors. For |
| 101 * example, if the program contains no code that can distinguish between the | 82 * example, if the program contains no code that can distinguish between the |
| 102 * numerous subclasses of `Element` then we can pretend that `Element` is a | 83 * numerous subclasses of `Element` then we can pretend that `Element` is a |
| 103 * leaf class, and all instances of subclasses of `Element` are instances of | 84 * leaf class, and all instances of subclasses of `Element` are instances of |
| 104 * `Element`. | 85 * `Element`. |
| 105 * | 86 * |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 needed = true; | 159 needed = true; |
| 179 } else if (neededByConstant.contains(classElement)) { | 160 } else if (neededByConstant.contains(classElement)) { |
| 180 needed = true; | 161 needed = true; |
| 181 } else if (modifiedClasses.contains(classElement)) { | 162 } else if (modifiedClasses.contains(classElement)) { |
| 182 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer | 163 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer |
| 183 // adds information to a class prototype or constructor. | 164 // adds information to a class prototype or constructor. |
| 184 needed = true; | 165 needed = true; |
| 185 } else if (extensionPoints.containsKey(classElement)) { | 166 } else if (extensionPoints.containsKey(classElement)) { |
| 186 needed = true; | 167 needed = true; |
| 187 } | 168 } |
| 188 if (classElement.isNative() && nativeForcedNonLeaf(classElement)) { | 169 if (classElement.isNative() && |
| 170 native.nativeTagsForcedNonLeaf(classElement)) { |
| 189 needed = true; | 171 needed = true; |
| 190 nonleafClasses.add(classElement); | 172 nonleafClasses.add(classElement); |
| 191 } | 173 } |
| 192 | 174 |
| 193 if (needed || neededClasses.contains(classElement)) { | 175 if (needed || neededClasses.contains(classElement)) { |
| 194 neededClasses.add(classElement); | 176 neededClasses.add(classElement); |
| 195 neededClasses.add(classElement.superclass); | 177 neededClasses.add(classElement.superclass); |
| 196 nonleafClasses.add(classElement.superclass); | 178 nonleafClasses.add(classElement.superclass); |
| 197 } | 179 } |
| 198 } | 180 } |
| 199 | 181 |
| 200 // Collect all the tags that map to each native class. | 182 // Collect all the tags that map to each native class. |
| 201 | 183 |
| 202 Map<ClassElement, Set<String>> leafTags = | 184 Map<ClassElement, Set<String>> leafTags = |
| 203 new Map<ClassElement, Set<String>>(); | 185 new Map<ClassElement, Set<String>>(); |
| 204 Map<ClassElement, Set<String>> nonleafTags = | 186 Map<ClassElement, Set<String>> nonleafTags = |
| 205 new Map<ClassElement, Set<String>>(); | 187 new Map<ClassElement, Set<String>>(); |
| 206 | 188 |
| 207 for (ClassElement classElement in classes) { | 189 for (ClassElement classElement in classes) { |
| 208 if (!classElement.isNative()) continue; | 190 if (!classElement.isNative()) continue; |
| 209 List<String> nativeTags = nativeTagsOfClass(classElement); | 191 List<String> nativeTags = native.nativeTagsOfClass(classElement); |
| 210 | 192 |
| 211 if (nonleafClasses.contains(classElement) || | 193 if (nonleafClasses.contains(classElement) || |
| 212 extensionPoints.containsKey(classElement)) { | 194 extensionPoints.containsKey(classElement)) { |
| 213 nonleafTags | 195 nonleafTags |
| 214 .putIfAbsent(classElement, () => new Set<String>()) | 196 .putIfAbsent(classElement, () => new Set<String>()) |
| 215 .addAll(nativeTags); | 197 .addAll(nativeTags); |
| 216 } else { | 198 } else { |
| 217 ClassElement sufficingInterceptor = classElement; | 199 ClassElement sufficingInterceptor = classElement; |
| 218 while (!neededClasses.contains(sufficingInterceptor)) { | 200 while (!neededClasses.contains(sufficingInterceptor)) { |
| 219 sufficingInterceptor = sufficingInterceptor.superclass; | 201 sufficingInterceptor = sufficingInterceptor.superclass; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 if (emitter.compiler.enableMinification) targetBuffer.add(';'); | 492 if (emitter.compiler.enableMinification) targetBuffer.add(';'); |
| 511 targetBuffer.add(jsAst.prettyPrint( | 493 targetBuffer.add(jsAst.prettyPrint( |
| 512 new jsAst.ExpressionStatement(init), compiler)); | 494 new jsAst.ExpressionStatement(init), compiler)); |
| 513 targetBuffer.add('\n'); | 495 targetBuffer.add('\n'); |
| 514 } | 496 } |
| 515 | 497 |
| 516 targetBuffer.add(nativeBuffer); | 498 targetBuffer.add(nativeBuffer); |
| 517 targetBuffer.add('\n'); | 499 targetBuffer.add('\n'); |
| 518 } | 500 } |
| 519 } | 501 } |
| OLD | NEW |