Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: pkg/compiler/lib/src/ssa/codegen.dart

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

Powered by Google App Engine
This is Rietveld 408576698