Chromium Code Reviews| 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 | 151 |
| 152 checkedClasses = new Set<ClassElement>(); | 152 checkedClasses = new Set<ClassElement>(); |
| 153 checkedTypedefs = new Set<TypedefElement>(); | 153 checkedTypedefs = new Set<TypedefElement>(); |
| 154 compiler.codegenWorld.isChecks.forEach((DartType t) { | 154 compiler.codegenWorld.isChecks.forEach((DartType t) { |
| 155 if (t is InterfaceType) { | 155 if (t is InterfaceType) { |
| 156 checkedClasses.add(t.element); | 156 checkedClasses.add(t.element); |
| 157 } else if (t is TypedefType) { | 157 } else if (t is TypedefType) { |
| 158 checkedTypedefs.add(t.element); | 158 checkedTypedefs.add(t.element); |
| 159 } | 159 } |
| 160 }); | 160 }); |
| 161 print(compiler.resolverWorld.isChecks); | |
| 162 print(compiler.codegenWorld.isChecks); | |
| 161 } | 163 } |
| 162 | 164 |
| 163 ClassElement computeMixinClass(MixinApplicationElement mixinApplication) { | 165 ClassElement computeMixinClass(MixinApplicationElement mixinApplication) { |
| 164 ClassElement mixin = mixinApplication.mixin; | 166 ClassElement mixin = mixinApplication.mixin; |
| 165 while (mixin.isMixinApplication) { | 167 while (mixin.isMixinApplication) { |
| 166 mixinApplication = mixin; | 168 mixinApplication = mixin; |
| 167 mixin = mixinApplication.mixin; | 169 mixin = mixinApplication.mixin; |
| 168 } | 170 } |
| 169 return mixin; | 171 return mixin; |
| 170 } | 172 } |
| (...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1752 } | 1754 } |
| 1753 | 1755 |
| 1754 return (ClassElement cls) => !unneededClasses.contains(cls); | 1756 return (ClassElement cls) => !unneededClasses.contains(cls); |
| 1755 } | 1757 } |
| 1756 | 1758 |
| 1757 void emitClosureClassIfNeeded(CodeBuffer buffer) { | 1759 void emitClosureClassIfNeeded(CodeBuffer buffer) { |
| 1758 // The closure class could have become necessary because of the generation | 1760 // The closure class could have become necessary because of the generation |
| 1759 // of stubs. | 1761 // of stubs. |
| 1760 ClassElement closureClass = compiler.closureClass; | 1762 ClassElement closureClass = compiler.closureClass; |
| 1761 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) { | 1763 if (needsClosureClass && !instantiatedClasses.contains(closureClass)) { |
| 1764 ClassElement objectClass = compiler.objectClass; | |
| 1765 if (!instantiatedClasses.contains(objectClass)) { | |
| 1766 generateClass(objectClass, bufferForElement(objectClass, buffer)); | |
| 1767 } | |
| 1762 generateClass(closureClass, bufferForElement(closureClass, buffer)); | 1768 generateClass(closureClass, bufferForElement(closureClass, buffer)); |
| 1763 } | 1769 } |
| 1764 } | 1770 } |
| 1765 | 1771 |
| 1766 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { | 1772 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) { |
| 1767 if (needsDefineClass) { | 1773 if (needsDefineClass) { |
| 1768 buffer.write('$finishClassesName($classesCollector,' | 1774 buffer.write('$finishClassesName($classesCollector,' |
| 1769 '$_$isolateProperties,' | 1775 '$_$isolateProperties,' |
| 1770 '${_}null)$N'); | 1776 '${_}null)$N'); |
| 1771 | 1777 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1807 | 1813 |
| 1808 // Is it possible the primary function was inlined but the bailout was not? | 1814 // Is it possible the primary function was inlined but the bailout was not? |
| 1809 for (Element element in | 1815 for (Element element in |
| 1810 Elements.sortedByPosition(pendingElementsWithBailouts)) { | 1816 Elements.sortedByPosition(pendingElementsWithBailouts)) { |
| 1811 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | 1817 CodeBuffer buffer = bufferForElement(element, eagerBuffer); |
| 1812 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; | 1818 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; |
| 1813 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); | 1819 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); |
| 1814 } | 1820 } |
| 1815 } | 1821 } |
| 1816 | 1822 |
| 1823 final Map<Element, Element> staticGetters = new Map<Element, Element>(); | |
| 1824 | |
| 1817 void emitStaticFunctionGetters(CodeBuffer eagerBuffer) { | 1825 void emitStaticFunctionGetters(CodeBuffer eagerBuffer) { |
| 1826 for (FunctionElement element in | |
| 1827 Elements.sortedByPosition(staticGetters.keys)) { | |
| 1828 Element closure = staticGetters[element]; | |
| 1829 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | |
| 1830 String closureClass = namer.isolateAccess(closure); | |
| 1831 String name = namer.getStaticClosureName(element); | |
| 1832 String staticName = namer.getName(element); | |
| 1833 | |
| 1834 String closureName = namer.getStaticClosureName(element); | |
| 1835 jsAst.Node assignment = js('$isolateProperties.$name = ' | |
| 1836 'new $closureClass($isolateProperties.$staticName, "$closureName")'); | |
|
ahe
2013/05/16 20:07:56
This broke deferred loading (and try.dartlang.org)
sra1
2013/05/16 20:28:33
This would 'just work' if static function closures
ahe
2013/05/16 20:30:44
I was thinking the same thing. Well, up to the se
| |
| 1837 buffer.write(jsAst.prettyPrint(assignment, compiler)); | |
| 1838 buffer.write('$N'); | |
| 1839 } | |
| 1840 } | |
| 1841 | |
| 1842 void emitStaticFunctionClosures() { | |
| 1818 Set<FunctionElement> functionsNeedingGetter = | 1843 Set<FunctionElement> functionsNeedingGetter = |
| 1819 compiler.codegenWorld.staticFunctionsNeedingGetter; | 1844 compiler.codegenWorld.staticFunctionsNeedingGetter; |
| 1820 for (FunctionElement element in | 1845 for (FunctionElement element in |
| 1821 Elements.sortedByPosition(functionsNeedingGetter)) { | 1846 Elements.sortedByPosition(functionsNeedingGetter)) { |
| 1822 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | 1847 String staticName = namer.getName(element); |
| 1848 String superName = namer.getName(compiler.closureClass); | |
| 1849 String name = 'Closure\$${element.name.slowToString()}'; | |
| 1850 needsClosureClass = true; | |
| 1823 | 1851 |
| 1824 // The static function does not have the correct name. Since | 1852 ClassElement closureClassElement = new ClosureClassElement( |
| 1825 // [addParameterStubs] use the name to create its stubs we simply | 1853 null, new SourceString(name), compiler, element, |
| 1826 // create a fake element with the correct name. | 1854 element.getCompilationUnit()); |
| 1855 // Now add the methods on the closure class. The instance method does not | |
| 1856 // have the correct name. Since [addParameterStubs] use the name to create | |
| 1857 // its stubs we simply create a fake element with the correct name. | |
| 1827 // Note: the callElement will not have any enclosingElement. | 1858 // Note: the callElement will not have any enclosingElement. |
| 1828 FunctionElement callElement = | 1859 FunctionElement callElement = |
| 1829 new ClosureInvocationElement(namer.closureInvocationSelectorName, | 1860 new ClosureInvocationElement(namer.closureInvocationSelectorName, |
| 1830 element); | 1861 element); |
| 1831 String staticName = namer.getName(element); | 1862 |
| 1832 String invocationName = namer.instanceMethodName(callElement); | 1863 String invocationName = namer.instanceMethodName(callElement); |
| 1833 String fieldAccess = '$isolateProperties.$staticName'; | 1864 String mangledName = namer.getName(closureClassElement); |
| 1834 buffer.write("$fieldAccess.$invocationName$_=$_$fieldAccess$N"); | |
| 1835 | 1865 |
| 1836 addParameterStubs(callElement, (String name, jsAst.Expression value) { | 1866 // Define the constructor with a name so that Object.toString can |
| 1837 jsAst.Expression assignment = | 1867 // find the class name of the closure class. |
| 1838 js('$isolateProperties.$staticName.$name = #', value); | 1868 ClassBuilder closureBuilder = new ClassBuilder(); |
| 1839 buffer.write(jsAst.prettyPrint(assignment.toStatement(), compiler)); | 1869 // If a static function is used as a closure we need to add its name |
| 1840 buffer.write('$N'); | 1870 // in case it is used in spawnFunction. |
| 1871 String methodName = namer.STATIC_CLOSURE_NAME_NAME; | |
| 1872 emitBoundClosureClassHeader( | |
| 1873 mangledName, superName, <String>[invocationName, methodName], | |
| 1874 closureBuilder); | |
| 1875 | |
| 1876 addParameterStubs(callElement, closureBuilder.addProperty); | |
| 1877 | |
| 1878 DartType type = element.computeType(compiler); | |
| 1879 getTypedefChecksOn(type).forEach((Element typedef) { | |
| 1880 String operator = namer.operatorIs(typedef); | |
| 1881 closureBuilder.addProperty(operator, js('true')); | |
| 1841 }); | 1882 }); |
| 1842 | 1883 |
| 1843 // If a static function is used as a closure we need to add its name | 1884 // TODO(ngeoffray): Cache common base classes for clsures, bound |
| 1844 // in case it is used in spawnFunction. | 1885 // closures, and static closures that have common type checks. |
| 1845 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; | 1886 boundClosures.add( |
| 1846 buffer.write('$fieldAccess.$fieldName$_=$_"$staticName"$N'); | 1887 js('$classesCollector.$mangledName = #', |
| 1847 getTypedefChecksOn(element.computeType(compiler)).forEach( | 1888 closureBuilder.toObjectInitializer())); |
| 1848 (Element typedef) { | 1889 |
| 1849 String operator = namer.operatorIs(typedef); | 1890 staticGetters[element] = closureClassElement; |
| 1850 buffer.write('$fieldAccess.$operator$_=${_}true$N'); | |
| 1851 } | |
| 1852 ); | |
| 1853 } | 1891 } |
| 1854 } | 1892 } |
| 1855 | 1893 |
| 1856 void emitBoundClosureClassHeader(String mangledName, | 1894 void emitBoundClosureClassHeader(String mangledName, |
| 1857 String superName, | 1895 String superName, |
| 1858 List<String> fieldNames, | 1896 List<String> fieldNames, |
| 1859 ClassBuilder builder) { | 1897 ClassBuilder builder) { |
| 1860 builder.addProperty('', | 1898 builder.addProperty('', |
| 1861 js.string("$superName;${fieldNames.join(',')}")); | 1899 js.string("$superName;${fieldNames.join(',')}")); |
| 1862 } | 1900 } |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2346 for (String jsName in addedJsNames.keys.toList()..sort()) { | 2384 for (String jsName in addedJsNames.keys.toList()..sort()) { |
| 2347 Selector selector = addedJsNames[jsName]; | 2385 Selector selector = addedJsNames[jsName]; |
| 2348 jsAst.Expression method = generateMethod(jsName, selector); | 2386 jsAst.Expression method = generateMethod(jsName, selector); |
| 2349 if (method != null) defineStub(jsName, method); | 2387 if (method != null) defineStub(jsName, method); |
| 2350 } | 2388 } |
| 2351 } | 2389 } |
| 2352 | 2390 |
| 2353 String buildIsolateSetup(CodeBuffer buffer, | 2391 String buildIsolateSetup(CodeBuffer buffer, |
| 2354 Element appMain, | 2392 Element appMain, |
| 2355 Element isolateMain) { | 2393 Element isolateMain) { |
| 2356 String mainAccess = "${namer.isolateAccess(appMain)}"; | 2394 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}"; |
| 2357 String currentIsolate = "${namer.CURRENT_ISOLATE}"; | 2395 String currentIsolate = "${namer.CURRENT_ISOLATE}"; |
| 2358 // Since we pass the closurized version of the main method to | 2396 // Since we pass the closurized version of the main method to |
| 2359 // the isolate method, we must make sure that it exists. | 2397 // the isolate method, we must make sure that it exists. |
| 2360 if (!compiler.codegenWorld.staticFunctionsNeedingGetter.contains(appMain)) { | |
| 2361 Selector selector = new Selector.callClosure(0); | |
| 2362 String invocationName = namer.invocationName(selector); | |
| 2363 buffer.write("$mainAccess.$invocationName = $mainAccess$N"); | |
| 2364 } | |
| 2365 return "${namer.isolateAccess(isolateMain)}($mainAccess)"; | 2398 return "${namer.isolateAccess(isolateMain)}($mainAccess)"; |
| 2366 } | 2399 } |
| 2367 | 2400 |
| 2368 String get nameOfDispatchPropertyInitializer => 'initializeDispatchProperty'; | 2401 String get nameOfDispatchPropertyInitializer => 'initializeDispatchProperty'; |
| 2369 | 2402 |
| 2370 jsAst.Expression generateDispatchPropertyInitialization() { | 2403 jsAst.Expression generateDispatchPropertyInitialization() { |
| 2371 String ref(Element element) { | 2404 String ref(Element element) { |
| 2372 return '${namer.CURRENT_ISOLATE}.${namer.getName(element)}'; | 2405 return '${namer.CURRENT_ISOLATE}.${namer.getName(element)}'; |
| 2373 } | 2406 } |
| 2374 | 2407 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2446 throw 'internal error'; | 2479 throw 'internal error'; |
| 2447 } else if (cls == backend.jsArrayClass || | 2480 } else if (cls == backend.jsArrayClass || |
| 2448 cls == backend.jsMutableArrayClass || | 2481 cls == backend.jsMutableArrayClass || |
| 2449 cls == backend.jsFixedArrayClass || | 2482 cls == backend.jsFixedArrayClass || |
| 2450 cls == backend.jsExtendableArrayClass) { | 2483 cls == backend.jsExtendableArrayClass) { |
| 2451 condition = js('receiver.constructor == Array'); | 2484 condition = js('receiver.constructor == Array'); |
| 2452 } else if (cls == backend.jsStringClass) { | 2485 } else if (cls == backend.jsStringClass) { |
| 2453 condition = js('(typeof receiver) == "string"'); | 2486 condition = js('(typeof receiver) == "string"'); |
| 2454 } else if (cls == backend.jsNullClass) { | 2487 } else if (cls == backend.jsNullClass) { |
| 2455 condition = js('receiver == null'); | 2488 condition = js('receiver == null'); |
| 2456 } else if (cls == backend.jsFunctionClass) { | |
| 2457 condition = js('(typeof receiver) == "function"'); | |
| 2458 } else { | 2489 } else { |
| 2459 throw 'internal error'; | 2490 throw 'internal error'; |
| 2460 } | 2491 } |
| 2461 return js.if_(condition, buildReturnInterceptor(cls)); | 2492 return js.if_(condition, buildReturnInterceptor(cls)); |
| 2462 } | 2493 } |
| 2463 | 2494 |
| 2464 bool hasArray = false; | 2495 bool hasArray = false; |
| 2465 bool hasBool = false; | 2496 bool hasBool = false; |
| 2466 bool hasDouble = false; | 2497 bool hasDouble = false; |
| 2467 bool hasFunction = false; | |
| 2468 bool hasInt = false; | 2498 bool hasInt = false; |
| 2469 bool hasNull = false; | 2499 bool hasNull = false; |
| 2470 bool hasNumber = false; | 2500 bool hasNumber = false; |
| 2471 bool hasString = false; | 2501 bool hasString = false; |
| 2472 bool hasNative = false; | 2502 bool hasNative = false; |
| 2473 for (ClassElement cls in classes) { | 2503 for (ClassElement cls in classes) { |
| 2474 if (cls == backend.jsArrayClass || | 2504 if (cls == backend.jsArrayClass || |
| 2475 cls == backend.jsMutableArrayClass || | 2505 cls == backend.jsMutableArrayClass || |
| 2476 cls == backend.jsFixedArrayClass || | 2506 cls == backend.jsFixedArrayClass || |
| 2477 cls == backend.jsExtendableArrayClass) hasArray = true; | 2507 cls == backend.jsExtendableArrayClass) hasArray = true; |
| 2478 else if (cls == backend.jsBoolClass) hasBool = true; | 2508 else if (cls == backend.jsBoolClass) hasBool = true; |
| 2479 else if (cls == backend.jsDoubleClass) hasDouble = true; | 2509 else if (cls == backend.jsDoubleClass) hasDouble = true; |
| 2480 else if (cls == backend.jsFunctionClass) hasFunction = true; | |
| 2481 else if (cls == backend.jsIntClass) hasInt = true; | 2510 else if (cls == backend.jsIntClass) hasInt = true; |
| 2482 else if (cls == backend.jsNullClass) hasNull = true; | 2511 else if (cls == backend.jsNullClass) hasNull = true; |
| 2483 else if (cls == backend.jsNumberClass) hasNumber = true; | 2512 else if (cls == backend.jsNumberClass) hasNumber = true; |
| 2484 else if (cls == backend.jsStringClass) hasString = true; | 2513 else if (cls == backend.jsStringClass) hasString = true; |
| 2485 else { | 2514 else { |
| 2486 // TODO(sra): The set of classes includes classes mixed-in to | 2515 // TODO(sra): The set of classes includes classes mixed-in to |
| 2487 // interceptor classes. | 2516 // interceptor classes. |
| 2488 // assert(cls == compiler.objectClass || cls.isNative()); | 2517 // assert(cls == compiler.objectClass || cls.isNative()); |
| 2489 if (cls.isNative()) hasNative = true; | 2518 if (cls.isNative()) hasNative = true; |
| 2490 } | 2519 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2531 } | 2560 } |
| 2532 if (hasNull) { | 2561 if (hasNull) { |
| 2533 block.statements.add(buildInterceptorCheck(backend.jsNullClass)); | 2562 block.statements.add(buildInterceptorCheck(backend.jsNullClass)); |
| 2534 } else { | 2563 } else { |
| 2535 // Returning "undefined" or "null" here will provoke a JavaScript | 2564 // Returning "undefined" or "null" here will provoke a JavaScript |
| 2536 // TypeError which is later identified as a null-error by | 2565 // TypeError which is later identified as a null-error by |
| 2537 // [unwrapException] in js_helper.dart. | 2566 // [unwrapException] in js_helper.dart. |
| 2538 block.statements.add(js.if_('receiver == null', | 2567 block.statements.add(js.if_('receiver == null', |
| 2539 js.return_(js('receiver')))); | 2568 js.return_(js('receiver')))); |
| 2540 } | 2569 } |
| 2541 if (hasFunction) { | |
| 2542 block.statements.add(buildInterceptorCheck(backend.jsFunctionClass)); | |
| 2543 } | |
| 2544 if (hasBool) { | 2570 if (hasBool) { |
| 2545 block.statements.add(buildInterceptorCheck(backend.jsBoolClass)); | 2571 block.statements.add(buildInterceptorCheck(backend.jsBoolClass)); |
| 2546 } | 2572 } |
| 2547 // TODO(ahe): It might be faster to check for Array before | 2573 // TODO(ahe): It might be faster to check for Array before |
| 2548 // function and bool. | 2574 // function and bool. |
| 2549 if (hasArray) { | 2575 if (hasArray) { |
| 2550 block.statements.add(buildInterceptorCheck(backend.jsArrayClass)); | 2576 block.statements.add(buildInterceptorCheck(backend.jsArrayClass)); |
| 2551 } | 2577 } |
| 2552 | 2578 |
| 2553 if (hasNative) { | 2579 if (hasNative) { |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2913 addComment(HOOKS_API_USAGE, mainBuffer); | 2939 addComment(HOOKS_API_USAGE, mainBuffer); |
| 2914 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); | 2940 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); |
| 2915 mainBuffer.add('init()$N$n'); | 2941 mainBuffer.add('init()$N$n'); |
| 2916 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 2942 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
| 2917 isolateProperties = namer.CURRENT_ISOLATE; | 2943 isolateProperties = namer.CURRENT_ISOLATE; |
| 2918 mainBuffer.add( | 2944 mainBuffer.add( |
| 2919 'var $isolateProperties$_=$_$isolatePropertiesName$N'); | 2945 'var $isolateProperties$_=$_$isolatePropertiesName$N'); |
| 2920 | 2946 |
| 2921 if (!regularClasses.isEmpty || | 2947 if (!regularClasses.isEmpty || |
| 2922 !deferredClasses.isEmpty || | 2948 !deferredClasses.isEmpty || |
| 2923 !nativeClasses.isEmpty) { | 2949 !nativeClasses.isEmpty || |
| 2950 !compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty) { | |
| 2924 // Shorten the code by using "$$" as temporary. | 2951 // Shorten the code by using "$$" as temporary. |
| 2925 classesCollector = r"$$"; | 2952 classesCollector = r"$$"; |
| 2926 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); | 2953 mainBuffer.add('var $classesCollector$_=$_{}$N$n'); |
| 2927 } | 2954 } |
| 2928 | 2955 |
| 2929 // As a side-effect, emitting classes will produce "bound closures" in | 2956 // As a side-effect, emitting classes will produce "bound closures" in |
| 2930 // [boundClosures]. The bound closures are JS AST nodes that add | 2957 // [boundClosures]. The bound closures are JS AST nodes that add |
| 2931 // properties to $$ [classesCollector]. The bound closures are not | 2958 // properties to $$ [classesCollector]. The bound closures are not |
| 2932 // emitted until we have emitted all other classes (native or not). | 2959 // emitted until we have emitted all other classes (native or not). |
| 2933 | 2960 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2959 generateClass(element, deferredBuffer); | 2986 generateClass(element, deferredBuffer); |
| 2960 } | 2987 } |
| 2961 | 2988 |
| 2962 deferredBuffer.add('$finishClassesName(\$\$,' | 2989 deferredBuffer.add('$finishClassesName(\$\$,' |
| 2963 '$_${namer.CURRENT_ISOLATE},' | 2990 '$_${namer.CURRENT_ISOLATE},' |
| 2964 '$_$isolatePropertiesName)$N'); | 2991 '$_$isolatePropertiesName)$N'); |
| 2965 // Reset the map. | 2992 // Reset the map. |
| 2966 deferredBuffer.add("\$\$$_=${_}null$N$n"); | 2993 deferredBuffer.add("\$\$$_=${_}null$N$n"); |
| 2967 } | 2994 } |
| 2968 | 2995 |
| 2996 emitStaticFunctionClosures(); | |
| 2969 emitClosureClassIfNeeded(mainBuffer); | 2997 emitClosureClassIfNeeded(mainBuffer); |
| 2970 | 2998 |
| 2971 addComment('Bound closures', mainBuffer); | 2999 addComment('Bound closures', mainBuffer); |
| 2972 // Now that we have emitted all classes, we know all the bound | 3000 // Now that we have emitted all classes, we know all the bound |
| 2973 // closures that will be needed. | 3001 // closures that will be needed. |
| 2974 for (jsAst.Node node in boundClosures) { | 3002 for (jsAst.Node node in boundClosures) { |
| 2975 // TODO(ahe): Some of these can be deferred. | 3003 // TODO(ahe): Some of these can be deferred. |
| 2976 mainBuffer.add(jsAst.prettyPrint(node, compiler)); | 3004 mainBuffer.add(jsAst.prettyPrint(node, compiler)); |
| 2977 mainBuffer.add("$N$n"); | 3005 mainBuffer.add("$N$n"); |
| 2978 } | 3006 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3089 """; | 3117 """; |
| 3090 const String HOOKS_API_USAGE = """ | 3118 const String HOOKS_API_USAGE = """ |
| 3091 // The code supports the following hooks: | 3119 // The code supports the following hooks: |
| 3092 // dartPrint(message) - if this function is defined it is called | 3120 // dartPrint(message) - if this function is defined it is called |
| 3093 // instead of the Dart [print] method. | 3121 // instead of the Dart [print] method. |
| 3094 // dartMainRunner(main) - if this function is defined, the Dart [main] | 3122 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 3095 // method will not be invoked directly. | 3123 // method will not be invoked directly. |
| 3096 // Instead, a closure that will invoke [main] is | 3124 // Instead, a closure that will invoke [main] is |
| 3097 // passed to [dartMainRunner]. | 3125 // passed to [dartMainRunner]. |
| 3098 """; | 3126 """; |
| OLD | NEW |