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

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

Issue 10855174: Lazy implementation of final variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase wrt CL 10832351. 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 SsaBuilderTask(JavaScriptBackend backend) 144 SsaBuilderTask(JavaScriptBackend backend)
145 : interceptors = new Interceptors(backend.compiler), 145 : interceptors = new Interceptors(backend.compiler),
146 emitter = backend.emitter, 146 emitter = backend.emitter,
147 functionsCalledInLoop = new Set<FunctionElement>(), 147 functionsCalledInLoop = new Set<FunctionElement>(),
148 selectorsCalledInLoop = new Map<SourceString, Selector>(), 148 selectorsCalledInLoop = new Map<SourceString, Selector>(),
149 backend = backend, 149 backend = backend,
150 super(backend.compiler); 150 super(backend.compiler);
151 151
152 HGraph build(WorkItem work) { 152 HGraph build(WorkItem work) {
153 return measure(() { 153 return measure(() {
154 FunctionElement element = work.element; 154 Element element = work.element;
155 HInstruction.idCounter = 0; 155 HInstruction.idCounter = 0;
156 SsaBuilder builder = new SsaBuilder(this, work); 156 SsaBuilder builder = new SsaBuilder(this, work);
157 HGraph graph; 157 HGraph graph;
158 ElementKind kind = element.kind; 158 ElementKind kind = element.kind;
159 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 159 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
160 graph = compileConstructor(builder, work); 160 graph = compileConstructor(builder, work);
161 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 161 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
162 kind === ElementKind.FUNCTION || 162 kind === ElementKind.FUNCTION ||
163 kind === ElementKind.GETTER || 163 kind === ElementKind.GETTER ||
164 kind === ElementKind.SETTER) { 164 kind === ElementKind.SETTER) {
165 graph = builder.buildMethod(work.element); 165 graph = builder.buildMethod(work.element);
166 } else if (kind === ElementKind.FIELD) {
167 graph = builder.buildLazyInitializer(work.element);
166 } 168 }
167 assert(graph.isValid()); 169 assert(graph.isValid());
168 bool inLoop = functionsCalledInLoop.contains(element); 170 if (kind !== ElementKind.FIELD) {
169 if (!inLoop) { 171 bool inLoop = functionsCalledInLoop.contains(element);
170 Selector selector = selectorsCalledInLoop[element.name]; 172 if (!inLoop) {
171 inLoop = selector !== null && selector.applies(element, compiler); 173 Selector selector = selectorsCalledInLoop[element.name];
172 } 174 inLoop = selector !== null && selector.applies(element, compiler);
173 graph.calledInLoop = inLoop; 175 }
176 graph.calledInLoop = inLoop;
174 177
175 // If there is an estimate of the parameter types assume these types when 178 // If there is an estimate of the parameter types assume these types
176 // compiling. 179 // when compiling.
177 List<HType> parameterTypes = 180 List<HType> parameterTypes =
178 backend.optimisticParameterTypesWithRecompilationOnTypeChange( 181 backend.optimisticParameterTypesWithRecompilationOnTypeChange(
179 element); 182 element);
180 if (parameterTypes != null) { 183 if (parameterTypes != null) {
181 FunctionSignature signature = element.computeSignature(compiler); 184 FunctionElement functionElement = element;
182 int i = 0; 185 FunctionSignature signature =
183 signature.forEachParameter((Element param) { 186 functionElement.computeSignature(compiler);
184 builder.parameters[param].guaranteedType = parameterTypes[i++]; 187 int i = 0;
185 }); 188 signature.forEachParameter((Element param) {
189 builder.parameters[param].guaranteedType = parameterTypes[i++];
190 });
191 }
186 } 192 }
187 193
188 if (compiler.tracer.enabled) { 194 if (compiler.tracer.enabled) {
189 String name; 195 String name;
190 if (element.isMember()) { 196 if (element.isMember()) {
191 String className = element.getEnclosingClass().name.slowToString(); 197 String className = element.getEnclosingClass().name.slowToString();
192 String memberName = element.name.slowToString(); 198 String memberName = element.name.slowToString();
193 name = "$className.$memberName"; 199 name = "$className.$memberName";
194 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 200 if (element.isGenerativeConstructorBody()) {
195 name = "$name (body)"; 201 name = "$name (body)";
196 } 202 }
197 } else { 203 } else {
198 name = "${element.name.slowToString()}"; 204 name = "${element.name.slowToString()}";
199 } 205 }
200 compiler.tracer.traceCompilation(name, work.compilationContext); 206 compiler.tracer.traceCompilation(name, work.compilationContext);
201 compiler.tracer.traceGraph('builder', graph); 207 compiler.tracer.traceGraph('builder', graph);
202 } 208 }
203 return graph; 209 return graph;
204 }); 210 });
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 // TODO(floitsch): Clean up this hack. Should we create a box-object by 282 // TODO(floitsch): Clean up this hack. Should we create a box-object by
277 // just creating an empty object literal? 283 // just creating an empty object literal?
278 HInstruction box = createBox(); 284 HInstruction box = createBox();
279 // Add the box to the known locals. 285 // Add the box to the known locals.
280 directLocals[scopeData.boxElement] = box; 286 directLocals[scopeData.boxElement] = box;
281 // Make sure that accesses to the boxed locals go into the box. We also 287 // Make sure that accesses to the boxed locals go into the box. We also
282 // need to make sure that parameters are copied into the box if necessary. 288 // need to make sure that parameters are copied into the box if necessary.
283 scopeData.capturedVariableMapping.forEach((Element from, Element to) { 289 scopeData.capturedVariableMapping.forEach((Element from, Element to) {
284 // The [from] can only be a parameter for function-scopes and not 290 // The [from] can only be a parameter for function-scopes and not
285 // loop scopes. 291 // loop scopes.
286 if (from.kind == ElementKind.PARAMETER) { 292 if (from.isParameter()) {
287 // Store the captured parameter in the box. Get the current value 293 // Store the captured parameter in the box. Get the current value
288 // before we put the redirection in place. 294 // before we put the redirection in place.
289 HInstruction instruction = readLocal(from); 295 HInstruction instruction = readLocal(from);
290 redirectElement(from, to); 296 redirectElement(from, to);
291 // Now that the redirection is set up, the update to the local will 297 // Now that the redirection is set up, the update to the local will
292 // write the parameter value into the box. 298 // write the parameter value into the box.
293 updateLocal(from, instruction); 299 updateLocal(from, instruction);
294 } else { 300 } else {
295 redirectElement(from, to); 301 redirectElement(from, to);
296 } 302 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 HInstruction fieldGet = new HFieldGet.withElement(redirect, receiver); 422 HInstruction fieldGet = new HFieldGet.withElement(redirect, receiver);
417 builder.add(fieldGet); 423 builder.add(fieldGet);
418 return fieldGet; 424 return fieldGet;
419 } else if (isBoxed(element)) { 425 } else if (isBoxed(element)) {
420 Element redirect = redirectionMapping[element]; 426 Element redirect = redirectionMapping[element];
421 // In the function that declares the captured variable the box is 427 // In the function that declares the captured variable the box is
422 // accessed as direct local. Inside the nested closure the box is 428 // accessed as direct local. Inside the nested closure the box is
423 // accessed through a closure-field. 429 // accessed through a closure-field.
424 // Calling [readLocal] makes sure we generate the correct code to get 430 // Calling [readLocal] makes sure we generate the correct code to get
425 // the box. 431 // the box.
426 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); 432 assert(redirect.enclosingElement.isVariable());
427 HInstruction box = readLocal(redirect.enclosingElement); 433 HInstruction box = readLocal(redirect.enclosingElement);
428 HInstruction lookup = new HFieldGet.withElement(redirect, box); 434 HInstruction lookup = new HFieldGet.withElement(redirect, box);
429 builder.add(lookup); 435 builder.add(lookup);
430 return lookup; 436 return lookup;
431 } else { 437 } else {
432 assert(isUsedInTry(element)); 438 assert(isUsedInTry(element));
433 HLocalValue local = getLocal(element); 439 HLocalValue local = getLocal(element);
434 HInstruction variable = new HLocalGet(element, local); 440 HInstruction variable = new HLocalGet(element, local);
435 builder.add(variable); 441 builder.add(variable);
436 return variable; 442 return variable;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 void updateLocal(Element element, HInstruction value) { 482 void updateLocal(Element element, HInstruction value) {
477 assert(!isStoredInClosureField(element)); 483 assert(!isStoredInClosureField(element));
478 if (isAccessedDirectly(element)) { 484 if (isAccessedDirectly(element)) {
479 directLocals[element] = value; 485 directLocals[element] = value;
480 } else if (isBoxed(element)) { 486 } else if (isBoxed(element)) {
481 Element redirect = redirectionMapping[element]; 487 Element redirect = redirectionMapping[element];
482 // The box itself could be captured, or be local. A local variable that 488 // The box itself could be captured, or be local. A local variable that
483 // is captured will be boxed, but the box itself will be a local. 489 // is captured will be boxed, but the box itself will be a local.
484 // Inside the closure the box is stored in a closure-field and cannot 490 // Inside the closure the box is stored in a closure-field and cannot
485 // be accessed directly. 491 // be accessed directly.
486 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); 492 assert(redirect.enclosingElement.isVariable());
487 HInstruction box = readLocal(redirect.enclosingElement); 493 HInstruction box = readLocal(redirect.enclosingElement);
488 builder.add(new HFieldSet.withElement(redirect, box, value)); 494 builder.add(new HFieldSet.withElement(redirect, box, value));
489 } else { 495 } else {
490 assert(isUsedInTry(element)); 496 assert(isUsedInTry(element));
491 HLocalValue local = getLocal(element); 497 HLocalValue local = getLocal(element);
492 builder.add(new HLocalSet(element, local, value)); 498 builder.add(new HLocalSet(element, local, value));
493 } 499 }
494 } 500 }
495 501
496 /** 502 /**
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 methodInterceptionEnabled = true; 857 methodInterceptionEnabled = true;
852 } 858 }
853 859
854 HGraph buildMethod(FunctionElement functionElement) { 860 HGraph buildMethod(FunctionElement functionElement) {
855 FunctionExpression function = functionElement.parseNode(compiler); 861 FunctionExpression function = functionElement.parseNode(compiler);
856 openFunction(functionElement, function); 862 openFunction(functionElement, function);
857 function.body.accept(this); 863 function.body.accept(this);
858 return closeFunction(); 864 return closeFunction();
859 } 865 }
860 866
867 HGraph buildLazyInitializer(VariableElement variable) {
868 HBasicBlock block = graph.addNewBlock();
869 open(graph.entry);
870 close(new HGoto()).addSuccessor(block);
871 open(block);
872 SendSet node = variable.parseNode(compiler);
873 Link<Node> link = node.arguments;
874 assert(!link.isEmpty() && link.tail.isEmpty());
875 visit(link.head);
876 close(new HReturn(pop())).addSuccessor(graph.exit);
877 graph.finalize();
878 return graph;
879 }
880
861 /** 881 /**
862 * Returns the constructor body associated with the given constructor or 882 * Returns the constructor body associated with the given constructor or
863 * creates a new constructor body, if none can be found. 883 * creates a new constructor body, if none can be found.
864 * 884 *
865 * Returns [:null:] if the constructor does not have a body. 885 * Returns [:null:] if the constructor does not have a body.
866 */ 886 */
867 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 887 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
868 assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR); 888 assert(constructor.isGenerativeConstructor());
869 if (constructor is SynthesizedConstructorElement) return null; 889 if (constructor is SynthesizedConstructorElement) return null;
870 FunctionExpression node = constructor.parseNode(compiler); 890 FunctionExpression node = constructor.parseNode(compiler);
871 // If we know the body doesn't have any code, we don't generate 891 // If we know the body doesn't have any code, we don't generate
872 // it. 892 // it.
873 if (node.body.asBlock() !== null) { 893 if (node.body.asBlock() !== null) {
874 NodeList statements = node.body.asBlock().statements; 894 NodeList statements = node.body.asBlock().statements;
875 if (statements.isEmpty()) return null; 895 if (statements.isEmpty()) return null;
876 } 896 }
877 ClassElement classElement = constructor.getEnclosingClass(); 897 ClassElement classElement = constructor.getEnclosingClass();
878 ConstructorBodyElement bodyElement; 898 ConstructorBodyElement bodyElement;
879 for (Link<Element> backendMembers = classElement.backendMembers; 899 for (Link<Element> backendMembers = classElement.backendMembers;
880 !backendMembers.isEmpty(); 900 !backendMembers.isEmpty();
881 backendMembers = backendMembers.tail) { 901 backendMembers = backendMembers.tail) {
882 Element backendMember = backendMembers.head; 902 Element backendMember = backendMembers.head;
883 if (backendMember.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 903 if (backendMember.isGenerativeConstructorBody()) {
884 ConstructorBodyElement body = backendMember; 904 ConstructorBodyElement body = backendMember;
885 if (body.constructor == constructor) { 905 if (body.constructor == constructor) {
886 bodyElement = backendMember; 906 bodyElement = backendMember;
887 break; 907 break;
888 } 908 }
889 } 909 }
890 } 910 }
891 if (bodyElement === null) { 911 if (bodyElement === null) {
892 bodyElement = new ConstructorBodyElement(constructor); 912 bodyElement = new ConstructorBodyElement(constructor);
893 TreeElements treeElements = 913 TreeElements treeElements =
894 compiler.resolver.resolveMethodElement(constructor); 914 compiler.resolver.resolveMethodElement(constructor);
895 compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements); 915 compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements);
896 classElement.backendMembers = 916 classElement.backendMembers =
897 classElement.backendMembers.prepend(bodyElement); 917 classElement.backendMembers.prepend(bodyElement);
898 } 918 }
899 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY); 919 assert(bodyElement.isGenerativeConstructorBody());
900 return bodyElement; 920 return bodyElement;
901 } 921 }
902 922
903 void inlineSuperOrRedirect(FunctionElement constructor, 923 void inlineSuperOrRedirect(FunctionElement constructor,
904 Selector selector, 924 Selector selector,
905 Link<Node> arguments, 925 Link<Node> arguments,
906 List<FunctionElement> constructors, 926 List<FunctionElement> constructors,
907 Map<Element, HInstruction> fieldValues) { 927 Map<Element, HInstruction> fieldValues) {
908 constructors.addLast(constructor); 928 constructors.addLast(constructor);
909 929
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 // Call the JavaScript constructor with the fields as argument. 1064 // Call the JavaScript constructor with the fields as argument.
1045 List<HInstruction> constructorArguments = <HInstruction>[]; 1065 List<HInstruction> constructorArguments = <HInstruction>[];
1046 classElement.forEachInstanceField( 1066 classElement.forEachInstanceField(
1047 includeBackendMembers: true, 1067 includeBackendMembers: true,
1048 includeSuperMembers: true, 1068 includeSuperMembers: true,
1049 f: (ClassElement enclosingClass, Element member) { 1069 f: (ClassElement enclosingClass, Element member) {
1050 HInstruction value = fieldValues[member]; 1070 HInstruction value = fieldValues[member];
1051 if (value === null) { 1071 if (value === null) {
1052 // The field has no value in the initializer list. Initialize it 1072 // The field has no value in the initializer list. Initialize it
1053 // with the declaration-site constant (if any). 1073 // with the declaration-site constant (if any).
1054 Constant fieldValue = compiler.constantHandler.compileVariable(member); 1074 Constant fieldValue = compiler.compileConstant(member);
1055 value = graph.addConstant(fieldValue); 1075 value = graph.addConstant(fieldValue);
1056 } 1076 }
1057 constructorArguments.add(value); 1077 constructorArguments.add(value);
1058 }); 1078 });
1059 1079
1060 HForeignNew newObject = new HForeignNew(classElement, constructorArguments); 1080 HForeignNew newObject = new HForeignNew(classElement, constructorArguments);
1061 add(newObject); 1081 add(newObject);
1062 // Generate calls to the constructor bodies. 1082 // Generate calls to the constructor bodies.
1063 for (int index = constructors.length - 1; index >= 0; index--) { 1083 for (int index = constructors.length - 1; index >= 0; index--) {
1064 FunctionElement constructor = constructors[index]; 1084 FunctionElement constructor = constructors[index];
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 // TODO(ahe): This should be registered in codegen, not here. 1578 // TODO(ahe): This should be registered in codegen, not here.
1559 compiler.enqueuer.codegen.addToWorkList(callElement, elements); 1579 compiler.enqueuer.codegen.addToWorkList(callElement, elements);
1560 // TODO(ahe): This should be registered in codegen, not here. 1580 // TODO(ahe): This should be registered in codegen, not here.
1561 compiler.enqueuer.codegen.registerInstantiatedClass(closureClassElement); 1581 compiler.enqueuer.codegen.registerInstantiatedClass(closureClassElement);
1562 assert(closureClassElement.localScope.isEmpty()); 1582 assert(closureClassElement.localScope.isEmpty());
1563 1583
1564 List<HInstruction> capturedVariables = <HInstruction>[]; 1584 List<HInstruction> capturedVariables = <HInstruction>[];
1565 for (Element member in closureClassElement.backendMembers) { 1585 for (Element member in closureClassElement.backendMembers) {
1566 // The backendMembers also contains the call method(s). We are only 1586 // The backendMembers also contains the call method(s). We are only
1567 // interested in the fields. 1587 // interested in the fields.
1568 if (member.kind == ElementKind.FIELD) { 1588 if (member.isField()) {
1569 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 1589 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
1570 assert(capturedLocal != null); 1590 assert(capturedLocal != null);
1571 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 1591 capturedVariables.add(localsHandler.readLocal(capturedLocal));
1572 } 1592 }
1573 } 1593 }
1574 1594
1575 push(new HForeignNew(closureClassElement, capturedVariables)); 1595 push(new HForeignNew(closureClassElement, capturedVariables));
1576 } 1596 }
1577 1597
1578 visitFunctionDeclaration(FunctionDeclaration node) { 1598 visitFunctionDeclaration(FunctionDeclaration node) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 add(target); 1777 add(target);
1758 List<HInstruction> inputs = <HInstruction>[target, receiver]; 1778 List<HInstruction> inputs = <HInstruction>[target, receiver];
1759 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true)); 1779 push(new HInvokeInterceptor(selector, getterName, inputs, getter: true));
1760 } else { 1780 } else {
1761 push(new HInvokeDynamicGetter(selector, null, getterName, receiver)); 1781 push(new HInvokeDynamicGetter(selector, null, getterName, receiver));
1762 } 1782 }
1763 } 1783 }
1764 1784
1765 void generateGetter(Send send, Element element) { 1785 void generateGetter(Send send, Element element) {
1766 if (Elements.isStaticOrTopLevelField(element)) { 1786 if (Elements.isStaticOrTopLevelField(element)) {
1767 if (element.kind == ElementKind.FIELD && !element.isAssignable()) { 1787 Constant value;
1768 // A static final. Get its constant value and inline it. 1788 if (element.isField() && !element.isAssignable()) {
1769 Constant value = compiler.constantHandler.compileVariable(element); 1789 // A static final or const. Get its constant value and inline it if
1790 // the value can be compiled eagerly.
1791 value = compiler.compileVariable(element);
1792 }
1793 if (value != null) {
1770 stack.add(graph.addConstant(value)); 1794 stack.add(graph.addConstant(value));
1795 } else if (element.isField() && compiler.isLazilyInitialized(element)) {
1796 push(new HLazyStatic(element));
1771 } else { 1797 } else {
1772 push(new HStatic(element)); 1798 push(new HStatic(element));
1773 if (element.kind == ElementKind.GETTER) { 1799 if (element.isGetter()) {
1774 push(new HInvokeStatic(<HInstruction>[pop()])); 1800 push(new HInvokeStatic(<HInstruction>[pop()]));
1775 } 1801 }
1776 } 1802 }
1777 } else if (Elements.isInstanceSend(send, elements)) { 1803 } else if (Elements.isInstanceSend(send, elements)) {
1778 HInstruction receiver = generateInstanceSendReceiver(send); 1804 HInstruction receiver = generateInstanceSendReceiver(send);
1779 generateInstanceGetterWithCompiledReceiver(send, receiver); 1805 generateInstanceGetterWithCompiledReceiver(send, receiver);
1780 } else if (Elements.isStaticOrTopLevelFunction(element)) { 1806 } else if (Elements.isStaticOrTopLevelFunction(element)) {
1781 push(new HStatic(element)); 1807 push(new HStatic(element));
1782 // TODO(ahe): This should be registered in codegen. 1808 // TODO(ahe): This should be registered in codegen.
1783 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 1809 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
(...skipping 20 matching lines...) Expand all
1804 selector, dartSetterName, inputs, setter: true)); 1830 selector, dartSetterName, inputs, setter: true));
1805 } else { 1831 } else {
1806 add(new HInvokeDynamicSetter(selector, null, dartSetterName, 1832 add(new HInvokeDynamicSetter(selector, null, dartSetterName,
1807 receiver, value)); 1833 receiver, value));
1808 } 1834 }
1809 stack.add(value); 1835 stack.add(value);
1810 } 1836 }
1811 1837
1812 void generateSetter(SendSet send, Element element, HInstruction value) { 1838 void generateSetter(SendSet send, Element element, HInstruction value) {
1813 if (Elements.isStaticOrTopLevelField(element)) { 1839 if (Elements.isStaticOrTopLevelField(element)) {
1814 if (element.kind == ElementKind.SETTER) { 1840 if (element.isSetter()) {
1815 HStatic target = new HStatic(element); 1841 HStatic target = new HStatic(element);
1816 add(target); 1842 add(target);
1817 add(new HInvokeStatic(<HInstruction>[target, value])); 1843 add(new HInvokeStatic(<HInstruction>[target, value]));
1818 } else { 1844 } else {
1819 add(new HStaticStore(element, value)); 1845 add(new HStaticStore(element, value));
1820 } 1846 }
1821 stack.add(value); 1847 stack.add(value);
1822 } else if (element === null || Elements.isInstanceField(element)) { 1848 } else if (element === null || Elements.isInstanceField(element)) {
1823 HInstruction receiver = generateInstanceSendReceiver(send); 1849 HInstruction receiver = generateInstanceSendReceiver(send);
1824 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 1850 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1896 typeAnnotation = argument.asSend().receiver; 1922 typeAnnotation = argument.asSend().receiver;
1897 isNot = true; 1923 isNot = true;
1898 } 1924 }
1899 1925
1900 Type type = elements.getType(typeAnnotation); 1926 Type type = elements.getType(typeAnnotation);
1901 HInstruction typeInfo = null; 1927 HInstruction typeInfo = null;
1902 if (compiler.codegenWorld.rti.hasTypeArguments(type)) { 1928 if (compiler.codegenWorld.rti.hasTypeArguments(type)) {
1903 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); 1929 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression);
1904 typeInfo = pop(); 1930 typeInfo = pop();
1905 } 1931 }
1906 if (type.element.kind === ElementKind.TYPE_VARIABLE) { 1932 if (type.element.isTypeVariable()) {
1907 // TODO(karlklose): We emulate the frog behavior and answer 1933 // TODO(karlklose): We emulate the frog behavior and answer
1908 // true to any is check involving a type variable -- both is T 1934 // true to any is check involving a type variable -- both is T
1909 // and is !T -- until we have a proper implementation of 1935 // and is !T -- until we have a proper implementation of
1910 // reified generics. 1936 // reified generics.
1911 stack.add(graph.addConstantBool(true)); 1937 stack.add(graph.addConstantBool(true));
1912 } else { 1938 } else {
1913 HInstruction instruction; 1939 HInstruction instruction;
1914 if (typeInfo !== null) { 1940 if (typeInfo !== null) {
1915 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo); 1941 instruction = new HIs.withTypeInfoCall(type, expression, typeInfo);
1916 } else { 1942 } else {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 bool addStaticSendArgumentsToList(Selector selector, 2007 bool addStaticSendArgumentsToList(Selector selector,
1982 Link<Node> arguments, 2008 Link<Node> arguments,
1983 FunctionElement element, 2009 FunctionElement element,
1984 List<HInstruction> list) { 2010 List<HInstruction> list) {
1985 HInstruction compileArgument(Node argument) { 2011 HInstruction compileArgument(Node argument) {
1986 visit(argument); 2012 visit(argument);
1987 return pop(); 2013 return pop();
1988 } 2014 }
1989 2015
1990 HInstruction compileConstant(Element constantElement) { 2016 HInstruction compileConstant(Element constantElement) {
1991 Constant constant = compiler.compileVariable(constantElement); 2017 Constant constant = compiler.compileConstant(constantElement);
1992 return graph.addConstant(constant); 2018 return graph.addConstant(constant);
1993 } 2019 }
1994 2020
1995 return selector.addArgumentsToList(arguments, 2021 return selector.addArgumentsToList(arguments,
1996 list, 2022 list,
1997 element, 2023 element,
1998 compileArgument, 2024 compileArgument,
1999 compileConstant, 2025 compileConstant,
2000 compiler); 2026 compiler);
2001 } 2027 }
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 visitSuperSend(Send node) { 2285 visitSuperSend(Send node) {
2260 Selector selector = elements.getSelector(node); 2286 Selector selector = elements.getSelector(node);
2261 Element element = elements[node]; 2287 Element element = elements[node];
2262 if (element === null) return generateSuperNoSuchMethodSend(node); 2288 if (element === null) return generateSuperNoSuchMethodSend(node);
2263 HInstruction target = new HStatic(element); 2289 HInstruction target = new HStatic(element);
2264 HInstruction context = localsHandler.readThis(); 2290 HInstruction context = localsHandler.readThis();
2265 add(target); 2291 add(target);
2266 var inputs = <HInstruction>[target, context]; 2292 var inputs = <HInstruction>[target, context];
2267 if (node.isPropertyAccess) { 2293 if (node.isPropertyAccess) {
2268 push(new HInvokeSuper(inputs)); 2294 push(new HInvokeSuper(inputs));
2269 } else if (element.kind == ElementKind.FUNCTION || 2295 } else if (element.isFunction() || element.isGenerativeConstructor()) {
2270 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
2271 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2296 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2272 element, inputs); 2297 element, inputs);
2273 if (!succeeded) { 2298 if (!succeeded) {
2274 // TODO(ngeoffray): Match the VM behavior and throw an 2299 // TODO(ngeoffray): Match the VM behavior and throw an
2275 // exception at runtime. 2300 // exception at runtime.
2276 compiler.cancel('Unimplemented non-matching static call', node); 2301 compiler.cancel('Unimplemented non-matching static call', node);
2277 } 2302 }
2278 push(new HInvokeSuper(inputs)); 2303 push(new HInvokeSuper(inputs));
2279 } else { 2304 } else {
2280 target = new HInvokeSuper(inputs); 2305 target = new HInvokeSuper(inputs);
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 } 3242 }
3218 else { 3243 else {
3219 VariableDefinitions declaration = catchBlock.formals.nodes.head; 3244 VariableDefinitions declaration = catchBlock.formals.nodes.head;
3220 HInstruction condition = null; 3245 HInstruction condition = null;
3221 if (declaration.type == null) { 3246 if (declaration.type == null) {
3222 condition = graph.addConstantBool(true); 3247 condition = graph.addConstantBool(true);
3223 stack.add(condition); 3248 stack.add(condition);
3224 } else { 3249 } else {
3225 // TODO(aprelev@gmail.com): Once old catch syntax is removed 3250 // TODO(aprelev@gmail.com): Once old catch syntax is removed
3226 // "if" condition above and this "else" branch should be deleted as 3251 // "if" condition above and this "else" branch should be deleted as
3227 // type of declared variable won't matter for the catch 3252 // type of declared variable won't matter for the catch
3228 // condition 3253 // condition
kasperl 2012/08/17 09:30:04 Terminate comment with .
floitsch 2012/09/04 17:32:21 Done.
3229 Type type = elements.getType(declaration.type); 3254 Type type = elements.getType(declaration.type);
3230 if (type == null) { 3255 if (type == null) {
3231 compiler.cancel('Catch with unresolved type', node: catchBlock); 3256 compiler.cancel('Catch with unresolved type', node: catchBlock);
3232 } 3257 }
3233 condition = new HIs(type, unwrappedException, nullOk: true); 3258 condition = new HIs(type, unwrappedException, nullOk: true);
3234 push(condition); 3259 push(condition);
3235 } 3260 }
3236 } 3261 }
3237 } 3262 }
3238 3263
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
3621 new HSubGraphBlockInformation(elseBranch.graph)); 3646 new HSubGraphBlockInformation(elseBranch.graph));
3622 3647
3623 HBasicBlock conditionStartBlock = conditionBranch.block; 3648 HBasicBlock conditionStartBlock = conditionBranch.block;
3624 conditionStartBlock.setBlockFlow(info, joinBlock); 3649 conditionStartBlock.setBlockFlow(info, joinBlock);
3625 SubGraph conditionGraph = conditionBranch.graph; 3650 SubGraph conditionGraph = conditionBranch.graph;
3626 HIf branch = conditionGraph.end.last; 3651 HIf branch = conditionGraph.end.last;
3627 assert(branch is HIf); 3652 assert(branch is HIf);
3628 branch.blockInformation = conditionStartBlock.blockFlow; 3653 branch.blockInformation = conditionStartBlock.blockFlow;
3629 } 3654 }
3630 } 3655 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698