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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 | 7 |
8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
9 final Compiler compiler; | 9 final Compiler compiler; |
10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 String get generateAccessorHolder | 151 String get generateAccessorHolder |
152 => '$isolatePropertiesName.\$generateAccessor'; | 152 => '$isolatePropertiesName.\$generateAccessor'; |
153 String get finishClassesProperty | 153 String get finishClassesProperty |
154 => r'$finishClasses'; | 154 => r'$finishClasses'; |
155 String get finishClassesName | 155 String get finishClassesName |
156 => '${namer.isolateName}.$finishClassesProperty'; | 156 => '${namer.isolateName}.$finishClassesProperty'; |
157 String get finishIsolateConstructorName | 157 String get finishIsolateConstructorName |
158 => '${namer.isolateName}.\$finishIsolateConstructor'; | 158 => '${namer.isolateName}.\$finishIsolateConstructor'; |
159 String get isolatePropertiesName | 159 String get isolatePropertiesName |
160 => '${namer.isolateName}.${namer.isolatePropertiesName}'; | 160 => '${namer.isolateName}.${namer.isolatePropertiesName}'; |
161 String get lazyInitializerProperty | |
162 => r'$lazy'; | |
161 String get lazyInitializerName | 163 String get lazyInitializerName |
162 => '${namer.isolateName}.\$lazy'; | 164 => '${namer.isolateName}.${lazyInitializerProperty}'; |
163 String get initName => 'init'; | 165 String get initName => 'init'; |
164 String get makeConstListProperty | 166 String get makeConstListProperty |
165 => namer.getMappedInstanceName('makeConstantList'); | 167 => namer.getMappedInstanceName('makeConstantList'); |
166 | 168 |
167 /// For deferred loading we communicate the initializers via this global var. | 169 /// For deferred loading we communicate the initializers via this global var. |
168 final String deferredInitializers = r"$dart_deferred_initializers"; | 170 final String deferredInitializers = r"$dart_deferred_initializers"; |
169 | 171 |
170 /// All the global state can be passed around with this variable. | 172 /// All the global state can be passed around with this variable. |
171 String get globalsHolder => namer.getMappedGlobalName("globalsHolder"); | 173 String get globalsHolder => namer.getMappedGlobalName("globalsHolder"); |
172 | 174 |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
589 interceptorsByTagAccess, | 591 interceptorsByTagAccess, |
590 leafTagsAccess]); | 592 leafTagsAccess]); |
591 } | 593 } |
592 | 594 |
593 jsAst.Fun get finishIsolateConstructorFunction { | 595 jsAst.Fun get finishIsolateConstructorFunction { |
594 // We replace the old Isolate function with a new one that initializes | 596 // We replace the old Isolate function with a new one that initializes |
595 // all its fields with the initial (and often final) value of all globals. | 597 // all its fields with the initial (and often final) value of all globals. |
596 // | 598 // |
597 // We also copy over old values like the prototype, and the | 599 // We also copy over old values like the prototype, and the |
598 // isolateProperties themselves. | 600 // isolateProperties themselves. |
599 return js(''' | 601 return js( |
602 """ | |
600 function (oldIsolate) { | 603 function (oldIsolate) { |
601 var isolateProperties = oldIsolate.#; // isolatePropertiesName | 604 var isolateProperties = oldIsolate.#isolatePropertiesName; |
602 function Isolate() { | 605 function Isolate() { |
603 var hasOwnProperty = Object.prototype.hasOwnProperty; | 606 var hasOwnProperty = Object.prototype.hasOwnProperty; |
604 for (var staticName in isolateProperties) | 607 for (var staticName in isolateProperties) |
605 if (hasOwnProperty.call(isolateProperties, staticName)) | 608 if (hasOwnProperty.call(isolateProperties, staticName)) |
606 this[staticName] = isolateProperties[staticName]; | 609 this[staticName] = isolateProperties[staticName]; |
607 | 610 |
608 // Reset lazy initializers to null. | 611 // Reset lazy initializers to null. |
609 // When forcing the object to fast mode (below) v8 will consider | 612 // When forcing the object to fast mode (below) v8 will consider |
610 // functions as part the object's map. Since we will change them | 613 // functions as part the object's map. Since we will change them |
611 // (after the first call to the getter), we would have a map | 614 // (after the first call to the getter), we would have a map |
(...skipping 11 matching lines...) Expand all Loading... | |
623 new ForceEfficientMap(); | 626 new ForceEfficientMap(); |
624 | 627 |
625 // Now, after being a fast map we can set the lazies again. | 628 // Now, after being a fast map we can set the lazies again. |
626 for (var lazyInit in lazies) { | 629 for (var lazyInit in lazies) { |
627 var lazyInitName = lazies[lazyInit]; | 630 var lazyInitName = lazies[lazyInit]; |
628 this[lazyInitName] = isolateProperties[lazyInitName]; | 631 this[lazyInitName] = isolateProperties[lazyInitName]; |
629 } | 632 } |
630 } | 633 } |
631 Isolate.prototype = oldIsolate.prototype; | 634 Isolate.prototype = oldIsolate.prototype; |
632 Isolate.prototype.constructor = Isolate; | 635 Isolate.prototype.constructor = Isolate; |
633 Isolate.# = isolateProperties; // isolatePropertiesName | 636 Isolate.#isolatePropertiesName = isolateProperties; |
634 if (#) // needsDefineClass. | 637 if (#needsDefineClass) |
635 Isolate.# = oldIsolate.#; // finishClassesProperty * 2 | 638 Isolate.#finishClassesProperty = oldIsolate.#finishClassesProperty; |
636 if (#) // outputContainsConstantList | 639 if (#outputContainsConstantList) |
637 Isolate.# = oldIsolate.#; // makeConstListProperty * 2 | 640 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; |
638 return Isolate; | 641 if (#hasIncrementalSupport) |
639 }''', | 642 Isolate.#lazyInitializerProperty = oldIsolate.#lazyInitializerProperty ; |
Johnni Winther
2014/12/09 11:53:52
Long line
ahe
2014/12/10 14:00:04
Done.
| |
640 [namer.isolatePropertiesName, namer.isolatePropertiesName, | 643 return Isolate; |
641 needsDefineClass, finishClassesProperty, finishClassesProperty, | 644 } |
642 task.outputContainsConstantList, | 645 """, |
643 makeConstListProperty, makeConstListProperty ]); | 646 { 'isolatePropertiesName': namer.isolatePropertiesName, |
647 'needsDefineClass': needsDefineClass, | |
648 'finishClassesProperty': finishClassesProperty, | |
649 'outputContainsConstantList': task.outputContainsConstantList, | |
650 'makeConstListProperty': makeConstListProperty, | |
651 'hasIncrementalSupport': compiler.hasIncrementalSupport, | |
652 'lazyInitializerProperty': lazyInitializerProperty, | |
653 }); | |
644 } | 654 } |
645 | 655 |
646 jsAst.Fun get lazyInitializerFunction { | 656 jsAst.Fun get lazyInitializerFunction { |
647 String isolate = namer.currentIsolate; | 657 String isolate = namer.currentIsolate; |
648 jsAst.Expression cyclicThrow = | 658 jsAst.Expression cyclicThrow = |
649 namer.elementAccess(backend.getCyclicThrowHelper()); | 659 namer.elementAccess(backend.getCyclicThrowHelper()); |
650 jsAst.Expression laziesAccess = | 660 jsAst.Expression laziesAccess = |
651 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); | 661 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); |
652 | 662 |
653 return js(''' | 663 return js(''' |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
924 } | 934 } |
925 } | 935 } |
926 | 936 |
927 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { | 937 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { |
928 JavaScriptConstantCompiler handler = backend.constants; | 938 JavaScriptConstantCompiler handler = backend.constants; |
929 List<VariableElement> lazyFields = | 939 List<VariableElement> lazyFields = |
930 handler.getLazilyInitializedFieldsForEmission(); | 940 handler.getLazilyInitializedFieldsForEmission(); |
931 if (!lazyFields.isEmpty) { | 941 if (!lazyFields.isEmpty) { |
932 needsLazyInitializer = true; | 942 needsLazyInitializer = true; |
933 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { | 943 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { |
934 jsAst.Expression code = backend.generatedCode[element]; | 944 jsAst.Expression init = |
935 // The code is null if we ended up not needing the lazily | 945 buildLazilyInitializedStaticField(element, isolateProperties); |
936 // initialized field after all because of constant folding | 946 if (init == null) continue; |
937 // before code generation. | 947 buffer.write( |
938 if (code == null) continue; | 948 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask)); |
939 // The code only computes the initial value. We build the lazy-check | |
940 // here: | |
941 // lazyInitializer(prototype, 'name', fieldName, getterName, initial); | |
942 // The name is used for error reporting. The 'initial' must be a | |
943 // closure that constructs the initial value. | |
944 jsAst.Expression init = js('#(#,#,#,#,#)', | |
945 [js(lazyInitializerName), | |
946 js(isolateProperties), | |
947 js.string(element.name), | |
948 js.string(namer.getNameX(element)), | |
949 js.string(namer.getLazyInitializerName(element)), | |
950 code]); | |
951 buffer.write(jsAst.prettyPrint(init, compiler, | |
952 monitor: compiler.dumpInfoTask)); | |
953 buffer.write("$N"); | 949 buffer.write("$N"); |
954 } | 950 } |
955 } | 951 } |
956 } | 952 } |
957 | 953 |
954 jsAst.Expression buildLazilyInitializedStaticField( | |
955 VariableElement element, String isolateProperties) { | |
956 jsAst.Expression code = backend.generatedCode[element]; | |
957 // The code is null if we ended up not needing the lazily | |
958 // initialized field after all because of constant folding | |
959 // before code generation. | |
960 if (code == null) return null; | |
961 // The code only computes the initial value. We build the lazy-check | |
962 // here: | |
963 // lazyInitializer(prototype, 'name', fieldName, getterName, initial); | |
964 // The name is used for error reporting. The 'initial' must be a | |
965 // closure that constructs the initial value. | |
966 return js('#(#,#,#,#,#)', | |
967 [js(lazyInitializerName), | |
968 js(isolateProperties), | |
969 js.string(element.name), | |
970 js.string(namer.getNameX(element)), | |
971 js.string(namer.getLazyInitializerName(element)), | |
972 code]); | |
973 } | |
974 | |
958 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { | 975 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { |
959 if (constant.isFunction) return true; // Already emitted. | 976 if (constant.isFunction) return true; // Already emitted. |
960 if (constant.isPrimitive) return true; // Inlined. | 977 if (constant.isPrimitive) return true; // Inlined. |
961 if (constant.isDummy) return true; // Inlined. | 978 if (constant.isDummy) return true; // Inlined. |
962 // The name is null when the constant is already a JS constant. | 979 // The name is null when the constant is already a JS constant. |
963 // TODO(floitsch): every constant should be registered, so that we can | 980 // TODO(floitsch): every constant should be registered, so that we can |
964 // share the ones that take up too much space (like some strings). | 981 // share the ones that take up too much space (like some strings). |
965 if (namer.constantName(constant) == null) return true; | 982 if (namer.constantName(constant) == null) return true; |
966 return false; | 983 return false; |
967 } | 984 } |
(...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2093 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2110 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
2094 if (element.isInstanceMember) { | 2111 if (element.isInstanceMember) { |
2095 cachedClassBuilders.remove(element.enclosingClass); | 2112 cachedClassBuilders.remove(element.enclosingClass); |
2096 | 2113 |
2097 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2114 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
2098 | 2115 |
2099 } | 2116 } |
2100 } | 2117 } |
2101 } | 2118 } |
2102 } | 2119 } |
OLD | NEW |