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

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

Powered by Google App Engine
This is Rietveld 408576698