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

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: Remove lazy bailout initializers. Created 8 years, 3 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 247 }
245 str += "}\\n"; 248 str += "}\\n";
246 var newIsolate = new Function(str); 249 var newIsolate = new Function(str);
247 newIsolate.prototype = isolatePrototype; 250 newIsolate.prototype = isolatePrototype;
248 isolatePrototype.constructor = newIsolate; 251 isolatePrototype.constructor = newIsolate;
249 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; 252 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties;
250 return newIsolate; 253 return newIsolate;
251 }"""; 254 }""";
252 } 255 }
253 256
257 String get lazyInitializerFunction() {
258 String isolate = namer.CURRENT_ISOLATE;
259 String cyclicThrow = namer.isolateAccess(compiler.cyclicThrowHelper);
260 return """
261 function(prototype, staticName, fieldName, getterName, lazyValue) {
262 var sentinel_undefined = {};
kasperl 2012/09/05 08:25:24 Are you deliberately using a non-JS naming convent
floitsch 2012/09/05 09:31:07 Don't know why. Changed to JS convention. done.
263 var sentinel_in_progress = {};
264 prototype[fieldName] = sentinel_undefined;
265 var getter = new Function("{ return $isolate." + fieldName + ";}");
266 prototype[getterName] = function() {
267 var result = $isolate[fieldName];
268 try {
269 if (result === sentinel_undefined) {
270 $isolate[fieldName] = sentinel_in_progress;
271 try {
272 result = $isolate[fieldName] = lazyValue();
273 } catch (e) {
274 if ($isolate[fieldName] === sentinel_in_progress) {
275 $isolate[fieldName] = null;
276 }
277 throw e;
278 }
279 } else if(result === sentinel_in_progress) {
kasperl 2012/09/05 08:25:24 Add space between if and (.
floitsch 2012/09/05 09:31:07 Done.
280 $cyclicThrow(staticName);
281 }
282 return result;
283 } finally {
284 $isolate[getterName] = getter;
285 }
286 };
287 }""";
288 }
289
254 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) { 290 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) {
255 if (needsDefineClass) { 291 if (needsDefineClass) {
256 String isolate = namer.ISOLATE;
257 buffer.add("$defineClassName = $defineClassFunction;\n"); 292 buffer.add("$defineClassName = $defineClassFunction;\n");
258 buffer.add(protoSupportCheck); 293 buffer.add(protoSupportCheck);
259 buffer.add("$pendingClassesName = {};\n"); 294 buffer.add("$pendingClassesName = {};\n");
260 buffer.add("$finishClassesName = $finishClassesFunction;\n"); 295 buffer.add("$finishClassesName = $finishClassesFunction;\n");
261 } 296 }
262 } 297 }
263 298
299 void addLazyInitializerFunctionIfNecessary(CodeBuffer buffer) {
300 if (needsLazyInitializer) {
301 buffer.add("$lazyInitializerName = $lazyInitializerFunction;\n");
302 }
303 }
304
264 void emitFinishIsolateConstructor(CodeBuffer buffer) { 305 void emitFinishIsolateConstructor(CodeBuffer buffer) {
265 String name = finishIsolateConstructorName; 306 String name = finishIsolateConstructorName;
266 String value = finishIsolateConstructorFunction; 307 String value = finishIsolateConstructorFunction;
267 buffer.add("$name = $value;\n"); 308 buffer.add("$name = $value;\n");
268 } 309 }
269 310
270 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { 311 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
271 String isolate = namer.ISOLATE; 312 String isolate = namer.ISOLATE;
272 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n"); 313 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n");
273 } 314 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 DefineMemberFunction defineInstanceMember) { 422 DefineMemberFunction defineInstanceMember) {
382 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 423 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
383 if (selectors == null) return; 424 if (selectors == null) return;
384 for (Selector selector in selectors) { 425 for (Selector selector in selectors) {
385 if (!selector.applies(member, compiler)) continue; 426 if (!selector.applies(member, compiler)) continue;
386 addParameterStub(member, selector, defineInstanceMember); 427 addParameterStub(member, selector, defineInstanceMember);
387 } 428 }
388 } 429 }
389 430
390 bool instanceFieldNeedsGetter(Element member) { 431 bool instanceFieldNeedsGetter(Element member) {
391 assert(member.kind === ElementKind.FIELD); 432 assert(member.isField());
392 return compiler.codegenWorld.hasInvokedGetter(member, compiler); 433 return compiler.codegenWorld.hasInvokedGetter(member, compiler);
393 } 434 }
394 435
395 bool instanceFieldNeedsSetter(Element member) { 436 bool instanceFieldNeedsSetter(Element member) {
396 assert(member.kind === ElementKind.FIELD); 437 assert(member.isField());
397 return (member.modifiers === null || !member.modifiers.isFinalOrConst()) 438 return (member.modifiers === null || !member.modifiers.isFinalOrConst())
398 && compiler.codegenWorld.hasInvokedSetter(member, compiler); 439 && compiler.codegenWorld.hasInvokedSetter(member, compiler);
399 } 440 }
400 441
401 String compiledFieldName(Element member) { 442 String compiledFieldName(Element member) {
402 assert(member.kind === ElementKind.FIELD); 443 assert(member.isField());
403 return member.isNative() 444 return member.isNative()
404 ? member.name.slowToString() 445 ? member.name.slowToString()
405 : namer.getName(member); 446 : namer.getName(member);
406 } 447 }
407 448
408 void addInstanceMember(Element member, 449 void addInstanceMember(Element member,
409 DefineMemberFunction defineInstanceMember) { 450 DefineMemberFunction defineInstanceMember) {
410 // TODO(floitsch): we don't need to deal with members of 451 // TODO(floitsch): we don't need to deal with members of
411 // uninstantiated classes, that have been overwritten by subclasses. 452 // uninstantiated classes, that have been overwritten by subclasses.
412 453
413 if (member.kind === ElementKind.FUNCTION 454 if (member.isFunction()
414 || member.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY 455 || member.isGenerativeConstructorBody()
415 || member.kind === ElementKind.GETTER 456 || member.isGetter()
416 || member.kind === ElementKind.SETTER) { 457 || member.isSetter()) {
417 if (member.modifiers !== null && member.modifiers.isAbstract()) return; 458 if (member.modifiers !== null && member.modifiers.isAbstract()) return;
418 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member]; 459 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member];
419 if (codeBuffer == null) return; 460 if (codeBuffer == null) return;
420 defineInstanceMember(namer.getName(member), codeBuffer); 461 defineInstanceMember(namer.getName(member), codeBuffer);
421 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member]; 462 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member];
422 if (codeBuffer !== null) { 463 if (codeBuffer !== null) {
423 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer); 464 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer);
424 } 465 }
425 FunctionElement function = member; 466 FunctionElement function = member;
426 FunctionSignature parameters = function.computeSignature(compiler); 467 FunctionSignature parameters = function.computeSignature(compiler);
427 if (!parameters.optionalParameters.isEmpty()) { 468 if (!parameters.optionalParameters.isEmpty()) {
428 addParameterStubs(member, defineInstanceMember); 469 addParameterStubs(member, defineInstanceMember);
429 } 470 }
430 } else if (member.kind !== ElementKind.FIELD) { 471 } else if (!member.isField()) {
431 compiler.internalError('unexpected kind: "${member.kind}"', 472 compiler.internalError('unexpected kind: "${member.kind}"',
432 element: member); 473 element: member);
433 } 474 }
434 emitExtraAccessors(member, defineInstanceMember); 475 emitExtraAccessors(member, defineInstanceMember);
435 } 476 }
436 477
437 String generateCheckedSetter(Element member, String fieldName) { 478 String generateCheckedSetter(Element member, String fieldName) {
438 Type type = member.computeType(compiler); 479 Type type = member.computeType(compiler);
439 if (type.element.isTypeVariable() 480 if (type.element.isTypeVariable()
440 || type.element == compiler.dynamicClass 481 || type.element == compiler.dynamicClass
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 } 719 }
679 720
680 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { 721 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
681 if (needsDefineClass) { 722 if (needsDefineClass) {
682 buffer.add("$finishClassesName($classesCollector);\n"); 723 buffer.add("$finishClassesName($classesCollector);\n");
683 // Reset the map. 724 // Reset the map.
684 buffer.add("$classesCollector = {};\n"); 725 buffer.add("$classesCollector = {};\n");
685 } 726 }
686 } 727 }
687 728
729 void emitStaticFunctionWithNamer(CodeBuffer buffer,
730 Element element,
731 CodeBuffer functionBuffer,
732 String functionNamer(Element element)) {
733 String functionName = functionNamer(element);
734 buffer.add('$isolateProperties.$functionName = ');
735 addMappings(functionBuffer, buffer.length);
736 buffer.add(functionBuffer);
737 buffer.add(';\n\n');
738 }
688 void emitStaticFunctionsWithNamer(CodeBuffer buffer, 739 void emitStaticFunctionsWithNamer(CodeBuffer buffer,
689 Map<Element, CodeBuffer> generatedCode, 740 Map<Element, CodeBuffer> generatedCode,
690 String functionNamer(Element element)) { 741 String functionNamer(Element element)) {
691 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { 742 generatedCode.forEach((Element element, CodeBuffer functionBuffer) {
692 if (!element.isInstanceMember()) { 743 if (!element.isInstanceMember() && !element.isField()) {
693 String functionName = functionNamer(element); 744 emitStaticFunctionWithNamer(
694 buffer.add('$isolateProperties.$functionName = '); 745 buffer, element, functionBuffer,functionNamer);
695 addMappings(functionBuffer, buffer.length);
696 buffer.add(functionBuffer);
697 buffer.add(';\n\n');
698 } 746 }
699 }); 747 });
700 } 748 }
701 749
702 void emitStaticFunctions(CodeBuffer buffer) { 750 void emitStaticFunctions(CodeBuffer buffer) {
703 emitStaticFunctionsWithNamer(buffer, 751 emitStaticFunctionsWithNamer(buffer,
704 compiler.codegenWorld.generatedCode, 752 compiler.codegenWorld.generatedCode,
705 namer.getName); 753 namer.getName);
706 emitStaticFunctionsWithNamer(buffer, 754 emitStaticFunctionsWithNamer(buffer,
707 compiler.codegenWorld.generatedBailoutCode, 755 compiler.codegenWorld.generatedBailoutCode,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 CodeBuffer getterBuffer = new CodeBuffer(); 867 CodeBuffer getterBuffer = new CodeBuffer();
820 getterBuffer.add( 868 getterBuffer.add(
821 "function() { return new $closureClass(this, '$targetName'); }"); 869 "function() { return new $closureClass(this, '$targetName'); }");
822 defineInstanceMember(getterName, getterBuffer); 870 defineInstanceMember(getterName, getterBuffer);
823 } 871 }
824 872
825 void emitCallStubForGetter(Element member, 873 void emitCallStubForGetter(Element member,
826 Set<Selector> selectors, 874 Set<Selector> selectors,
827 DefineMemberFunction defineInstanceMember) { 875 DefineMemberFunction defineInstanceMember) {
828 String getter; 876 String getter;
829 if (member.kind == ElementKind.GETTER) { 877 if (member.isGetter()) {
830 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; 878 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
831 } else { 879 } else {
832 String name = namer.instanceFieldName(member.getLibrary(), member.name); 880 String name = namer.instanceFieldName(member.getLibrary(), member.name);
833 getter = "this.$name"; 881 getter = "this.$name";
834 } 882 }
835 for (Selector selector in selectors) { 883 for (Selector selector in selectors) {
836 if (selector.applies(member, compiler)) { 884 if (selector.applies(member, compiler)) {
837 String invocationName = 885 String invocationName =
838 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 886 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
839 selector); 887 selector);
(...skipping 20 matching lines...) Expand all
860 handler.getStaticNonFinalFieldsForEmission(); 908 handler.getStaticNonFinalFieldsForEmission();
861 for (Element element in staticNonFinalFields) { 909 for (Element element in staticNonFinalFields) {
862 buffer.add('$isolateProperties.${namer.getName(element)} = '); 910 buffer.add('$isolateProperties.${namer.getName(element)} = ');
863 compiler.withCurrentElement(element, () { 911 compiler.withCurrentElement(element, () {
864 handler.writeJsCodeForVariable(buffer, element); 912 handler.writeJsCodeForVariable(buffer, element);
865 }); 913 });
866 buffer.add(';\n'); 914 buffer.add(';\n');
867 } 915 }
868 } 916 }
869 917
918 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
919 ConstantHandler handler = compiler.constantHandler;
920 List<VariableElement> lazyFields =
921 handler.getLazilyInitializedFieldsForEmission();
922 if (!lazyFields.isEmpty()) {
923 needsLazyInitializer = true;
924 for (VariableElement element in lazyFields) {
925 assert(compiler.codegenWorld.generatedBailoutCode[element] === null);
926 StringBuffer code = compiler.codegenWorld.generatedCode[element];
927 assert(code != null);
928 // The code only computes the initial value. We build the lazy-check
929 // here:
930 // lazyInitializer(prototype, fieldName, getterName, initialValue);
931 buffer.add("$lazyInitializerName(");
932 buffer.add(isolateProperties);
933 buffer.add(", '");
934 buffer.add(element.name.slowToString());
935 buffer.add("', '");
936 buffer.add(namer.getName(element));
937 buffer.add("', '");
938 buffer.add(namer.getLazyInitializerName(element));
939 buffer.add("', ");
940 addMappings(code, buffer.length);
941 buffer.add(code);
942 buffer.add(");\n");
943 }
944 }
945 }
946
870 void emitCompileTimeConstants(CodeBuffer buffer) { 947 void emitCompileTimeConstants(CodeBuffer buffer) {
871 ConstantHandler handler = compiler.constantHandler; 948 ConstantHandler handler = compiler.constantHandler;
872 List<Constant> constants = handler.getConstantsForEmission(); 949 List<Constant> constants = handler.getConstantsForEmission();
873 bool addedMakeConstantList = false; 950 bool addedMakeConstantList = false;
874 for (Constant constant in constants) { 951 for (Constant constant in constants) {
875 String name = handler.getNameForConstant(constant); 952 String name = handler.getNameForConstant(constant);
876 // The name is null when the constant is already a JS constant. 953 // The name is null when the constant is already a JS constant.
877 // TODO(floitsch): every constant should be registered, so that we can 954 // TODO(floitsch): every constant should be registered, so that we can
878 // share the ones that take up too much space (like some strings). 955 // share the ones that take up too much space (like some strings).
879 if (name === null) continue; 956 if (name === null) continue;
(...skipping 12 matching lines...) Expand all
892 buffer.add(@'''.makeConstantList = function(list) { 969 buffer.add(@'''.makeConstantList = function(list) {
893 list.immutable$list = true; 970 list.immutable$list = true;
894 list.fixed$length = true; 971 list.fixed$length = true;
895 return list; 972 return list;
896 }; 973 };
897 '''); 974 ''');
898 } 975 }
899 976
900 void emitExtraAccessors(Element member, 977 void emitExtraAccessors(Element member,
901 DefineMemberFunction defineInstanceMember) { 978 DefineMemberFunction defineInstanceMember) {
902 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { 979 if (member.isGetter() || member.isField()) {
903 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 980 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
904 if (selectors !== null && !selectors.isEmpty()) { 981 if (selectors !== null && !selectors.isEmpty()) {
905 emitCallStubForGetter(member, selectors, defineInstanceMember); 982 emitCallStubForGetter(member, selectors, defineInstanceMember);
906 } 983 }
907 } else if (member.kind == ElementKind.FUNCTION) { 984 } else if (member.isFunction()) {
908 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { 985 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
909 emitDynamicFunctionGetter(member, defineInstanceMember); 986 emitDynamicFunctionGetter(member, defineInstanceMember);
910 } 987 }
911 } 988 }
912 } 989 }
913 990
914 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { 991 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) {
915 // Do not generate no such method handlers if there is no class. 992 // Do not generate no such method handlers if there is no class.
916 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; 993 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return;
917 994
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 boundClosureBuffer.clear(); 1224 boundClosureBuffer.clear();
1148 emitStaticFunctions(mainBuffer); 1225 emitStaticFunctions(mainBuffer);
1149 emitStaticFunctionGetters(mainBuffer); 1226 emitStaticFunctionGetters(mainBuffer);
1150 // We need to finish the classes before we construct compile time 1227 // We need to finish the classes before we construct compile time
1151 // constants. 1228 // constants.
1152 emitFinishClassesInvocationIfNecessary(mainBuffer); 1229 emitFinishClassesInvocationIfNecessary(mainBuffer);
1153 emitCompileTimeConstants(mainBuffer); 1230 emitCompileTimeConstants(mainBuffer);
1154 // Static field initializations require the classes and compile-time 1231 // Static field initializations require the classes and compile-time
1155 // constants to be set up. 1232 // constants to be set up.
1156 emitStaticNonFinalFieldInitializations(mainBuffer); 1233 emitStaticNonFinalFieldInitializations(mainBuffer);
1234 emitLazilyInitializedStaticFields(mainBuffer);
1157 1235
1158 isolateProperties = isolatePropertiesName; 1236 isolateProperties = isolatePropertiesName;
1159 // The following code should not use the short-hand for the 1237 // The following code should not use the short-hand for the
1160 // initialStatics. 1238 // initialStatics.
1161 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); 1239 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n');
1162 mainBuffer.add(boundClosureBuffer); 1240 mainBuffer.add(boundClosureBuffer);
1163 emitFinishClassesInvocationIfNecessary(mainBuffer); 1241 emitFinishClassesInvocationIfNecessary(mainBuffer);
1164 // After this assignment we will produce invalid JavaScript code if we use 1242 // After this assignment we will produce invalid JavaScript code if we use
1165 // the classesCollector variable. 1243 // the classesCollector variable.
1166 classesCollector = 'classesCollector should not be used from now on'; 1244 classesCollector = 'classesCollector should not be used from now on';
1167 1245
1168 emitFinishIsolateConstructorInvocation(mainBuffer); 1246 emitFinishIsolateConstructorInvocation(mainBuffer);
1169 mainBuffer.add( 1247 mainBuffer.add(
1170 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); 1248 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
1171 1249
1172 nativeEmitter.assembleCode(mainBuffer); 1250 nativeEmitter.assembleCode(mainBuffer);
1173 emitMain(mainBuffer); 1251 emitMain(mainBuffer);
1174 mainBuffer.add('function init() {\n'); 1252 mainBuffer.add('function init() {\n');
1175 mainBuffer.add('$isolateProperties = {};\n'); 1253 mainBuffer.add('$isolateProperties = {};\n');
1176 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer); 1254 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer);
1255 addLazyInitializerFunctionIfNecessary(mainBuffer);
1177 emitFinishIsolateConstructor(mainBuffer); 1256 emitFinishIsolateConstructor(mainBuffer);
1178 mainBuffer.add('}\n'); 1257 mainBuffer.add('}\n');
1179 compiler.assembledCode = mainBuffer.toString(); 1258 compiler.assembledCode = mainBuffer.toString();
1180 1259
1181 if (generateSourceMap) { 1260 if (generateSourceMap) {
1182 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode); 1261 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
1183 String sourceMap = sourceMapBuilder.build(compiledFile); 1262 String sourceMap = sourceMapBuilder.build(compiledFile);
1184 // TODO(podivilov): We should find a better way to return source maps to 1263 // TODO(podivilov): We should find a better way to return source maps to
1185 // compiler. Using diagnostic handler for that purpose is a temporary 1264 // compiler. Using diagnostic handler for that purpose is a temporary
1186 // hack. 1265 // hack.
(...skipping 12 matching lines...) Expand all
1199 sourceName = token.slowToString(); 1278 sourceName = token.slowToString();
1200 } 1279 }
1201 int totalOffset = bufferOffset + offset; 1280 int totalOffset = bufferOffset + offset;
1202 sourceMapBuilder.addMapping( 1281 sourceMapBuilder.addMapping(
1203 sourceFile, token.charOffset, sourceName, totalOffset); 1282 sourceFile, token.charOffset, sourceName, totalOffset);
1204 }); 1283 });
1205 } 1284 }
1206 } 1285 }
1207 1286
1208 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1287 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698