| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 const SourceString('defineNativeMethodsExtended')); | 98 const SourceString('defineNativeMethodsExtended')); |
| 99 return backend.namer.isolateAccess(element); | 99 return backend.namer.isolateAccess(element); |
| 100 } | 100 } |
| 101 | 101 |
| 102 String get defineNativeMethodsFinishName { | 102 String get defineNativeMethodsFinishName { |
| 103 Element element = compiler.findHelper( | 103 Element element = compiler.findHelper( |
| 104 const SourceString('defineNativeMethodsFinish')); | 104 const SourceString('defineNativeMethodsFinish')); |
| 105 return backend.namer.isolateAccess(element); | 105 return backend.namer.isolateAccess(element); |
| 106 } | 106 } |
| 107 | 107 |
| 108 List<String> nativeTagsOfClass(ClassElement cls) { | 108 // The tags string contains comma-separated 'words' which are either dispatch |
| 109 // tags (having JavaScript identifier syntax) and directives that begin with |
| 110 // `!`. |
| 111 List<String> nativeTagsOfClassRaw(ClassElement cls) { |
| 109 String quotedName = cls.nativeTagInfo.slowToString(); | 112 String quotedName = cls.nativeTagInfo.slowToString(); |
| 110 return quotedName.substring(1, quotedName.length - 1).split(','); | 113 return quotedName.substring(1, quotedName.length - 1).split(','); |
| 111 } | 114 } |
| 112 | 115 |
| 116 List<String> nativeTagsOfClass(ClassElement cls) { |
| 117 return nativeTagsOfClassRaw(cls).where((s) => !s.startsWith('!')).toList(); |
| 118 } |
| 119 |
| 120 bool nativeHasTagsMarker(ClassElement cls, String marker) { |
| 121 return nativeTagsOfClassRaw(cls).contains(marker); |
| 122 } |
| 123 |
| 124 bool nativeForcedNonLeaf(ClassElement cls) => |
| 125 nativeHasTagsMarker(cls, '!nonleaf'); |
| 126 |
| 113 /** | 127 /** |
| 114 * Writes the class definitions for the interceptors to [mainBuffer]. | 128 * Writes the class definitions for the interceptors to [mainBuffer]. |
| 115 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. | 129 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. |
| 116 * | 130 * |
| 117 * The interceptors are filtered to avoid emitting trivial interceptors. For | 131 * The interceptors are filtered to avoid emitting trivial interceptors. For |
| 118 * example, if the program contains no code that can distinguish between the | 132 * example, if the program contains no code that can distinguish between the |
| 119 * numerous subclasses of `Element` then we can pretend that `Element` is a | 133 * numerous subclasses of `Element` then we can pretend that `Element` is a |
| 120 * leaf class, and all instances of subclasses of `Element` are instances of | 134 * leaf class, and all instances of subclasses of `Element` are instances of |
| 121 * `Element`. | 135 * `Element`. |
| 122 * | 136 * |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 needed = true; | 204 needed = true; |
| 191 } else if (neededByConstant.contains(classElement)) { | 205 } else if (neededByConstant.contains(classElement)) { |
| 192 needed = true; | 206 needed = true; |
| 193 } else if (modifiedClasses.contains(classElement)) { | 207 } else if (modifiedClasses.contains(classElement)) { |
| 194 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer | 208 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer |
| 195 // adds information to a class prototype or constructor. | 209 // adds information to a class prototype or constructor. |
| 196 needed = true; | 210 needed = true; |
| 197 } else if (extensionPoints.containsKey(classElement)) { | 211 } else if (extensionPoints.containsKey(classElement)) { |
| 198 needed = true; | 212 needed = true; |
| 199 } | 213 } |
| 214 if (classElement.isNative() && nativeForcedNonLeaf(classElement)) { |
| 215 needed = true; |
| 216 nonleafClasses.add(classElement); |
| 217 } |
| 200 | 218 |
| 201 if (needed || neededClasses.contains(classElement)) { | 219 if (needed || neededClasses.contains(classElement)) { |
| 202 neededClasses.add(classElement); | 220 neededClasses.add(classElement); |
| 203 neededClasses.add(classElement.superclass); | 221 neededClasses.add(classElement.superclass); |
| 204 nonleafClasses.add(classElement.superclass); | 222 nonleafClasses.add(classElement.superclass); |
| 205 } | 223 } |
| 206 } | 224 } |
| 207 | 225 |
| 208 // Collect all the tags that map to each native class. | 226 // Collect all the tags that map to each native class. |
| 209 | 227 |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 if (emitter.compiler.enableMinification) targetBuffer.add(';'); | 533 if (emitter.compiler.enableMinification) targetBuffer.add(';'); |
| 516 targetBuffer.add(jsAst.prettyPrint( | 534 targetBuffer.add(jsAst.prettyPrint( |
| 517 new jsAst.ExpressionStatement(init), compiler)); | 535 new jsAst.ExpressionStatement(init), compiler)); |
| 518 targetBuffer.add('\n'); | 536 targetBuffer.add('\n'); |
| 519 } | 537 } |
| 520 | 538 |
| 521 targetBuffer.add(nativeBuffer); | 539 targetBuffer.add(nativeBuffer); |
| 522 targetBuffer.add('\n'); | 540 targetBuffer.add('\n'); |
| 523 } | 541 } |
| 524 } | 542 } |
| OLD | NEW |