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

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

Issue 9930005: 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
« no previous file with comments | « lib/compiler/implementation/compile_time_constants.dart ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 TreeElements treeElements = 793 TreeElements treeElements =
794 compiler.resolver.resolveMethodElement(constructor); 794 compiler.resolver.resolveMethodElement(constructor);
795 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements)); 795 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements));
796 classElement.backendMembers = 796 classElement.backendMembers =
797 classElement.backendMembers.prepend(bodyElement); 797 classElement.backendMembers.prepend(bodyElement);
798 } 798 }
799 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY); 799 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY);
800 return bodyElement; 800 return bodyElement;
801 } 801 }
802 802
803 void inlineSuperOrRedirect(FunctionElement constructor,
804 Send send,
805 List<FunctionElement> constructors,
806 Map<Element, HInstruction> fieldValues) {
807 constructors.addLast(constructor);
808
809 List<HInstruction> arguments = new List<HInstruction>();
810 addStaticSendArgumentsToList(send, constructor, arguments);
811
812 int index = 0;
813 FunctionParameters parameters = constructor.computeParameters(compiler);
814 parameters.forEachParameter((Element parameter) {
815 HInstruction argument = arguments[index++];
816 localsHandler.updateLocal(parameter, argument);
817 // Don't forget to update the field, if the parameter is of the
818 // form [:this.x:].
819 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
820 FieldParameterElement fieldParameterElement = parameter;
821 fieldValues[fieldParameterElement.fieldElement] = argument;
822 }
823 });
824
825 // Build the initializers in the context of the new constructor.
826 TreeElements oldElements = elements;
827 elements = compiler.resolver.resolveMethodElement(constructor);
828 buildInitializers(constructor, constructors, fieldValues);
829 elements = oldElements;
830 }
803 /** 831 /**
804 * Run through the initializers and inline all field initializers. Recursively 832 * Run through the initializers and inline all field initializers. Recursively
805 * inlines super initializers. 833 * inlines super initializers.
806 * 834 *
807 * The constructors of the inlined initializers is added to [constructors] 835 * The constructors of the inlined initializers is added to [constructors]
808 * with sub constructors having a lower index than super constructors. 836 * with sub constructors having a lower index than super constructors.
809 */ 837 */
810 void inlineInitializers(FunctionElement constructor, 838 void buildInitializers(FunctionElement constructor,
811 List<FunctionElement> constructors, 839 List<FunctionElement> constructors,
812 Map<Element, HInstruction> fieldValues) { 840 Map<Element, HInstruction> fieldValues) {
813 TreeElements oldElements = elements;
814 constructors.addLast(constructor);
815 bool initializedSuper = false;
816 elements = compiler.resolver.resolveMethodElement(constructor);
817 FunctionExpression functionNode = constructor.parseNode(compiler); 841 FunctionExpression functionNode = constructor.parseNode(compiler);
818 842
843 bool foundSuperOrRedirect = false;
844
819 if (functionNode.initializers !== null) { 845 if (functionNode.initializers !== null) {
820 Link<Node> initializers = functionNode.initializers.nodes; 846 Link<Node> initializers = functionNode.initializers.nodes;
821 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 847 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
822 assert(link.head is Send); 848 assert(link.head is Send);
823 if (link.head is !SendSet) { 849 if (link.head is !SendSet) {
824 // A super initializer or constructor redirection. 850 // A super initializer or constructor redirection.
825 Send call = link.head; 851 Send call = link.head;
826 assert(Initializers.isSuperConstructorCall(call) || 852 assert(Initializers.isSuperConstructorCall(call) ||
827 Initializers.isConstructorRedirect(call)); 853 Initializers.isConstructorRedirect(call));
828 FunctionElement nextConstructor = elements[call]; 854 FunctionElement target = elements[call];
829 // Visit arguments and map the corresponding parameter value to 855 inlineSuperOrRedirect(target, call, constructors, fieldValues);
830 // the resulting HInstruction value. 856 foundSuperOrRedirect = true;
831 List<HInstruction> arguments = new List<HInstruction>();
832 addStaticSendArgumentsToList(call, nextConstructor, arguments);
833 int index = 0;
834 FunctionParameters parameters =
835 nextConstructor.computeParameters(compiler);
836 parameters.forEachParameter((Element parameter) {
837 HInstruction argument = arguments[index++];
838 localsHandler.updateLocal(parameter, argument);
839 // Don't forget to update the field, if the parameter is of the
840 // form [:this.x:].
841 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
842 FieldParameterElement fieldParameterElement = parameter;
843 fieldValues[fieldParameterElement.fieldElement] = argument;
844 }
845 });
846 inlineInitializers(nextConstructor, constructors, fieldValues);
847 initializedSuper = true;
848 } else { 857 } else {
849 // A field initializer. 858 // A field initializer.
850 SendSet init = link.head; 859 SendSet init = link.head;
851 Link<Node> arguments = init.arguments; 860 Link<Node> arguments = init.arguments;
852 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); 861 assert(!arguments.isEmpty() && arguments.tail.isEmpty());
853 visit(arguments.head); 862 visit(arguments.head);
854 fieldValues[elements[init]] = pop(); 863 fieldValues[elements[init]] = pop();
855 } 864 }
856 } 865 }
857 } 866 }
858 867
859 if (!initializedSuper) { 868 if (!foundSuperOrRedirect) {
860 // No super initializer found. Try to find the default constructor if 869 // No super initializer found. Try to find the default constructor if
861 // the class is not Object. 870 // the class is not Object.
862 ClassElement enclosingClass = constructor.enclosingElement; 871 ClassElement enclosingClass = constructor.enclosingElement;
863 ClassElement superClass = enclosingClass.superclass; 872 ClassElement superClass = enclosingClass.superclass;
864 if (enclosingClass != compiler.objectClass) { 873 if (enclosingClass != compiler.objectClass) {
865 assert(superClass !== null); 874 assert(superClass !== null);
866 assert(superClass.isResolved); 875 assert(superClass.isResolved);
867 FunctionElement nextConstructor = 876 FunctionElement target = superClass.lookupConstructor(superClass.name);
868 superClass.lookupConstructor(superClass.name); 877 if (target === null) {
869 if (nextConstructor === null) {
870 compiler.internalError("no default constructor available"); 878 compiler.internalError("no default constructor available");
871 } 879 }
872 inlineInitializers(nextConstructor, constructors, fieldValues); 880 NodeList emptyNodeList = new NodeList(nodes: const EmptyLink());
881 Send syntheticSend = new Send(null, null, emptyNodeList);
882 inlineSuperOrRedirect(target, syntheticSend, constructors, fieldValues);
873 } 883 }
874 } 884 }
875
876 elements = oldElements;
877 } 885 }
878 886
879 /** 887 /**
880 * Build the factory function corresponding to the constructor 888 * Build the factory function corresponding to the constructor
881 * [functionElement]: 889 * [functionElement]:
882 * - Initialize fields with the values of the field initializers of the 890 * - Initialize fields with the values of the field initializers of the
883 * current constructor and super constructors or constructors redirected 891 * current constructor and super constructors or constructors redirected
884 * to, starting from the current constructor. 892 * to, starting from the current constructor.
885 * - Call the the constructor bodies, starting from the constructor(s) in the 893 * - Call the the constructor bodies, starting from the constructor(s) in the
886 * super class(es). 894 * super class(es).
(...skipping 15 matching lines...) Expand all
902 // If the [element] is a field-parameter (such as [:this.x:] then 910 // If the [element] is a field-parameter (such as [:this.x:] then
903 // initialize the field element with its value. 911 // initialize the field element with its value.
904 FieldParameterElement fieldParameterElement = element; 912 FieldParameterElement fieldParameterElement = element;
905 HInstruction parameterValue = localsHandler.readLocal(element); 913 HInstruction parameterValue = localsHandler.readLocal(element);
906 fieldValues[fieldParameterElement.fieldElement] = parameterValue; 914 fieldValues[fieldParameterElement.fieldElement] = parameterValue;
907 } 915 }
908 }); 916 });
909 917
910 final Map<FunctionElement, TreeElements> constructorElements = 918 final Map<FunctionElement, TreeElements> constructorElements =
911 compiler.resolver.constructorElements; 919 compiler.resolver.constructorElements;
912 List<FunctionElement> constructors = new List<FunctionElement>(); 920 List<FunctionElement> constructors = <FunctionElement>[functionElement];
913 921
914 // Analyze the constructor and all referenced constructors and collect 922 // Analyze the constructor and all referenced constructors and collect
915 // initializers and constructor bodies. 923 // initializers and constructor bodies.
916 inlineInitializers(functionElement, constructors, fieldValues); 924 buildInitializers(functionElement, constructors, fieldValues);
917 925
918 // Call the JavaScript constructor with the fields as argument. 926 // Call the JavaScript constructor with the fields as argument.
919 List<HInstruction> constructorArguments = <HInstruction>[]; 927 List<HInstruction> constructorArguments = <HInstruction>[];
920 classElement.forEachInstanceField( 928 classElement.forEachInstanceField(
921 includeBackendMembers: true, 929 includeBackendMembers: true,
922 includeSuperMembers: true, 930 includeSuperMembers: true,
923 f: (ClassElement enclosingClass, Element member) { 931 f: (ClassElement enclosingClass, Element member) {
924 HInstruction value = fieldValues[member]; 932 HInstruction value = fieldValues[member];
925 if (value === null) { 933 if (value === null) {
926 // The field has no value in the initializer list. Initialize it 934 // The field has no value in the initializer list. Initialize it
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 visit(argument); 1751 visit(argument);
1744 return pop(); 1752 return pop();
1745 } 1753 }
1746 1754
1747 HInstruction compileConstant(Element constantElement) { 1755 HInstruction compileConstant(Element constantElement) {
1748 Constant constant = compiler.compileVariable(constantElement); 1756 Constant constant = compiler.compileVariable(constantElement);
1749 return graph.addConstant(constant); 1757 return graph.addConstant(constant);
1750 } 1758 }
1751 1759
1752 Selector selector = elements.getSelector(node); 1760 Selector selector = elements.getSelector(node);
1761 // For an implicit super call we construct a synthetic send which is not
1762 // in the elements.
1763 if (selector == null) {
1764 assert(node.argumentsNode.isEmpty());
1765 selector = Selector.INVOCATION_0;
1766 }
ngeoffray 2012/03/30 09:10:03 I think the creation of the synthethized node, and
floitsch 2012/03/30 18:18:28 Not sure. (I changed this line from "I disagree",
1753 FunctionParameters parameters = element.computeParameters(compiler); 1767 FunctionParameters parameters = element.computeParameters(compiler);
1754 bool succeeded = selector.addSendArgumentsToList(node, list, parameters, 1768 bool succeeded = selector.addSendArgumentsToList(node, list, parameters,
1755 compileArgument, 1769 compileArgument,
1756 compileConstant); 1770 compileConstant);
1757 if (!succeeded) { 1771 if (!succeeded) {
1758 // TODO(ngeoffray): Match the VM behavior and throw an 1772 // TODO(ngeoffray): Match the VM behavior and throw an
1759 // exception at runtime. 1773 // exception at runtime.
1760 compiler.cancel('Unimplemented non-matching static call', node: node); 1774 compiler.cancel('Unimplemented non-matching static call', node: node);
1761 } 1775 }
1762 } 1776 }
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2970 false, 2984 false,
2971 <HInstruction>[target, input])); 2985 <HInstruction>[target, input]));
2972 return builder.pop(); 2986 return builder.pop();
2973 } 2987 }
2974 2988
2975 HInstruction result() { 2989 HInstruction result() {
2976 flushLiterals(); 2990 flushLiterals();
2977 return prefix; 2991 return prefix;
2978 } 2992 }
2979 } 2993 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compile_time_constants.dart ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698