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

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9720030: Compile initializers in right order. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status files. Created 8 years, 9 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 | « no previous file | tests/co19/co19-leg.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 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 compiler.resolver.resolveMethodElement(constructor); 761 compiler.resolver.resolveMethodElement(constructor);
762 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements)); 762 compiler.enqueue(new WorkItem.toCodegen(bodyElement, treeElements));
763 classElement.backendMembers = 763 classElement.backendMembers =
764 classElement.backendMembers.prepend(bodyElement); 764 classElement.backendMembers.prepend(bodyElement);
765 } 765 }
766 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY); 766 assert(bodyElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY);
767 return bodyElement; 767 return bodyElement;
768 } 768 }
769 769
770 /** 770 /**
771 * Run through the initializers and inline all field initializers. Returns the 771 * Run through the initializers and inline all field initializers. Recursively
772 * next constructor to analyze. 772 * inlines super initializers.
773 *
774 * The constructors of the inlined initializers is added to [constructors]
775 * with sub constructors having a lower index then super constructors.
ngeoffray 2012/03/18 14:00:44 then -> than
floitsch 2012/03/18 15:36:10 Done.
773 */ 776 */
774 FunctionElement analyzeInitializers(Link<Node> initializers, 777 void inlineInitializers(FunctionElement constructor,
775 Map<Element, HInstruction> fieldValues) { 778 List<FunctionElement> constructors,
776 FunctionElement nextConstructor; 779 Map<Element, HInstruction> fieldValues) {
777 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 780 TreeElements oldElements = elements;
778 assert(link.head is Send); 781 constructors.addLast(constructor);
779 if (link.head is !SendSet) { 782 bool initializedSuper = false;
780 // A super initializer or constructor redirection. 783 elements = compiler.resolver.resolveMethodElement(constructor);
781 Send call = link.head; 784 FunctionExpression functionNode = constructor.parseNode(compiler);
782 assert(Initializers.isSuperConstructorCall(call) || 785
783 Initializers.isConstructorRedirect(call)); 786 if (functionNode.initializers !== null) {
784 assert(nextConstructor === null); 787 Link<Node> initializers = functionNode.initializers.nodes;
785 nextConstructor = elements[call]; 788 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
786 // Visit arguments and map the corresponding parameter value to 789 assert(link.head is Send);
787 // the resulting HInstruction value. 790 if (link.head is !SendSet) {
788 List<HInstruction> arguments = new List<HInstruction>(); 791 // A super initializer or constructor redirection.
789 addStaticSendArgumentsToList(call, nextConstructor, arguments); 792 Send call = link.head;
790 int index = 0; 793 assert(Initializers.isSuperConstructorCall(call) ||
791 FunctionParameters parameters = 794 Initializers.isConstructorRedirect(call));
792 nextConstructor.computeParameters(compiler); 795 FunctionElement nextConstructor = elements[call];
793 parameters.forEachParameter((Element parameter) { 796 // Visit arguments and map the corresponding parameter value to
794 HInstruction argument = arguments[index++]; 797 // the resulting HInstruction value.
795 localsHandler.updateLocal(parameter, argument); 798 List<HInstruction> arguments = new List<HInstruction>();
796 // Don't forget to update the field, if the parameter is of the 799 addStaticSendArgumentsToList(call, nextConstructor, arguments);
797 // form [:this.x:]. 800 int index = 0;
798 if (parameter.kind == ElementKind.FIELD_PARAMETER) { 801 FunctionParameters parameters =
799 FieldParameterElement fieldParameterElement = parameter; 802 nextConstructor.computeParameters(compiler);
800 fieldValues[fieldParameterElement.fieldElement] = argument; 803 parameters.forEachParameter((Element parameter) {
801 } 804 HInstruction argument = arguments[index++];
802 }); 805 localsHandler.updateLocal(parameter, argument);
803 } else { 806 // Don't forget to update the field, if the parameter is of the
804 // A field initializer. 807 // form [:this.x:].
805 SendSet init = link.head; 808 if (parameter.kind == ElementKind.FIELD_PARAMETER) {
806 Link<Node> arguments = init.arguments; 809 FieldParameterElement fieldParameterElement = parameter;
807 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); 810 fieldValues[fieldParameterElement.fieldElement] = argument;
808 visit(arguments.head); 811 }
809 fieldValues[elements[init]] = pop(); 812 });
813 inlineInitializers(nextConstructor, constructors, fieldValues);
814 initializedSuper = true;
815 } else {
816 // A field initializer.
817 SendSet init = link.head;
818 Link<Node> arguments = init.arguments;
819 assert(!arguments.isEmpty() && arguments.tail.isEmpty());
820 visit(arguments.head);
821 fieldValues[elements[init]] = pop();
822 }
810 } 823 }
811 } 824 }
812 return nextConstructor; 825
826 if (!initializedSuper) {
827 // No super initializer found. Try to find the default constructor if
ngeoffray 2012/03/18 14:00:44 default -> super
floitsch 2012/03/18 15:36:10 I think 'default' is correct here. We are trying t
ngeoffray 2012/03/18 15:44:53 Right. 'default' bothers me because it makes me th
828 // the class is not Object.
829 ClassElement enclosingClass = constructor.enclosingElement;
830 ClassElement superClass = enclosingClass.superclass;
831 ClassElement objectElement = compiler.coreLibrary.find(Types.OBJECT);
ngeoffray 2012/03/18 14:00:44 compiler.objectClass
floitsch 2012/03/18 15:36:10 Done.
832 if (enclosingClass != objectElement) {
833 assert(superClass !== null);
834 assert(superClass.isResolved);
835 FunctionElement nextConstructor =
836 superClass.lookupConstructor(superClass.name);
837 if (nextConstructor === null) {
838 compiler.internalError("no default constructor available");
ngeoffray 2012/03/18 14:00:44 default -> super
floitsch 2012/03/18 15:36:10 ditto.
839 }
840 inlineInitializers(nextConstructor, constructors, fieldValues);
841 }
842 }
843
844 elements = oldElements;
813 } 845 }
814 846
815 /** 847 /**
816 * Build the factory function corresponding to the constructor 848 * Build the factory function corresponding to the constructor
817 * [functionElement]: 849 * [functionElement]:
818 * - Initialize fields with the values of the field initializers of the 850 * - Initialize fields with the values of the field initializers of the
819 * current constructor and super constructors or constructors redirected 851 * current constructor and super constructors or constructors redirected
820 * to, starting from the current constructor. 852 * to, starting from the current constructor.
821 * - Call the the constructor bodies, starting from the constructor(s) in the 853 * - Call the the constructor bodies, starting from the constructor(s) in the
822 * super class(es). 854 * super class(es).
(...skipping 19 matching lines...) Expand all
842 fieldValues[fieldParameterElement.fieldElement] = parameterValue; 874 fieldValues[fieldParameterElement.fieldElement] = parameterValue;
843 } 875 }
844 }); 876 });
845 877
846 final Map<FunctionElement, TreeElements> constructorElements = 878 final Map<FunctionElement, TreeElements> constructorElements =
847 compiler.resolver.constructorElements; 879 compiler.resolver.constructorElements;
848 List<FunctionElement> constructors = new List<FunctionElement>(); 880 List<FunctionElement> constructors = new List<FunctionElement>();
849 881
850 // Analyze the constructor and all referenced constructors and collect 882 // Analyze the constructor and all referenced constructors and collect
851 // initializers and constructor bodies. 883 // initializers and constructor bodies.
852 FunctionElement nextConstructor = functionElement; 884 inlineInitializers(functionElement, constructors, fieldValues);
853 while (nextConstructor != null) { 885
854 FunctionElement constructor = nextConstructor;
855 constructors.addLast(constructor);
856 nextConstructor = null;
857 elements = compiler.resolver.resolveMethodElement(constructor);
858 FunctionExpression functionNode = constructor.parseNode(compiler);
859 Link<Node> initializers = const EmptyLink<Node>();
860 if (functionNode.initializers !== null) {
861 nextConstructor =
862 analyzeInitializers(functionNode.initializers.nodes, fieldValues);
863 }
864 if (nextConstructor === null) {
865 // No super initializer found. Try to find the default constructor if
866 // the class is not Object.
867 ClassElement enclosingClass = constructor.enclosingElement;
868 ClassElement superClass = enclosingClass.superclass;
869 ClassElement objectElement = compiler.coreLibrary.find(Types.OBJECT);
870 if (enclosingClass != objectElement) {
871 assert(superClass !== null);
872 assert(superClass.isResolved);
873 nextConstructor = superClass.lookupConstructor(superClass.name);
874 if (nextConstructor === null) {
875 compiler.internalError("no default constructor available");
876 }
877 }
878 }
879 }
880 // Call the JavaScript constructor with the fields as argument. 886 // Call the JavaScript constructor with the fields as argument.
881 // TODO(floitsch,karlklose): move this code to ClassElement and share with 887 // TODO(floitsch,karlklose): move this code to ClassElement and share with
882 // the emitter. 888 // the emitter.
883 List<HInstruction> constructorArguments = <HInstruction>[]; 889 List<HInstruction> constructorArguments = <HInstruction>[];
884 ClassElement element = classElement; 890 ClassElement element = classElement;
885 while (element != null) { 891 while (element != null) {
886 for (Element member in element.members) { 892 for (Element member in element.members) {
887 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 893 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
888 HInstruction value = fieldValues[member]; 894 HInstruction value = fieldValues[member];
889 if (value === null) { 895 if (value === null) {
(...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 buildBody() { 2552 buildBody() {
2547 // TODO(lrn): Make sure to take continue into account. 2553 // TODO(lrn): Make sure to take continue into account.
2548 visit(body); 2554 visit(body);
2549 if (isAborted()) { 2555 if (isAborted()) {
2550 compiler.reportWarning(body, "aborting loop body"); 2556 compiler.reportWarning(body, "aborting loop body");
2551 } 2557 }
2552 } 2558 }
2553 handleIf(buildBody, null); 2559 handleIf(buildBody, null);
2554 } 2560 }
2555 } 2561 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698