| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
| 9 * | 9 * |
| 10 * Names are generated through three stages: | 10 * Names are generated through three stages: |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 constantHasher = new ConstantCanonicalHasher(compiler), | 450 constantHasher = new ConstantCanonicalHasher(compiler), |
| 451 functionTypeNamer = new FunctionTypeNamer(compiler) { | 451 functionTypeNamer = new FunctionTypeNamer(compiler) { |
| 452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); | 452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); |
| 453 _literalGetterPrefix = new StringBackedName(getterPrefix); | 453 _literalGetterPrefix = new StringBackedName(getterPrefix); |
| 454 _literalSetterPrefix = new StringBackedName(setterPrefix); | 454 _literalSetterPrefix = new StringBackedName(setterPrefix); |
| 455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); | 455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); |
| 456 } | 456 } |
| 457 | 457 |
| 458 JavaScriptBackend get backend => compiler.backend; | 458 JavaScriptBackend get backend => compiler.backend; |
| 459 | 459 |
| 460 DiagnosticReporter get reporter => compiler.reporter; |
| 461 |
| 460 String get deferredTypesName => 'deferredTypes'; | 462 String get deferredTypesName => 'deferredTypes'; |
| 461 String get isolateName => 'Isolate'; | 463 String get isolateName => 'Isolate'; |
| 462 String get isolatePropertiesName => r'$isolateProperties'; | 464 String get isolatePropertiesName => r'$isolateProperties'; |
| 463 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); | 465 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); |
| 464 | 466 |
| 465 /** | 467 /** |
| 466 * Some closures must contain their name. The name is stored in | 468 * Some closures must contain their name. The name is stored in |
| 467 * [STATIC_CLOSURE_NAME_NAME]. | 469 * [STATIC_CLOSURE_NAME_NAME]. |
| 468 */ | 470 */ |
| 469 String get STATIC_CLOSURE_NAME_NAME => r'$name'; | 471 String get STATIC_CLOSURE_NAME_NAME => r'$name'; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 case JsGetName.IS_INDEXABLE_FIELD_NAME: | 508 case JsGetName.IS_INDEXABLE_FIELD_NAME: |
| 507 Element cls = backend.findHelper('JavaScriptIndexingBehavior'); | 509 Element cls = backend.findHelper('JavaScriptIndexingBehavior'); |
| 508 return operatorIs(cls); | 510 return operatorIs(cls); |
| 509 case JsGetName.NULL_CLASS_TYPE_NAME: | 511 case JsGetName.NULL_CLASS_TYPE_NAME: |
| 510 return runtimeTypeName(compiler.nullClass); | 512 return runtimeTypeName(compiler.nullClass); |
| 511 case JsGetName.OBJECT_CLASS_TYPE_NAME: | 513 case JsGetName.OBJECT_CLASS_TYPE_NAME: |
| 512 return runtimeTypeName(compiler.objectClass); | 514 return runtimeTypeName(compiler.objectClass); |
| 513 case JsGetName.FUNCTION_CLASS_TYPE_NAME: | 515 case JsGetName.FUNCTION_CLASS_TYPE_NAME: |
| 514 return runtimeTypeName(compiler.functionClass); | 516 return runtimeTypeName(compiler.functionClass); |
| 515 default: | 517 default: |
| 516 compiler.reportErrorMessage( | 518 reporter.reportErrorMessage( |
| 517 node, | 519 node, |
| 518 MessageKind.GENERIC, | 520 MessageKind.GENERIC, |
| 519 {'text': 'Error: Namer has no name for "$name".'}); | 521 {'text': 'Error: Namer has no name for "$name".'}); |
| 520 return asName('BROKEN'); | 522 return asName('BROKEN'); |
| 521 } | 523 } |
| 522 } | 524 } |
| 523 | 525 |
| 524 /// Return a reference to the given [name]. | 526 /// Return a reference to the given [name]. |
| 525 /// | 527 /// |
| 526 /// This is used to ensure that every use site of a name has a unique node so | 528 /// This is used to ensure that every use site of a name has a unique node so |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 List<String> suffix = callSuffixForStructure(selector.callStructure); | 700 List<String> suffix = callSuffixForStructure(selector.callStructure); |
| 699 if (selector.name == Identifiers.call) { | 701 if (selector.name == Identifiers.call) { |
| 700 // Derive the annotated name for this variant of 'call'. | 702 // Derive the annotated name for this variant of 'call'. |
| 701 return deriveCallMethodName(suffix); | 703 return deriveCallMethodName(suffix); |
| 702 } | 704 } |
| 703 jsAst.Name disambiguatedName = | 705 jsAst.Name disambiguatedName = |
| 704 _disambiguateMember(selector.memberName, suffix); | 706 _disambiguateMember(selector.memberName, suffix); |
| 705 return disambiguatedName; // Methods other than call are not annotated. | 707 return disambiguatedName; // Methods other than call are not annotated. |
| 706 | 708 |
| 707 default: | 709 default: |
| 708 compiler.internalError(compiler.currentElement, | 710 reporter.internalError( |
| 711 CURRENT_ELEMENT_SPANNABLE, |
| 709 'Unexpected selector kind: ${selector.kind}'); | 712 'Unexpected selector kind: ${selector.kind}'); |
| 710 return null; | 713 return null; |
| 711 } | 714 } |
| 712 } | 715 } |
| 713 | 716 |
| 714 /** | 717 /** |
| 715 * Returns the internal name used for an invocation mirror of this selector. | 718 * Returns the internal name used for an invocation mirror of this selector. |
| 716 */ | 719 */ |
| 717 jsAst.Name invocationMirrorInternalName(Selector selector) | 720 jsAst.Name invocationMirrorInternalName(Selector selector) |
| 718 => invocationName(selector); | 721 => invocationName(selector); |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 final Compiler compiler; | 1577 final Compiler compiler; |
| 1575 final ConstantCanonicalHasher hasher; | 1578 final ConstantCanonicalHasher hasher; |
| 1576 | 1579 |
| 1577 String root = null; // First word, usually a type name. | 1580 String root = null; // First word, usually a type name. |
| 1578 bool failed = false; // Failed to generate something pretty. | 1581 bool failed = false; // Failed to generate something pretty. |
| 1579 List<String> fragments = <String>[]; | 1582 List<String> fragments = <String>[]; |
| 1580 int length = 0; | 1583 int length = 0; |
| 1581 | 1584 |
| 1582 ConstantNamingVisitor(this.compiler, this.hasher); | 1585 ConstantNamingVisitor(this.compiler, this.hasher); |
| 1583 | 1586 |
| 1587 DiagnosticReporter get reporter => compiler.reporter; |
| 1588 |
| 1584 String getName(ConstantValue constant) { | 1589 String getName(ConstantValue constant) { |
| 1585 _visit(constant); | 1590 _visit(constant); |
| 1586 if (root == null) return 'CONSTANT'; | 1591 if (root == null) return 'CONSTANT'; |
| 1587 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; | 1592 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; |
| 1588 if (fragments.length == 1) return 'C_${root}'; | 1593 if (fragments.length == 1) return 'C_${root}'; |
| 1589 return fragments.join('_'); | 1594 return fragments.join('_'); |
| 1590 } | 1595 } |
| 1591 | 1596 |
| 1592 String getHashTag(ConstantValue constant, int width) => | 1597 String getHashTag(ConstantValue constant, int width) => |
| 1593 hashWord(hasher.getHash(constant), width); | 1598 hashWord(hasher.getHash(constant), width); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1736 case SyntheticConstantKind.DUMMY_INTERCEPTOR: | 1741 case SyntheticConstantKind.DUMMY_INTERCEPTOR: |
| 1737 add('dummy_receiver'); | 1742 add('dummy_receiver'); |
| 1738 break; | 1743 break; |
| 1739 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 1744 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
| 1740 // Omit. These are opaque deferred indexes with nothing helpful to add. | 1745 // Omit. These are opaque deferred indexes with nothing helpful to add. |
| 1741 break; | 1746 break; |
| 1742 case SyntheticConstantKind.NAME: | 1747 case SyntheticConstantKind.NAME: |
| 1743 add('name'); | 1748 add('name'); |
| 1744 break; | 1749 break; |
| 1745 default: | 1750 default: |
| 1746 compiler.internalError(compiler.currentElement, | 1751 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 1747 "Unexpected SyntheticConstantValue"); | 1752 "Unexpected SyntheticConstantValue"); |
| 1748 } | 1753 } |
| 1749 } | 1754 } |
| 1750 | 1755 |
| 1751 @override | 1756 @override |
| 1752 void visitDeferred(DeferredConstantValue constant, [_]) { | 1757 void visitDeferred(DeferredConstantValue constant, [_]) { |
| 1753 addRoot('Deferred'); | 1758 addRoot('Deferred'); |
| 1754 } | 1759 } |
| 1755 } | 1760 } |
| 1756 | 1761 |
| 1757 /** | 1762 /** |
| 1758 * Generates canonical hash values for [ConstantValue]s. | 1763 * Generates canonical hash values for [ConstantValue]s. |
| 1759 * | 1764 * |
| 1760 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, | 1765 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, |
| 1761 * so it can't be used for generating names. This hasher keeps consistency | 1766 * so it can't be used for generating names. This hasher keeps consistency |
| 1762 * between runs by basing hash values of the names of elements, rather than | 1767 * between runs by basing hash values of the names of elements, rather than |
| 1763 * their hashCodes. | 1768 * their hashCodes. |
| 1764 */ | 1769 */ |
| 1765 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> { | 1770 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> { |
| 1766 | 1771 |
| 1767 static const _MASK = 0x1fffffff; | 1772 static const _MASK = 0x1fffffff; |
| 1768 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; | 1773 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; |
| 1769 | 1774 |
| 1770 | 1775 |
| 1771 final Compiler compiler; | 1776 final Compiler compiler; |
| 1772 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); | 1777 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); |
| 1773 | 1778 |
| 1774 ConstantCanonicalHasher(this.compiler); | 1779 ConstantCanonicalHasher(this.compiler); |
| 1775 | 1780 |
| 1781 DiagnosticReporter get reporter => compiler.reporter; |
| 1782 |
| 1776 int getHash(ConstantValue constant) => _visit(constant); | 1783 int getHash(ConstantValue constant) => _visit(constant); |
| 1777 | 1784 |
| 1778 int _visit(ConstantValue constant) { | 1785 int _visit(ConstantValue constant) { |
| 1779 int hash = hashes[constant]; | 1786 int hash = hashes[constant]; |
| 1780 if (hash == null) { | 1787 if (hash == null) { |
| 1781 hash = _finish(constant.accept(this, null)); | 1788 hash = _finish(constant.accept(this, null)); |
| 1782 hashes[constant] = hash; | 1789 hashes[constant] = hash; |
| 1783 } | 1790 } |
| 1784 return hash; | 1791 return hash; |
| 1785 } | 1792 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 | 1856 |
| 1850 @override | 1857 @override |
| 1851 int visitSynthetic(SyntheticConstantValue constant, [_]) { | 1858 int visitSynthetic(SyntheticConstantValue constant, [_]) { |
| 1852 switch (constant.kind) { | 1859 switch (constant.kind) { |
| 1853 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 1860 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
| 1854 // These contain a deferred opaque index into metadata. There is nothing | 1861 // These contain a deferred opaque index into metadata. There is nothing |
| 1855 // we can access that is stable between compiles. Luckily, since they | 1862 // we can access that is stable between compiles. Luckily, since they |
| 1856 // resolve to integer indexes, they're always part of a larger constant. | 1863 // resolve to integer indexes, they're always part of a larger constant. |
| 1857 return 0; | 1864 return 0; |
| 1858 default: | 1865 default: |
| 1859 compiler.internalError(NO_LOCATION_SPANNABLE, | 1866 reporter.internalError( |
| 1860 'SyntheticConstantValue should never be named and
' | 1867 NO_LOCATION_SPANNABLE, |
| 1861 'never be subconstant'); | 1868 'SyntheticConstantValue should never be named and ' |
| 1869 'never be subconstant'); |
| 1862 return 0; | 1870 return 0; |
| 1863 } | 1871 } |
| 1864 } | 1872 } |
| 1865 | 1873 |
| 1866 @override | 1874 @override |
| 1867 int visitDeferred(DeferredConstantValue constant, [_]) { | 1875 int visitDeferred(DeferredConstantValue constant, [_]) { |
| 1868 int hash = constant.prefix.hashCode; | 1876 int hash = constant.prefix.hashCode; |
| 1869 return _combine(hash, _visit(constant.referenced)); | 1877 return _combine(hash, _visit(constant.referenced)); |
| 1870 } | 1878 } |
| 1871 | 1879 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 } | 2001 } |
| 1994 } | 2002 } |
| 1995 } | 2003 } |
| 1996 } | 2004 } |
| 1997 | 2005 |
| 1998 enum NamingScope { | 2006 enum NamingScope { |
| 1999 global, | 2007 global, |
| 2000 instance, | 2008 instance, |
| 2001 constant | 2009 constant |
| 2002 } | 2010 } |
| OLD | NEW |