Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 830703004: Emit to StreamCodeOutput instead of CodeBuffer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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;
11 11
12 final ContainerBuilder containerBuilder = new ContainerBuilder(); 12 final ContainerBuilder containerBuilder = new ContainerBuilder();
13 final ClassEmitter classEmitter = new ClassEmitter(); 13 final ClassEmitter classEmitter = new ClassEmitter();
14 final NsmEmitter nsmEmitter = new NsmEmitter(); 14 final NsmEmitter nsmEmitter = new NsmEmitter();
15 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter(); 15 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter();
16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); 16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter();
17 final MetadataEmitter metadataEmitter = new MetadataEmitter(); 17 final MetadataEmitter metadataEmitter = new MetadataEmitter();
18 18
19 // TODO(johnniwinther): Wrap these fields in a caching strategy.
19 final Set<ConstantValue> cachedEmittedConstants; 20 final Set<ConstantValue> cachedEmittedConstants;
20 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); 21 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer();
21 final Map<Element, ClassBuilder> cachedClassBuilders; 22 final Map<Element, ClassBuilder> cachedClassBuilders;
22 final Set<Element> cachedElements; 23 final Set<Element> cachedElements;
23 24
24 bool needsClassSupport = false; 25 bool needsClassSupport = false;
25 bool needsMixinSupport = false; 26 bool needsMixinSupport = false;
26 bool needsLazyInitializer = false; 27 bool needsLazyInitializer = false;
27 final Namer namer; 28 final Namer namer;
28 ConstantEmitter constantEmitter; 29 ConstantEmitter constantEmitter;
29 NativeEmitter get nativeEmitter => task.nativeEmitter; 30 NativeEmitter get nativeEmitter => task.nativeEmitter;
30 TypeTestRegistry get typeTestRegistry => task.typeTestRegistry; 31 TypeTestRegistry get typeTestRegistry => task.typeTestRegistry;
31 32
32 // The full code that is written to each hunk part-file. 33 // The full code that is written to each hunk part-file.
33 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); 34 Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
34 final CodeBuffer deferredConstants = new CodeBuffer();
35 35
36 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 36 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
37 well as in the generated code. */ 37 well as in the generated code. */
38 String isolateProperties; 38 String isolateProperties;
39 String classesCollector; 39 String classesCollector;
40 Set<ClassElement> get neededClasses => task.neededClasses; 40 Set<ClassElement> get neededClasses => task.neededClasses;
41 Map<OutputUnit, List<ClassElement>> get outputClassLists 41 Map<OutputUnit, List<ClassElement>> get outputClassLists
42 => task.outputClassLists; 42 => task.outputClassLists;
43 Map<OutputUnit, List<ConstantValue>> get outputConstantLists 43 Map<OutputUnit, List<ConstantValue>> get outputConstantLists
44 => task.outputConstantLists; 44 => task.outputConstantLists;
45 List<ClassElement> get nativeClasses => task.nativeClasses; 45 List<ClassElement> get nativeClasses => task.nativeClasses;
46 final Map<String, String> mangledFieldNames = <String, String>{}; 46 final Map<String, String> mangledFieldNames = <String, String>{};
47 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; 47 final Map<String, String> mangledGlobalFieldNames = <String, String>{};
48 final Set<String> recordedMangledNames = new Set<String>(); 48 final Set<String> recordedMangledNames = new Set<String>();
49 49
50 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties = 50 final Map<ClassElement, Map<String, jsAst.Expression>> additionalProperties =
51 new Map<ClassElement, Map<String, jsAst.Expression>>(); 51 new Map<ClassElement, Map<String, jsAst.Expression>>();
52 52
53 List<TypedefElement> get typedefsNeededForReflection => 53 List<TypedefElement> get typedefsNeededForReflection =>
54 task.typedefsNeededForReflection; 54 task.typedefsNeededForReflection;
55 55
56 JavaScriptBackend get backend => compiler.backend; 56 JavaScriptBackend get backend => compiler.backend;
57 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler; 57 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler;
58 58
59 String get _ => space; 59 String get _ => space;
60 String get space => compiler.enableMinification ? "" : " "; 60 String get space => compiler.enableMinification ? "" : " ";
61 String get n => compiler.enableMinification ? "" : "\n"; 61 String get n => compiler.enableMinification ? "" : "\n";
62 String get N => compiler.enableMinification ? "\n" : ";\n"; 62 String get N => compiler.enableMinification ? "\n" : ";\n";
63 63
64 CodeBuffer getBuffer(OutputUnit outputUnit) {
65 return outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer());
66 }
67
68 CodeBuffer get mainBuffer {
69 return getBuffer(compiler.deferredLoadTask.mainOutputUnit);
70 }
71
72 /** 64 /**
73 * List of expressions and statements that will be included in the 65 * List of expressions and statements that will be included in the
74 * precompiled function. 66 * precompiled function.
75 * 67 *
76 * To save space, dart2js normally generates constructors and accessors 68 * To save space, dart2js normally generates constructors and accessors
77 * dynamically. This doesn't work in CSP mode, so dart2js emits them directly 69 * dynamically. This doesn't work in CSP mode, so dart2js emits them directly
78 * when in CSP mode. 70 * when in CSP mode.
79 */ 71 */
80 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = 72 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions =
81 new Map<OutputUnit, List<jsAst.Node>>(); 73 new Map<OutputUnit, List<jsAst.Node>>();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 () => new List<jsAst.Expression>()); 118 () => new List<jsAst.Expression>());
127 } 119 }
128 120
129 /// Erases the precompiled information for csp mode for all output units. 121 /// Erases the precompiled information for csp mode for all output units.
130 /// Used by the incremental compiler. 122 /// Used by the incremental compiler.
131 void clearCspPrecompiledNodes() { 123 void clearCspPrecompiledNodes() {
132 _cspPrecompiledFunctions.clear(); 124 _cspPrecompiledFunctions.clear();
133 _cspPrecompiledConstructorNames.clear(); 125 _cspPrecompiledConstructorNames.clear();
134 } 126 }
135 127
136 void addComment(String comment, CodeBuffer buffer) { 128 void addComment(String comment, CodeOutput output) {
137 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler)); 129 output.addBuffer(jsAst.prettyPrint(js.comment(comment), compiler));
138 } 130 }
139 131
140 @override 132 @override
141 jsAst.Expression constantReference(ConstantValue value) { 133 jsAst.Expression constantReference(ConstantValue value) {
142 return constantEmitter.reference(value); 134 return constantEmitter.reference(value);
143 } 135 }
144 136
145 jsAst.Expression constantInitializerExpression(ConstantValue value) { 137 jsAst.Expression constantInitializerExpression(ConstantValue value) {
146 return constantEmitter.initializationExpression(value); 138 return constantEmitter.initializationExpression(value);
147 } 139 }
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 // this.x = t - v; 315 // this.x = t - v;
324 // }, 316 // },
325 // }); 317 // });
326 318
327 bool hasIsolateSupport = compiler.hasIsolateSupport; 319 bool hasIsolateSupport = compiler.hasIsolateSupport;
328 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; 320 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
329 321
330 jsAst.Expression defineClass = js(''' 322 jsAst.Expression defineClass = js('''
331 function(name, fields) { 323 function(name, fields) {
332 var accessors = []; 324 var accessors = [];
333 325
334 var str = "function " + name + "("; 326 var str = "function " + name + "(";
335 var body = ""; 327 var body = "";
336 if (#hasIsolateSupport) { var fieldNames = ""; } 328 if (#hasIsolateSupport) { var fieldNames = ""; }
337 329
338 for (var i = 0; i < fields.length; i++) { 330 for (var i = 0; i < fields.length; i++) {
339 if(i != 0) str += ", "; 331 if(i != 0) str += ", ";
340 332
341 var field = generateAccessor(fields[i], accessors, name); 333 var field = generateAccessor(fields[i], accessors, name);
342 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; } 334 if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
343 var parameter = "parameter_" + field; 335 var parameter = "parameter_" + field;
344 str += parameter; 336 str += parameter;
345 body += ("this." + field + " = " + parameter + ";\\n"); 337 body += ("this." + field + " = " + parameter + ";\\n");
346 } 338 }
347 str += ") {\\n" + body + "}\\n"; 339 str += ") {\\n" + body + "}\\n";
348 str += name + ".builtin\$cls=\\"" + name + "\\";\\n"; 340 str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
349 str += "\$desc=\$collectedClasses." + name + ";\\n"; 341 str += "\$desc=\$collectedClasses." + name + ";\\n";
350 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n"; 342 str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n";
351 str += name + ".prototype = \$desc;\\n"; 343 str += name + ".prototype = \$desc;\\n";
352 if (typeof defineClass.name != "string") { 344 if (typeof defineClass.name != "string") {
353 str += name + ".name=\\"" + name + "\\";\\n"; 345 str += name + ".name=\\"" + name + "\\";\\n";
354 } 346 }
355 if (#hasIsolateSupport) { 347 if (#hasIsolateSupport) {
356 str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n"; 348 str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n";
357 } 349 }
358 str += accessors.join(""); 350 str += accessors.join("");
359 351
360 return str; 352 return str;
361 }''', { 'hasIsolateSupport': hasIsolateSupport }); 353 }''', { 'hasIsolateSupport': hasIsolateSupport });
362 354
363 // Declare a function called "generateAccessor". This is used in 355 // Declare a function called "generateAccessor". This is used in
364 // defineClassFunction. 356 // defineClassFunction.
365 List result = <jsAst.Node>[ 357 List result = <jsAst.Node>[
366 generateAccessorFunction, 358 generateAccessorFunction,
367 new jsAst.FunctionDeclaration( 359 new jsAst.FunctionDeclaration(
368 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; 360 new jsAst.VariableDeclaration('defineClass'), defineClass) ];
369 361
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 } 561 }
570 }''', {'finishedClassesAccess': finishedClassesAccess, 562 }''', {'finishedClassesAccess': finishedClassesAccess,
571 'needsMixinSupport': needsMixinSupport, 563 'needsMixinSupport': needsMixinSupport,
572 'hasNativeClasses': nativeClasses.isNotEmpty, 564 'hasNativeClasses': nativeClasses.isNotEmpty,
573 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, 565 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME,
574 'interceptorsByTagAccess': interceptorsByTagAccess, 566 'interceptorsByTagAccess': interceptorsByTagAccess,
575 'leafTagsAccess': leafTagsAccess, 567 'leafTagsAccess': leafTagsAccess,
576 'allowNativesSubclassing': true}); 568 'allowNativesSubclassing': true});
577 } 569 }
578 570
579 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { 571 void emitFinishIsolateConstructorInvocation(CodeOutput output) {
580 String isolate = namer.isolateName; 572 String isolate = namer.isolateName;
581 buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N"); 573 output.add("$isolate = $finishIsolateConstructorName($isolate)$N");
582 } 574 }
583 575
584 /// In minified mode we want to keep the name for the most common core types. 576 /// In minified mode we want to keep the name for the most common core types.
585 bool _isNativeTypeNeedingReflectionName(Element element) { 577 bool _isNativeTypeNeedingReflectionName(Element element) {
586 if (!element.isClass) return false; 578 if (!element.isClass) return false;
587 return (element == compiler.intClass || 579 return (element == compiler.intClass ||
588 element == compiler.doubleClass || 580 element == compiler.doubleClass ||
589 element == compiler.numClass || 581 element == compiler.numClass ||
590 element == compiler.stringClass || 582 element == compiler.stringClass ||
591 element == compiler.boolClass || 583 element == compiler.boolClass ||
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 } 743 }
752 744
753 void emitStaticFunctions(List<Element> staticFunctions) { 745 void emitStaticFunctions(List<Element> staticFunctions) {
754 for (Element element in staticFunctions) { 746 for (Element element in staticFunctions) {
755 ClassBuilder builder = new ClassBuilder(element, namer); 747 ClassBuilder builder = new ClassBuilder(element, namer);
756 containerBuilder.addMember(element, builder); 748 containerBuilder.addMember(element, builder);
757 getElementDescriptor(element).properties.addAll(builder.properties); 749 getElementDescriptor(element).properties.addAll(builder.properties);
758 } 750 }
759 } 751 }
760 752
761 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer, 753 void emitStaticNonFinalFieldInitializations(CodeOutput output,
762 OutputUnit outputUnit) { 754 OutputUnit outputUnit) {
763 JavaScriptConstantCompiler handler = backend.constants; 755 JavaScriptConstantCompiler handler = backend.constants;
764 Iterable<VariableElement> staticNonFinalFields = 756 Iterable<VariableElement> staticNonFinalFields =
765 handler.getStaticNonFinalFieldsForEmission(); 757 handler.getStaticNonFinalFieldsForEmission();
766 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) { 758 for (Element element in Elements.sortedByPosition(staticNonFinalFields)) {
767 // [:interceptedNames:] is handled in [emitInterceptedNames]. 759 // [:interceptedNames:] is handled in [emitInterceptedNames].
768 if (element == backend.interceptedNames) continue; 760 if (element == backend.interceptedNames) continue;
769 // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor]. 761 // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor].
770 if (element == backend.mapTypeToInterceptor) continue; 762 if (element == backend.mapTypeToInterceptor) continue;
771 compiler.withCurrentElement(element, () { 763 compiler.withCurrentElement(element, () {
772 jsAst.Expression initialValue; 764 jsAst.Expression initialValue;
773 if (outputUnit != 765 if (outputUnit !=
774 compiler.deferredLoadTask.outputUnitForElement(element)) { 766 compiler.deferredLoadTask.outputUnitForElement(element)) {
775 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) { 767 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) {
776 // In the main output-unit we output a stub initializer for deferred 768 // In the main output-unit we output a stub initializer for deferred
777 // variables, such that `isolateProperties` stays a fast object. 769 // variables, such that `isolateProperties` stays a fast object.
778 initialValue = jsAst.number(0); 770 initialValue = jsAst.number(0);
779 } else { 771 } else {
780 // Don't output stubs outside the main output file. 772 // Don't output stubs outside the main output file.
781 return; 773 return;
782 } 774 }
783 } else { 775 } else {
784 initialValue = constantEmitter.referenceInInitializationContext( 776 initialValue = constantEmitter.referenceInInitializationContext(
785 handler.getInitialValueFor(element).value); 777 handler.getInitialValueFor(element).value);
786 778
787 } 779 }
788 jsAst.Expression init = 780 jsAst.Expression init =
789 js('$isolateProperties.# = #', 781 js('$isolateProperties.# = #',
790 [namer.getNameOfGlobalField(element), initialValue]); 782 [namer.getNameOfGlobalField(element), initialValue]);
791 buffer.write(jsAst.prettyPrint(init, compiler, 783 output.addBuffer(jsAst.prettyPrint(init, compiler,
792 monitor: compiler.dumpInfoTask)); 784 monitor: compiler.dumpInfoTask));
793 buffer.write('$N'); 785 output.add('$N');
794 }); 786 });
795 } 787 }
796 } 788 }
797 789
798 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { 790 void emitLazilyInitializedStaticFields(CodeOutput output) {
799 JavaScriptConstantCompiler handler = backend.constants; 791 JavaScriptConstantCompiler handler = backend.constants;
800 List<VariableElement> lazyFields = 792 List<VariableElement> lazyFields =
801 handler.getLazilyInitializedFieldsForEmission(); 793 handler.getLazilyInitializedFieldsForEmission();
802 if (!lazyFields.isEmpty) { 794 if (!lazyFields.isEmpty) {
803 needsLazyInitializer = true; 795 needsLazyInitializer = true;
804 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { 796 for (VariableElement element in Elements.sortedByPosition(lazyFields)) {
805 jsAst.Expression init = 797 jsAst.Expression init =
806 buildLazilyInitializedStaticField(element, isolateProperties); 798 buildLazilyInitializedStaticField(element, isolateProperties);
807 if (init == null) continue; 799 if (init == null) continue;
808 buffer.write( 800 output.addBuffer(
809 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask)); 801 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
810 buffer.write("$N"); 802 output.add("$N");
811 } 803 }
812 } 804 }
813 } 805 }
814 806
815 jsAst.Expression buildLazilyInitializedStaticField( 807 jsAst.Expression buildLazilyInitializedStaticField(
816 VariableElement element, String isolateProperties) { 808 VariableElement element, String isolateProperties) {
817 jsAst.Expression code = backend.generatedCode[element]; 809 jsAst.Expression code = backend.generatedCode[element];
818 // The code is null if we ended up not needing the lazily 810 // The code is null if we ended up not needing the lazily
819 // initialized field after all because of constant folding 811 // initialized field after all because of constant folding
820 // before code generation. 812 // before code generation.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 851
860 // Sorting by the long name clusters constants with the same constructor 852 // Sorting by the long name clusters constants with the same constructor
861 // which compresses a tiny bit better. 853 // which compresses a tiny bit better.
862 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b)); 854 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
863 if (r != 0) return r; 855 if (r != 0) return r;
864 // Resolve collisions in the long name by using the constant name (i.e. JS 856 // Resolve collisions in the long name by using the constant name (i.e. JS
865 // name) which is unique. 857 // name) which is unique.
866 return namer.constantName(a).compareTo(namer.constantName(b)); 858 return namer.constantName(a).compareTo(namer.constantName(b));
867 } 859 }
868 860
869 void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) { 861 void emitCompileTimeConstants(CodeOutput output, OutputUnit outputUnit) {
870 List<ConstantValue> constants = outputConstantLists[outputUnit]; 862 List<ConstantValue> constants = outputConstantLists[outputUnit];
871 if (constants == null) return; 863 if (constants == null) return;
872 bool isMainBuffer = buffer == mainBuffer; 864 CodeOutput constantOutput = output;
873 if (compiler.hasIncrementalSupport && isMainBuffer) { 865 if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
874 buffer = cachedEmittedConstantsBuffer; 866 constantOutput = cachedEmittedConstantsBuffer;
875 } 867 }
876 for (ConstantValue constant in constants) { 868 for (ConstantValue constant in constants) {
877 if (compiler.hasIncrementalSupport && isMainBuffer) { 869 if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
878 if (cachedEmittedConstants.contains(constant)) continue; 870 if (cachedEmittedConstants.contains(constant)) continue;
879 cachedEmittedConstants.add(constant); 871 cachedEmittedConstants.add(constant);
880 } 872 }
881 jsAst.Expression init = buildConstantInitializer(constant); 873 jsAst.Expression init = buildConstantInitializer(constant);
882 buffer.write(jsAst.prettyPrint(init, compiler, 874 constantOutput.addBuffer(jsAst.prettyPrint(init, compiler,
883 monitor: compiler.dumpInfoTask)); 875 monitor: compiler.dumpInfoTask));
884 buffer.write('$N'); 876 constantOutput.add('$N');
885 } 877 }
886 if (compiler.hasIncrementalSupport && isMainBuffer) { 878 if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
887 mainBuffer.write(cachedEmittedConstantsBuffer); 879 output.addBuffer(constantOutput);
888 } 880 }
889 } 881 }
890 882
891 jsAst.Expression buildConstantInitializer(ConstantValue constant) { 883 jsAst.Expression buildConstantInitializer(ConstantValue constant) {
892 String name = namer.constantName(constant); 884 String name = namer.constantName(constant);
893 return js('#.# = #', 885 return js('#.# = #',
894 [namer.globalObjectForConstant(constant), name, 886 [namer.globalObjectForConstant(constant), name,
895 constantInitializerExpression(constant)]); 887 constantInitializerExpression(constant)]);
896 } 888 }
897 889
898 jsAst.Template get makeConstantListTemplate { 890 jsAst.Template get makeConstantListTemplate {
899 // TODO(floitsch): there is no harm in caching the template. 891 // TODO(floitsch): there is no harm in caching the template.
900 return jsAst.js.uncachedExpressionTemplate( 892 return jsAst.js.uncachedExpressionTemplate(
901 '${namer.isolateName}.$makeConstListProperty(#)'); 893 '${namer.isolateName}.$makeConstListProperty(#)');
902 } 894 }
903 895
904 void emitMakeConstantList(CodeBuffer buffer) { 896 void emitMakeConstantList(CodeOutput output) {
905 buffer.write( 897 output.addBuffer(
906 jsAst.prettyPrint( 898 jsAst.prettyPrint(
907 // Functions are stored in the hidden class and not as properties in 899 // Functions are stored in the hidden class and not as properties in
908 // the object. We never actually look at the value, but only want 900 // the object. We never actually look at the value, but only want
909 // to know if the property exists. 901 // to know if the property exists.
910 js.statement(r'''#.# = function(list) { 902 js.statement(r'''#.# = function(list) {
911 list.immutable$list = Array; 903 list.immutable$list = Array;
912 list.fixed$length = Array; 904 list.fixed$length = Array;
913 return list; 905 return list;
914 }''', 906 }''',
915 [namer.isolateName, makeConstListProperty]), 907 [namer.isolateName, makeConstListProperty]),
916 compiler, monitor: compiler.dumpInfoTask)); 908 compiler, monitor: compiler.dumpInfoTask));
917 buffer.write(N); 909 output.add(N);
918 } 910 }
919 911
920 /// Returns the code equivalent to: 912 /// Returns the code equivalent to:
921 /// `function(args) { $.startRootIsolate(X.main$closure(), args); }` 913 /// `function(args) { $.startRootIsolate(X.main$closure(), args); }`
922 jsAst.Expression buildIsolateSetupClosure(Element appMain, 914 jsAst.Expression buildIsolateSetupClosure(Element appMain,
923 Element isolateMain) { 915 Element isolateMain) {
924 jsAst.Expression mainAccess = isolateStaticClosureAccess(appMain); 916 jsAst.Expression mainAccess = isolateStaticClosureAccess(appMain);
925 // Since we pass the closurized version of the main method to 917 // Since we pass the closurized version of the main method to
926 // the isolate method, we must make sure that it exists. 918 // the isolate method, we must make sure that it exists.
927 return js('function(a){ #(#, a); }', 919 return js('function(a){ #(#, a); }',
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 return js('# = #("dispatch_record")', 972 return js('# = #("dispatch_record")',
981 [dispatchPropertyNameAccess, 973 [dispatchPropertyNameAccess,
982 getIsolateTagAccess]); 974 getIsolateTagAccess]);
983 } 975 }
984 976
985 String generateIsolateTagRoot() { 977 String generateIsolateTagRoot() {
986 // TODO(sra): MD5 of contributing source code or URIs? 978 // TODO(sra): MD5 of contributing source code or URIs?
987 return 'ZxYxX'; 979 return 'ZxYxX';
988 } 980 }
989 981
990 emitMain(CodeBuffer buffer) { 982 emitMain(CodeOutput output) {
991 if (compiler.isMockCompilation) return; 983 if (compiler.isMockCompilation) return;
992 Element main = compiler.mainFunction; 984 Element main = compiler.mainFunction;
993 jsAst.Expression mainCallClosure = null; 985 jsAst.Expression mainCallClosure = null;
994 if (compiler.hasIsolateSupport) { 986 if (compiler.hasIsolateSupport) {
995 Element isolateMain = 987 Element isolateMain =
996 backend.isolateHelperLibrary.find(JavaScriptBackend.START_ROOT_ISOLATE); 988 backend.isolateHelperLibrary.find(JavaScriptBackend.START_ROOT_ISOLATE);
997 mainCallClosure = buildIsolateSetupClosure(main, isolateMain); 989 mainCallClosure = buildIsolateSetupClosure(main, isolateMain);
998 } else if (compiler.hasIncrementalSupport) { 990 } else if (compiler.hasIncrementalSupport) {
999 mainCallClosure = js( 991 mainCallClosure = js(
1000 'function() { return #(); }', 992 'function() { return #(); }',
1001 backend.emitter.staticFunctionAccess(main)); 993 backend.emitter.staticFunctionAccess(main));
1002 } else { 994 } else {
1003 mainCallClosure = backend.emitter.staticFunctionAccess(main); 995 mainCallClosure = backend.emitter.staticFunctionAccess(main);
1004 } 996 }
1005 997
1006 if (backend.needToInitializeIsolateAffinityTag) { 998 if (backend.needToInitializeIsolateAffinityTag) {
1007 buffer.write( 999 output.addBuffer(
1008 jsAst.prettyPrint(generateIsolateAffinityTagInitialization(), 1000 jsAst.prettyPrint(generateIsolateAffinityTagInitialization(),
1009 compiler, monitor: compiler.dumpInfoTask)); 1001 compiler, monitor: compiler.dumpInfoTask));
1010 buffer.write(N); 1002 output.add(N);
1011 } 1003 }
1012 if (backend.needToInitializeDispatchProperty) { 1004 if (backend.needToInitializeDispatchProperty) {
1013 assert(backend.needToInitializeIsolateAffinityTag); 1005 assert(backend.needToInitializeIsolateAffinityTag);
1014 buffer.write( 1006 output.addBuffer(
1015 jsAst.prettyPrint(generateDispatchPropertyNameInitialization(), 1007 jsAst.prettyPrint(generateDispatchPropertyNameInitialization(),
1016 compiler, monitor: compiler.dumpInfoTask)); 1008 compiler, monitor: compiler.dumpInfoTask));
1017 buffer.write(N); 1009 output.add(N);
1018 } 1010 }
1019 1011
1020 jsAst.Expression currentScriptAccess = 1012 jsAst.Expression currentScriptAccess =
1021 generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT); 1013 generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
1022 1014
1023 addComment('BEGIN invoke [main].', buffer); 1015 addComment('BEGIN invoke [main].', output);
1024 // This code finds the currently executing script by listening to the 1016 // This code finds the currently executing script by listening to the
1025 // onload event of all script tags and getting the first script which 1017 // onload event of all script tags and getting the first script which
1026 // finishes. Since onload is called immediately after execution this should 1018 // finishes. Since onload is called immediately after execution this should
1027 // not substantially change execution order. 1019 // not substantially change execution order.
1028 jsAst.Statement invokeMain = js.statement(''' 1020 jsAst.Statement invokeMain = js.statement('''
1029 (function (callback) { 1021 (function (callback) {
1030 if (typeof document === "undefined") { 1022 if (typeof document === "undefined") {
1031 callback(null); 1023 callback(null);
1032 return; 1024 return;
1033 } 1025 }
(...skipping 16 matching lines...) Expand all
1050 #currentScript = currentScript; 1042 #currentScript = currentScript;
1051 1043
1052 if (typeof dartMainRunner === "function") { 1044 if (typeof dartMainRunner === "function") {
1053 dartMainRunner(#mainCallClosure, []); 1045 dartMainRunner(#mainCallClosure, []);
1054 } else { 1046 } else {
1055 #mainCallClosure([]); 1047 #mainCallClosure([]);
1056 } 1048 }
1057 })''', {'currentScript': currentScriptAccess, 1049 })''', {'currentScript': currentScriptAccess,
1058 'mainCallClosure': mainCallClosure}); 1050 'mainCallClosure': mainCallClosure});
1059 1051
1060 buffer.write(';'); 1052 output.add(';');
1061 buffer.write(jsAst.prettyPrint(invokeMain, 1053 output.addBuffer(jsAst.prettyPrint(invokeMain,
1062 compiler, monitor: compiler.dumpInfoTask)); 1054 compiler, monitor: compiler.dumpInfoTask));
1063 buffer.write(N); 1055 output.add(N);
1064 addComment('END invoke [main].', buffer); 1056 addComment('END invoke [main].', output);
1065 } 1057 }
1066 1058
1067 void emitInitFunction(CodeBuffer buffer) { 1059 void emitInitFunction(CodeOutput output) {
1068 String isolate = namer.currentIsolate; 1060 String isolate = namer.currentIsolate;
1069 jsAst.Expression allClassesAccess = 1061 jsAst.Expression allClassesAccess =
1070 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); 1062 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
1071 jsAst.Expression interceptorsByTagAccess = 1063 jsAst.Expression interceptorsByTagAccess =
1072 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); 1064 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
1073 jsAst.Expression leafTagsAccess = 1065 jsAst.Expression leafTagsAccess =
1074 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); 1066 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
1075 jsAst.Expression finishedClassesAccess = 1067 jsAst.Expression finishedClassesAccess =
1076 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); 1068 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES);
1077 jsAst.Expression cyclicThrow = 1069 jsAst.Expression cyclicThrow =
1078 staticFunctionAccess(backend.getCyclicThrowHelper()); 1070 staticFunctionAccess(backend.getCyclicThrowHelper());
1079 jsAst.Expression laziesAccess = 1071 jsAst.Expression laziesAccess =
1080 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); 1072 generateEmbeddedGlobalAccess(embeddedNames.LAZIES);
1081 1073
1082 jsAst.FunctionDeclaration decl = js.statement(''' 1074 jsAst.FunctionDeclaration decl = js.statement('''
1083 function init() { 1075 function init() {
1084 $isolateProperties = Object.create(null); 1076 $isolateProperties = Object.create(null);
1085 (function(){ 1077 (function(){
1086 #allClasses = Object.create(null); 1078 #allClasses = Object.create(null);
1087 #interceptorsByTag = Object.create(null); 1079 #interceptorsByTag = Object.create(null);
1088 #leafTags = Object.create(null); 1080 #leafTags = Object.create(null);
1089 #finishedClasses = Object.create(null); 1081 #finishedClasses = Object.create(null);
1090 })(); 1082 })();
1091 1083
1092 if (#needsLazyInitializer) { 1084 if (#needsLazyInitializer) {
1093 $lazyInitializerName = function (prototype, staticName, fieldName, 1085 $lazyInitializerName = function (prototype, staticName, fieldName,
1094 getterName, lazyValue) { 1086 getterName, lazyValue) {
1095 if (!#lazies) #lazies = Object.create(null); 1087 if (!#lazies) #lazies = Object.create(null);
1096 #lazies[fieldName] = getterName; 1088 #lazies[fieldName] = getterName;
1097 1089
1098 var sentinelUndefined = {}; 1090 var sentinelUndefined = {};
1099 var sentinelInProgress = {}; 1091 var sentinelInProgress = {};
1100 prototype[fieldName] = sentinelUndefined; 1092 prototype[fieldName] = sentinelUndefined;
1101 1093
1102 prototype[getterName] = function () { 1094 prototype[getterName] = function () {
1103 var result = $isolate[fieldName]; 1095 var result = $isolate[fieldName];
1104 try { 1096 try {
1105 if (result === sentinelUndefined) { 1097 if (result === sentinelUndefined) {
1106 $isolate[fieldName] = sentinelInProgress; 1098 $isolate[fieldName] = sentinelInProgress;
1107 1099
1108 try { 1100 try {
1109 result = $isolate[fieldName] = lazyValue(); 1101 result = $isolate[fieldName] = lazyValue();
1110 } finally { 1102 } finally {
1111 // Use try-finally, not try-catch/throw as it destroys the 1103 // Use try-finally, not try-catch/throw as it destroys the
1112 // stack trace. 1104 // stack trace.
1113 if (result === sentinelUndefined) 1105 if (result === sentinelUndefined)
1114 $isolate[fieldName] = null; 1106 $isolate[fieldName] = null;
1115 } 1107 }
1116 } else { 1108 } else {
1117 if (result === sentinelInProgress) 1109 if (result === sentinelInProgress)
1118 #cyclicThrow(staticName); 1110 #cyclicThrow(staticName);
1119 } 1111 }
1120 1112
1121 return result; 1113 return result;
1122 } finally { 1114 } finally {
1123 $isolate[getterName] = function() { return this[fieldName]; }; 1115 $isolate[getterName] = function() { return this[fieldName]; };
1124 } 1116 }
1125 } 1117 }
1126 } 1118 }
1127 } 1119 }
1128 1120
1129 // We replace the old Isolate function with a new one that initializes 1121 // We replace the old Isolate function with a new one that initializes
1130 // all its fields with the initial (and often final) value of all 1122 // all its fields with the initial (and often final) value of all
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 Isolate.#isolatePropertiesName = isolateProperties; 1160 Isolate.#isolatePropertiesName = isolateProperties;
1169 if (#outputContainsConstantList) { 1161 if (#outputContainsConstantList) {
1170 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; 1162 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty;
1171 } 1163 }
1172 if (#hasIncrementalSupport) { 1164 if (#hasIncrementalSupport) {
1173 Isolate.#lazyInitializerProperty = 1165 Isolate.#lazyInitializerProperty =
1174 oldIsolate.#lazyInitializerProperty; 1166 oldIsolate.#lazyInitializerProperty;
1175 } 1167 }
1176 return Isolate; 1168 return Isolate;
1177 } 1169 }
1178 1170
1179 }''', {'allClasses': allClassesAccess, 1171 }''', {'allClasses': allClassesAccess,
1180 'interceptorsByTag': interceptorsByTagAccess, 1172 'interceptorsByTag': interceptorsByTagAccess,
1181 'leafTags': leafTagsAccess, 1173 'leafTags': leafTagsAccess,
1182 'finishedClasses': finishedClassesAccess, 1174 'finishedClasses': finishedClassesAccess,
1183 'needsLazyInitializer': needsLazyInitializer, 1175 'needsLazyInitializer': needsLazyInitializer,
1184 'lazies': laziesAccess, 'cyclicThrow': cyclicThrow, 1176 'lazies': laziesAccess, 'cyclicThrow': cyclicThrow,
1185 'isolatePropertiesName': namer.isolatePropertiesName, 1177 'isolatePropertiesName': namer.isolatePropertiesName,
1186 'outputContainsConstantList': task.outputContainsConstantList, 1178 'outputContainsConstantList': task.outputContainsConstantList,
1187 'makeConstListProperty': makeConstListProperty, 1179 'makeConstListProperty': makeConstListProperty,
1188 'hasIncrementalSupport': compiler.hasIncrementalSupport, 1180 'hasIncrementalSupport': compiler.hasIncrementalSupport,
1189 'lazyInitializerProperty': lazyInitializerProperty,}); 1181 'lazyInitializerProperty': lazyInitializerProperty,});
1190 1182
1191 buffer.write(jsAst.prettyPrint(decl, 1183 output.addBuffer(
1192 compiler, monitor: compiler.dumpInfoTask).getText()); 1184 jsAst.prettyPrint(decl, compiler, monitor: compiler.dumpInfoTask));
1193 if (compiler.enableMinification) buffer.write('\n'); 1185 if (compiler.enableMinification) {
1186 output.add('\n');
1187 }
1194 } 1188 }
1195 1189
1196 void emitConvertToFastObjectFunction() { 1190 void emitConvertToFastObjectFunction(CodeOutput output) {
1197 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; 1191 List<jsAst.Statement> debugCode = <jsAst.Statement>[];
1198 if (DEBUG_FAST_OBJECTS) { 1192 if (DEBUG_FAST_OBJECTS) {
1199 debugCode.add(js.statement(r''' 1193 debugCode.add(js.statement(r'''
1200 // The following only works on V8 when run with option 1194 // The following only works on V8 when run with option
1201 // "--allow-natives-syntax". We use'new Function' because the 1195 // "--allow-natives-syntax". We use'new Function' because the
1202 // miniparser does not understand V8 native syntax. 1196 // miniparser does not understand V8 native syntax.
1203 if (typeof print === "function") { 1197 if (typeof print === "function") {
1204 var HasFastProperties = 1198 var HasFastProperties =
1205 new Function("a", "return %HasFastProperties(a)"); 1199 new Function("a", "return %HasFastProperties(a)");
1206 print("Size of global object: " 1200 print("Size of global object: "
1207 + String(Object.getOwnPropertyNames(properties).length) 1201 + String(Object.getOwnPropertyNames(properties).length)
1208 + ", fast properties " + HasFastProperties(properties)); 1202 + ", fast properties " + HasFastProperties(properties));
1209 }''')); 1203 }'''));
1210 } 1204 }
1211 1205
1212 jsAst.Statement convertToFastObject = js.statement(r''' 1206 jsAst.Statement convertToFastObject = js.statement(r'''
1213 function convertToFastObject(properties) { 1207 function convertToFastObject(properties) {
1214 // Create an instance that uses 'properties' as prototype. This should 1208 // Create an instance that uses 'properties' as prototype. This should
1215 // make 'properties' a fast object. 1209 // make 'properties' a fast object.
1216 function MyClass() {}; 1210 function MyClass() {};
1217 MyClass.prototype = properties; 1211 MyClass.prototype = properties;
1218 new MyClass(); 1212 new MyClass();
1219 #; 1213 #;
1220 return properties; 1214 return properties;
1221 }''', [debugCode]); 1215 }''', [debugCode]);
1222 1216
1223 mainBuffer.write(jsAst.prettyPrint(convertToFastObject, compiler)); 1217 output.addBuffer(jsAst.prettyPrint(convertToFastObject, compiler));
1224 mainBuffer.write(N); 1218 output.add(N);
1225 } 1219 }
1226 1220
1227 void writeLibraryDescriptors(CodeBuffer buffer, LibraryElement library) { 1221 void writeLibraryDescriptors(CodeOutput output, LibraryElement library) {
1228 var uri = ""; 1222 var uri = "";
1229 if (!compiler.enableMinification || backend.mustPreserveUris) { 1223 if (!compiler.enableMinification || backend.mustPreserveUris) {
1230 uri = library.canonicalUri; 1224 uri = library.canonicalUri;
1231 if (uri.scheme == 'file' && compiler.outputUri != null) { 1225 if (uri.scheme == 'file' && compiler.outputUri != null) {
1232 uri = relativize(compiler.outputUri, library.canonicalUri, false); 1226 uri = relativize(compiler.outputUri, library.canonicalUri, false);
1233 } 1227 }
1234 } 1228 }
1235 ClassBuilder descriptor = elementDescriptors[library]; 1229 ClassBuilder descriptor = elementDescriptors[library];
1236 if (descriptor == null) { 1230 if (descriptor == null) {
1237 // Nothing of the library was emitted. 1231 // Nothing of the library was emitted.
1238 // TODO(floitsch): this should not happen. We currently have an example 1232 // TODO(floitsch): this should not happen. We currently have an example
1239 // with language/prefix6_negative_test.dart where we have an instance 1233 // with language/prefix6_negative_test.dart where we have an instance
1240 // method without its corresponding class. 1234 // method without its corresponding class.
1241 return; 1235 return;
1242 } 1236 }
1243 1237
1244 String libraryName = 1238 String libraryName =
1245 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? 1239 (!compiler.enableMinification || backend.mustRetainLibraryNames) ?
1246 library.getLibraryName() : 1240 library.getLibraryName() :
1247 ""; 1241 "";
1248 1242
1249 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); 1243 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library);
1250 1244
1251 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer(); 1245 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer();
1252 1246
1253 compiler.dumpInfoTask.registerElementAst(library, metadata); 1247 compiler.dumpInfoTask.registerElementAst(library, metadata);
1254 compiler.dumpInfoTask.registerElementAst(library, initializers); 1248 compiler.dumpInfoTask.registerElementAst(library, initializers);
1255 buffer 1249 output
1256 ..write('["$libraryName",$_') 1250 ..add('["$libraryName",$_')
1257 ..write('"${uri}",$_') 1251 ..add('"${uri}",$_');
1258 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata, 1252 if (metadata != null) {
1259 compiler, 1253 output.addBuffer(jsAst.prettyPrint(metadata,
1260 monitor: compiler.dumpInfoTask)) 1254 compiler,
1261 ..write(',$_') 1255 monitor: compiler.dumpInfoTask));
1262 ..write(namer.globalObjectFor(library)) 1256 }
1263 ..write(',$_') 1257 output
1264 ..write(jsAst.prettyPrint(initializers, 1258 ..add(',$_')
1265 compiler, 1259 ..add(namer.globalObjectFor(library))
1266 monitor: compiler.dumpInfoTask)) 1260 ..add(',$_')
1267 ..write(library == compiler.mainApp ? ',${n}1' : "") 1261 ..addBuffer(jsAst.prettyPrint(initializers,
1268 ..write('],$n'); 1262 compiler,
1263 monitor: compiler.dumpInfoTask))
1264 ..add(library == compiler.mainApp ? ',${n}1' : "")
1265 ..add('],$n');
1269 } 1266 }
1270 1267
1271 void emitPrecompiledConstructor(OutputUnit outputUnit, 1268 void emitPrecompiledConstructor(OutputUnit outputUnit,
1272 String constructorName, 1269 String constructorName,
1273 jsAst.Expression constructorAst, 1270 jsAst.Expression constructorAst,
1274 List<String> fields) { 1271 List<String> fields) {
1275 cspPrecompiledFunctionFor(outputUnit).add( 1272 cspPrecompiledFunctionFor(outputUnit).add(
1276 new jsAst.FunctionDeclaration( 1273 new jsAst.FunctionDeclaration(
1277 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1274 new jsAst.VariableDeclaration(constructorName), constructorAst));
1278 1275
1279 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; 1276 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
1280 bool hasIsolateSupport = compiler.hasIsolateSupport; 1277 bool hasIsolateSupport = compiler.hasIsolateSupport;
1281 jsAst.Node fieldNamesArray = 1278 jsAst.Node fieldNamesArray =
1282 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull(); 1279 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
1283 1280
1284 cspPrecompiledFunctionFor(outputUnit).add(js.statement(r''' 1281 cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
1285 { 1282 {
1286 #constructorName.builtin$cls = #constructorNameString; 1283 #constructorName.builtin$cls = #constructorNameString;
1287 if (!"name" in #constructorName) 1284 if (!"name" in #constructorName)
1288 #constructorName.name = #constructorNameString; 1285 #constructorName.name = #constructorNameString;
1289 $desc = $collectedClasses.#constructorName; 1286 $desc = $collectedClasses.#constructorName;
1290 if ($desc instanceof Array) $desc = $desc[1]; 1287 if ($desc instanceof Array) $desc = $desc[1];
1291 #constructorName.prototype = $desc; 1288 #constructorName.prototype = $desc;
1292 ''' /* next string is not a raw string */ ''' 1289 ''' /* next string is not a raw string */ '''
1293 if (#hasIsolateSupport) { 1290 if (#hasIsolateSupport) {
1294 #constructorName.$fieldNamesProperty = #fieldNamesArray; 1291 #constructorName.$fieldNamesProperty = #fieldNamesArray;
1295 } 1292 }
1296 }''', 1293 }''',
1297 {"constructorName": constructorName, 1294 {"constructorName": constructorName,
1298 "constructorNameString": js.string(constructorName), 1295 "constructorNameString": js.string(constructorName),
1299 "hasIsolateSupport": hasIsolateSupport, 1296 "hasIsolateSupport": hasIsolateSupport,
1300 "fieldNamesArray": fieldNamesArray})); 1297 "fieldNamesArray": fieldNamesArray}));
1301 1298
1302 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); 1299 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
1303 } 1300 }
1304 1301
1305 /// Extracts the output name of the compiler's outputUri. 1302 /// Extracts the output name of the compiler's outputUri.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 String constructorName = mangledName; 1364 String constructorName = mangledName;
1368 jsAst.Expression constructorAst = js('function() {}'); 1365 jsAst.Expression constructorAst = js('function() {}');
1369 List<String> fieldNames = []; 1366 List<String> fieldNames = [];
1370 emitPrecompiledConstructor(mainOutputUnit, 1367 emitPrecompiledConstructor(mainOutputUnit,
1371 constructorName, 1368 constructorName,
1372 constructorAst, 1369 constructorAst,
1373 fieldNames); 1370 fieldNames);
1374 } 1371 }
1375 } 1372 }
1376 1373
1377 void emitMangledNames() { 1374 void emitMangledNames(CodeOutput mainBuffer) {
1378 if (!mangledFieldNames.isEmpty) { 1375 if (!mangledFieldNames.isEmpty) {
1379 var keys = mangledFieldNames.keys.toList(); 1376 var keys = mangledFieldNames.keys.toList();
1380 keys.sort(); 1377 keys.sort();
1381 var properties = []; 1378 var properties = [];
1382 for (String key in keys) { 1379 for (String key in keys) {
1383 var value = js.string('${mangledFieldNames[key]}'); 1380 var value = js.string('${mangledFieldNames[key]}');
1384 properties.add(new jsAst.Property(js.string(key), value)); 1381 properties.add(new jsAst.Property(js.string(key), value));
1385 } 1382 }
1386 1383
1387 jsAst.Expression mangledNamesAccess = 1384 jsAst.Expression mangledNamesAccess =
1388 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES); 1385 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
1389 var map = new jsAst.ObjectInitializer(properties); 1386 var map = new jsAst.ObjectInitializer(properties);
1390 mainBuffer.write( 1387 mainBuffer.addBuffer(
1391 jsAst.prettyPrint( 1388 jsAst.prettyPrint(
1392 js.statement('# = #', [mangledNamesAccess, map]), 1389 js.statement('# = #', [mangledNamesAccess, map]),
1393 compiler, 1390 compiler,
1394 monitor: compiler.dumpInfoTask)); 1391 monitor: compiler.dumpInfoTask));
1395 if (compiler.enableMinification) { 1392 if (compiler.enableMinification) {
1396 mainBuffer.write(';'); 1393 mainBuffer.add(';');
1397 } 1394 }
1398 } 1395 }
1399 if (!mangledGlobalFieldNames.isEmpty) { 1396 if (!mangledGlobalFieldNames.isEmpty) {
1400 var keys = mangledGlobalFieldNames.keys.toList(); 1397 var keys = mangledGlobalFieldNames.keys.toList();
1401 keys.sort(); 1398 keys.sort();
1402 var properties = []; 1399 var properties = [];
1403 for (String key in keys) { 1400 for (String key in keys) {
1404 var value = js.string('${mangledGlobalFieldNames[key]}'); 1401 var value = js.string('${mangledGlobalFieldNames[key]}');
1405 properties.add(new jsAst.Property(js.string(key), value)); 1402 properties.add(new jsAst.Property(js.string(key), value));
1406 } 1403 }
1407 jsAst.Expression mangledGlobalNamesAccess = 1404 jsAst.Expression mangledGlobalNamesAccess =
1408 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); 1405 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
1409 var map = new jsAst.ObjectInitializer(properties); 1406 var map = new jsAst.ObjectInitializer(properties);
1410 mainBuffer.write( 1407 mainBuffer.addBuffer(
1411 jsAst.prettyPrint( 1408 jsAst.prettyPrint(
1412 js.statement('# = #', [mangledGlobalNamesAccess, map]), 1409 js.statement('# = #', [mangledGlobalNamesAccess, map]),
1413 compiler, 1410 compiler,
1414 monitor: compiler.dumpInfoTask)); 1411 monitor: compiler.dumpInfoTask));
1415 if (compiler.enableMinification) { 1412 if (compiler.enableMinification) {
1416 mainBuffer.write(';'); 1413 mainBuffer.add(';');
1417 } 1414 }
1418 } 1415 }
1419 } 1416 }
1420 1417
1421 void checkEverythingEmitted(Iterable<Element> elements) { 1418 void checkEverythingEmitted(Iterable<Element> elements) {
1422 List<Element> pendingStatics; 1419 List<Element> pendingStatics;
1423 if (!compiler.hasIncrementalSupport) { 1420 if (!compiler.hasIncrementalSupport) {
1424 pendingStatics = 1421 pendingStatics =
1425 Elements.sortedByPosition(elements.where((e) => !e.isLibrary)); 1422 Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
1426 1423
1427 pendingStatics.forEach((element) => 1424 pendingStatics.forEach((element) =>
1428 compiler.reportInfo( 1425 compiler.reportInfo(
1429 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); 1426 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1430 } 1427 }
1431 1428
1432 if (pendingStatics != null && !pendingStatics.isEmpty) { 1429 if (pendingStatics != null && !pendingStatics.isEmpty) {
1433 compiler.internalError(pendingStatics.first, 1430 compiler.internalError(pendingStatics.first,
1434 'Pending statics (see above).'); 1431 'Pending statics (see above).');
1435 } 1432 }
1436 } 1433 }
1437 1434
1438 void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes, 1435 void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes,
1439 CodeBuffer nativeBuffer) { 1436 CodeBuffer nativeBuffer) {
1437 LineColumnCollector lineColumnCollector;
1438 List<CodeOutputListener> codeOutputListeners;
1439 if (generateSourceMap) {
1440 lineColumnCollector = new LineColumnCollector();
1441 codeOutputListeners = <CodeOutputListener>[lineColumnCollector];
1442 }
1443
1444 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1445 CodeOutput mainOutput =
1446 new StreamCodeOutput(compiler.outputProvider('', 'js'),
1447 codeOutputListeners);
1448 outputBuffers[mainOutputUnit] = mainOutput;
1449
1440 bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit; 1450 bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
1441 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1442 1451
1443 mainBuffer.write(buildGeneratedBy()); 1452 mainOutput.add(buildGeneratedBy());
1444 addComment(HOOKS_API_USAGE, mainBuffer); 1453 addComment(HOOKS_API_USAGE, mainOutput);
1445 1454
1446 if (isProgramSplit) { 1455 if (isProgramSplit) {
1447 /// For deferred loading we communicate the initializers via this global 1456 /// For deferred loading we communicate the initializers via this global
1448 /// variable. The deferred hunks will add their initialization to this. 1457 /// variable. The deferred hunks will add their initialization to this.
1449 /// The semicolon is important in minified mode, without it the 1458 /// The semicolon is important in minified mode, without it the
1450 /// following parenthesis looks like a call to the object literal. 1459 /// following parenthesis looks like a call to the object literal.
1451 mainBuffer..write( 1460 mainOutput.add(
1452 'self.${deferredInitializers} = self.${deferredInitializers} || ' 1461 'self.${deferredInitializers} = self.${deferredInitializers} || '
1453 'Object.create(null);$n'); 1462 'Object.create(null);$n');
1454 } 1463 }
1455 1464
1456 // Using a named function here produces easier to read stack traces in 1465 // Using a named function here produces easier to read stack traces in
1457 // Chrome/V8. 1466 // Chrome/V8.
1458 mainBuffer.write('(function(${namer.currentIsolate})$_{\n'); 1467 mainOutput.add('(function(${namer.currentIsolate})$_{\n');
1459 if (compiler.hasIncrementalSupport) { 1468 if (compiler.hasIncrementalSupport) {
1460 mainBuffer.write(jsAst.prettyPrint(js.statement( 1469 mainOutput.addBuffer(jsAst.prettyPrint(js.statement(
1461 """ 1470 """
1462 { 1471 {
1463 #helper = #helper || Object.create(null); 1472 #helper = #helper || Object.create(null);
1464 #helper.patch = function(a) { eval(a)}; 1473 #helper.patch = function(a) { eval(a)};
1465 #helper.schemaChange = #schemaChange; 1474 #helper.schemaChange = #schemaChange;
1466 #helper.addMethod = #addMethod; 1475 #helper.addMethod = #addMethod;
1467 #helper.extractStubs = function(array, name, isStatic, originalDescriptor) { 1476 #helper.extractStubs = function(array, name, isStatic, originalDescriptor) {
1468 var descriptor = Object.create(null); 1477 var descriptor = Object.create(null);
1469 this.addStubs(descriptor, array, name, isStatic, originalDescriptor, []); 1478 this.addStubs(descriptor, array, name, isStatic, originalDescriptor, []);
1470 return descriptor; 1479 return descriptor;
1471 }; 1480 };
1472 }""", 1481 }""",
1473 { 'helper': js('this.#', [namer.incrementalHelperName]), 1482 { 'helper': js('this.#', [namer.incrementalHelperName]),
1474 'schemaChange': buildSchemaChangeFunction(), 1483 'schemaChange': buildSchemaChangeFunction(),
1475 'addMethod': buildIncrementalAddMethod() }), compiler)); 1484 'addMethod': buildIncrementalAddMethod() }), compiler));
1476 } 1485 }
1477 if (isProgramSplit) { 1486 if (isProgramSplit) {
1478 /// We collect all the global state of the, so it can be passed to the 1487 /// We collect all the global state of the, so it can be passed to the
1479 /// initializer of deferred files. 1488 /// initializer of deferred files.
1480 mainBuffer.write('var ${globalsHolder}$_=${_}Object.create(null)$N'); 1489 mainOutput.add('var ${globalsHolder}$_=${_}Object.create(null)$N');
1481 } 1490 }
1482 mainBuffer.write('function dart()$_{$n' 1491 mainOutput.add('function dart()$_{$n'
1483 '${_}${_}this.x$_=${_}0$N' 1492 '${_}${_}this.x$_=${_}0$N'
1484 '${_}${_}delete this.x$N' 1493 '${_}${_}delete this.x$N'
1485 '}$n'); 1494 '}$n');
1486 for (String globalObject in Namer.reservedGlobalObjectNames) { 1495 for (String globalObject in Namer.reservedGlobalObjectNames) {
1487 // The global objects start as so-called "slow objects". For V8, this 1496 // The global objects start as so-called "slow objects". For V8, this
1488 // means that it won't try to make map transitions as we add properties 1497 // means that it won't try to make map transitions as we add properties
1489 // to these objects. Later on, we attempt to turn these objects into 1498 // to these objects. Later on, we attempt to turn these objects into
1490 // fast objects by calling "convertToFastObject" (see 1499 // fast objects by calling "convertToFastObject" (see
1491 // [emitConvertToFastObjectFunction]). 1500 // [emitConvertToFastObjectFunction]).
1492 mainBuffer.write('var ${globalObject}$_=${_}'); 1501 mainOutput.add('var ${globalObject}$_=${_}');
1493 if(isProgramSplit) { 1502 if(isProgramSplit) {
1494 mainBuffer.write('${globalsHolder}.$globalObject$_=${_}'); 1503 mainOutput.add('${globalsHolder}.$globalObject$_=${_}');
1495 } 1504 }
1496 mainBuffer.write('new dart$N'); 1505 mainOutput.add('new dart$N');
1497 } 1506 }
1498 1507
1499 mainBuffer.write('function ${namer.isolateName}()$_{}\n'); 1508 mainOutput.add('function ${namer.isolateName}()$_{}\n');
1500 if (isProgramSplit) { 1509 if (isProgramSplit) {
1501 mainBuffer 1510 mainOutput
1502 .write('${globalsHolder}.${namer.isolateName}$_=$_' 1511 .add('${globalsHolder}.${namer.isolateName}$_=$_'
1503 '${namer.isolateName}$N' 1512 '${namer.isolateName}$N'
1504 '${globalsHolder}.$initName$_=${_}$initName$N'); 1513 '${globalsHolder}.$initName$_=${_}$initName$N');
1505 } 1514 }
1506 mainBuffer.write('init()$N$n'); 1515 mainOutput.add('init()$N$n');
1507 mainBuffer.write('$isolateProperties$_=$_$isolatePropertiesName$N'); 1516 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1508 1517
1509 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]); 1518 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
1510 1519
1511 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; 1520 List<ClassElement> classes = task.outputClassLists[mainOutputUnit];
1512 if (classes != null) { 1521 if (classes != null) {
1513 for (ClassElement element in classes) { 1522 for (ClassElement element in classes) {
1514 generateClass(element, getElementDescriptor(element)); 1523 generateClass(element, getElementDescriptor(element));
1515 } 1524 }
1516 } 1525 }
1517 1526
1518 if (compiler.enableMinification) { 1527 if (compiler.enableMinification) {
1519 mainBuffer.write(';'); 1528 mainOutput.add(';');
1520 } 1529 }
1521 1530
1522 if (elementDescriptors.isNotEmpty) { 1531 if (elementDescriptors.isNotEmpty) {
1523 Iterable<LibraryElement> libraries = 1532 Iterable<LibraryElement> libraries =
1524 task.outputLibraryLists[mainOutputUnit]; 1533 task.outputLibraryLists[mainOutputUnit];
1525 if (libraries == null) libraries = []; 1534 if (libraries == null) libraries = [];
1526 emitLibraries(libraries); 1535 emitLibraries(libraries);
1527 emitTypedefs(); 1536 emitTypedefs();
1528 emitMangledNames(); 1537 emitMangledNames(mainOutput);
1529 1538
1530 checkEverythingEmitted(elementDescriptors.keys); 1539 checkEverythingEmitted(elementDescriptors.keys);
1531 1540
1532 CodeBuffer libraryBuffer = new CodeBuffer(); 1541 mainOutput
1533 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1542 ..add('(')
1534 writeLibraryDescriptors(libraryBuffer, library); 1543 ..addBuffer(
1535 elementDescriptors.remove(library);
1536 }
1537
1538 mainBuffer
1539 ..write('(')
1540 ..write(
1541 jsAst.prettyPrint( 1544 jsAst.prettyPrint(
1542 getReflectionDataParser(this, backend), 1545 getReflectionDataParser(this, backend),
1543 compiler)) 1546 compiler))
1544 ..write(')') 1547 ..add(')')
1545 ..write('([$n') 1548 ..add('([$n');
1546 ..write(libraryBuffer) 1549 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1547 ..write('])$N'); 1550 writeLibraryDescriptors(mainOutput, library);
1551 elementDescriptors.remove(library);
1552 }
1553 mainOutput.add('])$N');
1548 } 1554 }
1549 1555
1550 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); 1556 interceptorEmitter.emitGetInterceptorMethods(mainOutput);
1551 interceptorEmitter.emitOneShotInterceptors(mainBuffer); 1557 interceptorEmitter.emitOneShotInterceptors(mainOutput);
1552 1558
1553 if (task.outputContainsConstantList) { 1559 if (task.outputContainsConstantList) {
1554 emitMakeConstantList(mainBuffer); 1560 emitMakeConstantList(mainOutput);
1555 } 1561 }
1556 1562
1557 // Constants in checked mode call into RTI code to set type information 1563 // Constants in checked mode call into RTI code to set type information
1558 // which may need getInterceptor (and one-shot interceptor) methods, so 1564 // which may need getInterceptor (and one-shot interceptor) methods, so
1559 // we have to make sure that [emitGetInterceptorMethods] and 1565 // we have to make sure that [emitGetInterceptorMethods] and
1560 // [emitOneShotInterceptors] have been called. 1566 // [emitOneShotInterceptors] have been called.
1561 emitCompileTimeConstants(mainBuffer, mainOutputUnit); 1567 emitCompileTimeConstants(mainOutput, mainOutputUnit);
1562 1568
1563 emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes); 1569 emitDeferredBoilerPlate(mainOutput, deferredLoadHashes);
1564 1570
1565 // Static field initializations require the classes and compile-time 1571 // Static field initializations require the classes and compile-time
1566 // constants to be set up. 1572 // constants to be set up.
1567 emitStaticNonFinalFieldInitializations(mainBuffer, mainOutputUnit); 1573 emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit);
1568 interceptorEmitter.emitInterceptedNames(mainBuffer); 1574 interceptorEmitter.emitInterceptedNames(mainOutput);
1569 interceptorEmitter.emitMapTypeToInterceptor(mainBuffer); 1575 interceptorEmitter.emitMapTypeToInterceptor(mainOutput);
1570 emitLazilyInitializedStaticFields(mainBuffer); 1576 emitLazilyInitializedStaticFields(mainOutput);
1571 1577
1572 mainBuffer.writeln(); 1578 mainOutput.add('\n');
1573 mainBuffer.write(nativeBuffer); 1579 mainOutput.addBuffer(nativeBuffer);
1574 1580
1575 metadataEmitter.emitMetadata(mainBuffer); 1581 metadataEmitter.emitMetadata(mainOutput);
1576 1582
1577 isolateProperties = isolatePropertiesName; 1583 isolateProperties = isolatePropertiesName;
1578 // The following code should not use the short-hand for the 1584 // The following code should not use the short-hand for the
1579 // initialStatics. 1585 // initialStatics.
1580 mainBuffer.write('${namer.currentIsolate}$_=${_}null$N'); 1586 mainOutput.add('${namer.currentIsolate}$_=${_}null$N');
1581 1587
1582 emitFinishIsolateConstructorInvocation(mainBuffer); 1588 emitFinishIsolateConstructorInvocation(mainOutput);
1583 mainBuffer.write( 1589 mainOutput.add(
1584 '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N'); 1590 '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
1585 1591
1586 emitConvertToFastObjectFunction(); 1592 emitConvertToFastObjectFunction(mainOutput);
1587 for (String globalObject in Namer.reservedGlobalObjectNames) { 1593 for (String globalObject in Namer.reservedGlobalObjectNames) {
1588 mainBuffer.write('$globalObject = convertToFastObject($globalObject)$N'); 1594 mainOutput.add('$globalObject = convertToFastObject($globalObject)$N');
1589 } 1595 }
1590 if (DEBUG_FAST_OBJECTS) { 1596 if (DEBUG_FAST_OBJECTS) {
1591 mainBuffer.write(r''' 1597 mainOutput.add(r'''
1592 // The following only works on V8 when run with option 1598 // The following only works on V8 when run with option
1593 // "--allow-natives-syntax". We use'new Function' because the 1599 // "--allow-natives-syntax". We use'new Function' because the
1594 // miniparser does not understand V8 native syntax. 1600 // miniparser does not understand V8 native syntax.
1595 if (typeof print === "function") { 1601 if (typeof print === "function") {
1596 var HasFastProperties = 1602 var HasFastProperties =
1597 new Function("a", "return %HasFastProperties(a)"); 1603 new Function("a", "return %HasFastProperties(a)");
1598 print("Size of global helper object: " 1604 print("Size of global helper object: "
1599 + String(Object.getOwnPropertyNames(H).length) 1605 + String(Object.getOwnPropertyNames(H).length)
1600 + ", fast properties " + HasFastProperties(H)); 1606 + ", fast properties " + HasFastProperties(H));
1601 print("Size of global platform object: " 1607 print("Size of global platform object: "
1602 + String(Object.getOwnPropertyNames(P).length) 1608 + String(Object.getOwnPropertyNames(P).length)
1603 + ", fast properties " + HasFastProperties(P)); 1609 + ", fast properties " + HasFastProperties(P));
1604 print("Size of global dart:html object: " 1610 print("Size of global dart:html object: "
1605 + String(Object.getOwnPropertyNames(W).length) 1611 + String(Object.getOwnPropertyNames(W).length)
1606 + ", fast properties " + HasFastProperties(W)); 1612 + ", fast properties " + HasFastProperties(W));
1607 print("Size of isolate properties object: " 1613 print("Size of isolate properties object: "
1608 + String(Object.getOwnPropertyNames($).length) 1614 + String(Object.getOwnPropertyNames($).length)
1609 + ", fast properties " + HasFastProperties($)); 1615 + ", fast properties " + HasFastProperties($));
1610 print("Size of constant object: " 1616 print("Size of constant object: "
1611 + String(Object.getOwnPropertyNames(C).length) 1617 + String(Object.getOwnPropertyNames(C).length)
1612 + ", fast properties " + HasFastProperties(C)); 1618 + ", fast properties " + HasFastProperties(C));
1613 var names = Object.getOwnPropertyNames($); 1619 var names = Object.getOwnPropertyNames($);
1614 for (var i = 0; i < names.length; i++) { 1620 for (var i = 0; i < names.length; i++) {
1615 print("$." + names[i]); 1621 print("$." + names[i]);
1616 } 1622 }
1617 } 1623 }
1618 '''); 1624 ''');
1619 for (String object in Namer.userGlobalObjects) { 1625 for (String object in Namer.userGlobalObjects) {
1620 mainBuffer.write(''' 1626 mainOutput.add('''
1621 if (typeof print === "function") { 1627 if (typeof print === "function") {
1622 print("Size of $object: " 1628 print("Size of $object: "
1623 + String(Object.getOwnPropertyNames($object).length) 1629 + String(Object.getOwnPropertyNames($object).length)
1624 + ", fast properties " + HasFastProperties($object)); 1630 + ", fast properties " + HasFastProperties($object));
1625 } 1631 }
1626 '''); 1632 ''');
1627 } 1633 }
1628 } 1634 }
1629 1635
1630 jsAst.FunctionDeclaration precompiledFunctionAst = 1636 jsAst.FunctionDeclaration precompiledFunctionAst =
1631 buildCspPrecompiledFunctionFor(mainOutputUnit); 1637 buildCspPrecompiledFunctionFor(mainOutputUnit);
1632 emitInitFunction(mainBuffer); 1638 emitInitFunction(mainOutput);
1633 emitMain(mainBuffer); 1639 emitMain(mainOutput);
1634 mainBuffer.write('})()\n'); 1640 mainOutput.add('})()\n');
1635 1641
1636 if (compiler.useContentSecurityPolicy) { 1642 if (compiler.useContentSecurityPolicy) {
1637 mainBuffer.write( 1643 mainOutput.addBuffer(
1638 jsAst.prettyPrint( 1644 jsAst.prettyPrint(
1639 precompiledFunctionAst, 1645 precompiledFunctionAst,
1640 compiler, 1646 compiler,
1641 monitor: compiler.dumpInfoTask, 1647 monitor: compiler.dumpInfoTask,
1642 allowVariableMinification: false).getText()); 1648 allowVariableMinification: false));
1643 } 1649 }
1644 1650
1645 String assembledCode = mainBuffer.getText();
1646 if (generateSourceMap) { 1651 if (generateSourceMap) {
1647 outputSourceMap(assembledCode, mainBuffer, '', 1652 mainOutput.add(
1648 compiler.sourceMapUri, compiler.outputUri);
1649 mainBuffer.write(
1650 generateSourceMapTag(compiler.sourceMapUri, compiler.outputUri)); 1653 generateSourceMapTag(compiler.sourceMapUri, compiler.outputUri));
1651 assembledCode = mainBuffer.getText();
1652 } 1654 }
1653 1655
1654 compiler.outputProvider('', 'js') 1656 mainOutput.close();
1655 ..add(assembledCode) 1657
1656 ..close(); 1658 if (generateSourceMap) {
1659 outputSourceMap(mainOutput, lineColumnCollector, '',
1660 compiler.sourceMapUri, compiler.outputUri);
1661 }
1657 } 1662 }
1658 1663
1659 /// Used by incremental compilation to patch up the prototype of 1664 /// Used by incremental compilation to patch up the prototype of
1660 /// [oldConstructor] for use as prototype of [newConstructor]. 1665 /// [oldConstructor] for use as prototype of [newConstructor].
1661 jsAst.Fun buildSchemaChangeFunction() { 1666 jsAst.Fun buildSchemaChangeFunction() {
1662 return js(''' 1667 return js('''
1663 function(newConstructor, oldConstructor, superclass) { 1668 function(newConstructor, oldConstructor, superclass) {
1664 // Invariant: newConstructor.prototype has no interesting properties besides 1669 // Invariant: newConstructor.prototype has no interesting properties besides
1665 // generated accessors. These are copied to oldPrototype which will be 1670 // generated accessors. These are copied to oldPrototype which will be
1666 // updated by other incremental changes. 1671 // updated by other incremental changes.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 generateClass(element, getElementDescriptor(element)); 1800 generateClass(element, getElementDescriptor(element));
1796 } 1801 }
1797 } 1802 }
1798 1803
1799 if (elementDescriptors.isNotEmpty) { 1804 if (elementDescriptors.isNotEmpty) {
1800 Iterable<LibraryElement> libraries = 1805 Iterable<LibraryElement> libraries =
1801 task.outputLibraryLists[outputUnit]; 1806 task.outputLibraryLists[outputUnit];
1802 if (libraries == null) libraries = []; 1807 if (libraries == null) libraries = [];
1803 emitLibraries(libraries); 1808 emitLibraries(libraries);
1804 1809
1810 // TODO(johnniwinther): Avoid creating [CodeBuffer]s.
1805 CodeBuffer buffer = new CodeBuffer(); 1811 CodeBuffer buffer = new CodeBuffer();
1806 outputBuffers[outputUnit] = buffer; 1812 outputBuffers[outputUnit] = buffer;
1807 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1813 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1808 writeLibraryDescriptors(buffer, library); 1814 writeLibraryDescriptors(buffer, library);
1809 elementDescriptors.remove(library); 1815 elementDescriptors.remove(library);
1810 } 1816 }
1811 } 1817 }
1812 } 1818 }
1813 1819
1814 return emitDeferredCode(outputBuffers); 1820 return emitDeferredCode(outputBuffers);
1815 } 1821 }
1816 1822
1817 CodeBuffer buildNativesBuffer() { 1823 CodeBuffer buildNativesBuffer() {
1818 // Emit native classes on [nativeBuffer]. 1824 // Emit native classes on [nativeBuffer].
1825 // TODO(johnniwinther): Avoid creating a [CodeBuffer].
1819 final CodeBuffer nativeBuffer = new CodeBuffer(); 1826 final CodeBuffer nativeBuffer = new CodeBuffer();
1820 1827
1821 if (nativeClasses.isEmpty) return nativeBuffer; 1828 if (nativeClasses.isEmpty) return nativeBuffer;
1822 1829
1823 1830
1824 addComment('Native classes', nativeBuffer); 1831 addComment('Native classes', nativeBuffer);
1825 1832
1826 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer, 1833 nativeEmitter.generateNativeClasses(nativeClasses, additionalProperties);
1827 additionalProperties);
1828 1834
1829 nativeEmitter.finishGenerateNativeClasses(); 1835 nativeEmitter.finishGenerateNativeClasses();
1830 nativeEmitter.assembleCode(nativeBuffer); 1836 nativeEmitter.assembleCode(nativeBuffer);
1831 1837
1832 return nativeBuffer; 1838 return nativeBuffer;
1833 } 1839 }
1834 1840
1835 int emitProgram(Program program) { 1841 int emitProgram(Program program) {
1836 // Shorten the code by using [namer.currentIsolate] as temporary. 1842 // Shorten the code by using [namer.currentIsolate] as temporary.
1837 isolateProperties = namer.currentIsolate; 1843 isolateProperties = namer.currentIsolate;
1838 1844
1839 // Emit deferred units first, so we have their hashes. 1845 // Emit deferred units first, so we have their hashes.
1840 // Map from OutputUnit to a hash of its content. The hash uniquely 1846 // Map from OutputUnit to a hash of its content. The hash uniquely
1841 // identifies the code of the output-unit. It does not include 1847 // identifies the code of the output-unit. It does not include
1842 // boilerplate JS code, like the sourcemap directives or the hash 1848 // boilerplate JS code, like the sourcemap directives or the hash
1843 // itself. 1849 // itself.
1844 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits(); 1850 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits();
1845 CodeBuffer nativeBuffer = buildNativesBuffer(); 1851 CodeBuffer nativeBuffer = buildNativesBuffer();
1846 emitMainOutputUnit(deferredLoadHashes, nativeBuffer); 1852 emitMainOutputUnit(deferredLoadHashes, nativeBuffer);
1847 1853
1848 if (backend.requiresPreamble && 1854 if (backend.requiresPreamble &&
1849 !backend.htmlLibraryIsLoaded) { 1855 !backend.htmlLibraryIsLoaded) {
1850 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); 1856 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE);
1851 } 1857 }
1852
1853 // Return the total program size. 1858 // Return the total program size.
1854 return outputBuffers.values.fold(0, (a, b) => a + b.length); 1859 return outputBuffers.values.fold(0, (a, b) => a + b.length);
1855 } 1860 }
1856 1861
1857 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) { 1862 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) {
1858 if (sourceMapUri != null && fileUri != null) { 1863 if (sourceMapUri != null && fileUri != null) {
1859 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); 1864 String sourceMapFileName = relativize(fileUri, sourceMapUri, false);
1860 return ''' 1865 return '''
1861 1866
1862 //# sourceMappingURL=$sourceMapFileName 1867 //# sourceMappingURL=$sourceMapFileName
(...skipping 18 matching lines...) Expand all
1881 } 1886 }
1882 } 1887 }
1883 if (owner == null) { 1888 if (owner == null) {
1884 compiler.internalError(element, 'Owner is null.'); 1889 compiler.internalError(element, 'Owner is null.');
1885 } 1890 }
1886 return elementDescriptors.putIfAbsent( 1891 return elementDescriptors.putIfAbsent(
1887 owner, 1892 owner,
1888 () => new ClassBuilder(owner, namer)); 1893 () => new ClassBuilder(owner, namer));
1889 } 1894 }
1890 1895
1891 /// Emits support-code for deferred loading into [buffer]. 1896 /// Emits support-code for deferred loading into [output].
1892 void emitDeferredBoilerPlate(CodeBuffer buffer, 1897 void emitDeferredBoilerPlate(CodeOutput output,
1893 Map<OutputUnit, String> deferredLoadHashes) { 1898 Map<OutputUnit, String> deferredLoadHashes) {
1894 // Function for checking if a hunk is loaded given its hash. 1899 // Function for checking if a hunk is loaded given its hash.
1895 buffer.write(jsAst.prettyPrint( 1900 output.addBuffer(jsAst.prettyPrint(
1896 js('# = function(hunkHash) {' 1901 js('# = function(hunkHash) {'
1897 ' return !!$deferredInitializers[hunkHash];' 1902 ' return !!$deferredInitializers[hunkHash];'
1898 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)), 1903 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)),
1899 compiler, monitor: compiler.dumpInfoTask)); 1904 compiler, monitor: compiler.dumpInfoTask));
1900 buffer.write('$N'); 1905 output.add('$N');
1901 // Function for initializing a loaded hunk, given its hash. 1906 // Function for initializing a loaded hunk, given its hash.
1902 buffer.write(jsAst.prettyPrint( 1907 output.addBuffer(jsAst.prettyPrint(
1903 js('# = function(hunkHash) {' 1908 js('# = function(hunkHash) {'
1904 ' $deferredInitializers[hunkHash](' 1909 ' $deferredInitializers[hunkHash]('
1905 '$globalsHolder, ${namer.currentIsolate})' 1910 '$globalsHolder, ${namer.currentIsolate})'
1906 '}', 1911 '}',
1907 generateEmbeddedGlobalAccess( 1912 generateEmbeddedGlobalAccess(
1908 embeddedNames.INITIALIZE_LOADED_HUNK)), 1913 embeddedNames.INITIALIZE_LOADED_HUNK)),
1909 compiler, monitor: compiler.dumpInfoTask)); 1914 compiler, monitor: compiler.dumpInfoTask));
1910 buffer.write('$N'); 1915 output.add('$N');
1911 // Write a javascript mapping from Deferred import load ids (derrived 1916 // Write a javascript mapping from Deferred import load ids (derrived
1912 // from the import prefix.) to a list of lists of uris of hunks to load, 1917 // from the import prefix.) to a list of lists of uris of hunks to load,
1913 // and a corresponding mapping to a list of hashes used by 1918 // and a corresponding mapping to a list of hashes used by
1914 // INITIALIZE_LOADED_HUNK and IS_HUNK_LOADED. 1919 // INITIALIZE_LOADED_HUNK and IS_HUNK_LOADED.
1915 Map<String, List<String>> deferredLibraryUris = 1920 Map<String, List<String>> deferredLibraryUris =
1916 new Map<String, List<String>>(); 1921 new Map<String, List<String>>();
1917 Map<String, List<String>> deferredLibraryHashes = 1922 Map<String, List<String>> deferredLibraryHashes =
1918 new Map<String, List<String>>(); 1923 new Map<String, List<String>>();
1919 compiler.deferredLoadTask.hunksToLoad.forEach( 1924 compiler.deferredLoadTask.hunksToLoad.forEach(
1920 (String loadId, List<OutputUnit>outputUnits) { 1925 (String loadId, List<OutputUnit>outputUnits) {
(...skipping 13 matching lines...) Expand all
1934 List<jsAst.Property> properties = new List<jsAst.Property>(); 1939 List<jsAst.Property> properties = new List<jsAst.Property>();
1935 mapping.forEach((String key, List<String> values) { 1940 mapping.forEach((String key, List<String> values) {
1936 properties.add(new jsAst.Property(js.escapedString(key), 1941 properties.add(new jsAst.Property(js.escapedString(key),
1937 new jsAst.ArrayInitializer( 1942 new jsAst.ArrayInitializer(
1938 values.map(js.escapedString).toList()))); 1943 values.map(js.escapedString).toList())));
1939 }); 1944 });
1940 jsAst.Node initializer = 1945 jsAst.Node initializer =
1941 new jsAst.ObjectInitializer(properties, isOneLiner: true); 1946 new jsAst.ObjectInitializer(properties, isOneLiner: true);
1942 1947
1943 jsAst.Node globalName = generateEmbeddedGlobalAccess(name); 1948 jsAst.Node globalName = generateEmbeddedGlobalAccess(name);
1944 buffer.write(jsAst.prettyPrint( 1949 output.addBuffer(jsAst.prettyPrint(
1945 js("# = #", [globalName, initializer]), 1950 js("# = #", [globalName, initializer]),
1946 compiler, monitor: compiler.dumpInfoTask)); 1951 compiler, monitor: compiler.dumpInfoTask));
1947 buffer.write('$N'); 1952 output.add('$N');
1948
1949 } 1953 }
1950 1954
1951 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); 1955 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris);
1952 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, 1956 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES,
1953 deferredLibraryHashes); 1957 deferredLibraryHashes);
1954 } 1958 }
1955 1959
1956 /// Emits code for all output units except the main. 1960 /// Emits code for all output units except the main.
1957 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that 1961 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that
1958 /// can be used for calling the initializer. 1962 /// can be used for calling the initializer.
1959 Map<OutputUnit, String> emitDeferredCode( 1963 Map<OutputUnit, String> emitDeferredCode(
1960 Map<OutputUnit, CodeBuffer> deferredBuffers) { 1964 Map<OutputUnit, CodeBuffer> deferredBuffers) {
1961 1965
1962 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); 1966 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
1963 1967
1964 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { 1968 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
1965 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue; 1969 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
1966 1970
1967 CodeBuffer libraryDescriptorBuffer = deferredBuffers[outputUnit]; 1971 CodeOutput libraryDescriptorBuffer = deferredBuffers[outputUnit];
1968 1972
1969 CodeBuffer outputBuffer = new CodeBuffer(); 1973 List<CodeOutputListener> outputListeners = <CodeOutputListener>[];
1974 Hasher hasher = new Hasher();
1975 outputListeners.add(hasher);
1970 1976
1971 outputBuffer..write(buildGeneratedBy()) 1977 LineColumnCollector lineColumnCollector;
1972 ..write('${deferredInitializers}.current$_=$_' 1978 if (generateSourceMap) {
1973 'function$_(${globalsHolder}) {$N'); 1979 lineColumnCollector = new LineColumnCollector();
1980 outputListeners.add(lineColumnCollector);
1981 }
1982
1983 String partPrefix = deferredPartFileName(outputUnit, addExtension: false);
1984 CodeOutput output = new StreamCodeOutput(
1985 compiler.outputProvider(partPrefix, 'part.js'),
1986 outputListeners);
1987
1988 outputBuffers[outputUnit] = output;
1989
1990 output
1991 ..add(buildGeneratedBy())
1992 ..add('${deferredInitializers}.current$_=$_'
1993 'function$_(${globalsHolder}) {$N');
1974 for (String globalObject in Namer.reservedGlobalObjectNames) { 1994 for (String globalObject in Namer.reservedGlobalObjectNames) {
1975 outputBuffer 1995 output
1976 .write('var $globalObject$_=$_' 1996 .add('var $globalObject$_=$_'
1977 '${globalsHolder}.$globalObject$N'); 1997 '${globalsHolder}.$globalObject$N');
1978 } 1998 }
1979 outputBuffer 1999 output
1980 ..write('var init$_=$_${globalsHolder}.init$N') 2000 ..add('var init$_=$_${globalsHolder}.init$N')
1981 ..write('var ${namer.isolateName}$_=$_' 2001 ..add('var ${namer.isolateName}$_=$_'
1982 '${globalsHolder}.${namer.isolateName}$N'); 2002 '${globalsHolder}.${namer.isolateName}$N');
1983 if (libraryDescriptorBuffer != null) { 2003 if (libraryDescriptorBuffer != null) {
1984 // TODO(ahe): This defines a lot of properties on the 2004 // TODO(ahe): This defines a lot of properties on the
1985 // Isolate.prototype object. We know this will turn it into a 2005 // Isolate.prototype object. We know this will turn it into a
1986 // slow object in V8, so instead we should do something similar 2006 // slow object in V8, so instead we should do something similar
1987 // to Isolate.$finishIsolateConstructor. 2007 // to Isolate.$finishIsolateConstructor.
1988 outputBuffer 2008 output
1989 ..write('var ${namer.currentIsolate}$_=$_$isolatePropertiesName;$n') 2009 ..add('var ${namer.currentIsolate}$_=$_$isolatePropertiesName;$n')
1990 ..write('(') 2010 ..add('(')
1991 ..write( 2011 ..addBuffer(
1992 jsAst.prettyPrint( 2012 jsAst.prettyPrint(
1993 getReflectionDataParser(this, backend), 2013 getReflectionDataParser(this, backend),
1994 compiler, monitor: compiler.dumpInfoTask)) 2014 compiler, monitor: compiler.dumpInfoTask))
1995 ..write(')') 2015 ..add(')')
1996 ..write('([$n') 2016 ..add('([$n')
1997 ..addBuffer(libraryDescriptorBuffer) 2017 ..addBuffer(libraryDescriptorBuffer)
1998 ..write('])$N'); 2018 ..add('])$N');
1999
2000 } 2019 }
2001 2020
2002 // Set the currentIsolate variable to the current isolate (which is 2021 // Set the currentIsolate variable to the current isolate (which is
2003 // provided as second argument). 2022 // provided as second argument).
2004 // We need to do this, because we use the same variable for setting up 2023 // We need to do this, because we use the same variable for setting up
2005 // the isolate-properties and for storing the current isolate. During 2024 // the isolate-properties and for storing the current isolate. During
2006 // the setup (the code above this lines) we must set the variable to 2025 // the setup (the code above this lines) we must set the variable to
2007 // the isolate-properties. 2026 // the isolate-properties.
2008 // After we have done the setup it must point to the current Isolate. 2027 // After we have done the setup it must point to the current Isolate.
2009 // Otherwise all methods/functions accessing isolate variables will 2028 // Otherwise all methods/functions accessing isolate variables will
2010 // access the wrong object. 2029 // access the wrong object.
2011 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N"); 2030 output.add("${namer.currentIsolate}$_=${_}arguments[1]$N");
2012 2031
2013 emitCompileTimeConstants(outputBuffer, outputUnit); 2032 emitCompileTimeConstants(output, outputUnit);
2014 emitStaticNonFinalFieldInitializations(outputBuffer, outputUnit); 2033 emitStaticNonFinalFieldInitializations(output, outputUnit);
2015 outputBuffer.write('}$N'); 2034 output.add('}$N');
2016 2035
2017 if (compiler.useContentSecurityPolicy) { 2036 if (compiler.useContentSecurityPolicy) {
2018 jsAst.FunctionDeclaration precompiledFunctionAst = 2037 jsAst.FunctionDeclaration precompiledFunctionAst =
2019 buildCspPrecompiledFunctionFor(outputUnit); 2038 buildCspPrecompiledFunctionFor(outputUnit);
2020 2039
2021 outputBuffer.write( 2040 output.addBuffer(
2022 jsAst.prettyPrint( 2041 jsAst.prettyPrint(
2023 precompiledFunctionAst, compiler, 2042 precompiledFunctionAst, compiler,
2024 monitor: compiler.dumpInfoTask, 2043 monitor: compiler.dumpInfoTask,
2025 allowVariableMinification: false).getText()); 2044 allowVariableMinification: false));
2026 } 2045 }
2027 2046
2028 // Make a unique hash of the code (before the sourcemaps are added) 2047 // Make a unique hash of the code (before the sourcemaps are added)
2029 // This will be used to retrieve the initializing function from the global 2048 // This will be used to retrieve the initializing function from the global
2030 // variable. 2049 // variable.
2031 String hash = hashOfString(outputBuffer.getText()); 2050 String hash = hasher.getHash();
2032 2051
2033 outputBuffer.write('${deferredInitializers}["$hash"]$_=$_' 2052 output.add('${deferredInitializers}["$hash"]$_=$_'
2034 '${deferredInitializers}.current$N'); 2053 '${deferredInitializers}.current$N');
2035 2054
2036 String partPrefix = deferredPartFileName(outputUnit, addExtension: false);
2037 if (generateSourceMap) { 2055 if (generateSourceMap) {
2056
2038 Uri mapUri, partUri; 2057 Uri mapUri, partUri;
2039 Uri sourceMapUri = compiler.sourceMapUri; 2058 Uri sourceMapUri = compiler.sourceMapUri;
2040 Uri outputUri = compiler.outputUri; 2059 Uri outputUri = compiler.outputUri;
2041 2060
2042 String partName = "$partPrefix.part"; 2061 String partName = "$partPrefix.part";
2043 2062
2044 if (sourceMapUri != null) { 2063 if (sourceMapUri != null) {
2045 String mapFileName = partName + ".js.map"; 2064 String mapFileName = partName + ".js.map";
2046 List<String> mapSegments = sourceMapUri.pathSegments.toList(); 2065 List<String> mapSegments = sourceMapUri.pathSegments.toList();
2047 mapSegments[mapSegments.length - 1] = mapFileName; 2066 mapSegments[mapSegments.length - 1] = mapFileName;
2048 mapUri = compiler.sourceMapUri.replace(pathSegments: mapSegments); 2067 mapUri = compiler.sourceMapUri.replace(pathSegments: mapSegments);
2049 } 2068 }
2050 2069
2051 if (outputUri != null) { 2070 if (outputUri != null) {
2052 String partFileName = partName + ".js"; 2071 String partFileName = partName + ".js";
2053 List<String> partSegments = outputUri.pathSegments.toList(); 2072 List<String> partSegments = outputUri.pathSegments.toList();
2054 partSegments[partSegments.length - 1] = partFileName; 2073 partSegments[partSegments.length - 1] = partFileName;
2055 partUri = compiler.outputUri.replace(pathSegments: partSegments); 2074 partUri = compiler.outputUri.replace(pathSegments: partSegments);
2056 } 2075 }
2057 2076
2058 outputSourceMap(outputBuffer.getText(), outputBuffer, partName, 2077 output.add(generateSourceMapTag(mapUri, partUri));
2059 mapUri, partUri); 2078 output.close();
2060 outputBuffer.write(generateSourceMapTag(mapUri, partUri)); 2079 outputSourceMap(output, lineColumnCollector, partName,
2080 mapUri, partUri);
2081 } else {
2082 output.close();
2061 } 2083 }
2062 2084
2063 outputBuffers[outputUnit] = outputBuffer;
2064 compiler.outputProvider(partPrefix, 'part.js')
2065 ..add(outputBuffer.getText())
2066 ..close();
2067
2068 hunkHashes[outputUnit] = hash; 2085 hunkHashes[outputUnit] = hash;
2069 } 2086 }
2070 return hunkHashes; 2087 return hunkHashes;
2071 } 2088 }
2072 2089
2073 String buildGeneratedBy() { 2090 String buildGeneratedBy() {
2074 var suffix = ''; 2091 var suffix = '';
2075 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}'; 2092 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}';
2076 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n'; 2093 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n';
2077 } 2094 }
2078 2095
2079 void outputSourceMap(String code, CodeBuffer buffer, String name, 2096 void outputSourceMap(CodeOutput output,
2080 [Uri sourceMapUri, Uri fileUri]) { 2097 LineColumnProvider lineColumnProvider,
2098 String name,
2099 [Uri sourceMapUri,
2100 Uri fileUri]) {
2081 if (!generateSourceMap) return; 2101 if (!generateSourceMap) return;
2082 // Create a source file for the compilation output. This allows using 2102 // Create a source file for the compilation output. This allows using
2083 // [:getLine:] to transform offsets to line numbers in [SourceMapBuilder]. 2103 // [:getLine:] to transform offsets to line numbers in [SourceMapBuilder].
2084 SourceFile compiledFile = new StringSourceFile(null, code);
2085 SourceMapBuilder sourceMapBuilder = 2104 SourceMapBuilder sourceMapBuilder =
2086 new SourceMapBuilder(sourceMapUri, fileUri, compiledFile); 2105 new SourceMapBuilder(sourceMapUri, fileUri, lineColumnProvider);
2087 buffer.forEachSourceLocation(sourceMapBuilder.addMapping); 2106 output.forEachSourceLocation(sourceMapBuilder.addMapping);
2088 String sourceMap = sourceMapBuilder.build(); 2107 String sourceMap = sourceMapBuilder.build();
2089 compiler.outputProvider(name, 'js.map') 2108 compiler.outputProvider(name, 'js.map')
2090 ..add(sourceMap) 2109 ..add(sourceMap)
2091 ..close(); 2110 ..close();
2092 } 2111 }
2093 2112
2094 void invalidateCaches() { 2113 void invalidateCaches() {
2095 if (!compiler.hasIncrementalSupport) return; 2114 if (!compiler.hasIncrementalSupport) return;
2096 if (cachedElements.isEmpty) return; 2115 if (cachedElements.isEmpty) return;
2097 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2116 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2098 if (element.isInstanceMember) { 2117 if (element.isInstanceMember) {
2099 cachedClassBuilders.remove(element.enclosingClass); 2118 cachedClassBuilders.remove(element.enclosingClass);
2100 2119
2101 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2120 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2102 2121
2103 } 2122 }
2104 } 2123 }
2105 } 2124 }
2106 } 2125 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698