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

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 and merge. 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,
(...skipping 14 matching lines...) Expand all
25 /** 25 /**
26 * Generates the code for all used classes in the program. Static fields (even 26 * Generates the code for all used classes in the program. Static fields (even
27 * in classes) are ignored, since they can be treated as non-class elements. 27 * in classes) are ignored, since they can be treated as non-class elements.
28 * 28 *
29 * The code for the containing (used) methods must exist in the [:universe:]. 29 * The code for the containing (used) methods must exist in the [:universe:].
30 */ 30 */
31 class CodeEmitterTask extends CompilerTask { 31 class CodeEmitterTask extends CompilerTask {
32 bool needsInheritFunction = false; 32 bool needsInheritFunction = false;
33 bool needsDefineClass = false; 33 bool needsDefineClass = false;
34 bool needsClosureClass = false; 34 bool needsClosureClass = false;
35 bool needsLazyInitializer = false;
35 final Namer namer; 36 final Namer namer;
36 NativeEmitter nativeEmitter; 37 NativeEmitter nativeEmitter;
37 CodeBuffer boundClosureBuffer; 38 CodeBuffer boundClosureBuffer;
38 CodeBuffer mainBuffer; 39 CodeBuffer mainBuffer;
39 /** Shorter access to [isolatePropertiesName]. Both here in the code, as 40 /** Shorter access to [isolatePropertiesName]. Both here in the code, as
40 well as in the generated code. */ 41 well as in the generated code. */
41 String isolateProperties; 42 String isolateProperties;
42 String classesCollector; 43 String classesCollector;
43 final Map<int, String> boundClosureCache; 44 final Map<int, String> boundClosureCache;
44 45
(...skipping 18 matching lines...) Expand all
63 String get finishClassesName 64 String get finishClassesName
64 => '${namer.ISOLATE}.\$finishClasses'; 65 => '${namer.ISOLATE}.\$finishClasses';
65 String get finishIsolateConstructorName 66 String get finishIsolateConstructorName
66 => '${namer.ISOLATE}.\$finishIsolateConstructor'; 67 => '${namer.ISOLATE}.\$finishIsolateConstructor';
67 String get pendingClassesName 68 String get pendingClassesName
68 => '${namer.ISOLATE}.\$pendingClasses'; 69 => '${namer.ISOLATE}.\$pendingClasses';
69 String get isolatePropertiesName 70 String get isolatePropertiesName
70 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; 71 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
71 String get supportsProtoName 72 String get supportsProtoName
72 => 'supportsProto'; 73 => 'supportsProto';
74 String get lazyInitializerName()
75 => '${namer.ISOLATE}.\$lazy';
73 76
74 final String GETTER_SUFFIX = "?"; 77 final String GETTER_SUFFIX = "?";
75 final String SETTER_SUFFIX = "!"; 78 final String SETTER_SUFFIX = "!";
76 final String GETTER_SETTER_SUFFIX = "="; 79 final String GETTER_SETTER_SUFFIX = "=";
77 80
78 String get generateGetterSetterFunction { 81 String get generateGetterSetterFunction {
79 return """ 82 return """
80 function(field, prototype) { 83 function(field, prototype) {
81 var len = field.length; 84 var len = field.length;
82 var lastChar = field[len - 1]; 85 var lastChar = field[len - 1];
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 } 255 }
253 str += "}\\n"; 256 str += "}\\n";
254 var newIsolate = new Function(str); 257 var newIsolate = new Function(str);
255 newIsolate.prototype = isolatePrototype; 258 newIsolate.prototype = isolatePrototype;
256 isolatePrototype.constructor = newIsolate; 259 isolatePrototype.constructor = newIsolate;
257 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; 260 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties;
258 return newIsolate; 261 return newIsolate;
259 }"""; 262 }""";
260 } 263 }
261 264
265 String get lazyInitializerFunction() {
266 String isolate = namer.CURRENT_ISOLATE;
267 JavaScriptBackend backend = compiler.backend;
268 String cyclicThrow = namer.isolateAccess(backend.cyclicThrowHelper);
269 return """
270 function(prototype, staticName, fieldName, getterName, lazyValue) {
271 var sentinelUndefined = {};
272 var sentinelInProgress = {};
273 prototype[fieldName] = sentinelUndefined;
274 var getter = new Function("{ return $isolate." + fieldName + ";}");
275 prototype[getterName] = function() {
276 var result = $isolate[fieldName];
277 try {
278 if (result === sentinelUndefined) {
279 $isolate[fieldName] = sentinelInProgress;
280 try {
281 result = $isolate[fieldName] = lazyValue();
282 } catch (e) {
283 if ($isolate[fieldName] === sentinelInProgress) {
284 $isolate[fieldName] = null;
285 }
286 throw e;
287 }
288 } else if (result === sentinelInProgress) {
289 $cyclicThrow(staticName);
290 }
291 return result;
292 } finally {
293 $isolate[getterName] = getter;
294 }
295 };
296 }""";
297 }
298
262 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) { 299 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) {
263 if (needsDefineClass) { 300 if (needsDefineClass) {
264 String isolate = namer.ISOLATE;
265 buffer.add("$defineClassName = $defineClassFunction;\n"); 301 buffer.add("$defineClassName = $defineClassFunction;\n");
266 buffer.add(protoSupportCheck); 302 buffer.add(protoSupportCheck);
267 buffer.add("$pendingClassesName = {};\n"); 303 buffer.add("$pendingClassesName = {};\n");
268 buffer.add("$finishClassesName = $finishClassesFunction;\n"); 304 buffer.add("$finishClassesName = $finishClassesFunction;\n");
269 } 305 }
270 } 306 }
271 307
308 void addLazyInitializerFunctionIfNecessary(CodeBuffer buffer) {
309 if (needsLazyInitializer) {
310 buffer.add("$lazyInitializerName = $lazyInitializerFunction;\n");
311 }
312 }
313
272 void emitFinishIsolateConstructor(CodeBuffer buffer) { 314 void emitFinishIsolateConstructor(CodeBuffer buffer) {
273 String name = finishIsolateConstructorName; 315 String name = finishIsolateConstructorName;
274 String value = finishIsolateConstructorFunction; 316 String value = finishIsolateConstructorFunction;
275 buffer.add("$name = $value;\n"); 317 buffer.add("$name = $value;\n");
276 } 318 }
277 319
278 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) { 320 void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
279 String isolate = namer.ISOLATE; 321 String isolate = namer.ISOLATE;
280 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n"); 322 buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n");
281 } 323 }
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 DefineMemberFunction defineInstanceMember) { 439 DefineMemberFunction defineInstanceMember) {
398 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 440 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
399 if (selectors == null) return; 441 if (selectors == null) return;
400 for (Selector selector in selectors) { 442 for (Selector selector in selectors) {
401 if (!selector.applies(member, compiler)) continue; 443 if (!selector.applies(member, compiler)) continue;
402 addParameterStub(member, selector, defineInstanceMember); 444 addParameterStub(member, selector, defineInstanceMember);
403 } 445 }
404 } 446 }
405 447
406 bool instanceFieldNeedsGetter(Element member) { 448 bool instanceFieldNeedsGetter(Element member) {
407 assert(member.kind === ElementKind.FIELD); 449 assert(member.isField());
408 return compiler.codegenWorld.hasInvokedGetter(member, compiler); 450 return compiler.codegenWorld.hasInvokedGetter(member, compiler);
409 } 451 }
410 452
411 bool instanceFieldNeedsSetter(Element member) { 453 bool instanceFieldNeedsSetter(Element member) {
412 assert(member.kind === ElementKind.FIELD); 454 assert(member.isField());
413 return (member.modifiers === null || !member.modifiers.isFinalOrConst()) 455 return (member.modifiers === null || !member.modifiers.isFinalOrConst())
414 && compiler.codegenWorld.hasInvokedSetter(member, compiler); 456 && compiler.codegenWorld.hasInvokedSetter(member, compiler);
415 } 457 }
416 458
417 String compiledFieldName(Element member) { 459 String compiledFieldName(Element member) {
418 assert(member.kind === ElementKind.FIELD); 460 assert(member.isField());
419 return member.isNative() 461 return member.isNative()
420 ? member.name.slowToString() 462 ? member.name.slowToString()
421 : namer.getName(member); 463 : namer.getName(member);
422 } 464 }
423 465
424 void addInstanceMember(Element member, 466 void addInstanceMember(Element member,
425 DefineMemberFunction defineInstanceMember) { 467 DefineMemberFunction defineInstanceMember) {
426 // TODO(floitsch): we don't need to deal with members of 468 // TODO(floitsch): we don't need to deal with members of
427 // uninstantiated classes, that have been overwritten by subclasses. 469 // uninstantiated classes, that have been overwritten by subclasses.
428 470
429 if (member.kind === ElementKind.FUNCTION 471 if (member.isFunction()
430 || member.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY 472 || member.isGenerativeConstructorBody()
431 || member.kind === ElementKind.GETTER 473 || member.isGetter()
432 || member.kind === ElementKind.SETTER) { 474 || member.isSetter()) {
433 if (member.modifiers !== null && member.modifiers.isAbstract()) return; 475 if (member.modifiers !== null && member.modifiers.isAbstract()) return;
434 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member]; 476 CodeBuffer codeBuffer = compiler.codegenWorld.generatedCode[member];
435 if (codeBuffer == null) return; 477 if (codeBuffer == null) return;
436 defineInstanceMember(namer.getName(member), codeBuffer); 478 defineInstanceMember(namer.getName(member), codeBuffer);
437 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member]; 479 codeBuffer = compiler.codegenWorld.generatedBailoutCode[member];
438 if (codeBuffer !== null) { 480 if (codeBuffer !== null) {
439 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer); 481 defineInstanceMember(compiler.namer.getBailoutName(member), codeBuffer);
440 } 482 }
441 FunctionElement function = member; 483 FunctionElement function = member;
442 FunctionSignature parameters = function.computeSignature(compiler); 484 FunctionSignature parameters = function.computeSignature(compiler);
443 if (!parameters.optionalParameters.isEmpty()) { 485 if (!parameters.optionalParameters.isEmpty()) {
444 addParameterStubs(member, defineInstanceMember); 486 addParameterStubs(member, defineInstanceMember);
445 } 487 }
446 } else if (member.kind !== ElementKind.FIELD) { 488 } else if (!member.isField()) {
447 compiler.internalError('unexpected kind: "${member.kind}"', 489 compiler.internalError('unexpected kind: "${member.kind}"',
448 element: member); 490 element: member);
449 } 491 }
450 emitExtraAccessors(member, defineInstanceMember); 492 emitExtraAccessors(member, defineInstanceMember);
451 } 493 }
452 494
453 String generateCheckedSetter(Element member, String fieldName) { 495 String generateCheckedSetter(Element member, String fieldName) {
454 Type type = member.computeType(compiler); 496 Type type = member.computeType(compiler);
455 if (type.element.isTypeVariable() 497 if (type.element.isTypeVariable()
456 || type.element == compiler.dynamicClass 498 || type.element == compiler.dynamicClass
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 } 736 }
695 737
696 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { 738 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
697 if (needsDefineClass) { 739 if (needsDefineClass) {
698 buffer.add("$finishClassesName($classesCollector);\n"); 740 buffer.add("$finishClassesName($classesCollector);\n");
699 // Reset the map. 741 // Reset the map.
700 buffer.add("$classesCollector = {};\n"); 742 buffer.add("$classesCollector = {};\n");
701 } 743 }
702 } 744 }
703 745
746 void emitStaticFunctionWithNamer(CodeBuffer buffer,
747 Element element,
748 CodeBuffer functionBuffer,
749 String functionNamer(Element element)) {
750 String functionName = functionNamer(element);
751 buffer.add('$isolateProperties.$functionName = ');
752 addMappings(functionBuffer, buffer.length);
753 buffer.add(functionBuffer);
754 buffer.add(';\n\n');
755 }
704 void emitStaticFunctionsWithNamer(CodeBuffer buffer, 756 void emitStaticFunctionsWithNamer(CodeBuffer buffer,
705 Map<Element, CodeBuffer> generatedCode, 757 Map<Element, CodeBuffer> generatedCode,
706 String functionNamer(Element element)) { 758 String functionNamer(Element element)) {
707 generatedCode.forEach((Element element, CodeBuffer functionBuffer) { 759 generatedCode.forEach((Element element, CodeBuffer functionBuffer) {
708 if (!element.isInstanceMember()) { 760 if (!element.isInstanceMember() && !element.isField()) {
709 String functionName = functionNamer(element); 761 emitStaticFunctionWithNamer(
710 buffer.add('$isolateProperties.$functionName = '); 762 buffer, element, functionBuffer,functionNamer);
711 addMappings(functionBuffer, buffer.length);
712 buffer.add(functionBuffer);
713 buffer.add(';\n\n');
714 } 763 }
715 }); 764 });
716 } 765 }
717 766
718 void emitStaticFunctions(CodeBuffer buffer) { 767 void emitStaticFunctions(CodeBuffer buffer) {
719 emitStaticFunctionsWithNamer(buffer, 768 emitStaticFunctionsWithNamer(buffer,
720 compiler.codegenWorld.generatedCode, 769 compiler.codegenWorld.generatedCode,
721 namer.getName); 770 namer.getName);
722 emitStaticFunctionsWithNamer(buffer, 771 emitStaticFunctionsWithNamer(buffer,
723 compiler.codegenWorld.generatedBailoutCode, 772 compiler.codegenWorld.generatedBailoutCode,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 CodeBuffer getterBuffer = new CodeBuffer(); 884 CodeBuffer getterBuffer = new CodeBuffer();
836 getterBuffer.add( 885 getterBuffer.add(
837 "function() { return new $closureClass(this, '$targetName'); }"); 886 "function() { return new $closureClass(this, '$targetName'); }");
838 defineInstanceMember(getterName, getterBuffer); 887 defineInstanceMember(getterName, getterBuffer);
839 } 888 }
840 889
841 void emitCallStubForGetter(Element member, 890 void emitCallStubForGetter(Element member,
842 Set<Selector> selectors, 891 Set<Selector> selectors,
843 DefineMemberFunction defineInstanceMember) { 892 DefineMemberFunction defineInstanceMember) {
844 String getter; 893 String getter;
845 if (member.kind == ElementKind.GETTER) { 894 if (member.isGetter()) {
846 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()"; 895 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
847 } else { 896 } else {
848 String name = namer.instanceFieldName(member.getLibrary(), member.name); 897 String name = namer.instanceFieldName(member.getLibrary(), member.name);
849 getter = "this.$name"; 898 getter = "this.$name";
850 } 899 }
851 for (Selector selector in selectors) { 900 for (Selector selector in selectors) {
852 if (selector.applies(member, compiler)) { 901 if (selector.applies(member, compiler)) {
853 String invocationName = 902 String invocationName =
854 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 903 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
855 selector); 904 selector);
(...skipping 20 matching lines...) Expand all
876 handler.getStaticNonFinalFieldsForEmission(); 925 handler.getStaticNonFinalFieldsForEmission();
877 for (Element element in staticNonFinalFields) { 926 for (Element element in staticNonFinalFields) {
878 buffer.add('$isolateProperties.${namer.getName(element)} = '); 927 buffer.add('$isolateProperties.${namer.getName(element)} = ');
879 compiler.withCurrentElement(element, () { 928 compiler.withCurrentElement(element, () {
880 handler.writeJsCodeForVariable(buffer, element); 929 handler.writeJsCodeForVariable(buffer, element);
881 }); 930 });
882 buffer.add(';\n'); 931 buffer.add(';\n');
883 } 932 }
884 } 933 }
885 934
935 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
936 ConstantHandler handler = compiler.constantHandler;
937 List<VariableElement> lazyFields =
938 handler.getLazilyInitializedFieldsForEmission();
939 if (!lazyFields.isEmpty()) {
940 needsLazyInitializer = true;
941 for (VariableElement element in lazyFields) {
942 assert(compiler.codegenWorld.generatedBailoutCode[element] === null);
943 StringBuffer code = compiler.codegenWorld.generatedCode[element];
944 assert(code != null);
945 // The code only computes the initial value. We build the lazy-check
946 // here:
947 // lazyInitializer(prototype, 'name', fieldName, getterName, initial);
948 // The name is used for error reporting. The 'initial' must be a
949 // closure that constructs the initial value.
950 buffer.add("$lazyInitializerName(");
951 buffer.add(isolateProperties);
952 buffer.add(", '");
953 buffer.add(element.name.slowToString());
954 buffer.add("', '");
955 buffer.add(namer.getName(element));
956 buffer.add("', '");
957 buffer.add(namer.getLazyInitializerName(element));
958 buffer.add("', ");
959 addMappings(code, buffer.length);
960 buffer.add(code);
961 buffer.add(");\n");
962 }
963 }
964 }
965
886 void emitCompileTimeConstants(CodeBuffer buffer) { 966 void emitCompileTimeConstants(CodeBuffer buffer) {
887 ConstantHandler handler = compiler.constantHandler; 967 ConstantHandler handler = compiler.constantHandler;
888 List<Constant> constants = handler.getConstantsForEmission(); 968 List<Constant> constants = handler.getConstantsForEmission();
889 bool addedMakeConstantList = false; 969 bool addedMakeConstantList = false;
890 for (Constant constant in constants) { 970 for (Constant constant in constants) {
891 String name = handler.getNameForConstant(constant); 971 String name = handler.getNameForConstant(constant);
892 // The name is null when the constant is already a JS constant. 972 // The name is null when the constant is already a JS constant.
893 // TODO(floitsch): every constant should be registered, so that we can 973 // TODO(floitsch): every constant should be registered, so that we can
894 // share the ones that take up too much space (like some strings). 974 // share the ones that take up too much space (like some strings).
895 if (name === null) continue; 975 if (name === null) continue;
(...skipping 12 matching lines...) Expand all
908 buffer.add(@'''.makeConstantList = function(list) { 988 buffer.add(@'''.makeConstantList = function(list) {
909 list.immutable$list = true; 989 list.immutable$list = true;
910 list.fixed$length = true; 990 list.fixed$length = true;
911 return list; 991 return list;
912 }; 992 };
913 '''); 993 ''');
914 } 994 }
915 995
916 void emitExtraAccessors(Element member, 996 void emitExtraAccessors(Element member,
917 DefineMemberFunction defineInstanceMember) { 997 DefineMemberFunction defineInstanceMember) {
918 if (member.kind == ElementKind.GETTER || member.kind == ElementKind.FIELD) { 998 if (member.isGetter() || member.isField()) {
919 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; 999 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
920 if (selectors !== null && !selectors.isEmpty()) { 1000 if (selectors !== null && !selectors.isEmpty()) {
921 emitCallStubForGetter(member, selectors, defineInstanceMember); 1001 emitCallStubForGetter(member, selectors, defineInstanceMember);
922 } 1002 }
923 } else if (member.kind == ElementKind.FUNCTION) { 1003 } else if (member.isFunction()) {
924 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { 1004 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
925 emitDynamicFunctionGetter(member, defineInstanceMember); 1005 emitDynamicFunctionGetter(member, defineInstanceMember);
926 } 1006 }
927 } 1007 }
928 } 1008 }
929 1009
930 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { 1010 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) {
931 // Do not generate no such method handlers if there is no class. 1011 // Do not generate no such method handlers if there is no class.
932 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; 1012 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return;
933 1013
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 boundClosureBuffer.clear(); 1243 boundClosureBuffer.clear();
1164 emitStaticFunctions(mainBuffer); 1244 emitStaticFunctions(mainBuffer);
1165 emitStaticFunctionGetters(mainBuffer); 1245 emitStaticFunctionGetters(mainBuffer);
1166 // We need to finish the classes before we construct compile time 1246 // We need to finish the classes before we construct compile time
1167 // constants. 1247 // constants.
1168 emitFinishClassesInvocationIfNecessary(mainBuffer); 1248 emitFinishClassesInvocationIfNecessary(mainBuffer);
1169 emitCompileTimeConstants(mainBuffer); 1249 emitCompileTimeConstants(mainBuffer);
1170 // Static field initializations require the classes and compile-time 1250 // Static field initializations require the classes and compile-time
1171 // constants to be set up. 1251 // constants to be set up.
1172 emitStaticNonFinalFieldInitializations(mainBuffer); 1252 emitStaticNonFinalFieldInitializations(mainBuffer);
1253 emitLazilyInitializedStaticFields(mainBuffer);
1173 1254
1174 isolateProperties = isolatePropertiesName; 1255 isolateProperties = isolatePropertiesName;
1175 // The following code should not use the short-hand for the 1256 // The following code should not use the short-hand for the
1176 // initialStatics. 1257 // initialStatics.
1177 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); 1258 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n');
1178 mainBuffer.add(boundClosureBuffer); 1259 mainBuffer.add(boundClosureBuffer);
1179 emitFinishClassesInvocationIfNecessary(mainBuffer); 1260 emitFinishClassesInvocationIfNecessary(mainBuffer);
1180 // After this assignment we will produce invalid JavaScript code if we use 1261 // After this assignment we will produce invalid JavaScript code if we use
1181 // the classesCollector variable. 1262 // the classesCollector variable.
1182 classesCollector = 'classesCollector should not be used from now on'; 1263 classesCollector = 'classesCollector should not be used from now on';
1183 1264
1184 emitFinishIsolateConstructorInvocation(mainBuffer); 1265 emitFinishIsolateConstructorInvocation(mainBuffer);
1185 mainBuffer.add( 1266 mainBuffer.add(
1186 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n'); 1267 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
1187 1268
1188 nativeEmitter.assembleCode(mainBuffer); 1269 nativeEmitter.assembleCode(mainBuffer);
1189 emitMain(mainBuffer); 1270 emitMain(mainBuffer);
1190 mainBuffer.add('function init() {\n'); 1271 mainBuffer.add('function init() {\n');
1191 mainBuffer.add('$isolateProperties = {};\n'); 1272 mainBuffer.add('$isolateProperties = {};\n');
1192 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer); 1273 addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer);
1274 addLazyInitializerFunctionIfNecessary(mainBuffer);
1193 emitFinishIsolateConstructor(mainBuffer); 1275 emitFinishIsolateConstructor(mainBuffer);
1194 mainBuffer.add('}\n'); 1276 mainBuffer.add('}\n');
1195 compiler.assembledCode = mainBuffer.toString(); 1277 compiler.assembledCode = mainBuffer.toString();
1196 1278
1197 if (generateSourceMap) { 1279 if (generateSourceMap) {
1198 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode); 1280 SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
1199 String sourceMap = sourceMapBuilder.build(compiledFile); 1281 String sourceMap = sourceMapBuilder.build(compiledFile);
1200 // TODO(podivilov): We should find a better way to return source maps to 1282 // TODO(podivilov): We should find a better way to return source maps to
1201 // compiler. Using diagnostic handler for that purpose is a temporary 1283 // compiler. Using diagnostic handler for that purpose is a temporary
1202 // hack. 1284 // hack.
(...skipping 12 matching lines...) Expand all
1215 sourceName = token.slowToString(); 1297 sourceName = token.slowToString();
1216 } 1298 }
1217 int totalOffset = bufferOffset + offset; 1299 int totalOffset = bufferOffset + offset;
1218 sourceMapBuilder.addMapping( 1300 sourceMapBuilder.addMapping(
1219 sourceFile, token.charOffset, sourceName, totalOffset); 1301 sourceFile, token.charOffset, sourceName, totalOffset);
1220 }); 1302 });
1221 } 1303 }
1222 } 1304 }
1223 1305
1224 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1306 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW
« no previous file with comments | « lib/compiler/implementation/js_backend/backend.dart ('k') | lib/compiler/implementation/lib/errors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698