Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |