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

Side by Side Diff: lib/compiler/implementation/js_backend/emitter.dart

Issue 10855174: Lazy implementation of final variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase wrt CL 10832351. Created 8 years, 4 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * A function element that represents a closure call. The signature is copied 6 * A function element that represents a closure call. The signature is copied
7 * from the given element. 7 * from the given element.
8 */ 8 */
9 class ClosureInvocationElement extends FunctionElement { 9 class ClosureInvocationElement extends FunctionElement {
10 ClosureInvocationElement(SourceString name, 10 ClosureInvocationElement(SourceString name,
11 FunctionElement other) 11 FunctionElement other)
12 : super.from(name, other, other.enclosingElement); 12 : super.from(name, other, other.enclosingElement);
13 13
14 isInstanceMember() => true; 14 isInstanceMember() => true;
15 } 15 }
16 16
17 /** 17 /**
18 * Generates the code for all used classes in the program. Static fields (even 18 * Generates the code for all used classes in the program. Static fields (even
19 * in classes) are ignored, since they can be treated as non-class elements. 19 * in classes) are ignored, since they can be treated as non-class elements.
20 * 20 *
21 * The code for the containing (used) methods must exist in the [:universe:]. 21 * The code for the containing (used) methods must exist in the [:universe:].
22 */ 22 */
23 class CodeEmitterTask extends CompilerTask { 23 class CodeEmitterTask extends CompilerTask {
24 bool needsInheritFunction = false; 24 bool needsInheritFunction = false;
25 bool needsDefineClass = false; 25 bool needsDefineClass = false;
26 bool needsClosureClass = false; 26 bool needsClosureClass = false;
27 bool needsLazyInitializer = false;
27 final Namer namer; 28 final Namer namer;
28 NativeEmitter nativeEmitter; 29 NativeEmitter nativeEmitter;
29 CodeBuffer boundClosureBuffer; 30 CodeBuffer boundClosureBuffer;
30 CodeBuffer mainBuffer; 31 CodeBuffer mainBuffer;
31 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 32 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
32 well as in the generated code. */ 33 well as in the generated code. */
33 String isolateProperties; 34 String isolateProperties;
34 String classesCollector; 35 String classesCollector;
35 final Map<int, String> boundClosureCache; 36 final Map<int, String> boundClosureCache;
36 37
(...skipping 18 matching lines...) Expand all
55 String get finishClassesName() 56 String get finishClassesName()
56 => '${namer.ISOLATE}.\$finishClasses'; 57 => '${namer.ISOLATE}.\$finishClasses';
57 String get finishIsolateConstructorName() 58 String get finishIsolateConstructorName()
58 => '${namer.ISOLATE}.\$finishIsolateConstructor'; 59 => '${namer.ISOLATE}.\$finishIsolateConstructor';
59 String get pendingClassesName() 60 String get pendingClassesName()
60 => '${namer.ISOLATE}.\$pendingClasses'; 61 => '${namer.ISOLATE}.\$pendingClasses';
61 String get isolatePropertiesName() 62 String get isolatePropertiesName()
62 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; 63 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
63 String get supportsProtoName() 64 String get supportsProtoName()
64 => 'supportsProto'; 65 => 'supportsProto';
66 String get lazyInitializerName()
67 => '${namer.ISOLATE}.\$lazy';
65 68
66 final String GETTER_SUFFIX = "?"; 69 final String GETTER_SUFFIX = "?";
67 final String SETTER_SUFFIX = "!"; 70 final String SETTER_SUFFIX = "!";
68 final String GETTER_SETTER_SUFFIX = "="; 71 final String GETTER_SETTER_SUFFIX = "=";
69 72
70 String get generateGetterSetterFunction() { 73 String get generateGetterSetterFunction() {
71 return """ 74 return """
72 function(field, prototype) { 75 function(field, prototype) {
73 var len = field.length; 76 var len = field.length;
74 var lastChar = field[len - 1]; 77 var lastChar = field[len - 1];
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } 245 }
243 str += "}\\n"; 246 str += "}\\n";
244 var newIsolate = new Function(str); 247 var newIsolate = new Function(str);
245 newIsolate.prototype = isolatePrototype; 248 newIsolate.prototype = isolatePrototype;
246 isolatePrototype.constructor = newIsolate; 249 isolatePrototype.constructor = newIsolate;
247 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; 250 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties;
248 return newIsolate; 251 return newIsolate;
249 }"""; 252 }""";
250 } 253 }
251 254
255 String get lazyInitializerFunction() {
256 String isolate = namer.CURRENT_ISOLATE;
257 return """
258 function(prototype, fieldName, getterName, lazyValue) {
259 var sentinel = {};
260 prototype[fieldName] = sentinel;
261 var getter = new Function("{ return $isolate." + fieldName + ";}");
262 prototype[getterName] = function() {
263 var result = $isolate[fieldName];
264 try {
265 if (result === sentinel) {
kasperl 2012/08/17 09:30:04 I guess this doesn't catch cyclic initialization.
floitsch 2012/09/04 17:32:21 Done.
266 try {
267 result = $isolate[fieldName] = lazyValue();
268 } catch (e) {
269 if ($isolate[fieldName] === sentinel) {
270 $isolate[fieldName] = null;
271 }
272 throw e;
273 }
274 }
275 return result;
276 } finally {
277 $isolate[getterName] = getter;
278 }
279 };
280 }""";
281 }
282
252 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) { 283 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) {
253 if (needsDefineClass) { 284 if (needsDefineClass) {
254 String isolate = namer.ISOLATE;
255 buffer.add("$defineClassName = $defineClassFunction;\n"); 285 buffer.add("$defineClassName = $defineClassFunction;\n");
256 buffer.add(protoSupportCheck); 286 buffer.add(protoSupportCheck);
257 buffer.add("$pendingClassesName = {};\n"); 287 buffer.add("$pendingClassesName = {};\n");
258 buffer.add("$finishClassesName = $finishClassesFunction;\n"); 288 buffer.add("$finishClassesName = $finishClassesFunction;\n");
259 } 289 }
260 } 290 }
261 291
292 void addLazyInitializerFunctionIfNecessary(CodeBuffer buffer) {
293 if (needsLazyInitializer) {
294 buffer.add("$lazyInitializerName = $lazyInitializerFunction;\n");
295 }
296 }
297
262 void emitFinishIsolateConstructor(CodeBuffer buffer) { 298 void emitFinishIsolateConstructor(CodeBuffer buffer) {
263 String name = finishIsolateConstructorName; 299 String name = finishIsolateConstructorName;
264 String value = finishIsolateConstructorFunction; 300 String value = finishIsolateConstructorFunction;
265 buffer.add("$name = $value;\n"); 301 buffer.add("$name = $value;\n");
266 } 302 }
267 303
268 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { 304 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
269 String isolate = namer.ISOLATE; 305 String isolate = namer.ISOLATE;
270 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n"); 306 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n");
271 } 307 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 DefineMemberFunction defineInstanceMember) { 415 DefineMemberFunction defineInstanceMember) {
380 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 416 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
381 if (selectors == null) return; 417 if (selectors == null) return;
382 for (Selector selector in selectors) { 418 for (Selector selector in selectors) {
383 if (!selector.applies(member, compiler)) continue; 419 if (!selector.applies(member, compiler)) continue;
384 addParameterStub(member, selector, defineInstanceMember); 420 addParameterStub(member, selector, defineInstanceMember);
385 } 421 }
386 } 422 }
387 423
388 bool instanceFieldNeedsGetter(Element member) { 424 bool instanceFieldNeedsGetter(Element member) {
389 assert(member.kind === ElementKind.FIELD); 425 assert(member.isField());
390 return compiler.codegenWorld.hasInvokedGetter(member, compiler); 426 return compiler.codegenWorld.hasInvokedGetter(member, compiler);
391 } 427 }
392 428
393 bool instanceFieldNeedsSetter(Element member) { 429 bool instanceFieldNeedsSetter(Element member) {
394 assert(member.kind === ElementKind.FIELD); 430 assert(member.isField());
395 return (member.modifiers === null || !member.modifiers.isFinal()) 431 return (member.modifiers === null || !member.modifiers.isFinal())
396 && compiler.codegenWorld.hasInvokedSetter(member, compiler); 432 && compiler.codegenWorld.hasInvokedSetter(member, compiler);
397 } 433 }
398 434
399 String compiledFieldName(Element member) { 435 String compiledFieldName(Element member) {
400 assert(member.kind === ElementKind.FIELD); 436 assert(member.isField());
401 return member.isNative() 437 return member.isNative()
402 ? member.name.slowToString() 438 ? member.name.slowToString()
403 : namer.getName(member); 439 : namer.getName(member);
404 } 440 }
405 441
406 void addInstanceMember(Element member, 442 void addInstanceMember(Element member,
407 DefineMemberFunction defineInstanceMember) { 443 DefineMemberFunction defineInstanceMember) {
408 // TODO(floitsch): we don't need to deal with members of 444 // TODO(floitsch): we don't need to deal with members of
409 // uninstantiated classes, that have been overwritten by subclasses. 445 // uninstantiated classes, that have been overwritten by subclasses.
410 446
411 if (member.kind === ElementKind.FUNCTION 447 if (member.isFunction()
412 || member.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY 448 || member.isGenerativeConstructorBody()
413 || member.kind === ElementKind.GETTER 449 || member.isGetter()
414 || member.kind === ElementKind.SETTER) { 450 || member.isSetter()) {
415 if (member.modifiers !== null && member.modifiers.isAbstract()) return; 451 if (member.modifiers !== null && member.modifiers.isAbstract()) return;
416 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member]; 452 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member];
417 if (codeBuffer == null) return; 453 if (codeBuffer == null) return;
418 defineInstanceMember(namer.getName(member), codeBuffer); 454 defineInstanceMember(namer.getName(member), codeBuffer);
419 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member]; 455 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member];
420 if (codeBuffer !== null) { 456 if (codeBuffer !== null) {
421 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer); 457 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer);
422 } 458 }
423 FunctionElement function = member; 459 FunctionElement function = member;
424 FunctionSignature parameters = function.computeSignature(compiler); 460 FunctionSignature parameters = function.computeSignature(compiler);
425 if (!parameters.optionalParameters.isEmpty()) { 461 if (!parameters.optionalParameters.isEmpty()) {
426 addParameterStubs(member, defineInstanceMember); 462 addParameterStubs(member, defineInstanceMember);
427 } 463 }
428 } else if (member.kind !== ElementKind.FIELD) { 464 } else if (!member.isField()) {
429 compiler.internalError('unexpected kind: "${member.kind}"', 465 compiler.internalError('unexpected kind: "${member.kind}"',
430 element: member); 466 element: member);
431 } 467 }
432 emitExtraAccessors(member, defineInstanceMember); 468 emitExtraAccessors(member, defineInstanceMember);
433 } 469 }
434 470
435 Set<Element> emitClassFields(ClassElement classElement, CodeBuffer buffer) { 471 Set<Element> emitClassFields(ClassElement classElement, CodeBuffer buffer) {
436 // If the class is never instantiated we still need to set it up for 472 // If the class is never instantiated we still need to set it up for
437 // inheritance purposes, but we can simplify its JavaScript constructor. 473 // inheritance purposes, but we can simplify its JavaScript constructor.
438 bool isInstantiated = 474 bool isInstantiated =
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 } 682 }
647 683
648 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { 684 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
649 if (needsDefineClass) { 685 if (needsDefineClass) {
650 buffer.add("$finishClassesName($classesCollector);\n"); 686 buffer.add("$finishClassesName($classesCollector);\n");
651 // Reset the map. 687 // Reset the map.
652 buffer.add("$classesCollector = {};\n"); 688 buffer.add("$classesCollector = {};\n");
653 } 689 }
654 } 690 }
655 691
692 void emitStaticFunctionWithNamer(CodeBuffer buffer,
693 Element element,
694 CodeBuffer functionBuffer,
695 String functionNamer(Element element)) {
696 String functionName = functionNamer(element);
697 buffer.add('$isolateProperties.$functionName = ');
698 addMappings(functionBuffer, buffer.length);
699 buffer.add(functionBuffer);
700 buffer.add(';\n\n');
701 }
656 void emitStaticFunctionsWithNamer(CodeBuffer buffer, 702 void emitStaticFunctionsWithNamer(CodeBuffer buffer,
657 Map<Element, CodeBuffer> generatedCode, 703 Map<Element, CodeBuffer> generatedCode,
658 String functionNamer(Element element)) { 704 String functionNamer(Element element)) {
659 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { 705 generatedCode.forEach((Element element, CodeBuffer functionBuffer) {
660 if (!element.isInstanceMember()) { 706 if (!element.isInstanceMember() && !element.isField()) {
661 String functionName = functionNamer(element); 707 emitStaticFunctionWithNamer(
662 buffer.add('$isolateProperties.$functionName = '); 708 buffer, element, functionBuffer,functionNamer);
663 addMappings(functionBuffer, buffer.length);
664 buffer.add(functionBuffer);
665 buffer.add(';\n\n');
666 } 709 }
667 }); 710 });
668 } 711 }
669 712
670 void emitStaticFunctions(CodeBuffer buffer) { 713 void emitStaticFunctions(CodeBuffer buffer) {
671 emitStaticFunctionsWithNamer(buffer, 714 emitStaticFunctionsWithNamer(buffer,
672 compiler.codegenWorld.generatedCode, 715 compiler.codegenWorld.generatedCode,
673 namer.getName); 716 namer.getName);
674 emitStaticFunctionsWithNamer(buffer, 717 emitStaticFunctionsWithNamer(buffer,
675 compiler.codegenWorld.generatedBailoutCode, 718 compiler.codegenWorld.generatedBailoutCode,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 CodeBuffer getterBuffer = new CodeBuffer(); 830 CodeBuffer getterBuffer = new CodeBuffer();
788 getterBuffer.add( 831 getterBuffer.add(
789 "function() { return new $closureClass(this, '$targetName'); }"); 832 "function() { return new $closureClass(this, '$targetName'); }");
790 defineInstanceMember(getterName, getterBuffer); 833 defineInstanceMember(getterName, getterBuffer);
791 } 834 }
792 835
793 void emitCallStubForGetter(Element member, 836 void emitCallStubForGetter(Element member,
794 Set<Selector> selectors, 837 Set<Selector> selectors,
795 DefineMemberFunction defineInstanceMember) { 838 DefineMemberFunction defineInstanceMember) {
796 String getter; 839 String getter;
797 if (member.kind == ElementKind.GETTER) { 840 if (member.isGetter()) {
798 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; 841 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
799 } else { 842 } else {
800 String name = namer.instanceFieldName(member.getLibrary(), member.name); 843 String name = namer.instanceFieldName(member.getLibrary(), member.name);
801 getter = "this.$name"; 844 getter = "this.$name";
802 } 845 }
803 for (Selector selector in selectors) { 846 for (Selector selector in selectors) {
804 if (selector.applies(member, compiler)) { 847 if (selector.applies(member, compiler)) {
805 String invocationName = 848 String invocationName =
806 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 849 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
807 selector); 850 selector);
(...skipping 20 matching lines...) Expand all
828 handler.getStaticNonFinalFieldsForEmission(); 871 handler.getStaticNonFinalFieldsForEmission();
829 for (Element element in staticNonFinalFields) { 872 for (Element element in staticNonFinalFields) {
830 buffer.add('$isolateProperties.${namer.getName(element)} = '); 873 buffer.add('$isolateProperties.${namer.getName(element)} = ');
831 compiler.withCurrentElement(element, () { 874 compiler.withCurrentElement(element, () {
832 handler.writeJsCodeForVariable(buffer, element); 875 handler.writeJsCodeForVariable(buffer, element);
833 }); 876 });
834 buffer.add(';\n'); 877 buffer.add(';\n');
835 } 878 }
836 } 879 }
837 880
881 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
882 ConstantHandler handler = compiler.constantHandler;
883 List<VariableElement> lazyFields =
884 handler.getLazilyInitializedFieldsForEmission();
885 if (!lazyFields.isEmpty()) {
886 needsLazyInitializer = true;
887 for (VariableElement element in lazyFields) {
888 StringBuffer code = compiler.codegenWorld.generatedCode[element];
889 assert(code != null);
890 // The code only computes the initial value. We build the lazy-check
891 // here:
892 // lazyInitializer(prototype, fieldName, getterName, initialValue);
893 buffer.add("$lazyInitializerName(");
894 buffer.add(isolateProperties);
895 buffer.add(", '");
896 buffer.add(namer.getName(element));
897 buffer.add("', '");
898 buffer.add(namer.getLazyInitializerName(element));
899 buffer.add("', ");
900 addMappings(code, buffer.length);
901 buffer.add(code);
902 buffer.add(");\n");
903
904 CodeBuffer bailoutCode =
905 compiler.codegenWorld.generatedBailoutCode[element];
906 if (bailoutCode != null) {
907 Function functionNamer = namer.getLazyInitializerBailoutName;
908 emitStaticFunctionWithNamer(
909 buffer, element, bailoutCode, functionNamer);
910 }
911 }
912 }
913 }
914
838 void emitCompileTimeConstants(CodeBuffer buffer) { 915 void emitCompileTimeConstants(CodeBuffer buffer) {
839 ConstantHandler handler = compiler.constantHandler; 916 ConstantHandler handler = compiler.constantHandler;
840 List<Constant> constants = handler.getConstantsForEmission(); 917 List<Constant> constants = handler.getConstantsForEmission();
841 bool addedMakeConstantList = false; 918 bool addedMakeConstantList = false;
842 for (Constant constant in constants) { 919 for (Constant constant in constants) {
843 String name = handler.getNameForConstant(constant); 920 String name = handler.getNameForConstant(constant);
844 // The name is null when the constant is already a JS constant. 921 // The name is null when the constant is already a JS constant.
845 // TODO(floitsch): every constant should be registered, so that we can 922 // TODO(floitsch): every constant should be registered, so that we can
846 // share the ones that take up too much space (like some strings). 923 // share the ones that take up too much space (like some strings).
847 if (name === null) continue; 924 if (name === null) continue;
(...skipping 12 matching lines...) Expand all
860 buffer.add(@'''.makeConstantList = function(list) { 937 buffer.add(@'''.makeConstantList = function(list) {
861 list.immutable$list = true; 938 list.immutable$list = true;
862 list.fixed$length = true; 939 list.fixed$length = true;
863 return list; 940 return list;
864 }; 941 };
865 '''); 942 ''');
866 } 943 }
867 944
868 void emitExtraAccessors(Element member, 945 void emitExtraAccessors(Element member,
869 DefineMemberFunction defineInstanceMember) { 946 DefineMemberFunction defineInstanceMember) {
870 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { 947 if (member.isGetter() || member.isField()) {
871 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 948 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
872 if (selectors !== null && !selectors.isEmpty()) { 949 if (selectors !== null && !selectors.isEmpty()) {
873 emitCallStubForGetter(member, selectors, defineInstanceMember); 950 emitCallStubForGetter(member, selectors, defineInstanceMember);
874 } 951 }
875 } else if (member.kind == ElementKind.FUNCTION) { 952 } else if (member.isFunction()) {
876 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { 953 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
877 emitDynamicFunctionGetter(member, defineInstanceMember); 954 emitDynamicFunctionGetter(member, defineInstanceMember);
878 } 955 }
879 } 956 }
880 } 957 }
881 958
882 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { 959 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) {
883 // Do not generate no such method handlers if there is no class. 960 // Do not generate no such method handlers if there is no class.
884 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; 961 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return;
885 962
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 boundClosureBuffer.clear(); 1200 boundClosureBuffer.clear();
1124 emitStaticFunctions(mainBuffer); 1201 emitStaticFunctions(mainBuffer);
1125 emitStaticFunctionGetters(mainBuffer); 1202 emitStaticFunctionGetters(mainBuffer);
1126 // We need to finish the classes before we construct compile time 1203 // We need to finish the classes before we construct compile time
1127 // constants. 1204 // constants.
1128 emitFinishClassesInvocationIfNecessary(mainBuffer); 1205 emitFinishClassesInvocationIfNecessary(mainBuffer);
1129 emitCompileTimeConstants(mainBuffer); 1206 emitCompileTimeConstants(mainBuffer);
1130 // Static field initializations require the classes and compile-time 1207 // Static field initializations require the classes and compile-time
1131 // constants to be set up. 1208 // constants to be set up.
1132 emitStaticNonFinalFieldInitializations(mainBuffer); 1209 emitStaticNonFinalFieldInitializations(mainBuffer);
1210 emitLazilyInitializedStaticFields(mainBuffer);
1133 1211
1134 isolateProperties = isolatePropertiesName; 1212 isolateProperties = isolatePropertiesName;
1135 // The following code should not use the short-hand for the 1213 // The following code should not use the short-hand for the
1136 // initialStatics. 1214 // initialStatics.
1137 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); 1215 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n');
1138 mainBuffer.add(boundClosureBuffer); 1216 mainBuffer.add(boundClosureBuffer);
1139 emitFinishClassesInvocationIfNecessary(mainBuffer); 1217 emitFinishClassesInvocationIfNecessary(mainBuffer);
1140 // After this assignment we will produce invalid JavaScript code if we use 1218 // After this assignment we will produce invalid JavaScript code if we use
1141 // the classesCollector variable. 1219 // the classesCollector variable.
1142 classesCollector = 'classesCollector should not be used from now on'; 1220 classesCollector = 'classesCollector should not be used from now on';
1143 1221
1144 emitFinishIsolateConstructorInvocation(mainBuffer); 1222 emitFinishIsolateConstructorInvocation(mainBuffer);
1145 mainBuffer.add( 1223 mainBuffer.add(
1146 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); 1224 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
1147 1225
1148 nativeEmitter.assembleCode(mainBuffer); 1226 nativeEmitter.assembleCode(mainBuffer);
1149 emitMain(mainBuffer); 1227 emitMain(mainBuffer);
1150 mainBuffer.add('function init() {\n'); 1228 mainBuffer.add('function init() {\n');
1151 mainBuffer.add('$isolateProperties = {};\n'); 1229 mainBuffer.add('$isolateProperties = {};\n');
1152 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer); 1230 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer);
1231 addLazyInitializerFunctionIfNecessary(mainBuffer);
1153 emitFinishIsolateConstructor(mainBuffer); 1232 emitFinishIsolateConstructor(mainBuffer);
1154 mainBuffer.add('}\n'); 1233 mainBuffer.add('}\n');
1155 compiler.assembledCode = mainBuffer.toString(); 1234 compiler.assembledCode = mainBuffer.toString();
1156 1235
1157 if (generateSourceMap) { 1236 if (generateSourceMap) {
1158 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode); 1237 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
1159 String sourceMap = sourceMapBuilder.build(compiledFile); 1238 String sourceMap = sourceMapBuilder.build(compiledFile);
1160 // TODO(podivilov): We should find a better way to return source maps to 1239 // TODO(podivilov): We should find a better way to return source maps to
1161 // compiler. Using diagnostic handler for that purpose is a temporary 1240 // compiler. Using diagnostic handler for that purpose is a temporary
1162 // hack. 1241 // hack.
(...skipping 12 matching lines...) Expand all
1175 sourceName = token.slowToString(); 1254 sourceName = token.slowToString();
1176 } 1255 }
1177 int totalOffset = bufferOffset + offset; 1256 int totalOffset = bufferOffset + offset;
1178 sourceMapBuilder.addMapping( 1257 sourceMapBuilder.addMapping(
1179 sourceFile, token.charOffset, sourceName, totalOffset); 1258 sourceFile, token.charOffset, sourceName, totalOffset);
1180 }); 1259 });
1181 } 1260 }
1182 } 1261 }
1183 1262
1184 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1263 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698