OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 | 7 |
8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
9 final Compiler compiler; | 9 final Compiler compiler; |
10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 // Chrome/V8. | 1445 // Chrome/V8. |
1446 mainBuffer.add('(function(${namer.currentIsolate})$_{\n'); | 1446 mainBuffer.add('(function(${namer.currentIsolate})$_{\n'); |
1447 if (compiler.hasIncrementalSupport) { | 1447 if (compiler.hasIncrementalSupport) { |
1448 mainBuffer.add( | 1448 mainBuffer.add( |
1449 'this.\$dart_unsafe_eval =' | 1449 'this.\$dart_unsafe_eval =' |
1450 ' this.\$dart_unsafe_eval || Object.create(null)$N'); | 1450 ' this.\$dart_unsafe_eval || Object.create(null)$N'); |
1451 mainBuffer.add( | 1451 mainBuffer.add( |
1452 'this.\$dart_unsafe_eval.patch = function(a) { eval(a) }$N'); | 1452 'this.\$dart_unsafe_eval.patch = function(a) { eval(a) }$N'); |
1453 String schemaChange = | 1453 String schemaChange = |
1454 jsAst.prettyPrint(buildSchemaChangeFunction(), compiler).getText(); | 1454 jsAst.prettyPrint(buildSchemaChangeFunction(), compiler).getText(); |
| 1455 String addMethod = |
| 1456 jsAst.prettyPrint(buildIncrementalAddMethod(), compiler).getText(); |
1455 mainBuffer.add( | 1457 mainBuffer.add( |
1456 'this.\$dart_unsafe_eval.schemaChange$_=$_$schemaChange$N'); | 1458 'this.\$dart_unsafe_eval.schemaChange$_=$_$schemaChange$N'); |
| 1459 mainBuffer.add( |
| 1460 'this.\$dart_unsafe_eval.addMethod$_=$_$addMethod$N'); |
1457 } | 1461 } |
1458 if (isProgramSplit) { | 1462 if (isProgramSplit) { |
1459 /// We collect all the global state of the, so it can be passed to the | 1463 /// We collect all the global state of the, so it can be passed to the |
1460 /// initializer of deferred files. | 1464 /// initializer of deferred files. |
1461 mainBuffer.add('var ${globalsHolder}$_=${_}Object.create(null)$N'); | 1465 mainBuffer.add('var ${globalsHolder}$_=${_}Object.create(null)$N'); |
1462 } | 1466 } |
1463 mainBuffer.add('function dart()$_{$n' | 1467 mainBuffer.add('function dart()$_{$n' |
1464 '${_}${_}this.x$_=${_}0$N' | 1468 '${_}${_}this.x$_=${_}0$N' |
1465 '${_}${_}delete this.x$N' | 1469 '${_}${_}delete this.x$N' |
1466 '}$n'); | 1470 '}$n'); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 oldPrototype[property] = newPrototype[property]; | 1679 oldPrototype[property] = newPrototype[property]; |
1676 } | 1680 } |
1677 } | 1681 } |
1678 oldPrototype.__proto__ = newConstructor.prototype.__proto__; | 1682 oldPrototype.__proto__ = newConstructor.prototype.__proto__; |
1679 oldPrototype.constructor = newConstructor; | 1683 oldPrototype.constructor = newConstructor; |
1680 newConstructor.prototype = oldPrototype; | 1684 newConstructor.prototype = oldPrototype; |
1681 return newConstructor; | 1685 return newConstructor; |
1682 }'''); | 1686 }'''); |
1683 } | 1687 } |
1684 | 1688 |
| 1689 /// Used by incremental compilation to patch up an object ([holder]) with a |
| 1690 /// new (or updated) method. [arrayOrFunction] is either the new method, or |
| 1691 /// an array containing the method (see |
| 1692 /// [ContainerBuilder.addMemberMethodFromInfo]). [name] is the name of the |
| 1693 /// new method. [isStatic] tells if method is static (or |
| 1694 /// top-level). [globalFunctionsAccess] is a reference to |
| 1695 /// [embeddedNames.GLOBAL_FUNCTIONS]. |
| 1696 jsAst.Fun buildIncrementalAddMethod() { |
| 1697 return js(r''' |
| 1698 function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
| 1699 var arrayOrFunction = originalDescriptor[name]; |
| 1700 var method; |
| 1701 if (arrayOrFunction.constructor === Array) { |
| 1702 var existing = holder[name]; |
| 1703 var array = arrayOrFunction; |
| 1704 var descriptor = Object.create(null); |
| 1705 this.addStubs( |
| 1706 descriptor, arrayOrFunction, name, isStatic, originalDescriptor, []); |
| 1707 method = descriptor[name]; |
| 1708 for (var property in descriptor) { |
| 1709 if (!Object.prototype.hasOwnProperty.call(descriptor, property)) continue; |
| 1710 var stub = descriptor[property]; |
| 1711 var existingStub = holder[property]; |
| 1712 if (stub === method || !existingStub) { |
| 1713 // Not replacing an existing stub. |
| 1714 holder[property] = method; |
| 1715 continue; |
| 1716 } |
| 1717 if (!stub.$getterStub) { |
| 1718 var error = new Error("Unexpected stub."); |
| 1719 error.stub = stub; |
| 1720 throw error; |
| 1721 } |
| 1722 // Invoke the existing stub to obtain the tear-off closure. |
| 1723 existingStub = existingStub(); |
| 1724 // A stub already exist. Update all its references to [existing] to |
| 1725 // [method]. |
| 1726 for (var reference in existingStub) { |
| 1727 if (existingStub[reference] === existing) { |
| 1728 existingStub[reference] = method; |
| 1729 } |
| 1730 } |
| 1731 } |
| 1732 } else { |
| 1733 method = arrayOrFunction; |
| 1734 holder[name] = method; |
| 1735 } |
| 1736 if (isStatic) globalFunctionsAccess[name] = method; |
| 1737 }'''); |
| 1738 } |
| 1739 |
1685 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely | 1740 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely |
1686 /// identifies the code of the output-unit. It does not include | 1741 /// identifies the code of the output-unit. It does not include |
1687 /// boilerplate JS code, like the sourcemap directives or the hash | 1742 /// boilerplate JS code, like the sourcemap directives or the hash |
1688 /// itself. | 1743 /// itself. |
1689 Map<OutputUnit, String> emitDeferredOutputUnits() { | 1744 Map<OutputUnit, String> emitDeferredOutputUnits() { |
1690 if (!compiler.deferredLoadTask.isProgramSplit) return const {}; | 1745 if (!compiler.deferredLoadTask.isProgramSplit) return const {}; |
1691 | 1746 |
1692 Map<OutputUnit, CodeBuffer> outputBuffers = | 1747 Map<OutputUnit, CodeBuffer> outputBuffers = |
1693 new Map<OutputUnit, CodeBuffer>(); | 1748 new Map<OutputUnit, CodeBuffer>(); |
1694 | 1749 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2068 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
2014 if (element.isInstanceMember) { | 2069 if (element.isInstanceMember) { |
2015 cachedClassBuilders.remove(element.enclosingClass); | 2070 cachedClassBuilders.remove(element.enclosingClass); |
2016 | 2071 |
2017 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2072 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
2018 | 2073 |
2019 } | 2074 } |
2020 } | 2075 } |
2021 } | 2076 } |
2022 } | 2077 } |
OLD | NEW |