| 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 '../../closure.dart' show ClosureFieldElement; | 7 import '../../closure.dart' show ClosureFieldElement; |
| 8 import '../../common.dart'; | 8 import '../../common.dart'; |
| 9 import '../../common/names.dart' show Names, Selectors; | 9 import '../../common/names.dart' show Names, Selectors; |
| 10 import '../../compiler.dart' show Compiler; | 10 import '../../compiler.dart' show Compiler; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // already registered earlier, and that we just call the register to get | 284 // already registered earlier, and that we just call the register to get |
| 285 // the holder-instance. | 285 // the holder-instance. |
| 286 return new StaticField( | 286 return new StaticField( |
| 287 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 287 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
| 288 } | 288 } |
| 289 | 289 |
| 290 List<StaticField> _buildStaticLazilyInitializedFields( | 290 List<StaticField> _buildStaticLazilyInitializedFields( |
| 291 LibrariesMap librariesMap) { | 291 LibrariesMap librariesMap) { |
| 292 JavaScriptConstantCompiler handler = backend.constants; | 292 JavaScriptConstantCompiler handler = backend.constants; |
| 293 DeferredLoadTask loadTask = _compiler.deferredLoadTask; | 293 DeferredLoadTask loadTask = _compiler.deferredLoadTask; |
| 294 Iterable<VariableElement> lazyFields = handler | 294 Iterable<FieldElement> lazyFields = handler |
| 295 .getLazilyInitializedFieldsForEmission() | 295 .getLazilyInitializedFieldsForEmission() |
| 296 .where((element) => | 296 .where((element) => |
| 297 loadTask.outputUnitForElement(element) == librariesMap.outputUnit); | 297 loadTask.outputUnitForElement(element) == librariesMap.outputUnit); |
| 298 return Elements | 298 return Elements |
| 299 .sortedByPosition(lazyFields) | 299 .sortedByPosition(lazyFields) |
| 300 .map(_buildLazyField) | 300 .map(_buildLazyField) |
| 301 .where((field) => field != null) // Happens when the field was unused. | 301 .where((field) => field != null) // Happens when the field was unused. |
| 302 .toList(growable: false); | 302 .toList(growable: false); |
| 303 } | 303 } |
| 304 | 304 |
| 305 StaticField _buildLazyField(Element element) { | 305 StaticField _buildLazyField(FieldElement element) { |
| 306 js.Expression code = backend.generatedCode[element]; | 306 js.Expression code = backend.generatedCode[element]; |
| 307 // The code is null if we ended up not needing the lazily | 307 // The code is null if we ended up not needing the lazily |
| 308 // initialized field after all because of constant folding | 308 // initialized field after all because of constant folding |
| 309 // before code generation. | 309 // before code generation. |
| 310 if (code == null) return null; | 310 if (code == null) return null; |
| 311 | 311 |
| 312 js.Name name = namer.globalPropertyName(element); | 312 js.Name name = namer.globalPropertyName(element); |
| 313 bool isFinal = element.isFinal; | 313 bool isFinal = element.isFinal; |
| 314 bool isLazy = true; | 314 bool isLazy = true; |
| 315 // TODO(floitsch): we shouldn't update the registry in the middle of | 315 // TODO(floitsch): we shouldn't update the registry in the middle of |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 if (backend.isJsInterop(element)) { | 597 if (backend.isJsInterop(element)) { |
| 598 typeTests.properties.forEach((js.Name name, js.Node code) { | 598 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 599 _classes[helpers.jsInterceptorClass] | 599 _classes[helpers.jsInterceptorClass] |
| 600 .isChecks | 600 .isChecks |
| 601 .add(_buildStubMethod(name, code)); | 601 .add(_buildStubMethod(name, code)); |
| 602 }); | 602 }); |
| 603 } else { | 603 } else { |
| 604 for (Field field in instanceFields) { | 604 for (Field field in instanceFields) { |
| 605 if (field.needsCheckedSetter) { | 605 if (field.needsCheckedSetter) { |
| 606 assert(!field.needsUncheckedSetter); | 606 assert(!field.needsUncheckedSetter); |
| 607 Element element = field.element; | 607 FieldElement element = field.element; |
| 608 js.Expression code = backend.generatedCode[element]; | 608 js.Expression code = backend.generatedCode[element]; |
| 609 assert(code != null); | 609 assert(code != null); |
| 610 js.Name name = namer.deriveSetterName(field.accessorName); | 610 js.Name name = namer.deriveSetterName(field.accessorName); |
| 611 checkedSetters.add(_buildStubMethod(name, code, element: element)); | 611 checkedSetters.add(_buildStubMethod(name, code, element: element)); |
| 612 } | 612 } |
| 613 } | 613 } |
| 614 | 614 |
| 615 typeTests.properties.forEach((js.Name name, js.Node code) { | 615 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 616 isChecks.add(_buildStubMethod(name, code)); | 616 isChecks.add(_buildStubMethod(name, code)); |
| 617 }); | 617 }); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 signature.forEachOptionalParameter((ParameterElement parameter) { | 707 signature.forEachOptionalParameter((ParameterElement parameter) { |
| 708 ConstantValue def = | 708 ConstantValue def = |
| 709 backend.constants.getConstantValue(parameter.constant); | 709 backend.constants.getConstantValue(parameter.constant); |
| 710 optionalParameterDefaultValues.add(def); | 710 optionalParameterDefaultValues.add(def); |
| 711 }); | 711 }); |
| 712 } | 712 } |
| 713 return optionalParameterDefaultValues; | 713 return optionalParameterDefaultValues; |
| 714 } | 714 } |
| 715 | 715 |
| 716 DartMethod _buildMethod(MethodElement element) { | 716 DartMethod _buildMethod(MethodElement element) { |
| 717 assert(element.isDeclaration); |
| 717 js.Name name = namer.methodPropertyName(element); | 718 js.Name name = namer.methodPropertyName(element); |
| 718 js.Expression code = backend.generatedCode[element]; | 719 js.Expression code = backend.generatedCode[element]; |
| 719 | 720 |
| 720 // TODO(kasperl): Figure out under which conditions code is null. | 721 // TODO(kasperl): Figure out under which conditions code is null. |
| 721 if (code == null) return null; | 722 if (code == null) return null; |
| 722 | 723 |
| 723 bool canTearOff = false; | 724 bool canTearOff = false; |
| 724 js.Name tearOffName; | 725 js.Name tearOffName; |
| 725 bool isClosureCallMethod = false; | 726 bool isClosureCallMethod = false; |
| 726 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 727 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 | 819 |
| 819 ParameterStubGenerator generator = | 820 ParameterStubGenerator generator = |
| 820 new ParameterStubGenerator(_compiler, namer, backend, closedWorld); | 821 new ParameterStubGenerator(_compiler, namer, backend, closedWorld); |
| 821 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 822 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
| 822 } | 823 } |
| 823 | 824 |
| 824 /// Builds a stub method. | 825 /// Builds a stub method. |
| 825 /// | 826 /// |
| 826 /// Stub methods may have an element that can be used for code-size | 827 /// Stub methods may have an element that can be used for code-size |
| 827 /// attribution. | 828 /// attribution. |
| 828 Method _buildStubMethod(js.Name name, js.Expression code, {Element element}) { | 829 Method _buildStubMethod(js.Name name, js.Expression code, |
| 830 {MemberElement element}) { |
| 829 return new StubMethod(name, code, element: element); | 831 return new StubMethod(name, code, element: element); |
| 830 } | 832 } |
| 831 | 833 |
| 832 // The getInterceptor methods directly access the prototype of classes. | 834 // The getInterceptor methods directly access the prototype of classes. |
| 833 // We must evaluate these classes eagerly so that the prototype is | 835 // We must evaluate these classes eagerly so that the prototype is |
| 834 // accessible. | 836 // accessible. |
| 835 void _markEagerInterceptorClasses() { | 837 void _markEagerInterceptorClasses() { |
| 836 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = | 838 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = |
| 837 backend.specializedGetInterceptors; | 839 backend.specializedGetInterceptors; |
| 838 for (Set<ClassElement> classes in specializedGetInterceptors.values) { | 840 for (Set<ClassElement> classes in specializedGetInterceptors.values) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 // generating the interceptor methods. | 918 // generating the interceptor methods. |
| 917 Holder holder = _registry.registerHolder(holderName); | 919 Holder holder = _registry.registerHolder(holderName); |
| 918 | 920 |
| 919 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); | 921 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); |
| 920 return names.map((js.Name name) { | 922 return names.map((js.Name name) { |
| 921 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 923 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
| 922 return new StaticStubMethod(name, holder, code); | 924 return new StaticStubMethod(name, holder, code); |
| 923 }); | 925 }); |
| 924 } | 926 } |
| 925 | 927 |
| 926 StaticDartMethod _buildStaticMethod(FunctionElement element) { | 928 StaticDartMethod _buildStaticMethod(MethodElement element) { |
| 927 js.Name name = namer.methodPropertyName(element); | 929 js.Name name = namer.methodPropertyName(element); |
| 928 String holder = namer.globalObjectFor(element); | 930 String holder = namer.globalObjectFor(element); |
| 929 js.Expression code = backend.generatedCode[element]; | 931 js.Expression code = backend.generatedCode[element]; |
| 930 | 932 |
| 931 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 933 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
| 932 bool canBeApplied = _methodCanBeApplied(element); | 934 bool canBeApplied = _methodCanBeApplied(element); |
| 933 bool canBeReflected = _methodCanBeReflected(element); | 935 bool canBeReflected = _methodCanBeReflected(element); |
| 934 | 936 |
| 935 bool needsTearOff = isApplyTarget && | 937 bool needsTearOff = isApplyTarget && |
| 936 (canBeReflected || | 938 (canBeReflected || |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 Constant constant = new Constant(name, holder, constantValue); | 991 Constant constant = new Constant(name, holder, constantValue); |
| 990 _constants[constantValue] = constant; | 992 _constants[constantValue] = constant; |
| 991 } | 993 } |
| 992 } | 994 } |
| 993 | 995 |
| 994 Holder _registerStaticStateHolder() { | 996 Holder _registerStaticStateHolder() { |
| 995 return _registry.registerHolder(namer.staticStateHolder, | 997 return _registry.registerHolder(namer.staticStateHolder, |
| 996 isStaticStateHolder: true); | 998 isStaticStateHolder: true); |
| 997 } | 999 } |
| 998 } | 1000 } |
| OLD | NEW |