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

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: Updated cf. comments 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 SsaBuilderTask(JavaScriptBackend backend) 160 SsaBuilderTask(JavaScriptBackend backend)
161 : interceptors = new Interceptors(backend.compiler), 161 : interceptors = new Interceptors(backend.compiler),
162 emitter = backend.emitter, 162 emitter = backend.emitter,
163 functionsCalledInLoop = new Set<FunctionElement>(), 163 functionsCalledInLoop = new Set<FunctionElement>(),
164 selectorsCalledInLoop = new Map<SourceString, Selector>(), 164 selectorsCalledInLoop = new Map<SourceString, Selector>(),
165 backend = backend, 165 backend = backend,
166 super(backend.compiler); 166 super(backend.compiler);
167 167
168 HGraph build(WorkItem work) { 168 HGraph build(WorkItem work) {
169 return measure(() { 169 return measure(() {
170 Element element = work.element; 170 Element element = work.element.implementation;
ngeoffray 2012/09/20 11:38:37 I think in this method you could just use element
Johnni Winther 2012/09/21 09:18:25 But then we would have to change line 182, 184, an
171 HInstruction.idCounter = 0; 171 HInstruction.idCounter = 0;
172 ConstantSystem constantSystem = compiler.backend.constantSystem; 172 ConstantSystem constantSystem = compiler.backend.constantSystem;
173 SsaBuilder builder = new SsaBuilder(constantSystem, this, work); 173 SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
174 HGraph graph; 174 HGraph graph;
175 ElementKind kind = element.kind; 175 ElementKind kind = element.kind;
176 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) { 176 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
177 graph = compileConstructor(builder, work); 177 graph = compileConstructor(builder, work);
178 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 178 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
179 kind === ElementKind.FUNCTION || 179 kind === ElementKind.FUNCTION ||
180 kind === ElementKind.GETTER || 180 kind === ElementKind.GETTER ||
181 kind === ElementKind.SETTER) { 181 kind === ElementKind.SETTER) {
182 graph = builder.buildMethod(work.element); 182 graph = builder.buildMethod(element);
183 } else if (kind === ElementKind.FIELD) { 183 } else if (kind === ElementKind.FIELD) {
184 graph = builder.buildLazyInitializer(work.element); 184 graph = builder.buildLazyInitializer(element);
185 } 185 }
186 assert(graph.isValid()); 186 assert(graph.isValid());
187 if (kind !== ElementKind.FIELD) { 187 if (kind !== ElementKind.FIELD) {
188 bool inLoop = functionsCalledInLoop.contains(element); 188 bool inLoop = functionsCalledInLoop.contains(element.declaration);
189 if (!inLoop) { 189 if (!inLoop) {
190 Selector selector = selectorsCalledInLoop[element.name]; 190 Selector selector = selectorsCalledInLoop[element.name];
191 inLoop = selector !== null && selector.applies(element, compiler); 191 inLoop = selector !== null && selector.applies(element, compiler);
192 } 192 }
193 graph.calledInLoop = inLoop; 193 graph.calledInLoop = inLoop;
194 194
195 // If there is an estimate of the parameter types assume these types whe n 195 // If there is an estimate of the parameter types assume these types
196 // compiling. 196 // when compiling.
197 OptionalParameterTypes defaultValueTypes = null; 197 OptionalParameterTypes defaultValueTypes = null;
198 FunctionSignature signature = element.computeSignature(compiler); 198 FunctionSignature signature = element.computeSignature(compiler);
199 if (signature.optionalParameterCount > 0) { 199 if (signature.optionalParameterCount > 0) {
200 defaultValueTypes = 200 defaultValueTypes =
201 new OptionalParameterTypes(signature.optionalParameterCount); 201 new OptionalParameterTypes(signature.optionalParameterCount);
202 int index = 0; 202 int index = 0;
203 signature.forEachOptionalParameter((Element parameter) { 203 signature.forEachOptionalParameter((Element parameter) {
204 Constant defaultValue = compiler.compileVariable(parameter); 204 Constant defaultValue = compiler.compileVariable(parameter);
205 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); 205 HType type = HGraph.mapConstantTypeToSsaType(defaultValue);
206 defaultValueTypes.update(index, parameter.name, type); 206 defaultValueTypes.update(index, parameter.name, type);
207 index++; 207 index++;
208 }); 208 });
209 } 209 }
210 HTypeList parameterTypes = 210 HTypeList parameterTypes =
211 backend.optimisticParameterTypes(element, defaultValueTypes); 211 backend.optimisticParameterTypes(element.declaration,
212 defaultValueTypes);
212 if (!parameterTypes.allUnknown) { 213 if (!parameterTypes.allUnknown) {
213 int i = 0; 214 int i = 0;
214 signature.forEachParameter((Element param) { 215 signature.forEachParameter((Element param) {
215 builder.parameters[param].guaranteedType = parameterTypes[i++]; 216 builder.parameters[param].guaranteedType = parameterTypes[i++];
216 }); 217 });
217 } 218 }
218 backend.registerParameterTypesOptimization( 219 backend.registerParameterTypesOptimization(
219 element, parameterTypes, defaultValueTypes); 220 element, parameterTypes, defaultValueTypes);
220 } 221 }
221 222
(...skipping 12 matching lines...) Expand all
234 compiler.tracer.traceCompilation(name, work.compilationContext); 235 compiler.tracer.traceCompilation(name, work.compilationContext);
235 compiler.tracer.traceGraph('builder', graph); 236 compiler.tracer.traceGraph('builder', graph);
236 } 237 }
237 return graph; 238 return graph;
238 }); 239 });
239 } 240 }
240 241
241 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { 242 HGraph compileConstructor(SsaBuilder builder, WorkItem work) {
242 // The body of the constructor will be generated in a separate function. 243 // The body of the constructor will be generated in a separate function.
243 final ClassElement classElement = work.element.getEnclosingClass(); 244 final ClassElement classElement = work.element.getEnclosingClass();
244 return builder.buildFactory(classElement, work.element); 245 return builder.buildFactory(classElement, work.element.implementation);
245 } 246 }
246 } 247 }
247 248
248 /** 249 /**
249 * Keeps track of locals (including parameters and phis) when building. The 250 * Keeps track of locals (including parameters and phis) when building. The
250 * 'this' reference is treated as parameter and hence handled by this class, 251 * 'this' reference is treated as parameter and hence handled by this class,
251 * too. 252 * too.
252 */ 253 */
253 class LocalsHandler { 254 class LocalsHandler {
254 /** 255 /**
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 // [readLocal] uses the [boxElement] to find its box. By replacing it 346 // [readLocal] uses the [boxElement] to find its box. By replacing it
346 // behind its back we can still get to the old values. 347 // behind its back we can still get to the old values.
347 updateLocal(boxElement, oldBox); 348 updateLocal(boxElement, oldBox);
348 HInstruction oldValue = readLocal(boxedVariable); 349 HInstruction oldValue = readLocal(boxedVariable);
349 updateLocal(boxElement, newBox); 350 updateLocal(boxElement, newBox);
350 updateLocal(boxedVariable, oldValue); 351 updateLocal(boxedVariable, oldValue);
351 } 352 }
352 updateLocal(boxElement, newBox); 353 updateLocal(boxElement, newBox);
353 } 354 }
354 355
356 /**
357 * Documentation wanted -- johnniwinther
358 *
359 * Invariant: [function] must be an implementation element.
360 */
355 void startFunction(FunctionElement function, 361 void startFunction(FunctionElement function,
356 FunctionExpression node) { 362 FunctionExpression node) {
363 assert(invariant(function, function.isImplementation));
ahe 2012/09/20 11:12:07 First argument should be node.
Johnni Winther 2012/09/21 09:18:25 Done.
357 Compiler compiler = builder.compiler; 364 Compiler compiler = builder.compiler;
358 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( 365 closureData = compiler.closureToClassMapper.computeClosureToClassMapping(
359 node, builder.elements); 366 node, builder.elements);
360 FunctionSignature signature = function.computeSignature(compiler); 367 FunctionSignature signature = function.computeSignature(compiler);
361 signature.forEachParameter((Element element) { 368 signature.forEachParameter((Element element) {
362 HInstruction parameter = new HParameterValue(element); 369 HInstruction parameter = new HParameterValue(element);
363 builder.add(parameter); 370 builder.add(parameter);
364 builder.parameters[element] = parameter; 371 builder.parameters[element] = parameter;
365 directLocals[element] = parameter; 372 directLocals[element] = parameter;
366 parameter.guaranteedType = 373 parameter.guaranteedType =
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 void disableMethodInterception() { 897 void disableMethodInterception() {
891 assert(methodInterceptionEnabled); 898 assert(methodInterceptionEnabled);
892 methodInterceptionEnabled = false; 899 methodInterceptionEnabled = false;
893 } 900 }
894 901
895 void enableMethodInterception() { 902 void enableMethodInterception() {
896 assert(!methodInterceptionEnabled); 903 assert(!methodInterceptionEnabled);
897 methodInterceptionEnabled = true; 904 methodInterceptionEnabled = true;
898 } 905 }
899 906
907 /**
908 * Documentation wanted -- johnniwinther
909 *
910 * Invariant: [functionElement] must be an implementation element.
911 */
900 HGraph buildMethod(FunctionElement functionElement) { 912 HGraph buildMethod(FunctionElement functionElement) {
913 assert(invariant(functionElement, functionElement.isImplementation));
901 FunctionExpression function = functionElement.parseNode(compiler); 914 FunctionExpression function = functionElement.parseNode(compiler);
915 assert(function !== null);
916 assert(function.modifiers === null || !function.modifiers.isExternal());
917 assert(elements[function] !== null);
902 openFunction(functionElement, function); 918 openFunction(functionElement, function);
903 function.body.accept(this); 919 function.body.accept(this);
904 return closeFunction(); 920 return closeFunction();
905 } 921 }
906 922
907 HGraph buildLazyInitializer(VariableElement variable) { 923 HGraph buildLazyInitializer(VariableElement variable) {
908 HBasicBlock block = graph.addNewBlock(); 924 HBasicBlock block = graph.addNewBlock();
909 open(graph.entry); 925 open(graph.entry);
910 close(new HGoto()).addSuccessor(block); 926 close(new HGoto()).addSuccessor(block);
911 open(block); 927 open(block);
912 SendSet node = variable.parseNode(compiler); 928 SendSet node = variable.parseNode(compiler);
913 Link<Node> link = node.arguments; 929 Link<Node> link = node.arguments;
914 assert(!link.isEmpty() && link.tail.isEmpty()); 930 assert(!link.isEmpty() && link.tail.isEmpty());
915 visit(link.head); 931 visit(link.head);
916 HInstruction value = pop(); 932 HInstruction value = pop();
917 value = potentiallyCheckType(value, variable); 933 value = potentiallyCheckType(value, variable);
918 close(new HReturn(value)).addSuccessor(graph.exit); 934 close(new HReturn(value)).addSuccessor(graph.exit);
919 graph.finalize(); 935 graph.finalize();
920 return graph; 936 return graph;
921 } 937 }
922 938
923 /** 939 /**
924 * Returns the constructor body associated with the given constructor or 940 * Returns the constructor body associated with the given constructor or
925 * creates a new constructor body, if none can be found. 941 * creates a new constructor body, if none can be found.
926 * 942 *
927 * Returns [:null:] if the constructor does not have a body. 943 * Returns [:null:] if the constructor does not have a body.
928 */ 944 */
929 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 945 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
930 assert(constructor.isGenerativeConstructor()); 946 assert(constructor.isGenerativeConstructor());
947 assert(invariant(constructor, constructor.isImplementation));
931 if (constructor is SynthesizedConstructorElement) return null; 948 if (constructor is SynthesizedConstructorElement) return null;
932 FunctionExpression node = constructor.parseNode(compiler); 949 FunctionExpression node = constructor.parseNode(compiler);
933 // If we know the body doesn't have any code, we don't generate 950 // If we know the body doesn't have any code, we don't generate it.
934 // it.
935 if (node.body.asBlock() !== null) { 951 if (node.body.asBlock() !== null) {
936 NodeList statements = node.body.asBlock().statements; 952 NodeList statements = node.body.asBlock().statements;
937 if (statements.isEmpty()) return null; 953 if (statements.isEmpty()) return null;
938 } 954 }
939 ClassElement classElement = constructor.getEnclosingClass(); 955 ClassElement classElement = constructor.getEnclosingClass();
940 ConstructorBodyElement bodyElement; 956 ConstructorBodyElement bodyElement;
941 for (Link<Element> backendMembers = classElement.backendMembers; 957 for (Link<Element> backendMembers = classElement.backendMembers;
942 !backendMembers.isEmpty(); 958 !backendMembers.isEmpty();
943 backendMembers = backendMembers.tail) { 959 backendMembers = backendMembers.tail) {
944 Element backendMember = backendMembers.head; 960 Element backendMember = backendMembers.head;
945 if (backendMember.isGenerativeConstructorBody()) { 961 if (backendMember.isGenerativeConstructorBody()) {
946 ConstructorBodyElement body = backendMember; 962 ConstructorBodyElement body = backendMember;
947 if (body.constructor == constructor) { 963 if (body.constructor == constructor) {
948 bodyElement = backendMember; 964 bodyElement = backendMember;
949 break; 965 break;
950 } 966 }
951 } 967 }
952 } 968 }
953 if (bodyElement === null) { 969 if (bodyElement === null) {
954 bodyElement = new ConstructorBodyElement(constructor); 970 bodyElement = new ConstructorBodyElement(constructor);
955 TreeElements treeElements = 971 TreeElements treeElements =
ngeoffray 2012/09/20 11:38:37 Please add a comment here on why you need to use d
Johnni Winther 2012/09/21 09:18:25 Done.
956 compiler.resolver.resolveMethodElement(constructor); 972 compiler.resolver.resolveMethodElement(constructor.declaration);
957 compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements);
958 classElement.backendMembers = 973 classElement.backendMembers =
959 classElement.backendMembers.prepend(bodyElement); 974 classElement.backendMembers.prepend(bodyElement);
975 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration,
ngeoffray 2012/09/20 11:38:37 We just constructed bodyElement. Could we avoid ha
Johnni Winther 2012/09/21 09:18:25 If [constructor] is a patch we will need both. Thi
976 treeElements);
960 } 977 }
961 assert(bodyElement.isGenerativeConstructorBody()); 978 assert(bodyElement.isGenerativeConstructorBody());
962 return bodyElement; 979 return bodyElement;
963 } 980 }
964 981
982 /**
983 * Documentation wanted -- johnniwinther
984 *
985 * Invariant: [function] must be an implementation element.
986 */
965 InliningState enterInlinedMethod(PartialFunctionElement function, 987 InliningState enterInlinedMethod(PartialFunctionElement function,
966 Selector selector, 988 Selector selector,
967 Link<Node> arguments) { 989 Link<Node> arguments) {
990 assert(invariant(function, function.isImplementation));
991
968 // Once we start to compile the arguments we must be sure that we don't 992 // Once we start to compile the arguments we must be sure that we don't
969 // abort. 993 // abort.
970 List<HInstruction> compiledArguments = new List<HInstruction>(); 994 List<HInstruction> compiledArguments = new List<HInstruction>();
971 bool succeeded = addStaticSendArgumentsToList(selector, 995 bool succeeded = addStaticSendArgumentsToList(selector,
972 arguments, 996 arguments,
973 function, 997 function,
974 compiledArguments); 998 compiledArguments);
975 assert(succeeded); 999 assert(succeeded);
976 1000
977 InliningState state = 1001 InliningState state =
978 new InliningState(function, returnElement, elements, stack); 1002 new InliningState(function, returnElement, elements, stack);
979 inliningStack.add(state); 1003 inliningStack.add(state);
980 sourceElementStack.add(function); 1004 sourceElementStack.add(function);
981 stack = <HInstruction>[]; 1005 stack = <HInstruction>[];
982 returnElement = new Element(const SourceString("result"), 1006 returnElement = new Element(const SourceString("result"),
983 ElementKind.VARIABLE, 1007 ElementKind.VARIABLE,
984 function); 1008 function);
985 localsHandler.updateLocal(returnElement, 1009 localsHandler.updateLocal(returnElement,
986 graph.addConstantNull(constantSystem)); 1010 graph.addConstantNull(constantSystem));
987 elements = compiler.enqueuer.resolution.getCachedElements(function); 1011 elements = compiler.enqueuer.resolution.getCachedElements(function);
1012 assert(elements !== null);
988 FunctionSignature signature = function.computeSignature(compiler); 1013 FunctionSignature signature = function.computeSignature(compiler);
989 int index = 0; 1014 int index = 0;
990 signature.forEachParameter((Element parameter) { 1015 signature.forEachParameter((Element parameter) {
991 HInstruction argument = compiledArguments[index++]; 1016 HInstruction argument = compiledArguments[index++];
992 localsHandler.updateLocal(parameter, argument); 1017 localsHandler.updateLocal(parameter, argument);
993 potentiallyCheckType(argument, parameter); 1018 potentiallyCheckType(argument, parameter);
994 }); 1019 });
995 return state; 1020 return state;
996 } 1021 }
997 1022
998 void leaveInlinedMethod(InliningState state) { 1023 void leaveInlinedMethod(InliningState state) {
999 InliningState poppedState = inliningStack.removeLast(); 1024 InliningState poppedState = inliningStack.removeLast();
1000 assert(state == poppedState); 1025 assert(state == poppedState);
1001 FunctionElement poppedElement = sourceElementStack.removeLast(); 1026 FunctionElement poppedElement = sourceElementStack.removeLast();
1002 assert(poppedElement == poppedState.function); 1027 assert(poppedElement == poppedState.function);
1003 elements = state.oldElements; 1028 elements = state.oldElements;
1004 stack.add(localsHandler.readLocal(returnElement)); 1029 stack.add(localsHandler.readLocal(returnElement));
1005 returnElement = state.oldReturnElement; 1030 returnElement = state.oldReturnElement;
1006 assert(stack.length == 1); 1031 assert(stack.length == 1);
1007 state.oldStack.add(stack[0]); 1032 state.oldStack.add(stack[0]);
1008 stack = state.oldStack; 1033 stack = state.oldStack;
1009 } 1034 }
1010 1035
1036 /**
1037 * Documentation wanted -- johnniwinther
1038 *
1039 * Invariant: [element] must be an implementation element.
1040 */
1011 bool tryInlineMethod(Element element, 1041 bool tryInlineMethod(Element element,
1012 Selector selector, 1042 Selector selector,
1013 Link<Node> arguments) { 1043 Link<Node> arguments) {
1044 assert(invariant(element, element.isImplementation));
1014 // TODO(floitsch): we should be able to inline inside lazy initializers. 1045 // TODO(floitsch): we should be able to inline inside lazy initializers.
1015 if (!currentElement.isFunction()) return false; 1046 if (!currentElement.isFunction()) return false;
1016 // TODO(floitsch): we should be able to inline getters, setters and 1047 // TODO(floitsch): we should be able to inline getters, setters and
1017 // constructor bodies. 1048 // constructor bodies.
1018 if (!element.isFunction()) return false; 1049 if (!element.isFunction()) return false;
1019 // TODO(floitsch): find a cleaner way to know if the element is a function 1050 // TODO(floitsch): find a cleaner way to know if the element is a function
1020 // containing nodes. 1051 // containing nodes.
1021 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. 1052 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
1022 if (element is !PartialFunctionElement) return false; 1053 if (element is !PartialFunctionElement) return false;
1023 if (inliningStack.length > MAX_INLINING_DEPTH) return false; 1054 if (inliningStack.length > MAX_INLINING_DEPTH) return false;
(...skipping 20 matching lines...) Expand all
1044 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) { 1075 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) {
1045 return false; 1076 return false;
1046 } 1077 }
1047 1078
1048 InliningState state = enterInlinedMethod(function, selector, arguments); 1079 InliningState state = enterInlinedMethod(function, selector, arguments);
1049 functionExpression.body.accept(this); 1080 functionExpression.body.accept(this);
1050 leaveInlinedMethod(state); 1081 leaveInlinedMethod(state);
1051 return true; 1082 return true;
1052 } 1083 }
1053 1084
1085 /**
1086 * Documentation wanted -- johnniwinther
1087 *
1088 * Invariant: [constructor] and [constructors] must all be implementation
1089 * elements.
1090 */
1054 void inlineSuperOrRedirect(FunctionElement constructor, 1091 void inlineSuperOrRedirect(FunctionElement constructor,
1055 Selector selector, 1092 Selector selector,
1056 Link<Node> arguments, 1093 Link<Node> arguments,
1057 List<FunctionElement> constructors, 1094 List<FunctionElement> constructors,
1058 Map<Element, HInstruction> fieldValues) { 1095 Map<Element, HInstruction> fieldValues) {
1096 assert(invariant(constructor, constructor.isImplementation));
1059 constructors.addLast(constructor); 1097 constructors.addLast(constructor);
1060 1098
1061 List<HInstruction> compiledArguments = new List<HInstruction>(); 1099 List<HInstruction> compiledArguments = new List<HInstruction>();
1062 bool succeeded = addStaticSendArgumentsToList(selector, 1100 bool succeeded = addStaticSendArgumentsToList(selector,
1063 arguments, 1101 arguments,
1064 constructor, 1102 constructor,
1065 compiledArguments); 1103 compiledArguments);
1066 if (!succeeded) { 1104 if (!succeeded) {
1067 // Non-matching super and redirects are compile-time errors and thus 1105 // Non-matching super and redirects are compile-time errors and thus
1068 // checked by the resolver. 1106 // checked by the resolver.
(...skipping 23 matching lines...) Expand all
1092 buildInitializers(constructor, constructors, fieldValues); 1130 buildInitializers(constructor, constructors, fieldValues);
1093 elements = oldElements; 1131 elements = oldElements;
1094 } 1132 }
1095 1133
1096 /** 1134 /**
1097 * Run through the initializers and inline all field initializers. Recursively 1135 * Run through the initializers and inline all field initializers. Recursively
1098 * inlines super initializers. 1136 * inlines super initializers.
1099 * 1137 *
1100 * The constructors of the inlined initializers is added to [constructors] 1138 * The constructors of the inlined initializers is added to [constructors]
1101 * with sub constructors having a lower index than super constructors. 1139 * with sub constructors having a lower index than super constructors.
1140 *
1141 * Invariant: The [constructor] and elements in [constructors] must all be
1142 * implementation elements.
1102 */ 1143 */
1103 void buildInitializers(FunctionElement constructor, 1144 void buildInitializers(FunctionElement constructor,
1104 List<FunctionElement> constructors, 1145 List<FunctionElement> constructors,
1105 Map<Element, HInstruction> fieldValues) { 1146 Map<Element, HInstruction> fieldValues) {
1147 assert(invariant(constructor, constructor.isImplementation));
1106 FunctionExpression functionNode = constructor.parseNode(compiler); 1148 FunctionExpression functionNode = constructor.parseNode(compiler);
1107 1149
1108 bool foundSuperOrRedirect = false; 1150 bool foundSuperOrRedirect = false;
1109 1151
1110 if (functionNode.initializers !== null) { 1152 if (functionNode.initializers !== null) {
1111 Link<Node> initializers = functionNode.initializers.nodes; 1153 Link<Node> initializers = functionNode.initializers.nodes;
1112 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 1154 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
1113 assert(link.head is Send); 1155 assert(link.head is Send);
1114 if (link.head is !SendSet) { 1156 if (link.head is !SendSet) {
1115 // A super initializer or constructor redirection. 1157 // A super initializer or constructor redirection.
(...skipping 17 matching lines...) Expand all
1133 fieldValues[elements[init]] = pop(); 1175 fieldValues[elements[init]] = pop();
1134 } 1176 }
1135 } 1177 }
1136 } 1178 }
1137 1179
1138 if (!foundSuperOrRedirect) { 1180 if (!foundSuperOrRedirect) {
1139 // No super initializer found. Try to find the default constructor if 1181 // No super initializer found. Try to find the default constructor if
1140 // the class is not Object. 1182 // the class is not Object.
1141 ClassElement enclosingClass = constructor.getEnclosingClass(); 1183 ClassElement enclosingClass = constructor.getEnclosingClass();
1142 ClassElement superClass = enclosingClass.superclass; 1184 ClassElement superClass = enclosingClass.superclass;
1143 if (enclosingClass != compiler.objectClass) { 1185 if (!enclosingClass.isObject(compiler)) {
1144 assert(superClass !== null); 1186 assert(superClass !== null);
1145 assert(superClass.resolutionState == STATE_DONE); 1187 assert(superClass.resolutionState == STATE_DONE);
1146 Selector selector = 1188 Selector selector =
1147 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); 1189 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0);
1148 FunctionElement target = superClass.lookupConstructor(superClass.name); 1190 FunctionElement target = superClass.lookupConstructor(superClass.name);
1149 if (target === null) { 1191 if (target === null) {
1150 compiler.internalError("no default constructor available"); 1192 compiler.internalError("no default constructor available");
1151 } 1193 }
1152 inlineSuperOrRedirect(target, 1194 inlineSuperOrRedirect(target.implementation,
1153 selector, 1195 selector,
1154 const EmptyLink<Node>(), 1196 const EmptyLink<Node>(),
1155 constructors, 1197 constructors,
1156 fieldValues); 1198 fieldValues);
1157 } 1199 }
1158 } 1200 }
1159 } 1201 }
1160 1202
1161 /** 1203 /**
1162 * Run through the fields of [cls] and add their potential 1204 * Run through the fields of [cls] and add their potential
1163 * initializers. 1205 * initializers.
1206 *
1207 * Invariant: [classElement] must be a declaration element.
1164 */ 1208 */
1165 void buildFieldInitializers(ClassElement classElement, 1209 void buildFieldInitializers(ClassElement classElement,
1166 Map<Element, HInstruction> fieldValues) { 1210 Map<Element, HInstruction> fieldValues) {
1211 assert(invariant(classElement, classElement.isDeclaration));
1167 classElement.forEachInstanceField( 1212 classElement.forEachInstanceField(
1168 includeBackendMembers: true, 1213 includeBackendMembers: true,
1169 includeSuperMembers: false, 1214 includeSuperMembers: false,
1170 f: (ClassElement enclosingClass, Element member) { 1215 f: (ClassElement enclosingClass, Element member) {
1171 TreeElements definitions = compiler.analyzeElement(member); 1216 TreeElements definitions = compiler.analyzeElement(member);
1172 Node node = member.parseNode(compiler); 1217 Node node = member.parseNode(compiler);
1173 SendSet assignment = node.asSendSet(); 1218 SendSet assignment = node.asSendSet();
1174 HInstruction value; 1219 HInstruction value;
1175 if (assignment === null) { 1220 if (assignment === null) {
1176 value = graph.addConstantNull(constantSystem); 1221 value = graph.addConstantNull(constantSystem);
(...skipping 11 matching lines...) Expand all
1188 1233
1189 1234
1190 /** 1235 /**
1191 * Build the factory function corresponding to the constructor 1236 * Build the factory function corresponding to the constructor
1192 * [functionElement]: 1237 * [functionElement]:
1193 * - Initialize fields with the values of the field initializers of the 1238 * - Initialize fields with the values of the field initializers of the
1194 * current constructor and super constructors or constructors redirected 1239 * current constructor and super constructors or constructors redirected
1195 * to, starting from the current constructor. 1240 * to, starting from the current constructor.
1196 * - Call the the constructor bodies, starting from the constructor(s) in the 1241 * - Call the the constructor bodies, starting from the constructor(s) in the
1197 * super class(es). 1242 * super class(es).
1243 *
1244 * Invariants: [classElement] must be a declaration element, and
1245 * [functionElement] must be an implementation element.
1198 */ 1246 */
1199 HGraph buildFactory(ClassElement classElement, 1247 HGraph buildFactory(ClassElement classElement,
1200 FunctionElement functionElement) { 1248 FunctionElement functionElement) {
1249 assert(invariant(classElement, classElement.isDeclaration));
1250 assert(invariant(functionElement, functionElement.isImplementation));
1201 FunctionExpression function = functionElement.parseNode(compiler); 1251 FunctionExpression function = functionElement.parseNode(compiler);
1202 // Note that constructors (like any other static function) do not need 1252 // Note that constructors (like any other static function) do not need
1203 // to deal with optional arguments. It is the callers job to provide all 1253 // to deal with optional arguments. It is the callers job to provide all
1204 // arguments as if they were positional. 1254 // arguments as if they were positional.
1205 1255
1206 // The initializer list could contain closures. 1256 // The initializer list could contain closures.
1207 openFunction(functionElement, function); 1257 openFunction(functionElement, function);
1208 1258
1209 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); 1259 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
1210 1260
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 if (compiler.world.needsRti(classElement)) { 1298 if (compiler.world.needsRti(classElement)) {
1249 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1299 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1250 inputs.add(localsHandler.directLocals[typeVariable.element]); 1300 inputs.add(localsHandler.directLocals[typeVariable.element]);
1251 }); 1301 });
1252 callSetRuntimeTypeInfo(classElement, inputs, newObject); 1302 callSetRuntimeTypeInfo(classElement, inputs, newObject);
1253 } 1303 }
1254 1304
1255 // Generate calls to the constructor bodies. 1305 // Generate calls to the constructor bodies.
1256 for (int index = constructors.length - 1; index >= 0; index--) { 1306 for (int index = constructors.length - 1; index >= 0; index--) {
1257 FunctionElement constructor = constructors[index]; 1307 FunctionElement constructor = constructors[index];
1308 assert(invariant(functionElement, constructor.isImplementation));
1258 ConstructorBodyElement body = getConstructorBody(constructor); 1309 ConstructorBodyElement body = getConstructorBody(constructor);
1259 if (body === null) continue; 1310 if (body === null) continue;
1260 List bodyCallInputs = <HInstruction>[]; 1311 List bodyCallInputs = <HInstruction>[];
1261 bodyCallInputs.add(newObject); 1312 bodyCallInputs.add(newObject);
1262 int arity = body.functionSignature.parameterCount; 1313 FunctionSignature functionSignature = body.computeSignature(compiler);
1263 body.functionSignature.forEachParameter((parameter) { 1314 int arity = functionSignature.parameterCount;
1315 functionSignature.forEachParameter((parameter) {
1264 bodyCallInputs.add(localsHandler.readLocal(parameter)); 1316 bodyCallInputs.add(localsHandler.readLocal(parameter));
1265 }); 1317 });
1266 // TODO(ahe): The constructor name is statically resolved. See 1318 // TODO(ahe): The constructor name is statically resolved. See
1267 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner 1319 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
1268 // way to do this? 1320 // way to do this?
1269 SourceString name = new SourceString(backend.namer.getName(body)); 1321 SourceString name =
1322 new SourceString(backend.namer.getName(body.declaration));
1270 // TODO(kasperl): This seems fishy. We shouldn't be inventing all 1323 // TODO(kasperl): This seems fishy. We shouldn't be inventing all
1271 // these selectors. Maybe the resolver can do more of the work 1324 // these selectors. Maybe the resolver can do more of the work
1272 // for us here? 1325 // for us here?
1273 LibraryElement library = body.getLibrary(); 1326 LibraryElement library = body.getLibrary();
1274 Selector selector = new Selector.call(name, library, arity); 1327 Selector selector = new Selector.call(name, library, arity);
1275 add(new HInvokeDynamicMethod(selector, bodyCallInputs)); 1328 add(new HInvokeDynamicMethod(selector, bodyCallInputs));
1276 } 1329 }
1277 close(new HReturn(newObject)).addSuccessor(graph.exit); 1330 close(new HReturn(newObject)).addSuccessor(graph.exit);
1278 return closeFunction(); 1331 return closeFunction();
1279 } 1332 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 1370
1318 // Create the instruction that parameter checks will use. 1371 // Create the instruction that parameter checks will use.
1319 check = new HNot(check); 1372 check = new HNot(check);
1320 add(check); 1373 add(check);
1321 1374
1322 ClosureClassMap closureData = localsHandler.closureData; 1375 ClosureClassMap closureData = localsHandler.closureData;
1323 Element checkResultElement = closureData.parametersWithSentinel[element]; 1376 Element checkResultElement = closureData.parametersWithSentinel[element];
1324 localsHandler.updateLocal(checkResultElement, check); 1377 localsHandler.updateLocal(checkResultElement, check);
1325 } 1378 }
1326 1379
1380 /**
1381 * Documentation wanted -- johnniwinther
1382 *
1383 * Invariant: [functionElement] must be the implementation element.
1384 */
1327 void openFunction(FunctionElement functionElement, 1385 void openFunction(FunctionElement functionElement,
1328 FunctionExpression node) { 1386 FunctionExpression node) {
1387 assert(invariant(functionElement, functionElement.isImplementation));
1329 HBasicBlock block = graph.addNewBlock(); 1388 HBasicBlock block = graph.addNewBlock();
1330 open(graph.entry); 1389 open(graph.entry);
1331 1390
1332 localsHandler.startFunction(functionElement, node); 1391 localsHandler.startFunction(functionElement, node);
1333 close(new HGoto()).addSuccessor(block); 1392 close(new HGoto()).addSuccessor(block);
1334 1393
1335 open(block); 1394 open(block);
1336 1395
1337 FunctionSignature params = functionElement.computeSignature(compiler); 1396 FunctionSignature params = functionElement.computeSignature(compiler);
1338 params.forEachParameter((Element element) { 1397 params.forEachParameter((Element element) {
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 if (element.isField() && !element.isAssignable()) { 2112 if (element.isField() && !element.isAssignable()) {
2054 // A static final or const. Get its constant value and inline it if 2113 // A static final or const. Get its constant value and inline it if
2055 // the value can be compiled eagerly. 2114 // the value can be compiled eagerly.
2056 value = compiler.compileVariable(element); 2115 value = compiler.compileVariable(element);
2057 } 2116 }
2058 if (value != null) { 2117 if (value != null) {
2059 stack.add(graph.addConstant(value)); 2118 stack.add(graph.addConstant(value));
2060 } else if (element.isField() && compiler.isLazilyInitialized(element)) { 2119 } else if (element.isField() && compiler.isLazilyInitialized(element)) {
2061 push(new HLazyStatic(element)); 2120 push(new HLazyStatic(element));
2062 } else { 2121 } else {
2063 push(new HStatic(element)); 2122 push(new HStatic(element.declaration));
ngeoffray 2012/09/20 11:38:37 Please add TODO to try to get rid of this. Maybe a
Johnni Winther 2012/09/21 09:18:25 Done.
2064 if (element.isGetter()) { 2123 if (element.isGetter()) {
2065 push(new HInvokeStatic(<HInstruction>[pop()])); 2124 push(new HInvokeStatic(<HInstruction>[pop()]));
2066 } 2125 }
2067 } 2126 }
2068 } else if (Elements.isInstanceSend(send, elements)) { 2127 } else if (Elements.isInstanceSend(send, elements)) {
2069 HInstruction receiver = generateInstanceSendReceiver(send); 2128 HInstruction receiver = generateInstanceSendReceiver(send);
2070 generateInstanceGetterWithCompiledReceiver(send, receiver); 2129 generateInstanceGetterWithCompiledReceiver(send, receiver);
2071 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2130 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2072 push(new HStatic(element)); 2131 push(new HStatic(element.declaration));
ngeoffray 2012/09/20 11:38:37 Ditto.
Johnni Winther 2012/09/21 09:18:25 Done.
2073 // TODO(ahe): This should be registered in codegen. 2132 // TODO(ahe): This should be registered in codegen.
2074 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2133 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2075 } else if (Elements.isErroneousElement(element)) { 2134 } else if (Elements.isErroneousElement(element)) {
2076 // An erroneous element indicates an unresolved static getter. 2135 // An erroneous element indicates an unresolved static getter.
2077 generateThrowNoSuchMethod(send, 2136 generateThrowNoSuchMethod(send,
2078 getTargetName(element, 'get'), 2137 getTargetName(element, 'get'),
2079 const EmptyLink<Node>()); 2138 const EmptyLink<Node>());
2080 } else { 2139 } else {
2081 stack.add(localsHandler.readLocal(element)); 2140 stack.add(localsHandler.readLocal(element));
2082 } 2141 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2282 // selectors with the same named arguments. 2341 // selectors with the same named arguments.
2283 List<SourceString> orderedNames = selector.getOrderedNamedArguments(); 2342 List<SourceString> orderedNames = selector.getOrderedNamedArguments();
2284 for (SourceString name in orderedNames) { 2343 for (SourceString name in orderedNames) {
2285 list.add(instructions[name]); 2344 list.add(instructions[name]);
2286 } 2345 }
2287 } 2346 }
2288 } 2347 }
2289 2348
2290 /** 2349 /**
2291 * Returns true if the arguments were compatible with the function signature. 2350 * Returns true if the arguments were compatible with the function signature.
2351 *
2352 * Invariant: [element] must be an implementation element.
2292 */ 2353 */
2293 bool addStaticSendArgumentsToList(Selector selector, 2354 bool addStaticSendArgumentsToList(Selector selector,
2294 Link<Node> arguments, 2355 Link<Node> arguments,
2295 FunctionElement element, 2356 FunctionElement element,
2296 List<HInstruction> list) { 2357 List<HInstruction> list) {
2358 assert(invariant(element, element.isImplementation));
2359
2297 HInstruction compileArgument(Node argument) { 2360 HInstruction compileArgument(Node argument) {
2298 visit(argument); 2361 visit(argument);
2299 return pop(); 2362 return pop();
2300 } 2363 }
2301 2364
2302 HInstruction compileConstant(Element parameter) { 2365 HInstruction compileConstant(Element parameter) {
2303 Constant constant; 2366 Constant constant;
2304 TreeElements calleeElements = 2367 TreeElements calleeElements =
2305 compiler.enqueuer.resolution.getCachedElements(element); 2368 compiler.enqueuer.resolution.getCachedElements(element);
2306 if (calleeElements.isParameterChecked(parameter)) { 2369 if (calleeElements.isParameterChecked(parameter)) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2513 node: node.argumentsNode); 2576 node: node.argumentsNode);
2514 } 2577 }
2515 Node closure = node.arguments.head; 2578 Node closure = node.arguments.head;
2516 Element element = elements[closure]; 2579 Element element = elements[closure];
2517 if (!Elements.isStaticOrTopLevelFunction(element)) { 2580 if (!Elements.isStaticOrTopLevelFunction(element)) {
2518 compiler.cancel( 2581 compiler.cancel(
2519 'JS_TO_CLOSURE requires a static or top-level method', 2582 'JS_TO_CLOSURE requires a static or top-level method',
2520 node: closure); 2583 node: closure);
2521 } 2584 }
2522 FunctionElement function = element; 2585 FunctionElement function = element;
2523 FunctionSignature params = function.computeSignature(compiler); 2586 FunctionSignature params
2587 = function.implementation.computeSignature(compiler);
ngeoffray 2012/09/20 11:38:37 How can a declaration and an implementation have a
Johnni Winther 2012/09/21 09:18:25 The signatures have different elements for the par
2524 if (params.optionalParameterCount !== 0) { 2588 if (params.optionalParameterCount !== 0) {
2525 compiler.cancel( 2589 compiler.cancel(
2526 'JS_TO_CLOSURE does not handle closure with optional parameters', 2590 'JS_TO_CLOSURE does not handle closure with optional parameters',
2527 node: closure); 2591 node: closure);
2528 } 2592 }
2529 visit(closure); 2593 visit(closure);
2530 List<HInstruction> inputs = <HInstruction>[pop()]; 2594 List<HInstruction> inputs = <HInstruction>[pop()];
2531 String invocationName = backend.namer.closureInvocationName( 2595 String invocationName = backend.namer.closureInvocationName(
2532 new Selector.callClosure(params.requiredParameterCount)); 2596 new Selector.callClosure(params.requiredParameterCount));
2533 push(new HForeign(new DartString.literal('#.$invocationName'), 2597 push(new HForeign(new DartString.literal('#.$invocationName'),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2580 if (element !== null && element === work.element) { 2644 if (element !== null && element === work.element) {
2581 graph.isRecursiveMethod = true; 2645 graph.isRecursiveMethod = true;
2582 } 2646 }
2583 super.visitSend(node); 2647 super.visitSend(node);
2584 } 2648 }
2585 2649
2586 visitSuperSend(Send node) { 2650 visitSuperSend(Send node) {
2587 Selector selector = elements.getSelector(node); 2651 Selector selector = elements.getSelector(node);
2588 Element element = elements[node]; 2652 Element element = elements[node];
2589 if (element === null) return generateSuperNoSuchMethodSend(node); 2653 if (element === null) return generateSuperNoSuchMethodSend(node);
2590 HInstruction target = new HStatic(element); 2654 HInstruction target = new HStatic(element.declaration);
ngeoffray 2012/09/20 11:38:37 Add TODO
Johnni Winther 2012/09/21 09:18:25 Done.
2591 HInstruction context = localsHandler.readThis(); 2655 HInstruction context = localsHandler.readThis();
2592 add(target); 2656 add(target);
2593 var inputs = <HInstruction>[target, context]; 2657 var inputs = <HInstruction>[target, context];
2594 if (node.isPropertyAccess) { 2658 if (node.isPropertyAccess) {
2595 push(new HInvokeSuper(inputs)); 2659 push(new HInvokeSuper(inputs));
2596 } else if (element.isFunction() || element.isGenerativeConstructor()) { 2660 } else if (element.isFunction() || element.isGenerativeConstructor()) {
2597 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2661 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2598 element, inputs); 2662 element.implementation,
ngeoffray 2012/09/20 11:38:37 ditto.
Johnni Winther 2012/09/21 09:18:25 Done.
2663 inputs);
2599 if (!succeeded) { 2664 if (!succeeded) {
2600 // TODO(ngeoffray): Match the VM behavior and throw an 2665 // TODO(ngeoffray): Match the VM behavior and throw an
2601 // exception at runtime. 2666 // exception at runtime.
2602 compiler.cancel('Unimplemented non-matching static call', node); 2667 compiler.cancel('Unimplemented non-matching static call', node);
2603 } 2668 }
2604 push(new HInvokeSuper(inputs)); 2669 push(new HInvokeSuper(inputs));
2605 } else { 2670 } else {
2606 target = new HInvokeSuper(inputs); 2671 target = new HInvokeSuper(inputs);
2607 add(target); 2672 add(target);
2608 inputs = <HInstruction>[target]; 2673 inputs = <HInstruction>[target];
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 } 2791 }
2727 } 2792 }
2728 2793
2729 Element constructor = elements[node]; 2794 Element constructor = elements[node];
2730 Selector selector = elements.getSelector(node); 2795 Selector selector = elements.getSelector(node);
2731 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) { 2796 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) {
2732 compiler.internalError("Unresolved element: $constructor", node: node); 2797 compiler.internalError("Unresolved element: $constructor", node: node);
2733 } 2798 }
2734 FunctionElement functionElement = constructor; 2799 FunctionElement functionElement = constructor;
2735 constructor = functionElement.defaultImplementation; 2800 constructor = functionElement.defaultImplementation;
2736 HInstruction target = new HStatic(constructor); 2801 HInstruction target = new HStatic(constructor.declaration);
ngeoffray 2012/09/20 11:38:37 ditto
Johnni Winther 2012/09/21 09:18:25 Done.
2737 add(target); 2802 add(target);
2738 var inputs = <HInstruction>[]; 2803 var inputs = <HInstruction>[];
2739 inputs.add(target); 2804 inputs.add(target);
2740 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2805 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2741 constructor, inputs); 2806 constructor.implementation,
ngeoffray 2012/09/20 11:38:37 ditto
Johnni Winther 2012/09/21 09:18:25 Done.
2807 inputs);
2742 if (!succeeded) { 2808 if (!succeeded) {
2743 // TODO(ngeoffray): Match the VM behavior and throw an 2809 // TODO(ngeoffray): Match the VM behavior and throw an
2744 // exception at runtime. 2810 // exception at runtime.
2745 compiler.cancel('Unimplemented non-matching static call', node: node); 2811 compiler.cancel('Unimplemented non-matching static call', node: node);
2746 } 2812 }
2747 2813
2748 TypeAnnotation annotation = node.getTypeAnnotation(); 2814 TypeAnnotation annotation = node.getTypeAnnotation();
2749 if (annotation == null) { 2815 if (annotation == null) {
2750 compiler.internalError("malformed send in new expression"); 2816 compiler.internalError("malformed send in new expression");
2751 } 2817 }
(...skipping 23 matching lines...) Expand all
2775 if (element.isErroneous()) { 2841 if (element.isErroneous()) {
2776 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); 2842 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
2777 return; 2843 return;
2778 } 2844 }
2779 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2845 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2780 stack.add(graph.addConstantNull(constantSystem)); 2846 stack.add(graph.addConstantNull(constantSystem));
2781 return; 2847 return;
2782 } 2848 }
2783 compiler.ensure(!element.isGenerativeConstructor()); 2849 compiler.ensure(!element.isGenerativeConstructor());
2784 if (element.isFunction()) { 2850 if (element.isFunction()) {
2785 if (tryInlineMethod(element, selector, node.arguments)) return; 2851 if (tryInlineMethod(element.implementation, selector, node.arguments)) {
ngeoffray 2012/09/20 11:38:37 I would fetch the implementation in tryInlineMetho
Johnni Winther 2012/09/21 09:18:25 Done.
2852 return;
2853 }
2786 2854
2787 HInstruction target = new HStatic(element); 2855 HInstruction target = new HStatic(element);
2788 add(target); 2856 add(target);
2789 var inputs = <HInstruction>[target]; 2857 var inputs = <HInstruction>[target];
2790 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2858 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2791 element, inputs); 2859 element.implementation,
ngeoffray 2012/09/20 11:38:37 TODO
Johnni Winther 2012/09/21 09:18:25 Done.
2860 inputs);
2792 if (!succeeded) { 2861 if (!succeeded) {
2793 // TODO(ngeoffray): Match the VM behavior and throw an 2862 // TODO(ngeoffray): Match the VM behavior and throw an
2794 // exception at runtime. 2863 // exception at runtime.
2795 compiler.cancel('Unimplemented non-matching static call', node: node); 2864 compiler.cancel('Unimplemented non-matching static call', node: node);
2796 } 2865 }
2797 HInvokeStatic instruction = new HInvokeStatic(inputs); 2866 HInvokeStatic instruction = new HInvokeStatic(inputs);
2798 // TODO(ngeoffray): Only do this if knowing the return type is 2867 // TODO(ngeoffray): Only do this if knowing the return type is
2799 // useful. 2868 // useful.
2800 HType returnType = 2869 HType returnType =
2801 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( 2870 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3987 void visitTryStatement(Node node) { 4056 void visitTryStatement(Node node) {
3988 tooDifficult = true; 4057 tooDifficult = true;
3989 } 4058 }
3990 4059
3991 void visitThrow(Node node) { 4060 void visitThrow(Node node) {
3992 tooDifficult = true; 4061 tooDifficult = true;
3993 } 4062 }
3994 } 4063 }
3995 4064
3996 class InliningState { 4065 class InliningState {
4066 /**
4067 * Documentation wanted -- johnniwinther
4068 *
4069 * Invariant: [function] must be an implementation element.
4070 */
3997 final PartialFunctionElement function; 4071 final PartialFunctionElement function;
3998 final Element oldReturnElement; 4072 final Element oldReturnElement;
3999 final TreeElements oldElements; 4073 final TreeElements oldElements;
4000 final List<HInstruction> oldStack; 4074 final List<HInstruction> oldStack;
4001 4075
4002 InliningState(this.function, 4076 InliningState(this.function,
4003 this.oldReturnElement, 4077 this.oldReturnElement,
4004 this.oldElements, 4078 this.oldElements,
4005 this.oldStack); 4079 this.oldStack) {
4080 assert(function.isImplementation);
4081 }
4006 } 4082 }
4007 4083
4008 class SsaBranch { 4084 class SsaBranch {
4009 final SsaBranchBuilder branchBuilder; 4085 final SsaBranchBuilder branchBuilder;
4010 final HBasicBlock block; 4086 final HBasicBlock block;
4011 LocalsHandler startLocals; 4087 LocalsHandler startLocals;
4012 LocalsHandler exitLocals; 4088 LocalsHandler exitLocals;
4013 SubGraph graph; 4089 SubGraph graph;
4014 4090
4015 SsaBranch(this.branchBuilder) : block = new HBasicBlock(); 4091 SsaBranch(this.branchBuilder) : block = new HBasicBlock();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4232 new HSubGraphBlockInformation(elseBranch.graph)); 4308 new HSubGraphBlockInformation(elseBranch.graph));
4233 4309
4234 HBasicBlock conditionStartBlock = conditionBranch.block; 4310 HBasicBlock conditionStartBlock = conditionBranch.block;
4235 conditionStartBlock.setBlockFlow(info, joinBlock); 4311 conditionStartBlock.setBlockFlow(info, joinBlock);
4236 SubGraph conditionGraph = conditionBranch.graph; 4312 SubGraph conditionGraph = conditionBranch.graph;
4237 HIf branch = conditionGraph.end.last; 4313 HIf branch = conditionGraph.end.last;
4238 assert(branch is HIf); 4314 assert(branch is HIf);
4239 branch.blockInformation = conditionStartBlock.blockFlow; 4315 branch.blockInformation = conditionStartBlock.blockFlow;
4240 } 4316 }
4241 } 4317 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698