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

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

Issue 10101001: Revert "Use default values of named arguments when invoking the default super constructor." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 TreeElements treeElements = 796 TreeElements treeElements =
797 compiler.resolver.resolveMethodElement(constructor); 797 compiler.resolver.resolveMethodElement(constructor);
798 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements)); 798 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements));
799 classElement.backendMembers = 799 classElement.backendMembers =
800 classElement.backendMembers.prepend(bodyElement); 800 classElement.backendMembers.prepend(bodyElement);
801 } 801 }
802 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY); 802 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY);
803 return bodyElement; 803 return bodyElement;
804 } 804 }
805 805
806 void inlineSuperOrRedirect(FunctionElement constructor,
807 Selector selector,
808 Link<Node> arguments,
809 List<FunctionElement> constructors,
810 Map<Element, HInstruction> fieldValues) {
811 constructors.addLast(constructor);
812
813 List<HInstruction> compiledArguments = new List<HInstruction>();
814 bool succeeded = addStaticSendArgumentsToList(selector,
815 arguments,
816 constructor,
817 compiledArguments);
818 if (!succeeded) {
819 // Non-matching super and redirects are compile-time errors and thus
820 // checked by the resolver.
821 compiler.internalError(
822 "Parameters and arguments didn't match for super/redirect call",
823 element: constructor);
824 }
825
826 int index = 0;
827 FunctionParameters parameters = constructor.computeParameters(compiler);
828 parameters.forEachParameter((Element parameter) {
829 HInstruction argument = compiledArguments[index++];
830 localsHandler.updateLocal(parameter, argument);
831 // Don't forget to update the field, if the parameter is of the
832 // form [:this.x:].
833 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
834 FieldParameterElement fieldParameterElement = parameter;
835 fieldValues[fieldParameterElement.fieldElement] = argument;
836 }
837 });
838
839 // Build the initializers in the context of the new constructor.
840 TreeElements oldElements = elements;
841 elements = compiler.resolver.resolveMethodElement(constructor);
842 buildInitializers(constructor, constructors, fieldValues);
843 elements = oldElements;
844 }
845 /** 806 /**
846 * Run through the initializers and inline all field initializers. Recursively 807 * Run through the initializers and inline all field initializers. Recursively
847 * inlines super initializers. 808 * inlines super initializers.
848 * 809 *
849 * The constructors of the inlined initializers is added to [constructors] 810 * The constructors of the inlined initializers is added to [constructors]
850 * with sub constructors having a lower index than super constructors. 811 * with sub constructors having a lower index than super constructors.
851 */ 812 */
852 void buildInitializers(FunctionElement constructor, 813 void inlineInitializers(FunctionElement constructor,
853 List<FunctionElement> constructors, 814 List<FunctionElement> constructors,
854 Map<Element, HInstruction> fieldValues) { 815 Map<Element, HInstruction> fieldValues) {
816 TreeElements oldElements = elements;
817 constructors.addLast(constructor);
818 bool initializedSuper = false;
819 elements = compiler.resolver.resolveMethodElement(constructor);
855 FunctionExpression functionNode = constructor.parseNode(compiler); 820 FunctionExpression functionNode = constructor.parseNode(compiler);
856 821
857 bool foundSuperOrRedirect = false;
858
859 if (functionNode.initializers !== null) { 822 if (functionNode.initializers !== null) {
860 Link<Node> initializers = functionNode.initializers.nodes; 823 Link<Node> initializers = functionNode.initializers.nodes;
861 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 824 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
862 assert(link.head is Send); 825 assert(link.head is Send);
863 if (link.head is !SendSet) { 826 if (link.head is !SendSet) {
864 // A super initializer or constructor redirection. 827 // A super initializer or constructor redirection.
865 Send call = link.head; 828 Send call = link.head;
866 assert(Initializers.isSuperConstructorCall(call) || 829 assert(Initializers.isSuperConstructorCall(call) ||
867 Initializers.isConstructorRedirect(call)); 830 Initializers.isConstructorRedirect(call));
868 FunctionElement target = elements[call]; 831 FunctionElement nextConstructor = elements[call];
869 Selector selector = elements.getSelector(call); 832 // Visit arguments and map the corresponding parameter value to
870 Link<Node> arguments = call.arguments; 833 // the resulting HInstruction value.
871 inlineSuperOrRedirect(target, selector, arguments, constructors, 834 List<HInstruction> arguments = new List<HInstruction>();
872 fieldValues); 835 addStaticSendArgumentsToList(call, nextConstructor, arguments);
873 foundSuperOrRedirect = true; 836 int index = 0;
837 FunctionParameters parameters =
838 nextConstructor.computeParameters(compiler);
839 parameters.forEachParameter((Element parameter) {
840 HInstruction argument = arguments[index++];
841 localsHandler.updateLocal(parameter, argument);
842 // Don't forget to update the field, if the parameter is of the
843 // form [:this.x:].
844 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
845 FieldParameterElement fieldParameterElement = parameter;
846 fieldValues[fieldParameterElement.fieldElement] = argument;
847 }
848 });
849 inlineInitializers(nextConstructor, constructors, fieldValues);
850 initializedSuper = true;
874 } else { 851 } else {
875 // A field initializer. 852 // A field initializer.
876 SendSet init = link.head; 853 SendSet init = link.head;
877 Link<Node> arguments = init.arguments; 854 Link<Node> arguments = init.arguments;
878 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); 855 assert(!arguments.isEmpty() && arguments.tail.isEmpty());
879 visit(arguments.head); 856 visit(arguments.head);
880 fieldValues[elements[init]] = pop(); 857 fieldValues[elements[init]] = pop();
881 } 858 }
882 } 859 }
883 } 860 }
884 861
885 if (!foundSuperOrRedirect) { 862 if (!initializedSuper) {
886 // No super initializer found. Try to find the default constructor if 863 // No super initializer found. Try to find the default constructor if
887 // the class is not Object. 864 // the class is not Object.
888 ClassElement enclosingClass = constructor.enclosingElement; 865 ClassElement enclosingClass = constructor.enclosingElement;
889 ClassElement superClass = enclosingClass.superclass; 866 ClassElement superClass = enclosingClass.superclass;
890 if (enclosingClass != compiler.objectClass) { 867 if (enclosingClass != compiler.objectClass) {
891 assert(superClass !== null); 868 assert(superClass !== null);
892 assert(superClass.isResolved); 869 assert(superClass.isResolved);
893 FunctionElement target = superClass.lookupConstructor(superClass.name); 870 FunctionElement nextConstructor =
894 if (target === null) { 871 superClass.lookupConstructor(superClass.name);
872 if (nextConstructor === null) {
895 compiler.internalError("no default constructor available"); 873 compiler.internalError("no default constructor available");
896 } 874 }
897 inlineSuperOrRedirect(target, 875 inlineInitializers(nextConstructor, constructors, fieldValues);
898 Selector.INVOCATION_0,
899 const EmptyLink<Node>(),
900 constructors,
901 fieldValues);
902 } 876 }
903 } 877 }
878
879 elements = oldElements;
904 } 880 }
905 881
906 /** 882 /**
907 * Build the factory function corresponding to the constructor 883 * Build the factory function corresponding to the constructor
908 * [functionElement]: 884 * [functionElement]:
909 * - Initialize fields with the values of the field initializers of the 885 * - Initialize fields with the values of the field initializers of the
910 * current constructor and super constructors or constructors redirected 886 * current constructor and super constructors or constructors redirected
911 * to, starting from the current constructor. 887 * to, starting from the current constructor.
912 * - Call the the constructor bodies, starting from the constructor(s) in the 888 * - Call the the constructor bodies, starting from the constructor(s) in the
913 * super class(es). 889 * super class(es).
(...skipping 15 matching lines...) Expand all
929 // If the [element] is a field-parameter (such as [:this.x:] then 905 // If the [element] is a field-parameter (such as [:this.x:] then
930 // initialize the field element with its value. 906 // initialize the field element with its value.
931 FieldParameterElement fieldParameterElement = element; 907 FieldParameterElement fieldParameterElement = element;
932 HInstruction parameterValue = localsHandler.readLocal(element); 908 HInstruction parameterValue = localsHandler.readLocal(element);
933 fieldValues[fieldParameterElement.fieldElement] = parameterValue; 909 fieldValues[fieldParameterElement.fieldElement] = parameterValue;
934 } 910 }
935 }); 911 });
936 912
937 final Map<FunctionElement, TreeElements> constructorElements = 913 final Map<FunctionElement, TreeElements> constructorElements =
938 compiler.resolver.constructorElements; 914 compiler.resolver.constructorElements;
939 List<FunctionElement> constructors = <FunctionElement>[functionElement]; 915 List<FunctionElement> constructors = new List<FunctionElement>();
940 916
941 // Analyze the constructor and all referenced constructors and collect 917 // Analyze the constructor and all referenced constructors and collect
942 // initializers and constructor bodies. 918 // initializers and constructor bodies.
943 buildInitializers(functionElement, constructors, fieldValues); 919 inlineInitializers(functionElement, constructors, fieldValues);
944 920
945 // Call the JavaScript constructor with the fields as argument. 921 // Call the JavaScript constructor with the fields as argument.
946 List<HInstruction> constructorArguments = <HInstruction>[]; 922 List<HInstruction> constructorArguments = <HInstruction>[];
947 classElement.forEachInstanceField( 923 classElement.forEachInstanceField(
948 includeBackendMembers: true, 924 includeBackendMembers: true,
949 includeSuperMembers: true, 925 includeSuperMembers: true,
950 f: (ClassElement enclosingClass, Element member) { 926 f: (ClassElement enclosingClass, Element member) {
951 HInstruction value = fieldValues[member]; 927 HInstruction value = fieldValues[member];
952 if (value === null) { 928 if (value === null) {
953 // The field has no value in the initializer list. Initialize it 929 // The field has no value in the initializer list. Initialize it
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 // Iterate through the named arguments to add them to the list 1771 // Iterate through the named arguments to add them to the list
1796 // of instructions, in an order that can be shared with 1772 // of instructions, in an order that can be shared with
1797 // selectors with the same named arguments. 1773 // selectors with the same named arguments.
1798 List<SourceString> orderedNames = selector.getOrderedNamedArguments(); 1774 List<SourceString> orderedNames = selector.getOrderedNamedArguments();
1799 for (SourceString name in orderedNames) { 1775 for (SourceString name in orderedNames) {
1800 list.add(instructions[name]); 1776 list.add(instructions[name]);
1801 } 1777 }
1802 } 1778 }
1803 } 1779 }
1804 1780
1805 /** 1781 void addStaticSendArgumentsToList(Send node,
1806 * Returns true if the arguments were compatible with the function signature.
1807 */
1808 bool addStaticSendArgumentsToList(Selector selector,
1809 Link<Node> arguments,
1810 FunctionElement element, 1782 FunctionElement element,
1811 List<HInstruction> list) { 1783 List<HInstruction> list) {
1812 HInstruction compileArgument(Node argument) { 1784 HInstruction compileArgument(Node argument) {
1813 visit(argument); 1785 visit(argument);
1814 return pop(); 1786 return pop();
1815 } 1787 }
1816 1788
1817 HInstruction compileConstant(Element constantElement) { 1789 HInstruction compileConstant(Element constantElement) {
1818 Constant constant = compiler.compileVariable(constantElement); 1790 Constant constant = compiler.compileVariable(constantElement);
1819 return graph.addConstant(constant); 1791 return graph.addConstant(constant);
1820 } 1792 }
1821 1793
1794 Selector selector = elements.getSelector(node);
1822 FunctionParameters parameters = element.computeParameters(compiler); 1795 FunctionParameters parameters = element.computeParameters(compiler);
1823 return selector.addArgumentsToList(arguments, list, parameters, 1796 bool succeeded = selector.addSendArgumentsToList(node, list, parameters,
1824 compileArgument, compileConstant); 1797 compileArgument,
1798 compileConstant);
1799 if (!succeeded) {
1800 // TODO(ngeoffray): Match the VM behavior and throw an
1801 // exception at runtime.
1802 compiler.cancel('Unimplemented non-matching static call', node: node);
1803 }
1825 } 1804 }
1826 1805
1827 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 1806 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
1828 for (; !link.isEmpty(); link = link.tail) { 1807 for (; !link.isEmpty(); link = link.tail) {
1829 visit(link.head); 1808 visit(link.head);
1830 list.add(pop()); 1809 list.add(pop());
1831 } 1810 }
1832 } 1811 }
1833 1812
1834 visitDynamicSend(Send node) { 1813 visitDynamicSend(Send node) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 push(new HInvokeSuper(const Selector(SelectorKind.INVOCATION, 2), 2059 push(new HInvokeSuper(const Selector(SelectorKind.INVOCATION, 2),
2081 inputs)); 2060 inputs));
2082 return; 2061 return;
2083 } 2062 }
2084 HInstruction target = new HStatic(element); 2063 HInstruction target = new HStatic(element);
2085 HInstruction context = localsHandler.readThis(); 2064 HInstruction context = localsHandler.readThis();
2086 add(target); 2065 add(target);
2087 var inputs = <HInstruction>[target, context]; 2066 var inputs = <HInstruction>[target, context];
2088 if (element.kind == ElementKind.FUNCTION || 2067 if (element.kind == ElementKind.FUNCTION ||
2089 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 2068 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
2090 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2069 addStaticSendArgumentsToList(node, element, inputs);
2091 element, inputs);
2092 if (!succeeded) {
2093 // TODO(ngeoffray): Match the VM behavior and throw an
2094 // exception at runtime.
2095 compiler.cancel('Unimplemented non-matching static call', node);
2096 }
2097 push(new HInvokeSuper(selector, inputs)); 2070 push(new HInvokeSuper(selector, inputs));
2098 } else { 2071 } else {
2099 target = new HInvokeSuper(Selector.GETTER, inputs); 2072 target = new HInvokeSuper(Selector.GETTER, inputs);
2100 add(target); 2073 add(target);
2101 inputs = <HInstruction>[target]; 2074 inputs = <HInstruction>[target];
2102 addDynamicSendArgumentsToList(node, inputs); 2075 addDynamicSendArgumentsToList(node, inputs);
2103 push(new HInvokeClosure(selector, inputs)); 2076 push(new HInvokeClosure(selector, inputs));
2104 } 2077 }
2105 } 2078 }
2106 2079
2107 visitStaticSend(Send node) { 2080 visitStaticSend(Send node) {
2108 Selector selector = elements.getSelector(node); 2081 Selector selector = elements.getSelector(node);
2109 Element element = elements[node]; 2082 Element element = elements[node];
2110 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 2083 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
2111 compiler.resolver.resolveMethodElement(element); 2084 compiler.resolver.resolveMethodElement(element);
2112 FunctionElement functionElement = element; 2085 FunctionElement functionElement = element;
2113 element = functionElement.defaultImplementation; 2086 element = functionElement.defaultImplementation;
2114 } 2087 }
2115 HInstruction target = new HStatic(element); 2088 HInstruction target = new HStatic(element);
2116 add(target); 2089 add(target);
2117 var inputs = <HInstruction>[]; 2090 var inputs = <HInstruction>[];
2118 inputs.add(target); 2091 inputs.add(target);
2119 if (element.kind == ElementKind.FUNCTION || 2092 if (element.kind == ElementKind.FUNCTION ||
2120 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 2093 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
2121 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2094 addStaticSendArgumentsToList(node, element, inputs);
2122 element, inputs);
2123 if (!succeeded) {
2124 // TODO(ngeoffray): Match the VM behavior and throw an
2125 // exception at runtime.
2126 compiler.cancel('Unimplemented non-matching static call', node: node);
2127 }
2128 push(new HInvokeStatic(selector, inputs)); 2095 push(new HInvokeStatic(selector, inputs));
2129 } else { 2096 } else {
2130 if (element.kind == ElementKind.GETTER) { 2097 if (element.kind == ElementKind.GETTER) {
2131 target = new HInvokeStatic(Selector.GETTER, inputs); 2098 target = new HInvokeStatic(Selector.GETTER, inputs);
2132 add(target); 2099 add(target);
2133 inputs = <HInstruction>[target]; 2100 inputs = <HInstruction>[target];
2134 } 2101 }
2135 addDynamicSendArgumentsToList(node, inputs); 2102 addDynamicSendArgumentsToList(node, inputs);
2136 push(new HInvokeClosure(selector, inputs)); 2103 push(new HInvokeClosure(selector, inputs));
2137 } 2104 }
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
3073 false, 3040 false,
3074 <HInstruction>[target, input])); 3041 <HInstruction>[target, input]));
3075 return builder.pop(); 3042 return builder.pop();
3076 } 3043 }
3077 3044
3078 HInstruction result() { 3045 HInstruction result() {
3079 flushLiterals(); 3046 flushLiterals();
3080 return prefix; 3047 return prefix;
3081 } 3048 }
3082 } 3049 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compile_time_constants.dart ('k') | lib/compiler/implementation/universe.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698