| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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); |
| OLD | NEW |