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

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10825337: Add name and library to selectors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months 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 | Annotate | Revision Log
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 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 } 982 }
983 983
984 if (!foundSuperOrRedirect) { 984 if (!foundSuperOrRedirect) {
985 // No super initializer found. Try to find the default constructor if 985 // No super initializer found. Try to find the default constructor if
986 // the class is not Object. 986 // the class is not Object.
987 ClassElement enclosingClass = constructor.getEnclosingClass(); 987 ClassElement enclosingClass = constructor.getEnclosingClass();
988 ClassElement superClass = enclosingClass.superclass; 988 ClassElement superClass = enclosingClass.superclass;
989 if (enclosingClass != compiler.objectClass) { 989 if (enclosingClass != compiler.objectClass) {
990 assert(superClass !== null); 990 assert(superClass !== null);
991 assert(superClass.resolutionState == ClassElement.STATE_DONE); 991 assert(superClass.resolutionState == ClassElement.STATE_DONE);
992 Selector selector =
993 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0);
992 FunctionElement target = superClass.lookupConstructor(superClass.name); 994 FunctionElement target = superClass.lookupConstructor(superClass.name);
993 if (target === null) { 995 if (target === null) {
994 compiler.internalError("no default constructor available"); 996 compiler.internalError("no default constructor available");
995 } 997 }
996 inlineSuperOrRedirect(target, 998 inlineSuperOrRedirect(target,
997 Selector.INVOCATION_0, 999 selector,
998 const EmptyLink<Node>(), 1000 const EmptyLink<Node>(),
999 constructors, 1001 constructors,
1000 fieldValues); 1002 fieldValues);
1001 } 1003 }
1002 } 1004 }
1003 } 1005 }
1004 1006
1005 /** 1007 /**
1006 * Build the factory function corresponding to the constructor 1008 * Build the factory function corresponding to the constructor
1007 * [functionElement]: 1009 * [functionElement]:
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 } 1768 }
1767 } 1769 }
1768 1770
1769 void generateGetter(Send send, Element element) { 1771 void generateGetter(Send send, Element element) {
1770 if (Elements.isStaticOrTopLevelField(element)) { 1772 if (Elements.isStaticOrTopLevelField(element)) {
1771 if (element.kind == ElementKind.FIELD && !element.isAssignable()) { 1773 if (element.kind == ElementKind.FIELD && !element.isAssignable()) {
1772 // A static final. Get its constant value and inline it. 1774 // A static final. Get its constant value and inline it.
1773 Constant value = compiler.constantHandler.compileVariable(element); 1775 Constant value = compiler.constantHandler.compileVariable(element);
1774 stack.add(graph.addConstant(value)); 1776 stack.add(graph.addConstant(value));
1775 } else { 1777 } else {
1776 Selector selector = elements.getSelector(send);
1777 push(new HStatic(element)); 1778 push(new HStatic(element));
1778 if (element.kind == ElementKind.GETTER) { 1779 if (element.kind == ElementKind.GETTER) {
1779 push(new HInvokeStatic(selector, <HInstruction>[pop()])); 1780 push(new HInvokeStatic(<HInstruction>[pop()]));
1780 } 1781 }
1781 } 1782 }
1782 } else if (Elements.isInstanceSend(send, elements)) { 1783 } else if (Elements.isInstanceSend(send, elements)) {
1783 HInstruction receiver = generateInstanceSendReceiver(send); 1784 HInstruction receiver = generateInstanceSendReceiver(send);
1784 generateInstanceGetterWithCompiledReceiver(send, receiver); 1785 generateInstanceGetterWithCompiledReceiver(send, receiver);
1785 } else if (Elements.isStaticOrTopLevelFunction(element)) { 1786 } else if (Elements.isStaticOrTopLevelFunction(element)) {
1786 push(new HStatic(element)); 1787 push(new HStatic(element));
1787 // TODO(ahe): This should be registered in codegen. 1788 // TODO(ahe): This should be registered in codegen.
1788 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 1789 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
1789 } else { 1790 } else {
(...skipping 19 matching lines...) Expand all
1809 selector, dartSetterName, inputs, setter: true)); 1810 selector, dartSetterName, inputs, setter: true));
1810 } else { 1811 } else {
1811 add(new HInvokeDynamicSetter(selector, null, dartSetterName, 1812 add(new HInvokeDynamicSetter(selector, null, dartSetterName,
1812 receiver, value)); 1813 receiver, value));
1813 } 1814 }
1814 stack.add(value); 1815 stack.add(value);
1815 } 1816 }
1816 1817
1817 void generateSetter(SendSet send, Element element, HInstruction value) { 1818 void generateSetter(SendSet send, Element element, HInstruction value) {
1818 if (Elements.isStaticOrTopLevelField(element)) { 1819 if (Elements.isStaticOrTopLevelField(element)) {
1819 Selector selector = elements.getSelector(send);
1820 if (element.kind == ElementKind.SETTER) { 1820 if (element.kind == ElementKind.SETTER) {
1821 HStatic target = new HStatic(element); 1821 HStatic target = new HStatic(element);
1822 add(target); 1822 add(target);
1823 add(new HInvokeStatic(selector, <HInstruction>[target, value])); 1823 add(new HInvokeStatic(<HInstruction>[target, value]));
1824 } else { 1824 } else {
1825 add(new HStaticStore(element, value)); 1825 add(new HStaticStore(element, value));
1826 } 1826 }
1827 stack.add(value); 1827 stack.add(value);
1828 } else if (element === null || Elements.isInstanceField(element)) { 1828 } else if (element === null || Elements.isInstanceField(element)) {
1829 HInstruction receiver = generateInstanceSendReceiver(send); 1829 HInstruction receiver = generateInstanceSendReceiver(send);
1830 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 1830 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
1831 } else { 1831 } else {
1832 stack.add(value); 1832 stack.add(value);
1833 // If the value does not already have a name, give it here. 1833 // If the value does not already have a name, give it here.
1834 if (value.sourceElement === null) { 1834 if (value.sourceElement === null) {
1835 value.sourceElement = element; 1835 value.sourceElement = element;
1836 } 1836 }
1837 HInstruction checked = potentiallyCheckType(value, element); 1837 HInstruction checked = potentiallyCheckType(value, element);
1838 if (checked !== value) { 1838 if (checked !== value) {
1839 pop(); 1839 pop();
1840 stack.add(checked); 1840 stack.add(checked);
1841 } 1841 }
1842 localsHandler.updateLocal(element, checked); 1842 localsHandler.updateLocal(element, checked);
1843 } 1843 }
1844 } 1844 }
1845 1845
1846 void pushInvokeHelper0(Element helper) {
Søren Gjesse 2012/08/14 12:01:38 How about "pushInvokeStatic0" and rename argument
kasperl 2012/08/14 12:15:46 I'll fix this in another CL. Still trying to merge
1847 HInstruction reference = new HStatic(helper);
1848 add(reference);
1849 List<HInstruction> inputs = <HInstruction>[reference];
1850 HInstruction result = new HInvokeStatic(inputs);
1851 push(result);
1852 }
1853
1854 void pushInvokeHelper1(Element helper, HInstruction a0) {
Søren Gjesse 2012/08/14 12:01:38 Ditto.
1855 HInstruction reference = new HStatic(helper);
1856 add(reference);
1857 List<HInstruction> inputs = <HInstruction>[reference, a0];
1858 HInstruction result = new HInvokeStatic(inputs);
1859 push(result);
1860 }
1861
1862 void pushInvokeHelper2(Element helper, HInstruction a0, HInstruction a1) {
Søren Gjesse 2012/08/14 12:01:38 Ditto.
1863 HInstruction reference = new HStatic(helper);
1864 add(reference);
1865 List<HInstruction> inputs = <HInstruction>[reference, a0, a1];
1866 HInstruction result = new HInvokeStatic(inputs);
1867 push(result);
1868 }
1869
1846 visitOperatorSend(node) { 1870 visitOperatorSend(node) {
1847 assert(node.selector is Operator); 1871 assert(node.selector is Operator);
1848 if (!methodInterceptionEnabled) { 1872 if (!methodInterceptionEnabled) {
1849 visitDynamicSend(node); 1873 visitDynamicSend(node);
1850 return; 1874 return;
1851 } 1875 }
1852 1876
1853 Operator op = node.selector; 1877 Operator op = node.selector;
1854 if (const SourceString("[]") == op.source) { 1878 if (const SourceString("[]") == op.source) {
1855 HStatic target = new HStatic(interceptors.getIndexInterceptor()); 1879 HStatic target = new HStatic(interceptors.getIndexInterceptor());
(...skipping 19 matching lines...) Expand all
1875 // TODO(ngeoffray): Duplicating pattern in resolver. We should 1899 // TODO(ngeoffray): Duplicating pattern in resolver. We should
1876 // add a new kind of node. 1900 // add a new kind of node.
1877 if (typeAnnotation == null) { 1901 if (typeAnnotation == null) {
1878 typeAnnotation = argument.asSend().receiver; 1902 typeAnnotation = argument.asSend().receiver;
1879 isNot = true; 1903 isNot = true;
1880 } 1904 }
1881 1905
1882 Type type = elements.getType(typeAnnotation); 1906 Type type = elements.getType(typeAnnotation);
1883 HInstruction typeInfo = null; 1907 HInstruction typeInfo = null;
1884 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { 1908 if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
1885 HInstruction typeInfoGetter = 1909 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression);
1886 new HStatic(interceptors.getGetRuntimeTypeInfo()); 1910 typeInfo = pop();
1887 add(typeInfoGetter);
1888 typeInfo = new HInvokeStatic(Selector.INVOCATION_1,
1889 <HInstruction>[typeInfoGetter,
1890 expression]);
1891 add(typeInfo);
1892 } 1911 }
1893 if (type.element.kind === ElementKind.TYPE_VARIABLE) { 1912 if (type.element.kind === ElementKind.TYPE_VARIABLE) {
1894 // TODO(karlklose): We emulate the frog behavior and answer 1913 // TODO(karlklose): We emulate the frog behavior and answer
1895 // true to any is check involving a type variable -- both is T 1914 // true to any is check involving a type variable -- both is T
1896 // and is !T -- until we have a proper implementation of 1915 // and is !T -- until we have a proper implementation of
1897 // reified generics. 1916 // reified generics.
1898 stack.add(graph.addConstantBool(true)); 1917 stack.add(graph.addConstantBool(true));
1899 } else { 1918 } else {
1900 HInstruction instruction; 1919 HInstruction instruction;
1901 if (typeInfo !== null) { 1920 if (typeInfo !== null) {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2135 } else { 2154 } else {
2136 // Call a helper method from the isolate library. The isolate 2155 // Call a helper method from the isolate library. The isolate
2137 // library uses its own isolate structure, that encapsulates 2156 // library uses its own isolate structure, that encapsulates
2138 // Leg's isolate. 2157 // Leg's isolate.
2139 Element element = compiler.isolateLibrary.find( 2158 Element element = compiler.isolateLibrary.find(
2140 const SourceString('_currentIsolate')); 2159 const SourceString('_currentIsolate'));
2141 if (element === null) { 2160 if (element === null) {
2142 compiler.cancel( 2161 compiler.cancel(
2143 'Isolate library and compiler mismatch', node: node); 2162 'Isolate library and compiler mismatch', node: node);
2144 } 2163 }
2145 HStatic target = new HStatic(element); 2164 pushInvokeHelper0(element);
2146 add(target);
2147 push(new HInvokeStatic(Selector.INVOCATION_0,
2148 <HInstruction>[target]));
2149 } 2165 }
2150 } 2166 }
2151 2167
2152 void handleForeignJsCallInIsolate(Send node) { 2168 void handleForeignJsCallInIsolate(Send node) {
2153 Link<Node> link = node.arguments; 2169 Link<Node> link = node.arguments;
2154 if (!compiler.hasIsolateSupport()) { 2170 if (!compiler.hasIsolateSupport()) {
2155 // If the isolate library is not used, we just invoke the 2171 // If the isolate library is not used, we just invoke the
2156 // closure. 2172 // closure.
2157 visit(link.tail.head); 2173 visit(link.tail.head);
2158 push(new HInvokeClosure(Selector.INVOCATION_0, 2174 Selector selector = new Selector.callAny(0);
2159 <HInstruction>[pop()])); 2175 push(new HInvokeClosure(selector, <HInstruction>[pop()]));
2160 } else { 2176 } else {
2161 // Call a helper method from the isolate library. 2177 // Call a helper method from the isolate library.
2162 Element element = compiler.isolateLibrary.find( 2178 Element element = compiler.isolateLibrary.find(
2163 const SourceString('_callInIsolate')); 2179 const SourceString('_callInIsolate'));
2164 if (element === null) { 2180 if (element === null) {
2165 compiler.cancel( 2181 compiler.cancel(
2166 'Isolate library and compiler mismatch', node: node); 2182 'Isolate library and compiler mismatch', node: node);
2167 } 2183 }
2168 HStatic target = new HStatic(element); 2184 HStatic target = new HStatic(element);
2169 add(target); 2185 add(target);
2170 List<HInstruction> inputs = <HInstruction>[target]; 2186 List<HInstruction> inputs = <HInstruction>[target];
2171 addGenericSendArgumentsToList(link, inputs); 2187 addGenericSendArgumentsToList(link, inputs);
2172 push(new HInvokeStatic(Selector.INVOCATION_0, inputs)); 2188 push(new HInvokeStatic(inputs));
2173 } 2189 }
2174 } 2190 }
2175 2191
2176 void handleForeignDartClosureToJs(Send node) { 2192 void handleForeignDartClosureToJs(Send node) {
2177 if (node.arguments.isEmpty() || !node.arguments.tail.isEmpty()) { 2193 if (node.arguments.isEmpty() || !node.arguments.tail.isEmpty()) {
2178 compiler.cancel('Exactly one argument required', 2194 compiler.cancel('Exactly one argument required',
2179 node: node.argumentsNode); 2195 node: node.argumentsNode);
2180 } 2196 }
2181 Node closure = node.arguments.head; 2197 Node closure = node.arguments.head;
2182 Element element = elements[closure]; 2198 Element element = elements[closure];
2183 if (!Elements.isStaticOrTopLevelFunction(element)) { 2199 if (!Elements.isStaticOrTopLevelFunction(element)) {
2184 compiler.cancel( 2200 compiler.cancel(
2185 'JS_TO_CLOSURE requires a static or top-level method', 2201 'JS_TO_CLOSURE requires a static or top-level method',
2186 node: closure); 2202 node: closure);
2187 } 2203 }
2188 FunctionElement function = element; 2204 FunctionElement function = element;
2189 FunctionSignature params = function.computeSignature(compiler); 2205 FunctionSignature params = function.computeSignature(compiler);
2190 if (params.optionalParameterCount !== 0) { 2206 if (params.optionalParameterCount !== 0) {
2191 compiler.cancel( 2207 compiler.cancel(
2192 'JS_TO_CLOSURE does not handle closure with optional parameters', 2208 'JS_TO_CLOSURE does not handle closure with optional parameters',
2193 node: closure); 2209 node: closure);
2194 } 2210 }
2195 visit(closure); 2211 visit(closure);
2196 List<HInstruction> inputs = <HInstruction>[pop()]; 2212 List<HInstruction> inputs = <HInstruction>[pop()];
2197 String invocationName = compiler.namer.closureInvocationName( 2213 String invocationName = compiler.namer.closureInvocationName(
2198 new Selector.invocation(params.requiredParameterCount)); 2214 new Selector.callAny(params.requiredParameterCount));
2199 push(new HForeign(new DartString.literal('#.$invocationName'), 2215 push(new HForeign(new DartString.literal('#.$invocationName'),
2200 const LiteralDartString('var'), 2216 const LiteralDartString('var'),
2201 inputs)); 2217 inputs));
2202 } 2218 }
2203 2219
2204 visitForeignSend(Send node) { 2220 visitForeignSend(Send node) {
2205 Element element = elements[node]; 2221 Element element = elements[node];
2206 if (element.name == const SourceString('JS')) { 2222 if (element.name == const SourceString('JS')) {
2207 handleForeignJs(node); 2223 handleForeignJs(node);
2208 } else if (element.name == const SourceString('UNINTERCEPTED')) { 2224 } else if (element.name == const SourceString('UNINTERCEPTED')) {
(...skipping 19 matching lines...) Expand all
2228 HInstruction self = localsHandler.readThis(); 2244 HInstruction self = localsHandler.readThis();
2229 Identifier identifier = node.selector.asIdentifier(); 2245 Identifier identifier = node.selector.asIdentifier();
2230 String name = identifier.source.slowToString(); 2246 String name = identifier.source.slowToString();
2231 // TODO(ahe): Add the arguments to this list. 2247 // TODO(ahe): Add the arguments to this list.
2232 push(new HLiteralList([])); 2248 push(new HLiteralList([]));
2233 var inputs = <HInstruction>[ 2249 var inputs = <HInstruction>[
2234 target, 2250 target,
2235 self, 2251 self,
2236 graph.addConstantString(new DartString.literal(name), node), 2252 graph.addConstantString(new DartString.literal(name), node),
2237 pop()]; 2253 pop()];
2238 push(new HInvokeSuper(Selector.INVOCATION_2, inputs)); 2254 push(new HInvokeSuper(inputs));
2239 } 2255 }
2240 2256
2241 visitSend(Send node) { 2257 visitSend(Send node) {
2242 Element element = elements[node]; 2258 Element element = elements[node];
2243 if (element !== null && element === work.element) { 2259 if (element !== null && element === work.element) {
2244 graph.isRecursiveMethod = true; 2260 graph.isRecursiveMethod = true;
2245 } 2261 }
2246 super.visitSend(node); 2262 super.visitSend(node);
2247 } 2263 }
2248 2264
2249 visitSuperSend(Send node) { 2265 visitSuperSend(Send node) {
2250 Selector selector = elements.getSelector(node); 2266 Selector selector = elements.getSelector(node);
2251 Element element = elements[node]; 2267 Element element = elements[node];
2252 if (element === null) return generateSuperNoSuchMethodSend(node); 2268 if (element === null) return generateSuperNoSuchMethodSend(node);
2253 HInstruction target = new HStatic(element); 2269 HInstruction target = new HStatic(element);
2254 HInstruction context = localsHandler.readThis(); 2270 HInstruction context = localsHandler.readThis();
2255 add(target); 2271 add(target);
2256 var inputs = <HInstruction>[target, context]; 2272 var inputs = <HInstruction>[target, context];
2257 if (node.isPropertyAccess) { 2273 if (node.isPropertyAccess) {
2258 push(new HInvokeSuper(selector, inputs)); 2274 push(new HInvokeSuper(inputs));
2259 } else if (element.kind == ElementKind.FUNCTION || 2275 } else if (element.kind == ElementKind.FUNCTION ||
2260 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 2276 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
2261 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2277 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2262 element, inputs); 2278 element, inputs);
2263 if (!succeeded) { 2279 if (!succeeded) {
2264 // TODO(ngeoffray): Match the VM behavior and throw an 2280 // TODO(ngeoffray): Match the VM behavior and throw an
2265 // exception at runtime. 2281 // exception at runtime.
2266 compiler.cancel('Unimplemented non-matching static call', node); 2282 compiler.cancel('Unimplemented non-matching static call', node);
2267 } 2283 }
2268 push(new HInvokeSuper(selector, inputs)); 2284 push(new HInvokeSuper(inputs));
2269 } else { 2285 } else {
2270 target = new HInvokeSuper(Selector.GETTER, inputs); 2286 target = new HInvokeSuper(inputs);
2271 add(target); 2287 add(target);
2272 inputs = <HInstruction>[target]; 2288 inputs = <HInstruction>[target];
2273 addDynamicSendArgumentsToList(node, inputs); 2289 addDynamicSendArgumentsToList(node, inputs);
2274 push(new HInvokeClosure(selector, inputs)); 2290 push(new HInvokeClosure(selector, inputs));
2275 } 2291 }
2276 } 2292 }
2277 2293
2278 visitNewSend(Send node) { 2294 visitNewSend(Send node) {
2279 computeType(element) { 2295 computeType(element) {
2280 Element originalElement = elements[node]; 2296 Element originalElement = elements[node];
(...skipping 24 matching lines...) Expand all
2305 inputs.add(target); 2321 inputs.add(target);
2306 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2322 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2307 element, inputs); 2323 element, inputs);
2308 if (!succeeded) { 2324 if (!succeeded) {
2309 // TODO(ngeoffray): Match the VM behavior and throw an 2325 // TODO(ngeoffray): Match the VM behavior and throw an
2310 // exception at runtime. 2326 // exception at runtime.
2311 compiler.cancel('Unimplemented non-matching static call', node: node); 2327 compiler.cancel('Unimplemented non-matching static call', node: node);
2312 } 2328 }
2313 2329
2314 HType elementType = computeType(element); 2330 HType elementType = computeType(element);
2315 HInstruction newInstance = new HInvokeStatic(selector, inputs, elementType); 2331 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
2316 pushWithPosition(newInstance, node); 2332 pushWithPosition(newInstance, node);
2317 2333
2318 TypeAnnotation annotation = getTypeAnnotationFromSend(node); 2334 TypeAnnotation annotation = getTypeAnnotationFromSend(node);
2319 Type type = elements.getType(annotation); 2335 Type type = elements.getType(annotation);
2320 generateSetRuntimeTypeInformation(newInstance, type); 2336 generateSetRuntimeTypeInformation(newInstance, type);
2321 } 2337 }
2322 2338
2323 generateSetRuntimeTypeInformation(HInstruction instance, Type type) { 2339 generateSetRuntimeTypeInformation(HInstruction instance, Type type) {
2324 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { 2340 if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
2325 String typeString = compiler.codegenWorld.rti.asJsString(type); 2341 String typeString = compiler.codegenWorld.rti.asJsString(type);
2326 HInstruction typeInfo = new HForeign(new LiteralDartString(typeString), 2342 HInstruction typeInfo = new HForeign(new LiteralDartString(typeString),
2327 new LiteralDartString('Object'), 2343 new LiteralDartString('Object'),
2328 <HInstruction>[]); 2344 <HInstruction>[]);
2329 add(typeInfo); 2345 add(typeInfo);
2330 HInstruction typeInfoSetter = 2346 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo();
2331 new HStatic(interceptors.getSetRuntimeTypeInfo()); 2347 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
2332 add(typeInfoSetter); 2348 add(typeInfoSetter);
2333 Selector setSelector = Selector.INVOCATION_2;
2334 var inputs = <HInstruction>[typeInfoSetter, instance, typeInfo]; 2349 var inputs = <HInstruction>[typeInfoSetter, instance, typeInfo];
2335 add(new HInvokeStatic(setSelector, inputs)); 2350 add(new HInvokeStatic(inputs));
2336 } 2351 }
2337 } 2352 }
2338 2353
2339 visitStaticSend(Send node) { 2354 visitStaticSend(Send node) {
2340 Selector selector = elements.getSelector(node); 2355 Selector selector = elements.getSelector(node);
2341 Element element = elements[node]; 2356 Element element = elements[node];
2342 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2357 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2343 stack.add(graph.addConstantNull()); 2358 stack.add(graph.addConstantNull());
2344 return; 2359 return;
2345 } 2360 }
2346 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); 2361 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR);
2347 HInstruction target = new HStatic(element); 2362 HInstruction target = new HStatic(element);
2348 add(target); 2363 add(target);
2349 var inputs = <HInstruction>[]; 2364 var inputs = <HInstruction>[];
2350 inputs.add(target); 2365 inputs.add(target);
2351 if (element.kind == ElementKind.FUNCTION) { 2366 if (element.kind == ElementKind.FUNCTION) {
2352 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2367 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2353 element, inputs); 2368 element, inputs);
2354 if (!succeeded) { 2369 if (!succeeded) {
2355 // TODO(ngeoffray): Match the VM behavior and throw an 2370 // TODO(ngeoffray): Match the VM behavior and throw an
2356 // exception at runtime. 2371 // exception at runtime.
2357 compiler.cancel('Unimplemented non-matching static call', node: node); 2372 compiler.cancel('Unimplemented non-matching static call', node: node);
2358 } 2373 }
2359 pushWithPosition(new HInvokeStatic(selector, inputs), node); 2374 pushWithPosition(new HInvokeStatic(inputs), node);
2360 } else { 2375 } else {
2361 if (element.kind == ElementKind.GETTER) { 2376 if (element.kind == ElementKind.GETTER) {
2362 target = new HInvokeStatic(Selector.GETTER, inputs); 2377 target = new HInvokeStatic(inputs);
2363 add(target); 2378 add(target);
2364 inputs = <HInstruction>[target]; 2379 inputs = <HInstruction>[target];
2365 } 2380 }
2366 addDynamicSendArgumentsToList(node, inputs); 2381 addDynamicSendArgumentsToList(node, inputs);
2367 pushWithPosition(new HInvokeClosure(selector, inputs), node); 2382 pushWithPosition(new HInvokeClosure(selector, inputs), node);
2368 } 2383 }
2369 } 2384 }
2370 2385
2371 visitGetterSend(Send node) { 2386 visitGetterSend(Send node) {
2372 generateGetter(node, elements[node]); 2387 generateGetter(node, elements[node]);
(...skipping 25 matching lines...) Expand all
2398 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2413 Constant constant = handler.compileNodeWithDefinitions(node, elements);
2399 stack.add(graph.addConstant(constant)); 2414 stack.add(graph.addConstant(constant));
2400 } else { 2415 } else {
2401 visitNewSend(node.send); 2416 visitNewSend(node.send);
2402 } 2417 }
2403 } 2418 }
2404 2419
2405 visitSendSet(SendSet node) { 2420 visitSendSet(SendSet node) {
2406 Operator op = node.assignmentOperator; 2421 Operator op = node.assignmentOperator;
2407 if (node.isSuperCall) { 2422 if (node.isSuperCall) {
2408 Selector selector = elements.getSelector(node);
2409 Element element = elements[node]; 2423 Element element = elements[node];
2410 if (element === null) return generateSuperNoSuchMethodSend(node); 2424 if (element === null) return generateSuperNoSuchMethodSend(node);
2411 HInstruction target = new HStatic(element); 2425 HInstruction target = new HStatic(element);
2412 HInstruction context = localsHandler.readThis(); 2426 HInstruction context = localsHandler.readThis();
2413 add(target); 2427 add(target);
2414 var inputs = <HInstruction>[target, context]; 2428 var inputs = <HInstruction>[target, context];
2415 addDynamicSendArgumentsToList(node, inputs); 2429 addDynamicSendArgumentsToList(node, inputs);
2416 push(new HInvokeSuper(selector, inputs)); 2430 push(new HInvokeSuper(inputs));
2417 } else if (node.isIndex) { 2431 } else if (node.isIndex) {
2418 if (!methodInterceptionEnabled) { 2432 if (!methodInterceptionEnabled) {
2419 assert(op.source.stringValue === '='); 2433 assert(op.source.stringValue === '=');
2420 visitDynamicSend(node); 2434 visitDynamicSend(node);
2421 } else { 2435 } else {
2422 HStatic target = new HStatic( 2436 HStatic target = new HStatic(
2423 interceptors.getIndexAssignmentInterceptor()); 2437 interceptors.getIndexAssignmentInterceptor());
2424 add(target); 2438 add(target);
2425 visit(node.receiver); 2439 visit(node.receiver);
2426 HInstruction receiver = pop(); 2440 HInstruction receiver = pop();
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 } 2726 }
2713 2727
2714 visitForIn(ForIn node) { 2728 visitForIn(ForIn node) {
2715 // Generate a structure equivalent to: 2729 // Generate a structure equivalent to:
2716 // Iterator<E> $iter = <iterable>.iterator() 2730 // Iterator<E> $iter = <iterable>.iterator()
2717 // while ($iter.hasNext()) { 2731 // while ($iter.hasNext()) {
2718 // E <declaredIdentifier> = $iter.next(); 2732 // E <declaredIdentifier> = $iter.next();
2719 // <body> 2733 // <body>
2720 // } 2734 // }
2721 2735
2722 // All the generated calls are to zero-argument functions.
2723 Selector selector = Selector.INVOCATION_0;
2724 // The iterator is shared between initializer, condition and body. 2736 // The iterator is shared between initializer, condition and body.
2725 HInstruction iterator; 2737 HInstruction iterator;
2726 void buildInitializer() { 2738 void buildInitializer() {
2727 SourceString iteratorName = const SourceString("iterator"); 2739 SourceString iteratorName = const SourceString("iterator");
2728 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); 2740 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0);
2729 assert(interceptor != null); 2741 assert(interceptor != null);
2730 HStatic target = new HStatic(interceptor);
2731 add(target);
2732 visit(node.expression); 2742 visit(node.expression);
2733 List<HInstruction> inputs = <HInstruction>[target, pop()]; 2743 pushInvokeHelper1(interceptor, pop());
2734 iterator = new HInvokeInterceptor(selector, iteratorName, inputs); 2744 iterator = pop();
2735 add(iterator);
2736 } 2745 }
2737 HInstruction buildCondition() { 2746 HInstruction buildCondition() {
2738 push(new HInvokeDynamicMethod( 2747 SourceString name = const SourceString('hasNext');
2739 selector, const SourceString('hasNext'), <HInstruction>[iterator])); 2748 Selector call = new Selector.call(name, work.element.getLibrary(), 0);
2749 push(new HInvokeDynamicMethod(call, name, <HInstruction>[iterator]));
2740 return popBoolified(); 2750 return popBoolified();
2741 } 2751 }
2742 void buildBody() { 2752 void buildBody() {
2743 push(new HInvokeDynamicMethod( 2753 SourceString name = const SourceString('next');
2744 selector, const SourceString('next'), <HInstruction>[iterator])); 2754 Selector call = new Selector.call(name, work.element.getLibrary(), 0);
2755 push(new HInvokeDynamicMethod(call, name, <HInstruction>[iterator]));
2745 2756
2746 Element variable; 2757 Element variable;
2747 if (node.declaredIdentifier.asSend() !== null) { 2758 if (node.declaredIdentifier.asSend() !== null) {
2748 variable = elements[node.declaredIdentifier]; 2759 variable = elements[node.declaredIdentifier];
2749 } else { 2760 } else {
2750 assert(node.declaredIdentifier.asVariableDefinitions() !== null); 2761 assert(node.declaredIdentifier.asVariableDefinitions() !== null);
2751 VariableDefinitions variableDefinitions = node.declaredIdentifier; 2762 VariableDefinitions variableDefinitions = node.declaredIdentifier;
2752 variable = elements[variableDefinitions.definitions.nodes.head]; 2763 variable = elements[variableDefinitions.definitions.nodes.head];
2753 } 2764 }
2754 localsHandler.updateLocal(variable, pop()); 2765 localsHandler.updateLocal(variable, pop());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 } 2831 }
2821 List<HInstruction> inputs = <HInstruction>[]; 2832 List<HInstruction> inputs = <HInstruction>[];
2822 for (Link<Node> link = node.entries.nodes; 2833 for (Link<Node> link = node.entries.nodes;
2823 !link.isEmpty(); 2834 !link.isEmpty();
2824 link = link.tail) { 2835 link = link.tail) {
2825 visit(link.head); 2836 visit(link.head);
2826 inputs.addLast(pop()); 2837 inputs.addLast(pop());
2827 inputs.addLast(pop()); 2838 inputs.addLast(pop());
2828 } 2839 }
2829 HLiteralList keyValuePairs = new HLiteralList(inputs); 2840 HLiteralList keyValuePairs = new HLiteralList(inputs);
2830 HStatic mapMaker = new HStatic(interceptors.getMapMaker());
2831 add(keyValuePairs); 2841 add(keyValuePairs);
2832 add(mapMaker); 2842 pushInvokeHelper1(interceptors.getMapMaker(), keyValuePairs);
2833 inputs = <HInstruction>[mapMaker, keyValuePairs];
2834 // TODO(ngeoffray): give the concrete type of our map literal.
2835 push(new HInvokeStatic(Selector.INVOCATION_1, inputs, HType.UNKNOWN));
2836 } 2843 }
2837 2844
2838 visitLiteralMapEntry(LiteralMapEntry node) { 2845 visitLiteralMapEntry(LiteralMapEntry node) {
2839 visit(node.value); 2846 visit(node.value);
2840 visit(node.key); 2847 visit(node.key);
2841 } 2848 }
2842 2849
2843 visitNamedArgument(NamedArgument node) { 2850 visitNamedArgument(NamedArgument node) {
2844 visit(node.expression); 2851 visit(node.expression);
2845 } 2852 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 if (switchCase.isDefaultCase) { 2962 if (switchCase.isDefaultCase) {
2956 // An HSwitch has n inputs and n+1 successors, the last being the 2963 // An HSwitch has n inputs and n+1 successors, the last being the
2957 // default case. 2964 // default case.
2958 expressionBlock.addSuccessor(block); 2965 expressionBlock.addSuccessor(block);
2959 hasDefault = true; 2966 hasDefault = true;
2960 } 2967 }
2961 open(block); 2968 open(block);
2962 localsHandler = new LocalsHandler.from(savedLocals); 2969 localsHandler = new LocalsHandler.from(savedLocals);
2963 visit(switchCase.statements); 2970 visit(switchCase.statements);
2964 if (!isAborted() && caseIterator.hasNext()) { 2971 if (!isAborted() && caseIterator.hasNext()) {
2965 push(new HStatic(getFallThroughErrorElement)); 2972 pushInvokeHelper0(getFallThroughErrorElement);
2966 HInstruction error = new HInvokeStatic( 2973 HInstruction error = pop();
2967 Selector.INVOCATION_0, <HInstruction>[pop()]);
2968 add(error);
2969 close(new HThrow(error)); 2974 close(new HThrow(error));
2970 } 2975 }
2971 statements.add( 2976 statements.add(
2972 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); 2977 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock)));
2973 } 2978 }
2974 2979
2975 // Add a join-block if necessary. 2980 // Add a join-block if necessary.
2976 // We create [joinBlock] early, and then go through the cases that might 2981 // We create [joinBlock] early, and then go through the cases that might
2977 // want to jump to it. In each case, if we add [joinBlock] as a successor 2982 // want to jump to it. In each case, if we add [joinBlock] as a successor
2978 // of another block, we also add an element to [caseLocals] that is used 2983 // of another block, we also add an element to [caseLocals] that is used
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 3044
3040 SwitchCase node = cases.head; 3045 SwitchCase node = cases.head;
3041 // Called for the statements on all but the last case block. 3046 // Called for the statements on all but the last case block.
3042 // Ensures that a user expecting a fallthrough gets an error. 3047 // Ensures that a user expecting a fallthrough gets an error.
3043 void visitStatementsAndAbort() { 3048 void visitStatementsAndAbort() {
3044 visit(node.statements); 3049 visit(node.statements);
3045 if (!isAborted()) { 3050 if (!isAborted()) {
3046 compiler.reportWarning(node, 'Missing break at end of switch case'); 3051 compiler.reportWarning(node, 'Missing break at end of switch case');
3047 Element element = 3052 Element element =
3048 compiler.findHelper(const SourceString("getFallThroughError")); 3053 compiler.findHelper(const SourceString("getFallThroughError"));
3049 push(new HStatic(element)); 3054 pushInvokeHelper0(element);
3050 HInstruction error = new HInvokeStatic( 3055 HInstruction error = pop();
3051 Selector.INVOCATION_0, <HInstruction>[pop()]);
3052 add(error);
3053 close(new HThrow(error)); 3056 close(new HThrow(error));
3054 } 3057 }
3055 } 3058 }
3056 3059
3057 Link<Node> skipLabels(Link<Node> labelsAndCases) { 3060 Link<Node> skipLabels(Link<Node> labelsAndCases) {
3058 while (!labelsAndCases.isEmpty() && labelsAndCases.head is Label) { 3061 while (!labelsAndCases.isEmpty() && labelsAndCases.head is Label) {
3059 labelsAndCases = labelsAndCases.tail; 3062 labelsAndCases = labelsAndCases.tail;
3060 } 3063 }
3061 return labelsAndCases; 3064 return labelsAndCases;
3062 } 3065 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3195 HBasicBlock block = graph.addNewBlock(); 3198 HBasicBlock block = graph.addNewBlock();
3196 enterBlock.addSuccessor(block); 3199 enterBlock.addSuccessor(block);
3197 open(block); 3200 open(block);
3198 // Note that the name of this element is irrelevant. 3201 // Note that the name of this element is irrelevant.
3199 Element element = new Element( 3202 Element element = new Element(
3200 const SourceString('exception'), ElementKind.PARAMETER, work.element); 3203 const SourceString('exception'), ElementKind.PARAMETER, work.element);
3201 exception = new HParameterValue(element); 3204 exception = new HParameterValue(element);
3202 add(exception); 3205 add(exception);
3203 HInstruction oldRethrowableException = rethrowableException; 3206 HInstruction oldRethrowableException = rethrowableException;
3204 rethrowableException = exception; 3207 rethrowableException = exception;
3205 push(new HStatic(interceptors.getExceptionUnwrapper())); 3208
3206 List<HInstruction> inputs = <HInstruction>[pop(), exception]; 3209 pushInvokeHelper1(interceptors.getExceptionUnwrapper(), exception);
3207 HInvokeStatic unwrappedException = 3210 HInvokeStatic unwrappedException = pop();
3208 new HInvokeStatic(Selector.INVOCATION_1, inputs);
3209 add(unwrappedException);
3210 tryInstruction.exception = exception; 3211 tryInstruction.exception = exception;
3211
3212 Link<Node> link = node.catchBlocks.nodes; 3212 Link<Node> link = node.catchBlocks.nodes;
3213 3213
3214 void pushCondition(CatchBlock catchBlock) { 3214 void pushCondition(CatchBlock catchBlock) {
3215 VariableDefinitions declaration = catchBlock.formals.nodes.head; 3215 VariableDefinitions declaration = catchBlock.formals.nodes.head;
3216 HInstruction condition = null; 3216 HInstruction condition = null;
3217 if (declaration.type == null) { 3217 if (declaration.type == null) {
3218 condition = graph.addConstantBool(true); 3218 condition = graph.addConstantBool(true);
3219 stack.add(condition); 3219 stack.add(condition);
3220 } else { 3220 } else {
3221 Type type = elements.getType(declaration.type); 3221 Type type = elements.getType(declaration.type);
3222 if (type == null) { 3222 if (type == null) {
3223 compiler.cancel('Catch with unresolved type', node: catchBlock); 3223 compiler.cancel('Catch with unresolved type', node: catchBlock);
3224 } 3224 }
3225 condition = new HIs(type, unwrappedException, nullOk: true); 3225 condition = new HIs(type, unwrappedException, nullOk: true);
3226 push(condition); 3226 push(condition);
3227 } 3227 }
3228 } 3228 }
3229 3229
3230 void visitThen() { 3230 void visitThen() {
3231 CatchBlock catchBlock = link.head; 3231 CatchBlock catchBlock = link.head;
3232 link = link.tail; 3232 link = link.tail;
3233 localsHandler.updateLocal(elements[catchBlock.exception], 3233 localsHandler.updateLocal(elements[catchBlock.exception],
3234 unwrappedException); 3234 unwrappedException);
3235 Node trace = catchBlock.trace; 3235 Node trace = catchBlock.trace;
3236 if (trace != null) { 3236 if (trace != null) {
3237 push(new HStatic(interceptors.getTraceFromException())); 3237 pushInvokeHelper1(interceptors.getTraceFromException(), exception);
3238 HInstruction traceInstruction = new HInvokeStatic( 3238 HInstruction traceInstruction = pop();
3239 Selector.INVOCATION_1, <HInstruction>[pop(), exception]);
3240 add(traceInstruction);
3241 localsHandler.updateLocal(elements[trace], traceInstruction); 3239 localsHandler.updateLocal(elements[trace], traceInstruction);
3242 } 3240 }
3243 visit(catchBlock); 3241 visit(catchBlock);
3244 } 3242 }
3245 3243
3246 void visitElse() { 3244 void visitElse() {
3247 if (link.isEmpty()) { 3245 if (link.isEmpty()) {
3248 close(new HThrow(exception, isRethrow: true)); 3246 close(new HThrow(exception, isRethrow: true));
3249 } else { 3247 } else {
3250 CatchBlock newBlock = link.head; 3248 CatchBlock newBlock = link.head;
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3614 new HSubGraphBlockInformation(elseBranch.graph)); 3612 new HSubGraphBlockInformation(elseBranch.graph));
3615 3613
3616 HBasicBlock conditionStartBlock = conditionBranch.block; 3614 HBasicBlock conditionStartBlock = conditionBranch.block;
3617 conditionStartBlock.setBlockFlow(info, joinBlock); 3615 conditionStartBlock.setBlockFlow(info, joinBlock);
3618 SubGraph conditionGraph = conditionBranch.graph; 3616 SubGraph conditionGraph = conditionBranch.graph;
3619 HIf branch = conditionGraph.end.last; 3617 HIf branch = conditionGraph.end.last;
3620 assert(branch is HIf); 3618 assert(branch is HIf);
3621 branch.blockInformation = conditionStartBlock.blockFlow; 3619 branch.blockInformation = conditionStartBlock.blockFlow;
3622 } 3620 }
3623 } 3621 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698