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 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1674 ${mainCall}; | 1674 ${mainCall}; |
1675 } | 1675 } |
1676 } | 1676 } |
1677 // | 1677 // |
1678 // END invoke [main]. | 1678 // END invoke [main]. |
1679 // | 1679 // |
1680 | 1680 |
1681 """); | 1681 """); |
1682 } | 1682 } |
1683 | 1683 |
1684 /** | |
1685 * Emit the code for doing a type check on [cls]. [cls] must | |
1686 * be an interceptor class. | |
1687 */ | |
1688 void emitTypeCheck(ClassElement cls, CodeBuffer buffer) { | |
ahe
2012/11/27 14:29:45
This is not really emitting a type check, which wo
ngeoffray
2012/11/27 15:50:54
I renamed the method emitInterceptorCheck.
| |
1689 JavaScriptBackend backend = compiler.backend; | |
1690 assert(backend.isInterceptorClass(cls)); | |
1691 String then = 'return ${namer.isolateAccess(cls)}.prototype;'; | |
ahe
2012/11/27 14:29:45
Weird variable name. How about interceptorObject?
ngeoffray
2012/11/27 15:50:54
Done.
| |
1692 if (cls == backend.jsBoolClass) { | |
1693 buffer.add("if (typeof receiver == 'boolean') $then"); | |
ahe
2012/11/27 14:29:45
This pattern really hurts my eyes :-)
How about:
ngeoffray
2012/11/27 15:50:54
Done.
| |
1694 } else if (cls == backend.jsIntClass) { | |
1695 buffer.add("if (typeof receiver == 'number' " | |
1696 "&& Math.floor(receiver) == receiver) $then"); | |
1697 } else if (cls == backend.jsDoubleClass || cls == backend.jsNumberClass) { | |
1698 buffer.add("if (typeof receiver == 'number') $then"); | |
1699 } else if (cls == backend.jsArrayClass) { | |
1700 buffer.add("if (receiver != null " | |
1701 "&& receiver.constructor == Array) $then"); | |
1702 } else if (cls == backend.jsStringClass) { | |
1703 buffer.add("if (typeof receiver == 'string') $then"); | |
1704 } else if (cls == backend.jsNullClass) { | |
1705 buffer.add("if (receiver == null) $then"); | |
1706 } else if (cls == backend.jsFunctionClass) { | |
1707 buffer.add("if (typeof receiver == 'function') $then"); | |
1708 } | |
1709 } | |
1710 | |
1711 /** | |
1712 * Emit all versions of the [:getInterceptor:] method. | |
1713 */ | |
1714 void emitGetInterceptors(CodeBuffer buffer) { | |
ahe
2012/11/27 14:29:45
How about "emitGetInterceptorMethods"?
ngeoffray
2012/11/27 15:50:54
Done.
| |
1715 JavaScriptBackend backend = compiler.backend; | |
1716 String objectName = namer.isolateAccess(backend.objectInterceptorClass); | |
1717 backend.specializedGetInterceptors.forEach( | |
1718 (String key, Collection<ClassElement> classes) { | |
1719 buffer.add('$isolateProperties.$key = function(receiver) {'); | |
1720 for (ClassElement cls in classes) { | |
1721 if (compiler.codegenWorld.instantiatedClasses.contains(cls)) { | |
1722 buffer.add('\n '); | |
1723 emitTypeCheck(cls, buffer); | |
1724 } | |
1725 } | |
1726 buffer.add('\n return $objectName.prototype;\n};\n'); | |
1727 }); | |
1728 } | |
1729 | |
1684 String assembleProgram() { | 1730 String assembleProgram() { |
1685 measure(() { | 1731 measure(() { |
1686 mainBuffer.add(HOOKS_API_USAGE); | 1732 mainBuffer.add(HOOKS_API_USAGE); |
1687 mainBuffer.add('function ${namer.ISOLATE}() {}\n'); | 1733 mainBuffer.add('function ${namer.ISOLATE}() {}\n'); |
1688 mainBuffer.add('init();\n\n'); | 1734 mainBuffer.add('init();\n\n'); |
1689 // Shorten the code by using "$$" as temporary. | 1735 // Shorten the code by using "$$" as temporary. |
1690 classesCollector = r"$$"; | 1736 classesCollector = r"$$"; |
1691 mainBuffer.add('var $classesCollector = {};\n'); | 1737 mainBuffer.add('var $classesCollector = {};\n'); |
1692 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. | 1738 // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary. |
1693 isolateProperties = namer.CURRENT_ISOLATE; | 1739 isolateProperties = namer.CURRENT_ISOLATE; |
1694 mainBuffer.add('var $isolateProperties = $isolatePropertiesName;\n'); | 1740 mainBuffer.add('var $isolateProperties = $isolatePropertiesName;\n'); |
1695 emitClasses(mainBuffer); | 1741 emitClasses(mainBuffer); |
1696 mainBuffer.add(boundClosureBuffer); | 1742 mainBuffer.add(boundClosureBuffer); |
1697 // Clear the buffer, so that we can reuse it for the native classes. | 1743 // Clear the buffer, so that we can reuse it for the native classes. |
1698 boundClosureBuffer.clear(); | 1744 boundClosureBuffer.clear(); |
1699 emitStaticFunctions(mainBuffer); | 1745 emitStaticFunctions(mainBuffer); |
1700 emitStaticFunctionGetters(mainBuffer); | 1746 emitStaticFunctionGetters(mainBuffer); |
1701 // We need to finish the classes before we construct compile time | 1747 // We need to finish the classes before we construct compile time |
1702 // constants. | 1748 // constants. |
1703 emitFinishClassesInvocationIfNecessary(mainBuffer); | 1749 emitFinishClassesInvocationIfNecessary(mainBuffer); |
1704 emitCompileTimeConstants(mainBuffer); | 1750 emitCompileTimeConstants(mainBuffer); |
1705 // Static field initializations require the classes and compile-time | 1751 // Static field initializations require the classes and compile-time |
1706 // constants to be set up. | 1752 // constants to be set up. |
1707 emitStaticNonFinalFieldInitializations(mainBuffer); | 1753 emitStaticNonFinalFieldInitializations(mainBuffer); |
1754 emitGetInterceptors(mainBuffer); | |
1708 emitLazilyInitializedStaticFields(mainBuffer); | 1755 emitLazilyInitializedStaticFields(mainBuffer); |
1709 | 1756 |
1710 isolateProperties = isolatePropertiesName; | 1757 isolateProperties = isolatePropertiesName; |
1711 // The following code should not use the short-hand for the | 1758 // The following code should not use the short-hand for the |
1712 // initialStatics. | 1759 // initialStatics. |
1713 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); | 1760 mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n'); |
1714 mainBuffer.add(boundClosureBuffer); | 1761 mainBuffer.add(boundClosureBuffer); |
1715 emitFinishClassesInvocationIfNecessary(mainBuffer); | 1762 emitFinishClassesInvocationIfNecessary(mainBuffer); |
1716 // After this assignment we will produce invalid JavaScript code if we use | 1763 // After this assignment we will produce invalid JavaScript code if we use |
1717 // the classesCollector variable. | 1764 // the classesCollector variable. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1756 const String HOOKS_API_USAGE = """ | 1803 const String HOOKS_API_USAGE = """ |
1757 // Generated by dart2js, the Dart to JavaScript compiler. | 1804 // Generated by dart2js, the Dart to JavaScript compiler. |
1758 // The code supports the following hooks: | 1805 // The code supports the following hooks: |
1759 // dartPrint(message) - if this function is defined it is called | 1806 // dartPrint(message) - if this function is defined it is called |
1760 // instead of the Dart [print] method. | 1807 // instead of the Dart [print] method. |
1761 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1808 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1762 // method will not be invoked directly. | 1809 // method will not be invoked directly. |
1763 // Instead, a closure that will invoke [main] is | 1810 // Instead, a closure that will invoke [main] is |
1764 // passed to [dartMainRunner]. | 1811 // passed to [dartMainRunner]. |
1765 """; | 1812 """; |
OLD | NEW |