OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library dart2js.js_emitter.program_builder; | 5 library dart2js.js_emitter.program_builder; |
6 | 6 |
7 import '../js_emitter.dart' show computeMixinClass, Emitter; | 7 import '../js_emitter.dart' show computeMixinClass, Emitter; |
8 import '../model.dart'; | 8 import '../model.dart'; |
9 | 9 |
10 import '../../common.dart'; | 10 import '../../common.dart'; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 75 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
76 | 76 |
77 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 77 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
78 /// generate the deferredLoadingMap (to know which hunks to load). | 78 /// generate the deferredLoadingMap (to know which hunks to load). |
79 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 79 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
80 | 80 |
81 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 81 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
82 /// update field-initializers to point to the ConstantModel. | 82 /// update field-initializers to point to the ConstantModel. |
83 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; | 83 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; |
84 | 84 |
| 85 /// Mapping from names to strings. |
| 86 /// |
| 87 /// This mapping is used to support `const Symbol` expressions. |
| 88 /// |
| 89 /// This map is filled when building classes. |
| 90 final Map<js.Name, String> _symbolsMap = <js.Name, String>{}; |
| 91 |
85 Set<Class> _unneededNativeClasses; | 92 Set<Class> _unneededNativeClasses; |
86 | 93 |
87 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { | 94 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { |
88 collector.collect(); | 95 collector.collect(); |
89 | 96 |
90 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; | 97 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; |
91 // Note: In rare cases (mostly tests) output units can be empty. This | 98 // Note: In rare cases (mostly tests) output units can be empty. This |
92 // happens when the deferred code is dead-code eliminated but we still need | 99 // happens when the deferred code is dead-code eliminated but we still need |
93 // to check that the library has been loaded. | 100 // to check that the library has been loaded. |
94 _compiler.deferredLoadTask.allOutputUnits.forEach( | 101 _compiler.deferredLoadTask.allOutputUnits.forEach( |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; | 162 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; |
156 if (backend.namer is js.TokenFinalizer) { | 163 if (backend.namer is js.TokenFinalizer) { |
157 var namingFinalizer = backend.namer; | 164 var namingFinalizer = backend.namer; |
158 finalizers.add(namingFinalizer); | 165 finalizers.add(namingFinalizer); |
159 } | 166 } |
160 | 167 |
161 return new Program( | 168 return new Program( |
162 fragments, | 169 fragments, |
163 holders, | 170 holders, |
164 _buildLoadMap(), | 171 _buildLoadMap(), |
| 172 _symbolsMap, |
165 _buildTypeToInterceptorMap(), | 173 _buildTypeToInterceptorMap(), |
166 _task.metadataCollector, | 174 _task.metadataCollector, |
167 finalizers, | 175 finalizers, |
168 needsNativeSupport: needsNativeSupport, | 176 needsNativeSupport: needsNativeSupport, |
169 outputContainsConstantList: collector.outputContainsConstantList, | 177 outputContainsConstantList: collector.outputContainsConstantList, |
170 hasIsolateSupport: _compiler.hasIsolateSupport); | 178 hasIsolateSupport: _compiler.hasIsolateSupport); |
171 } | 179 } |
172 | 180 |
173 void _markEagerClasses() { | 181 void _markEagerClasses() { |
174 _markEagerInterceptorClasses(); | 182 _markEagerInterceptorClasses(); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 callStubs.add(_buildStubMethod(name, code, element: member)); | 395 callStubs.add(_buildStubMethod(name, code, element: member)); |
388 }); | 396 }); |
389 } | 397 } |
390 } | 398 } |
391 } | 399 } |
392 | 400 |
393 List<StubMethod> typeVariableReaderStubs = | 401 List<StubMethod> typeVariableReaderStubs = |
394 runtimeTypeGenerator.generateTypeVariableReaderStubs(element); | 402 runtimeTypeGenerator.generateTypeVariableReaderStubs(element); |
395 | 403 |
396 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; | 404 List<StubMethod> noSuchMethodStubs = <StubMethod>[]; |
| 405 |
397 if (backend.enabledNoSuchMethod && element == _compiler.objectClass) { | 406 if (backend.enabledNoSuchMethod && element == _compiler.objectClass) { |
398 Map<js.Name, Selector> selectors = | 407 Map<js.Name, Selector> selectors = |
399 classStubGenerator.computeSelectorsForNsmHandlers(); | 408 classStubGenerator.computeSelectorsForNsmHandlers(); |
400 selectors.forEach((js.Name name, Selector selector) { | 409 selectors.forEach((js.Name name, Selector selector) { |
| 410 // If the program contains `const Symbol` names we have to retain them. |
| 411 String selectorName = selector.name; |
| 412 if (selector.isSetter) selectorName = "$selectorName="; |
| 413 if (backend.symbolsUsed.contains(selectorName)) { |
| 414 _symbolsMap[name] = selectorName; |
| 415 } |
401 noSuchMethodStubs | 416 noSuchMethodStubs |
402 .add(classStubGenerator.generateStubForNoSuchMethod(name, | 417 .add(classStubGenerator.generateStubForNoSuchMethod(name, |
403 selector)); | 418 selector)); |
404 }); | 419 }); |
405 } | 420 } |
406 | 421 |
407 if (element == backend.closureClass) { | 422 if (element == backend.closureClass) { |
408 // We add a special getter here to allow for tearing off a closure from | 423 // We add a special getter here to allow for tearing off a closure from |
409 // itself. | 424 // itself. |
410 js.Name name = namer.getterForMember(Selector.CALL_NAME); | 425 js.Name name = namer.getterForMember(Selector.CALL_NAME); |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 Constant constant = new Constant(name, holder, constantValue); | 829 Constant constant = new Constant(name, holder, constantValue); |
815 _constants[constantValue] = constant; | 830 _constants[constantValue] = constant; |
816 } | 831 } |
817 } | 832 } |
818 | 833 |
819 Holder _registerStaticStateHolder() { | 834 Holder _registerStaticStateHolder() { |
820 return _registry.registerHolder( | 835 return _registry.registerHolder( |
821 namer.staticStateHolder, isStaticStateHolder: true); | 836 namer.staticStateHolder, isStaticStateHolder: true); |
822 } | 837 } |
823 } | 838 } |
OLD | NEW |