| 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 import '../common.dart'; | 5 import '../common.dart'; |
| 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 7 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
| 8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 .withSourceInformation(node.sourceInformation)); | 1575 .withSourceInformation(node.sourceInformation)); |
| 1576 registry.registerUseInterceptor(); | 1576 registry.registerUseInterceptor(); |
| 1577 } | 1577 } |
| 1578 } | 1578 } |
| 1579 | 1579 |
| 1580 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 1580 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 1581 use(node.receiver); | 1581 use(node.receiver); |
| 1582 js.Expression object = pop(); | 1582 js.Expression object = pop(); |
| 1583 String methodName; | 1583 String methodName; |
| 1584 List<js.Expression> arguments = visitArguments(node.inputs); | 1584 List<js.Expression> arguments = visitArguments(node.inputs); |
| 1585 Element target = node.element; | 1585 MemberElement target = node.element; |
| 1586 | 1586 |
| 1587 // TODO(herhut): The namer should return the appropriate backendname here. | 1587 // TODO(herhut): The namer should return the appropriate backendname here. |
| 1588 if (target != null && !node.isInterceptedCall) { | 1588 if (target != null && !node.isInterceptedCall) { |
| 1589 if (target == helpers.jsArrayAdd) { | 1589 if (target == helpers.jsArrayAdd) { |
| 1590 methodName = 'push'; | 1590 methodName = 'push'; |
| 1591 } else if (target == helpers.jsArrayRemoveLast) { | 1591 } else if (target == helpers.jsArrayRemoveLast) { |
| 1592 methodName = 'pop'; | 1592 methodName = 'pop'; |
| 1593 } else if (target == helpers.jsStringSplit) { | 1593 } else if (target == helpers.jsStringSplit) { |
| 1594 methodName = 'split'; | 1594 methodName = 'split'; |
| 1595 // Split returns a List, so we make sure the backend knows the | 1595 // Split returns a List, so we make sure the backend knows the |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 // might hit a `noSuchMethod`, we register an untyped selector. | 1673 // might hit a `noSuchMethod`, we register an untyped selector. |
| 1674 return compiler.closedWorld.extendMaskIfReachesAll(selector, mask); | 1674 return compiler.closedWorld.extendMaskIfReachesAll(selector, mask); |
| 1675 } | 1675 } |
| 1676 | 1676 |
| 1677 void registerMethodInvoke(HInvokeDynamic node) { | 1677 void registerMethodInvoke(HInvokeDynamic node) { |
| 1678 Selector selector = node.selector; | 1678 Selector selector = node.selector; |
| 1679 | 1679 |
| 1680 // If we don't know what we're calling or if we are calling a getter, | 1680 // If we don't know what we're calling or if we are calling a getter, |
| 1681 // we need to register that fact that we may be calling a closure | 1681 // we need to register that fact that we may be calling a closure |
| 1682 // with the same arguments. | 1682 // with the same arguments. |
| 1683 Element target = node.element; | 1683 MemberElement target = node.element; |
| 1684 if (target == null || target.isGetter) { | 1684 if (target == null || target.isGetter) { |
| 1685 // TODO(kasperl): If we have a typed selector for the call, we | 1685 // TODO(kasperl): If we have a typed selector for the call, we |
| 1686 // may know something about the types of closures that need | 1686 // may know something about the types of closures that need |
| 1687 // the specific closure call method. | 1687 // the specific closure call method. |
| 1688 Selector call = new Selector.callClosureFrom(selector); | 1688 Selector call = new Selector.callClosureFrom(selector); |
| 1689 registry.registerDynamicUse(new DynamicUse(call, null)); | 1689 registry.registerDynamicUse(new DynamicUse(call, null)); |
| 1690 } | 1690 } |
| 1691 if (target != null) { | 1691 if (target != null) { |
| 1692 // This is a dynamic invocation which we have found to have a single | 1692 // This is a dynamic invocation which we have found to have a single |
| 1693 // target but for some reason haven't inlined. We are _still_ accessing | 1693 // target but for some reason haven't inlined. We are _still_ accessing |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1755 Selector call = new Selector.callClosureFrom(node.selector); | 1755 Selector call = new Selector.callClosureFrom(node.selector); |
| 1756 use(node.receiver); | 1756 use(node.receiver); |
| 1757 push(js | 1757 push(js |
| 1758 .propertyCall(pop(), backend.namer.invocationName(call), | 1758 .propertyCall(pop(), backend.namer.invocationName(call), |
| 1759 visitArguments(node.inputs)) | 1759 visitArguments(node.inputs)) |
| 1760 .withSourceInformation(node.sourceInformation)); | 1760 .withSourceInformation(node.sourceInformation)); |
| 1761 registry.registerDynamicUse(new DynamicUse(call, null)); | 1761 registry.registerDynamicUse(new DynamicUse(call, null)); |
| 1762 } | 1762 } |
| 1763 | 1763 |
| 1764 visitInvokeStatic(HInvokeStatic node) { | 1764 visitInvokeStatic(HInvokeStatic node) { |
| 1765 Element element = node.element; | 1765 MemberElement element = node.element; |
| 1766 List<DartType> instantiatedTypes = node.instantiatedTypes; | 1766 List<DartType> instantiatedTypes = node.instantiatedTypes; |
| 1767 | 1767 |
| 1768 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) { | 1768 if (instantiatedTypes != null && !instantiatedTypes.isEmpty) { |
| 1769 instantiatedTypes.forEach((type) { | 1769 instantiatedTypes.forEach((type) { |
| 1770 registry.registerInstantiation(type); | 1770 registry.registerInstantiation(type); |
| 1771 }); | 1771 }); |
| 1772 } | 1772 } |
| 1773 | 1773 |
| 1774 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); | 1774 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); |
| 1775 | 1775 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1802 registry.registerStaticUse(element.isConstructor | 1802 registry.registerStaticUse(element.isConstructor |
| 1803 ? new StaticUse.constructorInvoke(element, callStructure) | 1803 ? new StaticUse.constructorInvoke(element, callStructure) |
| 1804 : new StaticUse.staticInvoke(element, callStructure)); | 1804 : new StaticUse.staticInvoke(element, callStructure)); |
| 1805 push(backend.emitter.staticFunctionAccess(element)); | 1805 push(backend.emitter.staticFunctionAccess(element)); |
| 1806 push(new js.Call(pop(), arguments, | 1806 push(new js.Call(pop(), arguments, |
| 1807 sourceInformation: node.sourceInformation)); | 1807 sourceInformation: node.sourceInformation)); |
| 1808 } | 1808 } |
| 1809 } | 1809 } |
| 1810 | 1810 |
| 1811 visitInvokeSuper(HInvokeSuper node) { | 1811 visitInvokeSuper(HInvokeSuper node) { |
| 1812 Element superElement = node.element; | 1812 MemberElement superElement = node.element; |
| 1813 ClassElement superClass = superElement.enclosingClass; | 1813 ClassElement superClass = superElement.enclosingClass; |
| 1814 if (superElement.isField) { | 1814 if (superElement.isField) { |
| 1815 js.Name fieldName = backend.namer.instanceFieldPropertyName(superElement); | 1815 js.Name fieldName = backend.namer.instanceFieldPropertyName(superElement); |
| 1816 use(node.inputs[0]); | 1816 use(node.inputs[0]); |
| 1817 js.PropertyAccess access = new js.PropertyAccess(pop(), fieldName) | 1817 js.PropertyAccess access = new js.PropertyAccess(pop(), fieldName) |
| 1818 .withSourceInformation(node.sourceInformation); | 1818 .withSourceInformation(node.sourceInformation); |
| 1819 if (node.isSetter) { | 1819 if (node.isSetter) { |
| 1820 registry.registerStaticUse(superElement.isSetter | 1820 registry.registerStaticUse(superElement.isSetter |
| 1821 ? new StaticUse.superSetterSet(superElement) | 1821 ? new StaticUse.superSetterSet(superElement) |
| 1822 : new StaticUse.superFieldSet(superElement)); | 1822 : new StaticUse.superFieldSet(superElement)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 backend.namer.aliasedSuperMemberPropertyName(superElement), | 1860 backend.namer.aliasedSuperMemberPropertyName(superElement), |
| 1861 visitArguments(node.inputs, start: 1) | 1861 visitArguments(node.inputs, start: 1) |
| 1862 ]) // Skip receiver argument. | 1862 ]) // Skip receiver argument. |
| 1863 .withSourceInformation(node.sourceInformation)); | 1863 .withSourceInformation(node.sourceInformation)); |
| 1864 } | 1864 } |
| 1865 } | 1865 } |
| 1866 } | 1866 } |
| 1867 | 1867 |
| 1868 visitFieldGet(HFieldGet node) { | 1868 visitFieldGet(HFieldGet node) { |
| 1869 use(node.receiver); | 1869 use(node.receiver); |
| 1870 Element element = node.element; | 1870 MemberElement element = node.element; |
| 1871 if (node.isNullCheck) { | 1871 if (node.isNullCheck) { |
| 1872 // We access a JavaScript member we know all objects besides | 1872 // We access a JavaScript member we know all objects besides |
| 1873 // null and undefined have: V8 does not like accessing a member | 1873 // null and undefined have: V8 does not like accessing a member |
| 1874 // that does not exist. | 1874 // that does not exist. |
| 1875 push(new js.PropertyAccess.field(pop(), 'toString') | 1875 push(new js.PropertyAccess.field(pop(), 'toString') |
| 1876 .withSourceInformation(node.sourceInformation)); | 1876 .withSourceInformation(node.sourceInformation)); |
| 1877 } else if (element == helpers.jsIndexableLength) { | 1877 } else if (element == helpers.jsIndexableLength) { |
| 1878 // We're accessing a native JavaScript property called 'length' | 1878 // We're accessing a native JavaScript property called 'length' |
| 1879 // on a JS String or a JS array. Therefore, the name of that | 1879 // on a JS String or a JS array. Therefore, the name of that |
| 1880 // property should not be mangled. | 1880 // property should not be mangled. |
| 1881 push(new js.PropertyAccess.field(pop(), 'length') | 1881 push(new js.PropertyAccess.field(pop(), 'length') |
| 1882 .withSourceInformation(node.sourceInformation)); | 1882 .withSourceInformation(node.sourceInformation)); |
| 1883 } else { | 1883 } else { |
| 1884 js.Name name = backend.namer.instanceFieldPropertyName(element); | 1884 js.Name name = backend.namer.instanceFieldPropertyName(element); |
| 1885 push(new js.PropertyAccess(pop(), name) | 1885 push(new js.PropertyAccess(pop(), name) |
| 1886 .withSourceInformation(node.sourceInformation)); | 1886 .withSourceInformation(node.sourceInformation)); |
| 1887 registry.registerStaticUse(new StaticUse.fieldGet(element)); | 1887 registry.registerStaticUse(new StaticUse.fieldGet(element)); |
| 1888 } | 1888 } |
| 1889 } | 1889 } |
| 1890 | 1890 |
| 1891 visitFieldSet(HFieldSet node) { | 1891 visitFieldSet(HFieldSet node) { |
| 1892 Element element = node.element; | 1892 MemberElement element = node.element; |
| 1893 registry.registerStaticUse(new StaticUse.fieldSet(element)); | 1893 registry.registerStaticUse(new StaticUse.fieldSet(element)); |
| 1894 js.Name name = backend.namer.instanceFieldPropertyName(element); | 1894 js.Name name = backend.namer.instanceFieldPropertyName(element); |
| 1895 use(node.receiver); | 1895 use(node.receiver); |
| 1896 js.Expression receiver = pop(); | 1896 js.Expression receiver = pop(); |
| 1897 use(node.value); | 1897 use(node.value); |
| 1898 push(new js.Assignment(new js.PropertyAccess(receiver, name), pop()) | 1898 push(new js.Assignment(new js.PropertyAccess(receiver, name), pop()) |
| 1899 .withSourceInformation(node.sourceInformation)); | 1899 .withSourceInformation(node.sourceInformation)); |
| 1900 } | 1900 } |
| 1901 | 1901 |
| 1902 visitReadModifyWrite(HReadModifyWrite node) { | 1902 visitReadModifyWrite(HReadModifyWrite node) { |
| 1903 Element element = node.element; | 1903 FieldElement element = node.element; |
| 1904 registry.registerStaticUse(new StaticUse.fieldGet(element)); | 1904 registry.registerStaticUse(new StaticUse.fieldGet(element)); |
| 1905 registry.registerStaticUse(new StaticUse.fieldSet(element)); | 1905 registry.registerStaticUse(new StaticUse.fieldSet(element)); |
| 1906 js.Name name = backend.namer.instanceFieldPropertyName(element); | 1906 js.Name name = backend.namer.instanceFieldPropertyName(element); |
| 1907 use(node.receiver); | 1907 use(node.receiver); |
| 1908 js.Expression fieldReference = new js.PropertyAccess(pop(), name); | 1908 js.Expression fieldReference = new js.PropertyAccess(pop(), name); |
| 1909 if (node.isPreOp) { | 1909 if (node.isPreOp) { |
| 1910 push(new js.Prefix(node.jsOp, fieldReference) | 1910 push(new js.Prefix(node.jsOp, fieldReference) |
| 1911 .withSourceInformation(node.sourceInformation)); | 1911 .withSourceInformation(node.sourceInformation)); |
| 1912 } else if (node.isPostOp) { | 1912 } else if (node.isPostOp) { |
| 1913 push(new js.Postfix(node.jsOp, fieldReference) | 1913 push(new js.Postfix(node.jsOp, fieldReference) |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2272 js.Call value = new js.Call(jsHelper, [pop()]) | 2272 js.Call value = new js.Call(jsHelper, [pop()]) |
| 2273 .withSourceInformation(node.sourceInformation); | 2273 .withSourceInformation(node.sourceInformation); |
| 2274 push(value); | 2274 push(value); |
| 2275 } | 2275 } |
| 2276 | 2276 |
| 2277 void visitSwitch(HSwitch node) { | 2277 void visitSwitch(HSwitch node) { |
| 2278 // Switches are handled using [visitSwitchInfo]. | 2278 // Switches are handled using [visitSwitchInfo]. |
| 2279 } | 2279 } |
| 2280 | 2280 |
| 2281 void visitStatic(HStatic node) { | 2281 void visitStatic(HStatic node) { |
| 2282 Element element = node.element; | 2282 MemberLike element = node.element; |
| 2283 assert(element.isFunction || element.isField); | 2283 assert(element.isFunction || element.isField); |
| 2284 if (element.isFunction) { | 2284 if (element.isFunction) { |
| 2285 push(backend.emitter | 2285 push(backend.emitter |
| 2286 .isolateStaticClosureAccess(element) | 2286 .isolateStaticClosureAccess(element) |
| 2287 .withSourceInformation(node.sourceInformation)); | 2287 .withSourceInformation(node.sourceInformation)); |
| 2288 registry.registerStaticUse(new StaticUse.staticTearOff(element)); | 2288 registry.registerStaticUse(new StaticUse.staticTearOff(element)); |
| 2289 } else { | 2289 } else { |
| 2290 push(backend.emitter | 2290 push(backend.emitter |
| 2291 .staticFieldAccess(element) | 2291 .staticFieldAccess(element) |
| 2292 .withSourceInformation(node.sourceInformation)); | 2292 .withSourceInformation(node.sourceInformation)); |
| 2293 registry.registerStaticUse(new StaticUse.staticGet(element)); | 2293 registry.registerStaticUse(new StaticUse.staticGet(element)); |
| 2294 } | 2294 } |
| 2295 } | 2295 } |
| 2296 | 2296 |
| 2297 void visitLazyStatic(HLazyStatic node) { | 2297 void visitLazyStatic(HLazyStatic node) { |
| 2298 Element element = node.element; | 2298 FieldLike element = node.element; |
| 2299 registry.registerStaticUse(new StaticUse.staticInit(element)); | 2299 registry.registerStaticUse(new StaticUse.staticInit(element)); |
| 2300 js.Expression lazyGetter = | 2300 js.Expression lazyGetter = |
| 2301 backend.emitter.isolateLazyInitializerAccess(element); | 2301 backend.emitter.isolateLazyInitializerAccess(element); |
| 2302 js.Call call = new js.Call(lazyGetter, <js.Expression>[], | 2302 js.Call call = new js.Call(lazyGetter, <js.Expression>[], |
| 2303 sourceInformation: node.sourceInformation); | 2303 sourceInformation: node.sourceInformation); |
| 2304 push(call); | 2304 push(call); |
| 2305 } | 2305 } |
| 2306 | 2306 |
| 2307 void visitStaticStore(HStaticStore node) { | 2307 void visitStaticStore(HStaticStore node) { |
| 2308 registry.registerStaticUse(new StaticUse.staticSet(node.element)); | 2308 registry.registerStaticUse(new StaticUse.staticSet(node.element)); |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3028 registry.registerStaticUse(new StaticUse.staticInvoke( | 3028 registry.registerStaticUse(new StaticUse.staticInvoke( |
| 3029 helper, new CallStructure.unnamed(argumentCount))); | 3029 helper, new CallStructure.unnamed(argumentCount))); |
| 3030 return backend.emitter.staticFunctionAccess(helper); | 3030 return backend.emitter.staticFunctionAccess(helper); |
| 3031 } | 3031 } |
| 3032 | 3032 |
| 3033 @override | 3033 @override |
| 3034 void visitRef(HRef node) { | 3034 void visitRef(HRef node) { |
| 3035 visit(node.value); | 3035 visit(node.value); |
| 3036 } | 3036 } |
| 3037 } | 3037 } |
| OLD | NEW |