| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.startup_emitter.model_emitter; | 5 part of dart2js.js_emitter.startup_emitter.model_emitter; |
| 6 | 6 |
| 7 /// The name of the property that stores the tear-off getter on a static | 7 /// The name of the property that stores the tear-off getter on a static |
| 8 /// function. | 8 /// function. |
| 9 /// | 9 /// |
| 10 /// This property is only used when isolates are used. | 10 /// This property is only used when isolates are used. |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 inheritCalls | 922 inheritCalls |
| 923 .add(js.js.statement('# = #', [temp, superclassReference])); | 923 .add(js.js.statement('# = #', [temp, superclassReference])); |
| 924 } | 924 } |
| 925 for (Class cls in list) { | 925 for (Class cls in list) { |
| 926 inheritCalls.add( | 926 inheritCalls.add( |
| 927 js.js.statement('inherit(#, #)', [classReference(cls), temp])); | 927 js.js.statement('inherit(#, #)', [classReference(cls), temp])); |
| 928 } | 928 } |
| 929 } | 929 } |
| 930 } | 930 } |
| 931 | 931 |
| 932 return wrapPhase( | 932 return wrapPhase('inheritance', inheritCalls.toList()..addAll(mixinCalls)); |
| 933 'inheritance', js.js.statement('{#; #;}', [inheritCalls, mixinCalls])); | |
| 934 } | 933 } |
| 935 | 934 |
| 936 /// Emits the setup of method aliases. | 935 /// Emits the setup of method aliases. |
| 937 /// | 936 /// |
| 938 /// This step consists of simply copying JavaScript functions to their | 937 /// This step consists of simply copying JavaScript functions to their |
| 939 /// aliased names so they point to the same function. | 938 /// aliased names so they point to the same function. |
| 940 js.Statement emitInstanceMethodAliases(Fragment fragment) { | 939 js.Statement emitInstanceMethodAliases(Fragment fragment) { |
| 941 List<js.Statement> assignments = <js.Statement>[]; | 940 List<js.Statement> assignments = <js.Statement>[]; |
| 942 | 941 |
| 943 for (Library library in fragment.libraries) { | 942 for (Library library in fragment.libraries) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 "optionalParameterDefaultValues": optionalParameterDefaultValues, | 1053 "optionalParameterDefaultValues": optionalParameterDefaultValues, |
| 1055 "callNames": callNameArray, | 1054 "callNames": callNameArray, |
| 1056 "funsOrNames": funsOrNamesArray, | 1055 "funsOrNames": funsOrNamesArray, |
| 1057 "funType": method.functionType, | 1056 "funType": method.functionType, |
| 1058 }); | 1057 }); |
| 1059 } | 1058 } |
| 1060 | 1059 |
| 1061 /// Wraps the statement in a named function to that it shows up as a unit in | 1060 /// Wraps the statement in a named function to that it shows up as a unit in |
| 1062 /// profiles. | 1061 /// profiles. |
| 1063 // TODO(sra): Should this be conditional? | 1062 // TODO(sra): Should this be conditional? |
| 1064 js.Statement wrapPhase(String name, js.Statement statement) { | 1063 js.Statement wrapPhase(String name, List<js.Statement> statements) { |
| 1065 return js.js.statement('(function #(){#})();', [name, statement]); | 1064 js.Block block = new js.Block(statements); |
| 1065 if (statements.isEmpty) return block; |
| 1066 return js.js.statement('(function #(){#})();', [name, block]); |
| 1066 } | 1067 } |
| 1067 | 1068 |
| 1068 /// Emits the section that installs tear-off getters. | 1069 /// Emits the section that installs tear-off getters. |
| 1069 js.Statement emitInstallTearOffs(Fragment fragment) { | 1070 js.Statement emitInstallTearOffs(Fragment fragment) { |
| 1070 List<js.Statement> inits = <js.Statement>[]; | 1071 List<js.Statement> inits = <js.Statement>[]; |
| 1071 js.Expression temp; | 1072 js.Expression temp; |
| 1072 | 1073 |
| 1073 for (Library library in fragment.libraries) { | 1074 for (Library library in fragment.libraries) { |
| 1074 for (StaticMethod method in library.statics) { | 1075 for (StaticMethod method in library.statics) { |
| 1075 // TODO(floitsch): can there be anything else than a StaticDartMethod? | 1076 // TODO(floitsch): can there be anything else than a StaticDartMethod? |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1092 } | 1093 } |
| 1093 // First call uses assignment to temp to cache the container. | 1094 // First call uses assignment to temp to cache the container. |
| 1094 reference = js.js('# = #', [temp, container]); | 1095 reference = js.js('# = #', [temp, container]); |
| 1095 } | 1096 } |
| 1096 for (InstanceMethod method in methods) { | 1097 for (InstanceMethod method in methods) { |
| 1097 inits.add(emitInstallTearOff(reference, method)); | 1098 inits.add(emitInstallTearOff(reference, method)); |
| 1098 reference = temp; // Second and subsequent calls use temp. | 1099 reference = temp; // Second and subsequent calls use temp. |
| 1099 } | 1100 } |
| 1100 } | 1101 } |
| 1101 } | 1102 } |
| 1102 return wrapPhase('installTearOffs', new js.Block(inits)); | 1103 return wrapPhase('installTearOffs', inits); |
| 1103 } | 1104 } |
| 1104 | 1105 |
| 1105 /// Emits the constants section. | 1106 /// Emits the constants section. |
| 1106 js.Statement emitConstants(Fragment fragment) { | 1107 js.Statement emitConstants(Fragment fragment) { |
| 1107 List<js.Statement> assignments = <js.Statement>[]; | 1108 List<js.Statement> assignments = <js.Statement>[]; |
| 1108 for (Constant constant in fragment.constants) { | 1109 for (Constant constant in fragment.constants) { |
| 1109 // TODO(floitsch): instead of just updating the constant holder, we should | 1110 // TODO(floitsch): instead of just updating the constant holder, we should |
| 1110 // find the constants that don't have any dependency on other constants | 1111 // find the constants that don't have any dependency on other constants |
| 1111 // and create an object-literal with them (and assign it to the | 1112 // and create an object-literal with them (and assign it to the |
| 1112 // constant-holder variable). | 1113 // constant-holder variable). |
| 1113 var assignment = js.js.statement('#.# = #', [ | 1114 var assignment = js.js.statement('#.# = #', [ |
| 1114 constant.holder.name, | 1115 constant.holder.name, |
| 1115 constant.name, | 1116 constant.name, |
| 1116 constantEmitter.generate(constant.value) | 1117 constantEmitter.generate(constant.value) |
| 1117 ]); | 1118 ]); |
| 1118 compiler.dumpInfoTask.registerConstantAst(constant.value, assignment); | 1119 compiler.dumpInfoTask.registerConstantAst(constant.value, assignment); |
| 1119 assignments.add(assignment); | 1120 assignments.add(assignment); |
| 1120 } | 1121 } |
| 1121 return wrapPhase('constants', new js.Block(assignments)); | 1122 return wrapPhase('constants', assignments); |
| 1122 } | 1123 } |
| 1123 | 1124 |
| 1124 /// Emits the static non-final fields section. | 1125 /// Emits the static non-final fields section. |
| 1125 /// | 1126 /// |
| 1126 /// This section initializes all static non-final fields that don't require | 1127 /// This section initializes all static non-final fields that don't require |
| 1127 /// an initializer. | 1128 /// an initializer. |
| 1128 js.Statement emitStaticNonFinalFields(Fragment fragment) { | 1129 js.Statement emitStaticNonFinalFields(Fragment fragment) { |
| 1129 List<StaticField> fields = fragment.staticNonFinalFields; | 1130 List<StaticField> fields = fragment.staticNonFinalFields; |
| 1130 // TODO(floitsch): instead of assigning the fields one-by-one we should | 1131 // TODO(floitsch): instead of assigning the fields one-by-one we should |
| 1131 // create a literal and assign it to the static-state holder. | 1132 // create a literal and assign it to the static-state holder. |
| 1132 // TODO(floitsch): if we don't make a literal we should at least initialize | 1133 // TODO(floitsch): if we don't make a literal we should at least initialize |
| 1133 // statics that have the same initial value in the same expression: | 1134 // statics that have the same initial value in the same expression: |
| 1134 // `$.x = $.y = $.z = null;`. | 1135 // `$.x = $.y = $.z = null;`. |
| 1135 Iterable<js.Statement> statements = fields.map((StaticField field) { | 1136 Iterable<js.Statement> statements = fields.map((StaticField field) { |
| 1136 assert(field.holder.isStaticStateHolder); | 1137 assert(field.holder.isStaticStateHolder); |
| 1137 return js.js | 1138 return js.js |
| 1138 .statement("#.# = #;", [field.holder.name, field.name, field.code]); | 1139 .statement("#.# = #;", [field.holder.name, field.name, field.code]); |
| 1139 }); | 1140 }); |
| 1140 return wrapPhase('staticFields', new js.Block(statements.toList())); | 1141 return wrapPhase('staticFields', statements.toList()); |
| 1141 } | 1142 } |
| 1142 | 1143 |
| 1143 /// Emits lazy fields. | 1144 /// Emits lazy fields. |
| 1144 /// | 1145 /// |
| 1145 /// This section initializes all static (final and non-final) fields that | 1146 /// This section initializes all static (final and non-final) fields that |
| 1146 /// require an initializer. | 1147 /// require an initializer. |
| 1147 js.Statement emitLazilyInitializedStatics(Fragment fragment) { | 1148 js.Statement emitLazilyInitializedStatics(Fragment fragment) { |
| 1148 List<StaticField> fields = fragment.staticLazilyInitializedFields; | 1149 List<StaticField> fields = fragment.staticLazilyInitializedFields; |
| 1149 Iterable<js.Statement> statements = fields.map((StaticField field) { | 1150 Iterable<js.Statement> statements = fields.map((StaticField field) { |
| 1150 assert(field.holder.isStaticStateHolder); | 1151 assert(field.holder.isStaticStateHolder); |
| 1151 return js.js.statement("lazy(#, #, #, #);", [ | 1152 return js.js.statement("lazy(#, #, #, #);", [ |
| 1152 field.holder.name, | 1153 field.holder.name, |
| 1153 js.quoteName(field.name), | 1154 js.quoteName(field.name), |
| 1154 js.quoteName(namer.deriveLazyInitializerName(field.name)), | 1155 js.quoteName(namer.deriveLazyInitializerName(field.name)), |
| 1155 field.code | 1156 field.code |
| 1156 ]); | 1157 ]); |
| 1157 }); | 1158 }); |
| 1158 | 1159 |
| 1159 return wrapPhase('lazyInitializers', new js.Block(statements.toList())); | 1160 return wrapPhase('lazyInitializers', statements.toList()); |
| 1160 } | 1161 } |
| 1161 | 1162 |
| 1162 /// Emits the embedded globals that are needed for deferred loading. | 1163 /// Emits the embedded globals that are needed for deferred loading. |
| 1163 /// | 1164 /// |
| 1164 /// This function is only invoked for the main fragment. | 1165 /// This function is only invoked for the main fragment. |
| 1165 /// | 1166 /// |
| 1166 /// The [loadMap] contains a map from load-ids (for each deferred library) | 1167 /// The [loadMap] contains a map from load-ids (for each deferred library) |
| 1167 /// to the list of generated fragments that must be installed when the | 1168 /// to the list of generated fragments that must be installed when the |
| 1168 /// deferred library is loaded. | 1169 /// deferred library is loaded. |
| 1169 Iterable<js.Property> emitEmbeddedGlobalsForDeferredLoading( | 1170 Iterable<js.Property> emitEmbeddedGlobalsForDeferredLoading( |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 } | 1464 } |
| 1464 } | 1465 } |
| 1465 } | 1466 } |
| 1466 } | 1467 } |
| 1467 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1468 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
| 1468 js.objectLiteral(interceptorsByTag))); | 1469 js.objectLiteral(interceptorsByTag))); |
| 1469 statements.add( | 1470 statements.add( |
| 1470 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); | 1471 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); |
| 1471 statements.addAll(subclassAssignments); | 1472 statements.addAll(subclassAssignments); |
| 1472 | 1473 |
| 1473 return wrapPhase('nativeSupport', new js.Block(statements)); | 1474 return wrapPhase('nativeSupport', statements); |
| 1474 } | 1475 } |
| 1475 } | 1476 } |
| OLD | NEW |