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

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

Issue 10917285: Stub implementation of patch invariants for the patch refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Leftovers from rebase. Created 8 years, 3 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 String get name => 'SSA builder'; 146 String get name => 'SSA builder';
147 147
148 SsaBuilderTask(JavaScriptBackend backend) 148 SsaBuilderTask(JavaScriptBackend backend)
149 : interceptors = new Interceptors(backend.compiler), 149 : interceptors = new Interceptors(backend.compiler),
150 emitter = backend.emitter, 150 emitter = backend.emitter,
151 functionsCalledInLoop = new Set<FunctionElement>(), 151 functionsCalledInLoop = new Set<FunctionElement>(),
152 selectorsCalledInLoop = new Map<SourceString, Selector>(), 152 selectorsCalledInLoop = new Map<SourceString, Selector>(),
153 backend = backend, 153 backend = backend,
154 super(backend.compiler); 154 super(backend.compiler);
155 155
156 HGraph build(WorkItem work) { 156 HGraph build(WorkItem work) {
ngeoffray 2012/09/17 12:46:24 I'd really prefer if this guy did not have to care
ahe 2012/09/18 11:25:54 Agreed, ideally, the only change to this method sh
Johnni Winther 2012/09/20 08:12:23 Done.
157 return measure(() { 157 return measure(() {
158 Element element = work.element; 158 Element element = work.element;
159 Element implementation = element.implementation;
159 HInstruction.idCounter = 0; 160 HInstruction.idCounter = 0;
160 ConstantSystem constantSystem = compiler.backend.constantSystem; 161 ConstantSystem constantSystem = compiler.backend.constantSystem;
161 SsaBuilder builder = new SsaBuilder(constantSystem, this, work); 162 SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
162 HGraph graph; 163 HGraph graph;
163 ElementKind kind = element.kind; 164 ElementKind kind = element.kind;
164 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 165 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
165 graph = compileConstructor(builder, work); 166 graph = compileConstructor(builder, work);
166 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 167 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
167 kind === ElementKind.FUNCTION || 168 kind === ElementKind.FUNCTION ||
168 kind === ElementKind.GETTER || 169 kind === ElementKind.GETTER ||
169 kind === ElementKind.SETTER) { 170 kind === ElementKind.SETTER) {
170 graph = builder.buildMethod(work.element); 171 graph = builder.buildMethod(implementation);
171 } else if (kind === ElementKind.FIELD) { 172 } else if (kind === ElementKind.FIELD) {
172 graph = builder.buildLazyInitializer(work.element); 173 graph = builder.buildLazyInitializer(implementation);
173 } 174 }
174 assert(graph.isValid()); 175 assert(graph.isValid());
175 if (kind !== ElementKind.FIELD) { 176 if (kind !== ElementKind.FIELD) {
176 bool inLoop = functionsCalledInLoop.contains(element); 177 bool inLoop = functionsCalledInLoop.contains(element);
177 if (!inLoop) { 178 if (!inLoop) {
178 Selector selector = selectorsCalledInLoop[element.name]; 179 Selector selector = selectorsCalledInLoop[element.name];
179 inLoop = selector !== null && selector.applies(element, compiler); 180 inLoop = selector !== null && selector.applies(element, compiler);
180 } 181 }
181 graph.calledInLoop = inLoop; 182 graph.calledInLoop = inLoop;
182 183
183 // If there is an estimate of the parameter types assume these types whe n 184 // If there is an estimate of the parameter types assume these types whe n
184 // compiling. 185 // compiling.
185 OptionalParameterTypes defaultValueTypes = null; 186 OptionalParameterTypes defaultValueTypes = null;
186 FunctionSignature signature = element.computeSignature(compiler); 187 FunctionSignature signature = implementation.computeSignature(compiler);
187 if (signature.optionalParameterCount > 0) { 188 if (signature.optionalParameterCount > 0) {
188 defaultValueTypes = 189 defaultValueTypes =
189 new OptionalParameterTypes(signature.optionalParameterCount); 190 new OptionalParameterTypes(signature.optionalParameterCount);
190 int index = 0; 191 int index = 0;
191 signature.forEachOptionalParameter((Element parameter) { 192 signature.forEachOptionalParameter((Element parameter) {
192 Constant defaultValue = compiler.compileVariable(parameter); 193 Constant defaultValue = compiler.compileVariable(parameter);
193 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); 194 HType type = HGraph.mapConstantTypeToSsaType(defaultValue);
194 defaultValueTypes.update(index, parameter.name, type); 195 defaultValueTypes.update(index, parameter.name, type);
195 index++; 196 index++;
196 }); 197 });
(...skipping 25 matching lines...) Expand all
222 compiler.tracer.traceCompilation(name, work.compilationContext); 223 compiler.tracer.traceCompilation(name, work.compilationContext);
223 compiler.tracer.traceGraph('builder', graph); 224 compiler.tracer.traceGraph('builder', graph);
224 } 225 }
225 return graph; 226 return graph;
226 }); 227 });
227 } 228 }
228 229
229 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { 230 HGraph compileConstructor(SsaBuilder builder, WorkItem work) {
230 // The body of the constructor will be generated in a separate function. 231 // The body of the constructor will be generated in a separate function.
231 final ClassElement classElement = work.element.getEnclosingClass(); 232 final ClassElement classElement = work.element.getEnclosingClass();
232 return builder.buildFactory(classElement, work.element); 233 return builder.buildFactory(classElement, work.element.implementation);
233 } 234 }
234 } 235 }
235 236
236 /** 237 /**
237 * Keeps track of locals (including parameters and phis) when building. The 238 * Keeps track of locals (including parameters and phis) when building. The
238 * 'this' reference is treated as parameter and hence handled by this class, 239 * 'this' reference is treated as parameter and hence handled by this class,
239 * too. 240 * too.
240 */ 241 */
241 class LocalsHandler { 242 class LocalsHandler {
242 /** 243 /**
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 // [readLocal] uses the [boxElement] to find its box. By replacing it 334 // [readLocal] uses the [boxElement] to find its box. By replacing it
334 // behind its back we can still get to the old values. 335 // behind its back we can still get to the old values.
335 updateLocal(boxElement, oldBox); 336 updateLocal(boxElement, oldBox);
336 HInstruction oldValue = readLocal(boxedVariable); 337 HInstruction oldValue = readLocal(boxedVariable);
337 updateLocal(boxElement, newBox); 338 updateLocal(boxElement, newBox);
338 updateLocal(boxedVariable, oldValue); 339 updateLocal(boxedVariable, oldValue);
339 } 340 }
340 updateLocal(boxElement, newBox); 341 updateLocal(boxElement, newBox);
341 } 342 }
342 343
344 /**
345 * Invariant: [function] must be the implementation element.
ahe 2012/09/18 11:25:54 Not documentation.
Johnni Winther 2012/09/20 08:12:23 Done.
346 */
343 void startFunction(FunctionElement function, 347 void startFunction(FunctionElement function,
344 FunctionExpression node) { 348 FunctionExpression node) {
349 assert(function.isImplementation);
345 Compiler compiler = builder.compiler; 350 Compiler compiler = builder.compiler;
346 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 351 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
347 node, builder.elements); 352 node, builder.elements);
348 FunctionSignature signature = function.computeSignature(compiler); 353 FunctionSignature signature = function.computeSignature(compiler);
349 signature.forEachParameter((Element element) { 354 signature.forEachParameter((Element element) {
350 HInstruction parameter = new HParameterValue(element); 355 HInstruction parameter = new HParameterValue(element);
351 builder.add(parameter); 356 builder.add(parameter);
352 builder.parameters[element] = parameter; 357 builder.parameters[element] = parameter;
353 directLocals[element] = parameter; 358 directLocals[element] = parameter;
354 parameter.guaranteedType = 359 parameter.guaranteedType =
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 void disableMethodInterception() { 883 void disableMethodInterception() {
879 assert(methodInterceptionEnabled); 884 assert(methodInterceptionEnabled);
880 methodInterceptionEnabled = false; 885 methodInterceptionEnabled = false;
881 } 886 }
882 887
883 void enableMethodInterception() { 888 void enableMethodInterception() {
884 assert(!methodInterceptionEnabled); 889 assert(!methodInterceptionEnabled);
885 methodInterceptionEnabled = true; 890 methodInterceptionEnabled = true;
886 } 891 }
887 892
893 /**
894 * Invariant: [functionElement] must be the implementation element.
ahe 2012/09/18 11:25:54 Not documentation.
Johnni Winther 2012/09/20 08:12:23 Done.
895 */
888 HGraph buildMethod(FunctionElement functionElement) { 896 HGraph buildMethod(FunctionElement functionElement) {
897 assert(functionElement.isImplementation);
889 FunctionExpression function = functionElement.parseNode(compiler); 898 FunctionExpression function = functionElement.parseNode(compiler);
899 assert(function !== null);
900 if (function.modifiers !== null) {
ngeoffray 2012/09/17 12:46:24 Put the if in the assert
Johnni Winther 2012/09/20 08:12:23 Done.
901 assert(!function.modifiers.isExternal());
902 }
903 assert(elements[function] !== null);
890 openFunction(functionElement, function); 904 openFunction(functionElement, function);
891 function.body.accept(this); 905 function.body.accept(this);
892 return closeFunction(); 906 return closeFunction();
893 } 907 }
894 908
895 HGraph buildLazyInitializer(VariableElement variable) { 909 HGraph buildLazyInitializer(VariableElement variable) {
896 HBasicBlock block = graph.addNewBlock(); 910 HBasicBlock block = graph.addNewBlock();
897 open(graph.entry); 911 open(graph.entry);
898 close(new HGoto()).addSuccessor(block); 912 close(new HGoto()).addSuccessor(block);
899 open(block); 913 open(block);
900 SendSet node = variable.parseNode(compiler); 914 SendSet node = variable.parseNode(compiler);
901 Link<Node> link = node.arguments; 915 Link<Node> link = node.arguments;
902 assert(!link.isEmpty() && link.tail.isEmpty()); 916 assert(!link.isEmpty() && link.tail.isEmpty());
903 visit(link.head); 917 visit(link.head);
904 HInstruction value = pop(); 918 HInstruction value = pop();
905 value = potentiallyCheckType(value, variable); 919 value = potentiallyCheckType(value, variable);
906 close(new HReturn(value)).addSuccessor(graph.exit); 920 close(new HReturn(value)).addSuccessor(graph.exit);
907 graph.finalize(); 921 graph.finalize();
908 return graph; 922 return graph;
909 } 923 }
910 924
911 /** 925 /**
912 * Returns the constructor body associated with the given constructor or 926 * Returns the constructor body associated with the given constructor or
913 * creates a new constructor body, if none can be found. 927 * creates a new constructor body, if none can be found.
914 * 928 *
915 * Returns [:null:] if the constructor does not have a body. 929 * Returns [:null:] if the constructor does not have a body.
916 */ 930 */
917 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 931 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
918 assert(constructor.isGenerativeConstructor()); 932 assert(constructor.isGenerativeConstructor());
933 assert(constructor.isImplementation);
919 if (constructor is SynthesizedConstructorElement) return null; 934 if (constructor is SynthesizedConstructorElement) return null;
920 FunctionExpression node = constructor.parseNode(compiler); 935 FunctionExpression node = constructor.parseNode(compiler);
921 // If we know the body doesn't have any code, we don't generate 936 // If we know the body doesn't have any code, we don't generate it.
922 // it.
923 if (node.body.asBlock() !== null) { 937 if (node.body.asBlock() !== null) {
924 NodeList statements = node.body.asBlock().statements; 938 NodeList statements = node.body.asBlock().statements;
925 if (statements.isEmpty()) return null; 939 if (statements.isEmpty()) return null;
926 } 940 }
927 ClassElement classElement = constructor.getEnclosingClass(); 941 ClassElement classElement = constructor.getEnclosingClass();
928 ConstructorBodyElement bodyElement; 942 ConstructorBodyElement bodyElement;
929 for (Link<Element> backendMembers = classElement.backendMembers; 943 for (Link<Element> backendMembers = classElement.backendMembers;
930 !backendMembers.isEmpty(); 944 !backendMembers.isEmpty();
931 backendMembers = backendMembers.tail) { 945 backendMembers = backendMembers.tail) {
932 Element backendMember = backendMembers.head; 946 Element backendMember = backendMembers.head;
933 if (backendMember.isGenerativeConstructorBody()) { 947 if (backendMember.isGenerativeConstructorBody()) {
934 ConstructorBodyElement body = backendMember; 948 ConstructorBodyElement body = backendMember;
935 if (body.constructor == constructor) { 949 if (body.constructor == constructor) {
936 bodyElement = backendMember; 950 bodyElement = backendMember;
937 break; 951 break;
938 } 952 }
939 } 953 }
940 } 954 }
941 if (bodyElement === null) { 955 if (bodyElement === null) {
942 bodyElement = new ConstructorBodyElement(constructor); 956 bodyElement = new ConstructorBodyElement(constructor);
943 TreeElements treeElements = 957 TreeElements treeElements =
944 compiler.resolver.resolveMethodElement(constructor); 958 compiler.resolver.resolveMethodElement(constructor.declaration);
945 compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements);
946 classElement.backendMembers = 959 classElement.backendMembers =
947 classElement.backendMembers.prepend(bodyElement); 960 classElement.backendMembers.prepend(bodyElement);
961 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration,
962 treeElements);
948 } 963 }
949 assert(bodyElement.isGenerativeConstructorBody()); 964 assert(bodyElement.isGenerativeConstructorBody());
950 return bodyElement; 965 return bodyElement;
951 } 966 }
952 967
968 /**
969 * Invariant: [function] must be the implementation element.
ahe 2012/09/18 11:25:54 Not documentation.
970 */
953 InliningState enterInlinedMethod(PartialFunctionElement function, 971 InliningState enterInlinedMethod(PartialFunctionElement function,
954 Selector selector, 972 Selector selector,
955 Link<Node> arguments) { 973 Link<Node> arguments) {
974 assert(function.isImplementation);
975
956 // Once we start to compile the arguments we must be sure that we don't 976 // Once we start to compile the arguments we must be sure that we don't
957 // abort. 977 // abort.
958 List<HInstruction> compiledArguments = new List<HInstruction>(); 978 List<HInstruction> compiledArguments = new List<HInstruction>();
959 bool succeeded = addStaticSendArgumentsToList(selector, 979 bool succeeded = addStaticSendArgumentsToList(selector,
960 arguments, 980 arguments,
961 function, 981 function,
962 compiledArguments); 982 compiledArguments);
963 assert(succeeded); 983 assert(succeeded);
964 984
965 InliningState state = 985 InliningState state =
966 new InliningState(function, returnElement, elements, stack); 986 new InliningState(function, returnElement, elements, stack);
967 inliningStack.add(state); 987 inliningStack.add(state);
968 sourceElementStack.add(function); 988 sourceElementStack.add(function);
969 stack = <HInstruction>[]; 989 stack = <HInstruction>[];
970 returnElement = new Element(const SourceString("result"), 990 returnElement = new Element(const SourceString("result"),
971 ElementKind.VARIABLE, 991 ElementKind.VARIABLE,
972 function); 992 function);
973 localsHandler.updateLocal(returnElement, 993 localsHandler.updateLocal(returnElement,
974 graph.addConstantNull(constantSystem)); 994 graph.addConstantNull(constantSystem));
975 elements = compiler.enqueuer.resolution.getCachedElements(function); 995 elements = compiler.enqueuer.resolution.getCachedElements(function);
996 assert(elements !== null);
976 FunctionSignature signature = function.computeSignature(compiler); 997 FunctionSignature signature = function.computeSignature(compiler);
977 int index = 0; 998 int index = 0;
978 signature.forEachParameter((Element parameter) { 999 signature.forEachParameter((Element parameter) {
979 HInstruction argument = compiledArguments[index++]; 1000 HInstruction argument = compiledArguments[index++];
980 localsHandler.updateLocal(parameter, argument); 1001 localsHandler.updateLocal(parameter, argument);
981 potentiallyCheckType(argument, parameter); 1002 potentiallyCheckType(argument, parameter);
982 }); 1003 });
983 return state; 1004 return state;
984 } 1005 }
985 1006
986 void leaveInlinedMethod(InliningState state) { 1007 void leaveInlinedMethod(InliningState state) {
987 InliningState poppedState = inliningStack.removeLast(); 1008 InliningState poppedState = inliningStack.removeLast();
988 assert(state == poppedState); 1009 assert(state == poppedState);
989 FunctionElement poppedElement = sourceElementStack.removeLast(); 1010 FunctionElement poppedElement = sourceElementStack.removeLast();
990 assert(poppedElement == poppedState.function); 1011 assert(poppedElement == poppedState.function);
991 elements = state.oldElements; 1012 elements = state.oldElements;
992 stack.add(localsHandler.readLocal(returnElement)); 1013 stack.add(localsHandler.readLocal(returnElement));
993 returnElement = state.oldReturnElement; 1014 returnElement = state.oldReturnElement;
994 assert(stack.length == 1); 1015 assert(stack.length == 1);
995 state.oldStack.add(stack[0]); 1016 state.oldStack.add(stack[0]);
996 stack = state.oldStack; 1017 stack = state.oldStack;
997 } 1018 }
998 1019
1020 /**
1021 * Invariant: [element] must be the implementation element.
ahe 2012/09/18 11:25:54 Not documentation.
1022 */
999 bool tryInlineMethod(Element element, 1023 bool tryInlineMethod(Element element,
1000 Selector selector, 1024 Selector selector,
1001 Link<Node> arguments) { 1025 Link<Node> arguments) {
1026 assert(element.isImplementation);
1002 // TODO(floitsch): we should be able to inline inside lazy initializers. 1027 // TODO(floitsch): we should be able to inline inside lazy initializers.
1003 if (!currentElement.isFunction()) return false; 1028 if (!currentElement.isFunction()) return false;
1004 // TODO(floitsch): we should be able to inline getters, setters and 1029 // TODO(floitsch): we should be able to inline getters, setters and
1005 // constructor bodies. 1030 // constructor bodies.
1006 if (!element.isFunction()) return false; 1031 if (!element.isFunction()) return false;
1007 // TODO(floitsch): find a cleaner way to know if the element is a function 1032 // TODO(floitsch): find a cleaner way to know if the element is a function
1008 // containing nodes. 1033 // containing nodes.
1009 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. 1034 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
1010 if (element is !PartialFunctionElement) return false; 1035 if (element is !PartialFunctionElement) return false;
1011 if (inliningStack.length > MAX_INLINING_DEPTH) return false; 1036 if (inliningStack.length > MAX_INLINING_DEPTH) return false;
(...skipping 20 matching lines...) Expand all
1032 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) { 1057 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) {
1033 return false; 1058 return false;
1034 } 1059 }
1035 1060
1036 InliningState state = enterInlinedMethod(function, selector, arguments); 1061 InliningState state = enterInlinedMethod(function, selector, arguments);
1037 functionExpression.body.accept(this); 1062 functionExpression.body.accept(this);
1038 leaveInlinedMethod(state); 1063 leaveInlinedMethod(state);
1039 return true; 1064 return true;
1040 } 1065 }
1041 1066
1067 /**
1068 * Invariant: [constructor] and [constructors] must all be implementation
ahe 2012/09/18 11:25:54 Not documentation.
1069 * elements.
1070 */
1042 void inlineSuperOrRedirect(FunctionElement constructor, 1071 void inlineSuperOrRedirect(FunctionElement constructor,
1043 Selector selector, 1072 Selector selector,
1044 Link<Node> arguments, 1073 Link<Node> arguments,
1045 List<FunctionElement> constructors, 1074 List<FunctionElement> constructors,
1046 Map<Element, HInstruction> fieldValues) { 1075 Map<Element, HInstruction> fieldValues) {
1076 assert(constructor.isImplementation);
1047 constructors.addLast(constructor); 1077 constructors.addLast(constructor);
1048 1078
1049 List<HInstruction> compiledArguments = new List<HInstruction>(); 1079 List<HInstruction> compiledArguments = new List<HInstruction>();
1050 bool succeeded = addStaticSendArgumentsToList(selector, 1080 bool succeeded = addStaticSendArgumentsToList(selector,
1051 arguments, 1081 arguments,
1052 constructor, 1082 constructor,
1053 compiledArguments); 1083 compiledArguments);
1054 if (!succeeded) { 1084 if (!succeeded) {
1055 // Non-matching super and redirects are compile-time errors and thus 1085 // Non-matching super and redirects are compile-time errors and thus
1056 // checked by the resolver. 1086 // checked by the resolver.
(...skipping 23 matching lines...) Expand all
1080 buildInitializers(constructor, constructors, fieldValues); 1110 buildInitializers(constructor, constructors, fieldValues);
1081 elements = oldElements; 1111 elements = oldElements;
1082 } 1112 }
1083 1113
1084 /** 1114 /**
1085 * Run through the initializers and inline all field initializers. Recursively 1115 * Run through the initializers and inline all field initializers. Recursively
1086 * inlines super initializers. 1116 * inlines super initializers.
1087 * 1117 *
1088 * The constructors of the inlined initializers is added to [constructors] 1118 * The constructors of the inlined initializers is added to [constructors]
1089 * with sub constructors having a lower index than super constructors. 1119 * with sub constructors having a lower index than super constructors.
1120 *
1121 * Invariant: The [constructor] and elements in [constructors] must all be
1122 * implementation elements.
1090 */ 1123 */
1091 void buildInitializers(FunctionElement constructor, 1124 void buildInitializers(FunctionElement constructor,
1092 List<FunctionElement> constructors, 1125 List<FunctionElement> constructors,
1093 Map<Element, HInstruction> fieldValues) { 1126 Map<Element, HInstruction> fieldValues) {
1127 assert(constructor.isImplementation);
1094 FunctionExpression functionNode = constructor.parseNode(compiler); 1128 FunctionExpression functionNode = constructor.parseNode(compiler);
1095 1129
1096 bool foundSuperOrRedirect = false; 1130 bool foundSuperOrRedirect = false;
1097 1131
1098 if (functionNode.initializers !== null) { 1132 if (functionNode.initializers !== null) {
1099 Link<Node> initializers = functionNode.initializers.nodes; 1133 Link<Node> initializers = functionNode.initializers.nodes;
1100 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 1134 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
1101 assert(link.head is Send); 1135 assert(link.head is Send);
1102 if (link.head is !SendSet) { 1136 if (link.head is !SendSet) {
1103 // A super initializer or constructor redirection. 1137 // A super initializer or constructor redirection.
(...skipping 17 matching lines...) Expand all
1121 fieldValues[elements[init]] = pop(); 1155 fieldValues[elements[init]] = pop();
1122 } 1156 }
1123 } 1157 }
1124 } 1158 }
1125 1159
1126 if (!foundSuperOrRedirect) { 1160 if (!foundSuperOrRedirect) {
1127 // No super initializer found. Try to find the default constructor if 1161 // No super initializer found. Try to find the default constructor if
1128 // the class is not Object. 1162 // the class is not Object.
1129 ClassElement enclosingClass = constructor.getEnclosingClass(); 1163 ClassElement enclosingClass = constructor.getEnclosingClass();
1130 ClassElement superClass = enclosingClass.superclass; 1164 ClassElement superClass = enclosingClass.superclass;
1131 if (enclosingClass != compiler.objectClass) { 1165 if (!enclosingClass.isObject) {
ahe 2012/09/18 11:25:54 I'm not sure about the implementation of this.
Johnni Winther 2012/09/20 08:12:23 Changed.
1132 assert(superClass !== null); 1166 assert(superClass !== null);
1133 assert(superClass.resolutionState == STATE_DONE); 1167 assert(superClass.resolutionState == STATE_DONE);
1134 Selector selector = 1168 Selector selector =
1135 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); 1169 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0);
1136 FunctionElement target = superClass.lookupConstructor(superClass.name); 1170 FunctionElement target = superClass.lookupConstructor(superClass.name);
1137 if (target === null) { 1171 if (target === null) {
1138 compiler.internalError("no default constructor available"); 1172 compiler.internalError("no default constructor available");
1139 } 1173 }
1140 inlineSuperOrRedirect(target, 1174 inlineSuperOrRedirect(target.implementation,
1141 selector, 1175 selector,
1142 const EmptyLink<Node>(), 1176 const EmptyLink<Node>(),
1143 constructors, 1177 constructors,
1144 fieldValues); 1178 fieldValues);
1145 } 1179 }
1146 } 1180 }
1147 } 1181 }
1148 1182
1149 /** 1183 /**
1150 * Run through the fields of [cls] and add their potential 1184 * Run through the fields of [cls] and add their potential
1151 * initializers. 1185 * initializers.
1186 *
1187 * Invariant: [classElement] must be the declaration element.
1152 */ 1188 */
1153 void buildFieldInitializers(ClassElement classElement, 1189 void buildFieldInitializers(ClassElement classElement,
1154 Map<Element, HInstruction> fieldValues) { 1190 Map<Element, HInstruction> fieldValues) {
1191 assert(classElement.isDeclaration);
1155 classElement.forEachInstanceField( 1192 classElement.forEachInstanceField(
1156 includeBackendMembers: true, 1193 includeBackendMembers: true,
1157 includeSuperMembers: false, 1194 includeSuperMembers: false,
1158 f: (ClassElement enclosingClass, Element member) { 1195 f: (ClassElement enclosingClass, Element member) {
1159 TreeElements definitions = compiler.analyzeElement(member); 1196 TreeElements definitions = compiler.analyzeElement(member);
1160 Node node = member.parseNode(compiler); 1197 Node node = member.parseNode(compiler);
1161 SendSet assignment = node.asSendSet(); 1198 SendSet assignment = node.asSendSet();
1162 HInstruction value; 1199 HInstruction value;
1163 if (assignment === null) { 1200 if (assignment === null) {
1164 value = graph.addConstantNull(constantSystem); 1201 value = graph.addConstantNull(constantSystem);
(...skipping 11 matching lines...) Expand all
1176 1213
1177 1214
1178 /** 1215 /**
1179 * Build the factory function corresponding to the constructor 1216 * Build the factory function corresponding to the constructor
1180 * [functionElement]: 1217 * [functionElement]:
1181 * - Initialize fields with the values of the field initializers of the 1218 * - Initialize fields with the values of the field initializers of the
1182 * current constructor and super constructors or constructors redirected 1219 * current constructor and super constructors or constructors redirected
1183 * to, starting from the current constructor. 1220 * to, starting from the current constructor.
1184 * - Call the the constructor bodies, starting from the constructor(s) in the 1221 * - Call the the constructor bodies, starting from the constructor(s) in the
1185 * super class(es). 1222 * super class(es).
1223 *
1224 * Invariants: [classElement] must be the declaration element, and
1225 * [functionElement] must be the implementation element.
1186 */ 1226 */
1187 HGraph buildFactory(ClassElement classElement, 1227 HGraph buildFactory(ClassElement classElement,
1188 FunctionElement functionElement) { 1228 FunctionElement functionElement) {
1229 assert(classElement.isDeclaration);
1230 assert(functionElement.isImplementation);
1189 FunctionExpression function = functionElement.parseNode(compiler); 1231 FunctionExpression function = functionElement.parseNode(compiler);
1190 // Note that constructors (like any other static function) do not need 1232 // Note that constructors (like any other static function) do not need
1191 // to deal with optional arguments. It is the callers job to provide all 1233 // to deal with optional arguments. It is the callers job to provide all
1192 // arguments as if they were positional. 1234 // arguments as if they were positional.
1193 1235
1194 // The initializer list could contain closures. 1236 // The initializer list could contain closures.
1195 openFunction(functionElement, function); 1237 openFunction(functionElement, function);
1196 1238
1197 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); 1239 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
1198 1240
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 List<HInstruction> rtiInputs = <HInstruction>[]; 1278 List<HInstruction> rtiInputs = <HInstruction>[];
1237 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1279 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1238 rtiInputs.add(localsHandler.directLocals[typeVariable.element]); 1280 rtiInputs.add(localsHandler.directLocals[typeVariable.element]);
1239 }); 1281 });
1240 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject); 1282 callSetRuntimeTypeInfo(classElement, rtiInputs, newObject);
1241 } 1283 }
1242 1284
1243 // Generate calls to the constructor bodies. 1285 // Generate calls to the constructor bodies.
1244 for (int index = constructors.length - 1; index >= 0; index--) { 1286 for (int index = constructors.length - 1; index >= 0; index--) {
1245 FunctionElement constructor = constructors[index]; 1287 FunctionElement constructor = constructors[index];
1288 assert(constructor.isImplementation);
1246 ConstructorBodyElement body = getConstructorBody(constructor); 1289 ConstructorBodyElement body = getConstructorBody(constructor);
1247 if (body === null) continue; 1290 if (body === null) continue;
1248 List bodyCallInputs = <HInstruction>[]; 1291 List bodyCallInputs = <HInstruction>[];
1249 bodyCallInputs.add(newObject); 1292 bodyCallInputs.add(newObject);
1250 int arity = body.functionSignature.parameterCount; 1293 FunctionSignature functionSignature = body.computeSignature(compiler);
1251 body.functionSignature.forEachParameter((parameter) { 1294 int arity = functionSignature.parameterCount;
1295 functionSignature.forEachParameter((parameter) {
1252 bodyCallInputs.add(localsHandler.readLocal(parameter)); 1296 bodyCallInputs.add(localsHandler.readLocal(parameter));
1253 }); 1297 });
1254 // TODO(ahe): The constructor name is statically resolved. See 1298 // TODO(ahe): The constructor name is statically resolved. See
1255 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner 1299 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
1256 // way to do this? 1300 // way to do this?
1257 SourceString name = new SourceString(backend.namer.getName(body)); 1301 SourceString name =
1302 new SourceString(backend.namer.getName(body.declaration));
1258 // TODO(kasperl): This seems fishy. We shouldn't be inventing all 1303 // TODO(kasperl): This seems fishy. We shouldn't be inventing all
1259 // these selectors. Maybe the resolver can do more of the work 1304 // these selectors. Maybe the resolver can do more of the work
1260 // for us here? 1305 // for us here?
1261 LibraryElement library = body.getLibrary(); 1306 LibraryElement library = body.getLibrary();
1262 Selector selector = new Selector.call(name, library, arity); 1307 Selector selector = new Selector.call(name, library, arity);
1263 add(new HInvokeDynamicMethod(selector, bodyCallInputs)); 1308 add(new HInvokeDynamicMethod(selector, bodyCallInputs));
1264 } 1309 }
1265 close(new HReturn(newObject)).addSuccessor(graph.exit); 1310 close(new HReturn(newObject)).addSuccessor(graph.exit);
1266 return closeFunction(); 1311 return closeFunction();
1267 } 1312 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 1350
1306 // Create the instruction that parameter checks will use. 1351 // Create the instruction that parameter checks will use.
1307 check = new HNot(check); 1352 check = new HNot(check);
1308 add(check); 1353 add(check);
1309 1354
1310 ClosureClassMap closureData = localsHandler.closureData; 1355 ClosureClassMap closureData = localsHandler.closureData;
1311 Element checkResultElement = closureData.parametersWithSentinel[element]; 1356 Element checkResultElement = closureData.parametersWithSentinel[element];
1312 localsHandler.updateLocal(checkResultElement, check); 1357 localsHandler.updateLocal(checkResultElement, check);
1313 } 1358 }
1314 1359
1360 /**
1361 * Invariant: [functionElement] must be the implementation element.
ahe 2012/09/18 11:25:54 Not documentation.
1362 */
1315 void openFunction(FunctionElement functionElement, 1363 void openFunction(FunctionElement functionElement,
1316 FunctionExpression node) { 1364 FunctionExpression node) {
1365 assert(functionElement.isImplementation);
1317 HBasicBlock block = graph.addNewBlock(); 1366 HBasicBlock block = graph.addNewBlock();
1318 open(graph.entry); 1367 open(graph.entry);
1319 1368
1320 localsHandler.startFunction(functionElement, node); 1369 localsHandler.startFunction(functionElement, node);
1321 close(new HGoto()).addSuccessor(block); 1370 close(new HGoto()).addSuccessor(block);
1322 1371
1323 open(block); 1372 open(block);
1324 1373
1325 FunctionSignature params = functionElement.computeSignature(compiler); 1374 FunctionSignature params = functionElement.computeSignature(compiler);
1326 params.forEachParameter((Element element) { 1375 params.forEachParameter((Element element) {
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 if (element.isField() && !element.isAssignable()) { 2080 if (element.isField() && !element.isAssignable()) {
2032 // A static final or const. Get its constant value and inline it if 2081 // A static final or const. Get its constant value and inline it if
2033 // the value can be compiled eagerly. 2082 // the value can be compiled eagerly.
2034 value = compiler.compileVariable(element); 2083 value = compiler.compileVariable(element);
2035 } 2084 }
2036 if (value != null) { 2085 if (value != null) {
2037 stack.add(graph.addConstant(value)); 2086 stack.add(graph.addConstant(value));
2038 } else if (element.isField() && compiler.isLazilyInitialized(element)) { 2087 } else if (element.isField() && compiler.isLazilyInitialized(element)) {
2039 push(new HLazyStatic(element)); 2088 push(new HLazyStatic(element));
2040 } else { 2089 } else {
2041 push(new HStatic(element)); 2090 push(new HStatic(element.declaration));
ngeoffray 2012/09/17 12:46:24 Why this change?
Johnni Winther 2012/09/20 08:12:23 For some reason putting the invariant on the eleme
2042 if (element.isGetter()) { 2091 if (element.isGetter()) {
2043 push(new HInvokeStatic(<HInstruction>[pop()])); 2092 push(new HInvokeStatic(<HInstruction>[pop()]));
2044 } 2093 }
2045 } 2094 }
2046 } else if (Elements.isInstanceSend(send, elements)) { 2095 } else if (Elements.isInstanceSend(send, elements)) {
2047 HInstruction receiver = generateInstanceSendReceiver(send); 2096 HInstruction receiver = generateInstanceSendReceiver(send);
2048 generateInstanceGetterWithCompiledReceiver(send, receiver); 2097 generateInstanceGetterWithCompiledReceiver(send, receiver);
2049 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2098 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2050 push(new HStatic(element)); 2099 push(new HStatic(element.declaration));
2051 // TODO(ahe): This should be registered in codegen. 2100 // TODO(ahe): This should be registered in codegen.
2052 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2101 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2053 } else if (Elements.isErroneousElement(element)) { 2102 } else if (Elements.isErroneousElement(element)) {
2054 // An erroneous element indicates an unresolved static getter. 2103 // An erroneous element indicates an unresolved static getter.
2055 generateThrowNoSuchMethod(send, 2104 generateThrowNoSuchMethod(send,
2056 getTargetName(element, 'get '), 2105 getTargetName(element, 'get '),
2057 const EmptyLink<Node>()); 2106 const EmptyLink<Node>());
2058 } else { 2107 } else {
2059 stack.add(localsHandler.readLocal(element)); 2108 stack.add(localsHandler.readLocal(element));
2060 } 2109 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 // selectors with the same named arguments. 2309 // selectors with the same named arguments.
2261 List<SourceString> orderedNames = selector.getOrderedNamedArguments(); 2310 List<SourceString> orderedNames = selector.getOrderedNamedArguments();
2262 for (SourceString name in orderedNames) { 2311 for (SourceString name in orderedNames) {
2263 list.add(instructions[name]); 2312 list.add(instructions[name]);
2264 } 2313 }
2265 } 2314 }
2266 } 2315 }
2267 2316
2268 /** 2317 /**
2269 * Returns true if the arguments were compatible with the function signature. 2318 * Returns true if the arguments were compatible with the function signature.
2319 *
2320 * Invariant: [element] must be the implementation element.
2270 */ 2321 */
2271 bool addStaticSendArgumentsToList(Selector selector, 2322 bool addStaticSendArgumentsToList(Selector selector,
2272 Link<Node> arguments, 2323 Link<Node> arguments,
2273 FunctionElement element, 2324 FunctionElement element,
2274 List<HInstruction> list) { 2325 List<HInstruction> list) {
2326 assert(element.isImplementation);
2327
2275 HInstruction compileArgument(Node argument) { 2328 HInstruction compileArgument(Node argument) {
2276 visit(argument); 2329 visit(argument);
2277 return pop(); 2330 return pop();
2278 } 2331 }
2279 2332
2280 HInstruction compileConstant(Element parameter) { 2333 HInstruction compileConstant(Element parameter) {
2281 Constant constant; 2334 Constant constant;
2282 TreeElements calleeElements = 2335 TreeElements calleeElements =
2283 compiler.enqueuer.resolution.getCachedElements(element); 2336 compiler.enqueuer.resolution.getCachedElements(element);
2284 if (calleeElements.isParameterChecked(parameter)) { 2337 if (calleeElements.isParameterChecked(parameter)) {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 node: node.argumentsNode); 2535 node: node.argumentsNode);
2483 } 2536 }
2484 Node closure = node.arguments.head; 2537 Node closure = node.arguments.head;
2485 Element element = elements[closure]; 2538 Element element = elements[closure];
2486 if (!Elements.isStaticOrTopLevelFunction(element)) { 2539 if (!Elements.isStaticOrTopLevelFunction(element)) {
2487 compiler.cancel( 2540 compiler.cancel(
2488 'JS_TO_CLOSURE requires a static or top-level method', 2541 'JS_TO_CLOSURE requires a static or top-level method',
2489 node: closure); 2542 node: closure);
2490 } 2543 }
2491 FunctionElement function = element; 2544 FunctionElement function = element;
2492 FunctionSignature params = function.computeSignature(compiler); 2545 FunctionSignature params
2546 = function.implementation.computeSignature(compiler);
2493 if (params.optionalParameterCount !== 0) { 2547 if (params.optionalParameterCount !== 0) {
2494 compiler.cancel( 2548 compiler.cancel(
2495 'JS_TO_CLOSURE does not handle closure with optional parameters', 2549 'JS_TO_CLOSURE does not handle closure with optional parameters',
2496 node: closure); 2550 node: closure);
2497 } 2551 }
2498 visit(closure); 2552 visit(closure);
2499 List<HInstruction> inputs = <HInstruction>[pop()]; 2553 List<HInstruction> inputs = <HInstruction>[pop()];
2500 String invocationName = backend.namer.closureInvocationName( 2554 String invocationName = backend.namer.closureInvocationName(
2501 new Selector.callClosure(params.requiredParameterCount)); 2555 new Selector.callClosure(params.requiredParameterCount));
2502 push(new HForeign(new DartString.literal('#.$invocationName'), 2556 push(new HForeign(new DartString.literal('#.$invocationName'),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 if (element !== null && element === work.element) { 2603 if (element !== null && element === work.element) {
2550 graph.isRecursiveMethod = true; 2604 graph.isRecursiveMethod = true;
2551 } 2605 }
2552 super.visitSend(node); 2606 super.visitSend(node);
2553 } 2607 }
2554 2608
2555 visitSuperSend(Send node) { 2609 visitSuperSend(Send node) {
2556 Selector selector = elements.getSelector(node); 2610 Selector selector = elements.getSelector(node);
2557 Element element = elements[node]; 2611 Element element = elements[node];
2558 if (element === null) return generateSuperNoSuchMethodSend(node); 2612 if (element === null) return generateSuperNoSuchMethodSend(node);
2559 HInstruction target = new HStatic(element); 2613 HInstruction target = new HStatic(element.declaration);
2560 HInstruction context = localsHandler.readThis(); 2614 HInstruction context = localsHandler.readThis();
2561 add(target); 2615 add(target);
2562 var inputs = <HInstruction>[target, context]; 2616 var inputs = <HInstruction>[target, context];
2563 if (node.isPropertyAccess) { 2617 if (node.isPropertyAccess) {
2564 push(new HInvokeSuper(inputs)); 2618 push(new HInvokeSuper(inputs));
2565 } else if (element.isFunction() || element.isGenerativeConstructor()) { 2619 } else if (element.isFunction() || element.isGenerativeConstructor()) {
2566 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2620 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2567 element, inputs); 2621 element.implementation,
2622 inputs);
2568 if (!succeeded) { 2623 if (!succeeded) {
2569 // TODO(ngeoffray): Match the VM behavior and throw an 2624 // TODO(ngeoffray): Match the VM behavior and throw an
2570 // exception at runtime. 2625 // exception at runtime.
2571 compiler.cancel('Unimplemented non-matching static call', node); 2626 compiler.cancel('Unimplemented non-matching static call', node);
2572 } 2627 }
2573 push(new HInvokeSuper(inputs)); 2628 push(new HInvokeSuper(inputs));
2574 } else { 2629 } else {
2575 target = new HInvokeSuper(inputs); 2630 target = new HInvokeSuper(inputs);
2576 add(target); 2631 add(target);
2577 inputs = <HInstruction>[target]; 2632 inputs = <HInstruction>[target];
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 } 2720 }
2666 } 2721 }
2667 2722
2668 Element constructor = elements[node]; 2723 Element constructor = elements[node];
2669 Selector selector = elements.getSelector(node); 2724 Selector selector = elements.getSelector(node);
2670 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) { 2725 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) {
2671 compiler.internalError("Unresolved element: $constructor", node: node); 2726 compiler.internalError("Unresolved element: $constructor", node: node);
2672 } 2727 }
2673 FunctionElement functionElement = constructor; 2728 FunctionElement functionElement = constructor;
2674 constructor = functionElement.defaultImplementation; 2729 constructor = functionElement.defaultImplementation;
2675 HInstruction target = new HStatic(constructor); 2730 HInstruction target = new HStatic(constructor.declaration);
2676 add(target); 2731 add(target);
2677 var inputs = <HInstruction>[]; 2732 var inputs = <HInstruction>[];
2678 inputs.add(target); 2733 inputs.add(target);
2679 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2734 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2680 constructor, inputs); 2735 constructor.implementation,
2736 inputs);
2681 if (!succeeded) { 2737 if (!succeeded) {
2682 // TODO(ngeoffray): Match the VM behavior and throw an 2738 // TODO(ngeoffray): Match the VM behavior and throw an
2683 // exception at runtime. 2739 // exception at runtime.
2684 compiler.cancel('Unimplemented non-matching static call', node: node); 2740 compiler.cancel('Unimplemented non-matching static call', node: node);
2685 } 2741 }
2686 2742
2687 TypeAnnotation annotation = node.getTypeAnnotation(); 2743 TypeAnnotation annotation = node.getTypeAnnotation();
2688 if (annotation == null) { 2744 if (annotation == null) {
2689 compiler.internalError("malformed send in new expression"); 2745 compiler.internalError("malformed send in new expression");
2690 } 2746 }
(...skipping 21 matching lines...) Expand all
2712 if (element.isErroneous()) { 2768 if (element.isErroneous()) {
2713 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); 2769 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
2714 return; 2770 return;
2715 } 2771 }
2716 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2772 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2717 stack.add(graph.addConstantNull(constantSystem)); 2773 stack.add(graph.addConstantNull(constantSystem));
2718 return; 2774 return;
2719 } 2775 }
2720 compiler.ensure(!element.isGenerativeConstructor()); 2776 compiler.ensure(!element.isGenerativeConstructor());
2721 if (element.isFunction()) { 2777 if (element.isFunction()) {
2722 if (tryInlineMethod(element, selector, node.arguments)) return; 2778 if (tryInlineMethod(element.implementation, selector, node.arguments)) ret urn;
ngeoffray 2012/09/17 12:46:24 line too long
Johnni Winther 2012/09/20 08:12:23 Done.
2723 2779
2724 HInstruction target = new HStatic(element); 2780 HInstruction target = new HStatic(element);
2725 add(target); 2781 add(target);
2726 var inputs = <HInstruction>[target]; 2782 var inputs = <HInstruction>[target];
2727 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2783 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2728 element, inputs); 2784 element.implementation, inpu ts);
ngeoffray 2012/09/17 12:46:24 ditto
Johnni Winther 2012/09/20 08:12:23 Done.
2729 if (!succeeded) { 2785 if (!succeeded) {
2730 // TODO(ngeoffray): Match the VM behavior and throw an 2786 // TODO(ngeoffray): Match the VM behavior and throw an
2731 // exception at runtime. 2787 // exception at runtime.
2732 compiler.cancel('Unimplemented non-matching static call', node: node); 2788 compiler.cancel('Unimplemented non-matching static call', node: node);
2733 } 2789 }
2734 HInvokeStatic instruction = new HInvokeStatic(inputs); 2790 HInvokeStatic instruction = new HInvokeStatic(inputs);
2735 // TODO(ngeoffray): Only do this if knowing the return type is 2791 // TODO(ngeoffray): Only do this if knowing the return type is
2736 // useful. 2792 // useful.
2737 HType returnType = 2793 HType returnType =
2738 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( 2794 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 void visitTryStatement(Node node) { 3980 void visitTryStatement(Node node) {
3925 tooDifficult = true; 3981 tooDifficult = true;
3926 } 3982 }
3927 3983
3928 void visitThrow(Node node) { 3984 void visitThrow(Node node) {
3929 tooDifficult = true; 3985 tooDifficult = true;
3930 } 3986 }
3931 } 3987 }
3932 3988
3933 class InliningState { 3989 class InliningState {
3990 /// Invariant: [function] must be the implementation element.
3934 final PartialFunctionElement function; 3991 final PartialFunctionElement function;
3935 final Element oldReturnElement; 3992 final Element oldReturnElement;
3936 final TreeElements oldElements; 3993 final TreeElements oldElements;
3937 final List<HInstruction> oldStack; 3994 final List<HInstruction> oldStack;
3938 3995
3939 InliningState(this.function, 3996 InliningState(this.function,
3940 this.oldReturnElement, 3997 this.oldReturnElement,
3941 this.oldElements, 3998 this.oldElements,
3942 this.oldStack); 3999 this.oldStack) {
4000 assert(function.isImplementation);
4001 }
3943 } 4002 }
3944 4003
3945 class SsaBranch { 4004 class SsaBranch {
3946 final SsaBranchBuilder branchBuilder; 4005 final SsaBranchBuilder branchBuilder;
3947 final HBasicBlock block; 4006 final HBasicBlock block;
3948 LocalsHandler startLocals; 4007 LocalsHandler startLocals;
3949 LocalsHandler exitLocals; 4008 LocalsHandler exitLocals;
3950 SubGraph graph; 4009 SubGraph graph;
3951 4010
3952 SsaBranch(this.branchBuilder) : block = new HBasicBlock(); 4011 SsaBranch(this.branchBuilder) : block = new HBasicBlock();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4169 new HSubGraphBlockInformation(elseBranch.graph)); 4228 new HSubGraphBlockInformation(elseBranch.graph));
4170 4229
4171 HBasicBlock conditionStartBlock = conditionBranch.block; 4230 HBasicBlock conditionStartBlock = conditionBranch.block;
4172 conditionStartBlock.setBlockFlow(info, joinBlock); 4231 conditionStartBlock.setBlockFlow(info, joinBlock);
4173 SubGraph conditionGraph = conditionBranch.graph; 4232 SubGraph conditionGraph = conditionBranch.graph;
4174 HIf branch = conditionGraph.end.last; 4233 HIf branch = conditionGraph.end.last;
4175 assert(branch is HIf); 4234 assert(branch is HIf);
4176 branch.blockInformation = conditionStartBlock.blockFlow; 4235 branch.blockInformation = conditionStartBlock.blockFlow;
4177 } 4236 }
4178 } 4237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698