Chromium Code Reviews| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 | 77 |
| 78 /** | 78 /** |
| 79 * Accumulate properties for classes and libraries, describing their | 79 * Accumulate properties for classes and libraries, describing their |
| 80 * static/top-level members. | 80 * static/top-level members. |
| 81 * Later, these members are emitted when the class or library is emitted. | 81 * Later, these members are emitted when the class or library is emitted. |
| 82 * | 82 * |
| 83 * See [getElementDescriptor]. | 83 * See [getElementDescriptor]. |
| 84 */ | 84 */ |
| 85 // TODO(ahe): Generate statics with their class, and store only libraries in | 85 // TODO(ahe): Generate statics with their class, and store only libraries in |
| 86 // this map. | 86 // this map. |
| 87 final Map<Element, ClassBuilder> elementDescriptors = | 87 final Map<Fragment, Map<Element, ClassBuilder>> elementDescriptors = |
| 88 new Map<Element, ClassBuilder>(); | 88 new Map<Fragment, Map<Element, ClassBuilder>>(); |
| 89 | 89 |
| 90 final bool generateSourceMap; | 90 final bool generateSourceMap; |
| 91 | 91 |
| 92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) | 92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) |
| 93 : this.compiler = compiler, | 93 : this.compiler = compiler, |
| 94 this.namer = namer, | 94 this.namer = namer, |
| 95 cachedEmittedConstants = compiler.cacheStrategy.newSet(), | 95 cachedEmittedConstants = compiler.cacheStrategy.newSet(), |
| 96 cachedClassBuilders = compiler.cacheStrategy.newMap(), | 96 cachedClassBuilders = compiler.cacheStrategy.newMap(), |
| 97 cachedElements = compiler.cacheStrategy.newSet() { | 97 cachedElements = compiler.cacheStrategy.newSet() { |
| 98 constantEmitter = new ConstantEmitter( | 98 constantEmitter = new ConstantEmitter( |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 var \$desc; | 427 var \$desc; |
| 428 #; | 428 #; |
| 429 return #; | 429 return #; |
| 430 };''', | 430 };''', |
| 431 [generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), | 431 [generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), |
| 432 cspPrecompiledFunctionFor(outputUnit), | 432 cspPrecompiledFunctionFor(outputUnit), |
| 433 new jsAst.ArrayInitializer( | 433 new jsAst.ArrayInitializer( |
| 434 cspPrecompiledConstructorNamesFor(outputUnit))]); | 434 cspPrecompiledConstructorNamesFor(outputUnit))]); |
| 435 } | 435 } |
| 436 | 436 |
| 437 void emitClass(Class cls, ClassBuilder enclosingBuilder) { | 437 void assembleClass(Class cls, ClassBuilder enclosingBuilder, |
| 438 Fragment fragment) { | |
| 438 ClassElement classElement = cls.element; | 439 ClassElement classElement = cls.element; |
| 439 compiler.withCurrentElement(classElement, () { | 440 compiler.withCurrentElement(classElement, () { |
| 440 if (compiler.hasIncrementalSupport) { | 441 if (compiler.hasIncrementalSupport) { |
| 441 ClassBuilder cachedBuilder = | 442 ClassBuilder cachedBuilder = |
| 442 cachedClassBuilders.putIfAbsent(classElement, () { | 443 cachedClassBuilders.putIfAbsent(classElement, () { |
| 443 ClassBuilder builder = new ClassBuilder(classElement, namer); | 444 ClassBuilder builder = new ClassBuilder(classElement, namer); |
| 444 classEmitter.emitClass(cls, builder); | 445 classEmitter.emitClass(cls, builder, fragment); |
| 445 return builder; | 446 return builder; |
| 446 }); | 447 }); |
| 447 invariant(classElement, cachedBuilder.fields.isEmpty); | 448 invariant(classElement, cachedBuilder.fields.isEmpty); |
| 448 invariant(classElement, cachedBuilder.superName == null); | 449 invariant(classElement, cachedBuilder.superName == null); |
| 449 invariant(classElement, cachedBuilder.functionType == null); | 450 invariant(classElement, cachedBuilder.functionType == null); |
| 450 invariant(classElement, cachedBuilder.fieldMetadata == null); | 451 invariant(classElement, cachedBuilder.fieldMetadata == null); |
| 451 enclosingBuilder.properties.addAll(cachedBuilder.properties); | 452 enclosingBuilder.properties.addAll(cachedBuilder.properties); |
| 452 } else { | 453 } else { |
| 453 classEmitter.emitClass(cls, enclosingBuilder); | 454 classEmitter.emitClass(cls, enclosingBuilder, fragment); |
| 454 } | 455 } |
| 455 }); | 456 }); |
| 456 } | 457 } |
| 457 | 458 |
| 458 void emitStaticFunctions(Iterable<Method> staticFunctions) { | 459 void assembleStaticFunctions(Iterable<Method> staticFunctions, |
| 460 Fragment fragment) { | |
|
karlklose
2015/04/17 11:26:10
Align parameter.
herhut
2015/04/17 11:37:30
Done.
| |
| 459 if (staticFunctions == null) return; | 461 if (staticFunctions == null) return; |
| 460 | 462 |
| 461 for (Method method in staticFunctions) { | 463 for (Method method in staticFunctions) { |
| 462 Element element = method.element; | 464 Element element = method.element; |
| 463 // We need to filter out null-elements for the interceptors. | 465 // We need to filter out null-elements for the interceptors. |
| 464 // TODO(floitsch): use the precomputed interceptors here. | 466 // TODO(floitsch): use the precomputed interceptors here. |
| 465 if (element == null) continue; | 467 if (element == null) continue; |
| 466 ClassBuilder builder = new ClassBuilder(element, namer); | 468 ClassBuilder builder = new ClassBuilder(element, namer); |
| 467 containerBuilder.addMemberMethod(method, builder); | 469 containerBuilder.addMemberMethod(method, builder); |
| 468 getElementDescriptor(element).properties.addAll(builder.properties); | 470 getElementDescriptor(element, fragment).properties |
| 471 .addAll(builder.properties); | |
| 469 } | 472 } |
| 470 } | 473 } |
| 471 | 474 |
| 472 void emitStaticNonFinalFieldInitializations(CodeOutput output, | 475 void emitStaticNonFinalFieldInitializations(CodeOutput output, |
| 473 OutputUnit outputUnit) { | 476 OutputUnit outputUnit) { |
| 474 void emitInitialization(Element element, jsAst.Expression initialValue) { | 477 void emitInitialization(Element element, jsAst.Expression initialValue) { |
| 475 jsAst.Expression init = | 478 jsAst.Expression init = |
| 476 js('$isolateProperties.# = #', | 479 js('$isolateProperties.# = #', |
| 477 [namer.globalPropertyName(element), initialValue]); | 480 [namer.globalPropertyName(element), initialValue]); |
| 478 output.addBuffer(jsAst.prettyPrint(init, compiler, | 481 output.addBuffer(jsAst.prettyPrint(init, compiler, |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 944 return object.__proto__ && | 947 return object.__proto__ && |
| 945 object.__proto__.p === cls.prototype.p; | 948 object.__proto__.p === cls.prototype.p; |
| 946 })(); | 949 })(); |
| 947 '''); | 950 '''); |
| 948 } | 951 } |
| 949 | 952 |
| 950 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); | 953 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); |
| 951 output.add(N); | 954 output.add(N); |
| 952 } | 955 } |
| 953 | 956 |
| 954 void writeLibraryDescriptor(CodeOutput output, LibraryElement library) { | 957 void writeLibraryDescriptor(CodeOutput output, LibraryElement library, |
| 958 Fragment fragment) { | |
| 955 var uri = ""; | 959 var uri = ""; |
| 956 if (!compiler.enableMinification || backend.mustPreserveUris) { | 960 if (!compiler.enableMinification || backend.mustPreserveUris) { |
| 957 uri = library.canonicalUri; | 961 uri = library.canonicalUri; |
| 958 if (uri.scheme == 'file' && compiler.outputUri != null) { | 962 if (uri.scheme == 'file' && compiler.outputUri != null) { |
| 959 uri = relativize(compiler.outputUri, library.canonicalUri, false); | 963 uri = relativize(compiler.outputUri, library.canonicalUri, false); |
| 960 } | 964 } |
| 961 } | 965 } |
| 962 ClassBuilder descriptor = elementDescriptors[library]; | 966 ClassBuilder descriptor = elementDescriptors[fragment][library]; |
| 963 if (descriptor == null) { | 967 if (descriptor == null) { |
| 964 // Nothing of the library was emitted. | 968 // Nothing of the library was emitted. |
| 965 // TODO(floitsch): this should not happen. We currently have an example | 969 // TODO(floitsch): this should not happen. We currently have an example |
| 966 // with language/prefix6_negative_test.dart where we have an instance | 970 // with language/prefix6_negative_test.dart where we have an instance |
| 967 // method without its corresponding class. | 971 // method without its corresponding class. |
| 968 return; | 972 return; |
| 969 } | 973 } |
| 970 | 974 |
| 971 String libraryName = | 975 String libraryName = |
| 972 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? | 976 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 991 ..add(',$_') | 995 ..add(',$_') |
| 992 ..add(namer.globalObjectFor(library)) | 996 ..add(namer.globalObjectFor(library)) |
| 993 ..add(',$_') | 997 ..add(',$_') |
| 994 ..addBuffer(jsAst.prettyPrint(initializers, | 998 ..addBuffer(jsAst.prettyPrint(initializers, |
| 995 compiler, | 999 compiler, |
| 996 monitor: compiler.dumpInfoTask)) | 1000 monitor: compiler.dumpInfoTask)) |
| 997 ..add(library == compiler.mainApp ? ',${n}1' : "") | 1001 ..add(library == compiler.mainApp ? ',${n}1' : "") |
| 998 ..add('],$n'); | 1002 ..add('],$n'); |
| 999 } | 1003 } |
| 1000 | 1004 |
| 1001 void emitPrecompiledConstructor(OutputUnit outputUnit, | 1005 void assemblePrecompiledConstructor(OutputUnit outputUnit, |
| 1002 String constructorName, | 1006 String constructorName, |
|
karlklose
2015/04/17 11:26:10
Align parameters.
herhut
2015/04/17 11:37:30
Done.
| |
| 1003 jsAst.Expression constructorAst, | 1007 jsAst.Expression constructorAst, |
| 1004 List<String> fields) { | 1008 List<String> fields) { |
| 1005 cspPrecompiledFunctionFor(outputUnit).add( | 1009 cspPrecompiledFunctionFor(outputUnit).add( |
| 1006 new jsAst.FunctionDeclaration( | 1010 new jsAst.FunctionDeclaration( |
| 1007 new jsAst.VariableDeclaration(constructorName), constructorAst)); | 1011 new jsAst.VariableDeclaration(constructorName), constructorAst)); |
| 1008 | 1012 |
| 1009 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; | 1013 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; |
| 1010 bool hasIsolateSupport = compiler.hasIsolateSupport; | 1014 bool hasIsolateSupport = compiler.hasIsolateSupport; |
| 1011 jsAst.Node fieldNamesArray = | 1015 jsAst.Node fieldNamesArray = |
| 1012 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull(); | 1016 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1024 } | 1028 } |
| 1025 }''', | 1029 }''', |
| 1026 {"constructorName": constructorName, | 1030 {"constructorName": constructorName, |
| 1027 "constructorNameString": js.string(constructorName), | 1031 "constructorNameString": js.string(constructorName), |
| 1028 "hasIsolateSupport": hasIsolateSupport, | 1032 "hasIsolateSupport": hasIsolateSupport, |
| 1029 "fieldNamesArray": fieldNamesArray})); | 1033 "fieldNamesArray": fieldNamesArray})); |
| 1030 | 1034 |
| 1031 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); | 1035 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); |
| 1032 } | 1036 } |
| 1033 | 1037 |
| 1034 void emitTypedefs() { | 1038 void assembleTypedefs(Program program) { |
| 1035 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; | 1039 Fragment mainFragment = program.mainFragment; |
| 1040 OutputUnit mainOutputUnit = mainFragment.outputUnit; | |
| 1036 | 1041 |
| 1037 // Emit all required typedef declarations into the main output unit. | 1042 // Emit all required typedef declarations into the main output unit. |
| 1038 // TODO(karlklose): unify required classes and typedefs to declarations | 1043 // TODO(karlklose): unify required classes and typedefs to declarations |
| 1039 // and have builders for each kind. | 1044 // and have builders for each kind. |
| 1040 for (TypedefElement typedef in typedefsNeededForReflection) { | 1045 for (TypedefElement typedef in typedefsNeededForReflection) { |
| 1041 LibraryElement library = typedef.library; | 1046 LibraryElement library = typedef.library; |
| 1042 // TODO(karlklose): add a TypedefBuilder and move this code there. | 1047 // TODO(karlklose): add a TypedefBuilder and move this code there. |
| 1043 DartType type = typedef.alias; | 1048 DartType type = typedef.alias; |
| 1044 int typeIndex = task.metadataCollector.reifyType(type); | 1049 int typeIndex = task.metadataCollector.reifyType(type); |
| 1045 ClassBuilder builder = new ClassBuilder(typedef, namer); | 1050 ClassBuilder builder = new ClassBuilder(typedef, namer); |
| 1046 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, | 1051 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, |
| 1047 js.number(typeIndex)); | 1052 js.number(typeIndex)); |
| 1048 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, | 1053 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, |
| 1049 js.boolean(true)); | 1054 js.boolean(true)); |
| 1050 | 1055 |
| 1051 // We can be pretty sure that the objectClass is initialized, since | 1056 // We can be pretty sure that the objectClass is initialized, since |
| 1052 // typedefs are only emitted with reflection, which requires lots of | 1057 // typedefs are only emitted with reflection, which requires lots of |
| 1053 // classes. | 1058 // classes. |
| 1054 assert(compiler.objectClass != null); | 1059 assert(compiler.objectClass != null); |
| 1055 builder.superName = namer.className(compiler.objectClass); | 1060 builder.superName = namer.className(compiler.objectClass); |
| 1056 jsAst.Node declaration = builder.toObjectInitializer(); | 1061 jsAst.Node declaration = builder.toObjectInitializer(); |
| 1057 String mangledName = namer.globalPropertyName(typedef); | 1062 String mangledName = namer.globalPropertyName(typedef); |
| 1058 String reflectionName = getReflectionName(typedef, mangledName); | 1063 String reflectionName = getReflectionName(typedef, mangledName); |
| 1059 getElementDescriptor(library) | 1064 getElementDescriptor(library, mainFragment) |
| 1060 ..addProperty(mangledName, declaration) | 1065 ..addProperty(mangledName, declaration) |
| 1061 ..addProperty("+$reflectionName", js.string('')); | 1066 ..addProperty("+$reflectionName", js.string('')); |
| 1062 // Also emit a trivial constructor for CSP mode. | 1067 // Also emit a trivial constructor for CSP mode. |
| 1063 String constructorName = mangledName; | 1068 String constructorName = mangledName; |
| 1064 jsAst.Expression constructorAst = js('function() {}'); | 1069 jsAst.Expression constructorAst = js('function() {}'); |
| 1065 List<String> fieldNames = []; | 1070 List<String> fieldNames = []; |
| 1066 emitPrecompiledConstructor(mainOutputUnit, | 1071 assemblePrecompiledConstructor(mainOutputUnit, |
|
karlklose
2015/04/17 11:26:10
Align arguments.
herhut
2015/04/17 11:37:30
Done.
| |
| 1067 constructorName, | 1072 constructorName, |
| 1068 constructorAst, | 1073 constructorAst, |
| 1069 fieldNames); | 1074 fieldNames); |
| 1070 } | 1075 } |
| 1071 } | 1076 } |
| 1072 | 1077 |
| 1073 void emitMangledNames(CodeOutput output) { | 1078 void emitMangledNames(CodeOutput output) { |
| 1074 if (!mangledFieldNames.isEmpty) { | 1079 if (!mangledFieldNames.isEmpty) { |
| 1075 var keys = mangledFieldNames.keys.toList(); | 1080 var keys = mangledFieldNames.keys.toList(); |
| 1076 keys.sort(); | 1081 keys.sort(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1124 compiler.reportInfo( | 1129 compiler.reportInfo( |
| 1125 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); | 1130 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); |
| 1126 } | 1131 } |
| 1127 | 1132 |
| 1128 if (pendingStatics != null && !pendingStatics.isEmpty) { | 1133 if (pendingStatics != null && !pendingStatics.isEmpty) { |
| 1129 compiler.internalError(pendingStatics.first, | 1134 compiler.internalError(pendingStatics.first, |
| 1130 'Pending statics (see above).'); | 1135 'Pending statics (see above).'); |
| 1131 } | 1136 } |
| 1132 } | 1137 } |
| 1133 | 1138 |
| 1134 void emitLibrary(Library library) { | 1139 void assembleLibrary(Library library, Fragment fragment) { |
| 1135 LibraryElement libraryElement = library.element; | 1140 LibraryElement libraryElement = library.element; |
| 1136 | 1141 |
| 1137 emitStaticFunctions(library.statics); | 1142 assembleStaticFunctions(library.statics, fragment); |
| 1138 | 1143 |
| 1139 ClassBuilder libraryBuilder = getElementDescriptor(libraryElement); | 1144 ClassBuilder libraryBuilder = |
| 1145 getElementDescriptor(libraryElement, fragment); | |
| 1140 for (Class cls in library.classes) { | 1146 for (Class cls in library.classes) { |
| 1141 emitClass(cls, libraryBuilder); | 1147 assembleClass(cls, libraryBuilder, fragment); |
| 1142 } | 1148 } |
| 1143 | 1149 |
| 1144 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); | 1150 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); |
| 1145 } | 1151 } |
| 1146 | 1152 |
| 1153 void assembleProgram(Program program) { | |
| 1154 for (Fragment fragment in program.fragments) { | |
| 1155 for (Library library in fragment.libraries) { | |
| 1156 assembleLibrary(library, fragment); | |
| 1157 } | |
| 1158 } | |
| 1159 assembleTypedefs(program); | |
| 1160 } | |
| 1161 | |
| 1147 void emitMainOutputUnit(Program program, | 1162 void emitMainOutputUnit(Program program, |
| 1148 Map<OutputUnit, String> deferredLoadHashes) { | 1163 Map<OutputUnit, String> deferredLoadHashes) { |
| 1149 MainFragment mainFragment = program.fragments.first; | 1164 MainFragment mainFragment = program.fragments.first; |
| 1150 OutputUnit mainOutputUnit = mainFragment.outputUnit; | 1165 OutputUnit mainOutputUnit = mainFragment.outputUnit; |
| 1151 | 1166 |
| 1152 LineColumnCollector lineColumnCollector; | 1167 LineColumnCollector lineColumnCollector; |
| 1153 List<CodeOutputListener> codeOutputListeners; | 1168 List<CodeOutputListener> codeOutputListeners; |
| 1154 if (generateSourceMap) { | 1169 if (generateSourceMap) { |
| 1155 lineColumnCollector = new LineColumnCollector(); | 1170 lineColumnCollector = new LineColumnCollector(); |
| 1156 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; | 1171 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1236 mainOutput.add( | 1251 mainOutput.add( |
| 1237 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N' | 1252 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N' |
| 1238 '${globalsHolder}.$initName$_=${_}$initName$N' | 1253 '${globalsHolder}.$initName$_=${_}$initName$N' |
| 1239 '${globalsHolder}.$setupProgramName$_=$_' | 1254 '${globalsHolder}.$setupProgramName$_=$_' |
| 1240 '$setupProgramName$N'); | 1255 '$setupProgramName$N'); |
| 1241 } | 1256 } |
| 1242 mainOutput.add('init()$N$n'); | 1257 mainOutput.add('init()$N$n'); |
| 1243 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N'); | 1258 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N'); |
| 1244 | 1259 |
| 1245 emitFunctionThatReturnsNull(mainOutput); | 1260 emitFunctionThatReturnsNull(mainOutput); |
| 1246 mainFragment.libraries.forEach(emitLibrary); | |
| 1247 | 1261 |
| 1248 Iterable<LibraryElement> libraries = | 1262 Iterable<LibraryElement> libraries = |
| 1249 task.outputLibraryLists[mainOutputUnit]; | 1263 task.outputLibraryLists[mainOutputUnit]; |
| 1250 if (libraries == null) libraries = []; | 1264 if (libraries == null) libraries = []; |
| 1251 emitTypedefs(); | |
| 1252 emitMangledNames(mainOutput); | 1265 emitMangledNames(mainOutput); |
| 1253 | 1266 |
| 1254 checkEverythingEmitted(elementDescriptors.keys); | 1267 Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment]; |
| 1268 checkEverythingEmitted(descriptors.keys); | |
| 1255 | 1269 |
| 1256 CodeBuffer libraryBuffer = new CodeBuffer(); | 1270 CodeBuffer libraryBuffer = new CodeBuffer(); |
| 1257 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1271 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
| 1258 writeLibraryDescriptor(libraryBuffer, library); | 1272 writeLibraryDescriptor(libraryBuffer, library, mainFragment); |
| 1259 elementDescriptors.remove(library); | 1273 descriptors.remove(library); |
| 1260 } | 1274 } |
| 1261 | 1275 |
| 1262 if (elementDescriptors.isNotEmpty) { | 1276 if (descriptors.isNotEmpty) { |
| 1263 List<Element> remainingLibraries = elementDescriptors.keys | 1277 List<Element> remainingLibraries = descriptors.keys |
| 1264 .where((Element e) => e is LibraryElement) | 1278 .where((Element e) => e is LibraryElement) |
| 1265 .toList(); | 1279 .toList(); |
| 1266 | 1280 |
| 1267 // The remaining descriptors are only accessible through reflection. | 1281 // The remaining descriptors are only accessible through reflection. |
| 1268 // The program builder does not collect libraries that only | 1282 // The program builder does not collect libraries that only |
| 1269 // contain typedefs that are used for reflection. | 1283 // contain typedefs that are used for reflection. |
| 1270 for (LibraryElement element in remainingLibraries) { | 1284 for (LibraryElement element in remainingLibraries) { |
| 1271 assert(element is LibraryElement || compiler.hasIncrementalSupport); | 1285 assert(element is LibraryElement || compiler.hasIncrementalSupport); |
| 1272 if (element is LibraryElement) { | 1286 if (element is LibraryElement) { |
| 1273 writeLibraryDescriptor(libraryBuffer, element); | 1287 writeLibraryDescriptor(libraryBuffer, element, mainFragment); |
| 1274 elementDescriptors.remove(element); | 1288 descriptors.remove(element); |
| 1275 } | 1289 } |
| 1276 } | 1290 } |
| 1277 } | 1291 } |
| 1278 | 1292 |
| 1279 bool needsNativeSupport = program.needsNativeSupport; | 1293 bool needsNativeSupport = program.needsNativeSupport; |
| 1280 mainOutput.addBuffer( | 1294 mainOutput.addBuffer( |
| 1281 jsAst.prettyPrint( | 1295 jsAst.prettyPrint( |
| 1282 buildSetupProgram(program, compiler, backend, namer, this), | 1296 buildSetupProgram(program, compiler, backend, namer, this), |
| 1283 compiler)); | 1297 compiler)); |
| 1284 | 1298 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1530 /// itself. | 1544 /// itself. |
| 1531 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { | 1545 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { |
| 1532 if (!program.isSplit) return const {}; | 1546 if (!program.isSplit) return const {}; |
| 1533 | 1547 |
| 1534 Map<OutputUnit, CodeBuffer> outputBuffers = | 1548 Map<OutputUnit, CodeBuffer> outputBuffers = |
| 1535 new Map<OutputUnit, CodeBuffer>(); | 1549 new Map<OutputUnit, CodeBuffer>(); |
| 1536 | 1550 |
| 1537 for (Fragment fragment in program.deferredFragments) { | 1551 for (Fragment fragment in program.deferredFragments) { |
| 1538 OutputUnit outputUnit = fragment.outputUnit; | 1552 OutputUnit outputUnit = fragment.outputUnit; |
| 1539 | 1553 |
| 1554 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment]; | |
| 1540 | 1555 |
| 1541 fragment.libraries.forEach(emitLibrary); | 1556 if (descriptors.isNotEmpty) { |
| 1542 | |
| 1543 if (elementDescriptors.isNotEmpty) { | |
| 1544 Iterable<LibraryElement> libraries = | 1557 Iterable<LibraryElement> libraries = |
| 1545 task.outputLibraryLists[outputUnit]; | 1558 task.outputLibraryLists[outputUnit]; |
| 1546 if (libraries == null) libraries = []; | 1559 if (libraries == null) libraries = []; |
| 1547 | 1560 |
| 1548 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. | 1561 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. |
| 1549 CodeBuffer buffer = new CodeBuffer(); | 1562 CodeBuffer buffer = new CodeBuffer(); |
| 1550 outputBuffers[outputUnit] = buffer; | 1563 outputBuffers[outputUnit] = buffer; |
| 1551 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1564 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
| 1552 writeLibraryDescriptor(buffer, library); | 1565 writeLibraryDescriptor(buffer, library, fragment); |
| 1553 elementDescriptors.remove(library); | 1566 descriptors.remove(library); |
| 1554 } | 1567 } |
| 1555 } | 1568 } |
| 1556 } | 1569 } |
| 1557 | 1570 |
| 1558 return emitDeferredCode(program, outputBuffers); | 1571 return emitDeferredCode(program, outputBuffers); |
| 1559 } | 1572 } |
| 1560 | 1573 |
| 1561 int emitProgram(ProgramBuilder programBuilder) { | 1574 int emitProgram(ProgramBuilder programBuilder) { |
| 1562 Program program = programBuilder.buildProgram( | 1575 Program program = programBuilder.buildProgram( |
| 1563 storeFunctionTypesInMetadata: true); | 1576 storeFunctionTypesInMetadata: true); |
| 1564 | 1577 |
| 1578 assembleProgram(program); | |
| 1579 | |
| 1565 // Shorten the code by using [namer.currentIsolate] as temporary. | 1580 // Shorten the code by using [namer.currentIsolate] as temporary. |
| 1566 isolateProperties = namer.currentIsolate; | 1581 isolateProperties = namer.currentIsolate; |
| 1567 | 1582 |
| 1568 // Emit deferred units first, so we have their hashes. | 1583 // Emit deferred units first, so we have their hashes. |
| 1569 // Map from OutputUnit to a hash of its content. The hash uniquely | 1584 // Map from OutputUnit to a hash of its content. The hash uniquely |
| 1570 // identifies the code of the output-unit. It does not include | 1585 // identifies the code of the output-unit. It does not include |
| 1571 // boilerplate JS code, like the sourcemap directives or the hash | 1586 // boilerplate JS code, like the sourcemap directives or the hash |
| 1572 // itself. | 1587 // itself. |
| 1573 Map<OutputUnit, String> deferredLoadHashes = | 1588 Map<OutputUnit, String> deferredLoadHashes = |
| 1574 emitDeferredOutputUnits(program); | 1589 emitDeferredOutputUnits(program); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1586 if (sourceMapUri != null && fileUri != null) { | 1601 if (sourceMapUri != null && fileUri != null) { |
| 1587 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); | 1602 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); |
| 1588 return ''' | 1603 return ''' |
| 1589 | 1604 |
| 1590 //# sourceMappingURL=$sourceMapFileName | 1605 //# sourceMappingURL=$sourceMapFileName |
| 1591 '''; | 1606 '''; |
| 1592 } | 1607 } |
| 1593 return ''; | 1608 return ''; |
| 1594 } | 1609 } |
| 1595 | 1610 |
| 1596 ClassBuilder getElementDescriptor(Element element) { | 1611 ClassBuilder getElementDescriptor(Element element, Fragment fragment) { |
| 1597 Element owner = element.library; | 1612 Element owner = element.library; |
| 1598 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { | 1613 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { |
| 1599 // For static (not top level) elements, record their code in a buffer | 1614 // For static (not top level) elements, record their code in a buffer |
| 1600 // specific to the class. For now, not supported for native classes and | 1615 // specific to the class. For now, not supported for native classes and |
| 1601 // native elements. | 1616 // native elements. |
| 1602 ClassElement cls = | 1617 ClassElement cls = |
| 1603 element.enclosingClassOrCompilationUnit.declaration; | 1618 element.enclosingClassOrCompilationUnit.declaration; |
| 1604 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) && | 1619 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) && |
| 1605 !cls.isNative && | 1620 !cls.isNative && |
| 1606 compiler.deferredLoadTask.outputUnitForElement(element) == | 1621 compiler.deferredLoadTask.outputUnitForElement(element) == |
| 1607 compiler.deferredLoadTask.outputUnitForElement(cls)) { | 1622 compiler.deferredLoadTask.outputUnitForElement(cls)) { |
| 1608 owner = cls; | 1623 owner = cls; |
| 1609 } | 1624 } |
| 1610 } | 1625 } |
| 1611 if (owner == null) { | 1626 if (owner == null) { |
| 1612 compiler.internalError(element, 'Owner is null.'); | 1627 compiler.internalError(element, 'Owner is null.'); |
| 1613 } | 1628 } |
| 1614 return elementDescriptors.putIfAbsent( | 1629 return elementDescriptors.putIfAbsent( |
|
karlklose
2015/04/17 11:26:10
How about formatting this as:
return elementDesc
herhut
2015/04/17 11:37:30
How about this one?
| |
| 1630 fragment, | |
| 1631 () => new Map<Element, ClassBuilder>()).putIfAbsent( | |
| 1615 owner, | 1632 owner, |
| 1616 () => new ClassBuilder(owner, namer)); | 1633 () => new ClassBuilder(owner, namer)); |
| 1617 } | 1634 } |
| 1618 | 1635 |
| 1619 /// Emits support-code for deferred loading into [output]. | 1636 /// Emits support-code for deferred loading into [output]. |
| 1620 void emitDeferredBoilerPlate(CodeOutput output, | 1637 void emitDeferredBoilerPlate(CodeOutput output, |
| 1621 Map<OutputUnit, String> deferredLoadHashes) { | 1638 Map<OutputUnit, String> deferredLoadHashes) { |
| 1622 jsAst.Statement functions = js.statement(''' | 1639 jsAst.Statement functions = js.statement(''' |
| 1623 { | 1640 { |
| 1624 // Function for checking if a hunk is loaded given its hash. | 1641 // Function for checking if a hunk is loaded given its hash. |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1874 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1891 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 1875 if (element.isInstanceMember) { | 1892 if (element.isInstanceMember) { |
| 1876 cachedClassBuilders.remove(element.enclosingClass); | 1893 cachedClassBuilders.remove(element.enclosingClass); |
| 1877 | 1894 |
| 1878 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1895 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 1879 | 1896 |
| 1880 } | 1897 } |
| 1881 } | 1898 } |
| 1882 } | 1899 } |
| 1883 } | 1900 } |
| OLD | NEW |