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

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;
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(node, function.isImplementation));
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);
971 // [:resolveMethodElement:] require the passed element to be a
972 // declaration.
955 TreeElements treeElements = 973 TreeElements treeElements =
956 compiler.resolver.resolveMethodElement(constructor); 974 compiler.resolver.resolveMethodElement(constructor.declaration);
957 compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements);
958 classElement.backendMembers = 975 classElement.backendMembers =
959 classElement.backendMembers.prepend(bodyElement); 976 classElement.backendMembers.prepend(bodyElement);
977 compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration,
978 treeElements);
960 } 979 }
961 assert(bodyElement.isGenerativeConstructorBody()); 980 assert(bodyElement.isGenerativeConstructorBody());
962 return bodyElement; 981 return bodyElement;
963 } 982 }
964 983
984 /**
985 * Documentation wanted -- johnniwinther
986 *
987 * Invariant: [function] must be an implementation element.
988 */
965 InliningState enterInlinedMethod(PartialFunctionElement function, 989 InliningState enterInlinedMethod(PartialFunctionElement function,
966 Selector selector, 990 Selector selector,
967 Link<Node> arguments) { 991 Link<Node> arguments) {
992 assert(invariant(function, function.isImplementation));
993
968 // Once we start to compile the arguments we must be sure that we don't 994 // Once we start to compile the arguments we must be sure that we don't
969 // abort. 995 // abort.
970 List<HInstruction> compiledArguments = new List<HInstruction>(); 996 List<HInstruction> compiledArguments = new List<HInstruction>();
971 bool succeeded = addStaticSendArgumentsToList(selector, 997 bool succeeded = addStaticSendArgumentsToList(selector,
972 arguments, 998 arguments,
973 function, 999 function,
974 compiledArguments); 1000 compiledArguments);
975 assert(succeeded); 1001 assert(succeeded);
976 1002
977 InliningState state = 1003 InliningState state =
978 new InliningState(function, returnElement, elements, stack); 1004 new InliningState(function, returnElement, elements, stack);
979 inliningStack.add(state); 1005 inliningStack.add(state);
980 sourceElementStack.add(function); 1006 sourceElementStack.add(function);
981 stack = <HInstruction>[]; 1007 stack = <HInstruction>[];
982 returnElement = new Element(const SourceString("result"), 1008 returnElement = new Element(const SourceString("result"),
983 ElementKind.VARIABLE, 1009 ElementKind.VARIABLE,
984 function); 1010 function);
985 localsHandler.updateLocal(returnElement, 1011 localsHandler.updateLocal(returnElement,
986 graph.addConstantNull(constantSystem)); 1012 graph.addConstantNull(constantSystem));
987 elements = compiler.enqueuer.resolution.getCachedElements(function); 1013 elements = compiler.enqueuer.resolution.getCachedElements(function);
1014 assert(elements !== null);
988 FunctionSignature signature = function.computeSignature(compiler); 1015 FunctionSignature signature = function.computeSignature(compiler);
989 int index = 0; 1016 int index = 0;
990 signature.forEachParameter((Element parameter) { 1017 signature.forEachParameter((Element parameter) {
991 HInstruction argument = compiledArguments[index++]; 1018 HInstruction argument = compiledArguments[index++];
992 localsHandler.updateLocal(parameter, argument); 1019 localsHandler.updateLocal(parameter, argument);
993 potentiallyCheckType(argument, parameter); 1020 potentiallyCheckType(argument, parameter);
994 }); 1021 });
995 return state; 1022 return state;
996 } 1023 }
997 1024
998 void leaveInlinedMethod(InliningState state) { 1025 void leaveInlinedMethod(InliningState state) {
999 InliningState poppedState = inliningStack.removeLast(); 1026 InliningState poppedState = inliningStack.removeLast();
1000 assert(state == poppedState); 1027 assert(state == poppedState);
1001 FunctionElement poppedElement = sourceElementStack.removeLast(); 1028 FunctionElement poppedElement = sourceElementStack.removeLast();
1002 assert(poppedElement == poppedState.function); 1029 assert(poppedElement == poppedState.function);
1003 elements = state.oldElements; 1030 elements = state.oldElements;
1004 stack.add(localsHandler.readLocal(returnElement)); 1031 stack.add(localsHandler.readLocal(returnElement));
1005 returnElement = state.oldReturnElement; 1032 returnElement = state.oldReturnElement;
1006 assert(stack.length == 1); 1033 assert(stack.length == 1);
1007 state.oldStack.add(stack[0]); 1034 state.oldStack.add(stack[0]);
1008 stack = state.oldStack; 1035 stack = state.oldStack;
1009 } 1036 }
1010 1037
1038 /**
1039 * Documentation wanted -- johnniwinther
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 // Ensure that [element] is an implementation element.
1045 element = element.implementation;
1014 // TODO(floitsch): we should be able to inline inside lazy initializers. 1046 // TODO(floitsch): we should be able to inline inside lazy initializers.
1015 if (!currentElement.isFunction()) return false; 1047 if (!currentElement.isFunction()) return false;
1016 // TODO(floitsch): we should be able to inline getters, setters and 1048 // TODO(floitsch): we should be able to inline getters, setters and
1017 // constructor bodies. 1049 // constructor bodies.
1018 if (!element.isFunction()) return false; 1050 if (!element.isFunction()) return false;
1019 // TODO(floitsch): find a cleaner way to know if the element is a function 1051 // TODO(floitsch): find a cleaner way to know if the element is a function
1020 // containing nodes. 1052 // containing nodes.
1021 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. 1053 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
1022 if (element is !PartialFunctionElement) return false; 1054 if (element is !PartialFunctionElement) return false;
1023 if (inliningStack.length > MAX_INLINING_DEPTH) return false; 1055 if (inliningStack.length > MAX_INLINING_DEPTH) return false;
1024 // Don't inline recursive calls. We use the same elements for the inlined 1056 // Don't inline recursive calls. We use the same elements for the inlined
1025 // functions and would thus clobber our local variables. 1057 // functions and would thus clobber our local variables.
1026 if (work.element == element) return false; 1058 // Use [:element.declaration:] since [work.element] is always a declaration.
1059 if (work.element == element.declaration) return false;
1027 for (int i = 0; i < inliningStack.length; i++) { 1060 for (int i = 0; i < inliningStack.length; i++) {
1028 if (inliningStack[i].function == element) return false; 1061 if (inliningStack[i].function == element) return false;
1029 } 1062 }
1030 // TODO(ngeoffray): Inlining currently does not work in the presence of 1063 // TODO(ngeoffray): Inlining currently does not work in the presence of
1031 // private calls. 1064 // private calls.
1032 if (currentLibrary != element.getLibrary()) return false; 1065 if (currentLibrary != element.getLibrary()) return false;
1033 PartialFunctionElement function = element; 1066 PartialFunctionElement function = element;
1034 int sourceSize = 1067 int sourceSize =
1035 function.endToken.charOffset - function.beginToken.charOffset; 1068 function.endToken.charOffset - function.beginToken.charOffset;
1036 if (sourceSize > MAX_INLINING_SOURCE_SIZE) return false; 1069 if (sourceSize > MAX_INLINING_SOURCE_SIZE) return false;
1037 if (!selector.applies(function, compiler)) return false; 1070 if (!selector.applies(function, compiler)) return false;
1038 FunctionExpression functionExpression = function.parseNode(compiler); 1071 FunctionExpression functionExpression = function.parseNode(compiler);
1039 TreeElements newElements = 1072 TreeElements newElements =
1040 compiler.enqueuer.resolution.getCachedElements(function); 1073 compiler.enqueuer.resolution.getCachedElements(function);
1041 if (newElements === null) { 1074 if (newElements === null) {
1042 compiler.internalError("Element not resolved: $function"); 1075 compiler.internalError("Element not resolved: $function");
1043 } 1076 }
1044 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) { 1077 if (!InlineWeeder.canBeInlined(functionExpression, newElements)) {
1045 return false; 1078 return false;
1046 } 1079 }
1047 1080
1048 InliningState state = enterInlinedMethod(function, selector, arguments); 1081 InliningState state = enterInlinedMethod(function, selector, arguments);
1049 functionExpression.body.accept(this); 1082 functionExpression.body.accept(this);
1050 leaveInlinedMethod(state); 1083 leaveInlinedMethod(state);
1051 return true; 1084 return true;
1052 } 1085 }
1053 1086
1087 /**
1088 * Documentation wanted -- johnniwinther
1089 *
1090 * Invariant: [constructor] and [constructors] must all be implementation
1091 * elements.
1092 */
1054 void inlineSuperOrRedirect(FunctionElement constructor, 1093 void inlineSuperOrRedirect(FunctionElement constructor,
1055 Selector selector, 1094 Selector selector,
1056 Link<Node> arguments, 1095 Link<Node> arguments,
1057 List<FunctionElement> constructors, 1096 List<FunctionElement> constructors,
1058 Map<Element, HInstruction> fieldValues) { 1097 Map<Element, HInstruction> fieldValues) {
1098 assert(invariant(constructor, constructor.isImplementation));
1059 constructors.addLast(constructor); 1099 constructors.addLast(constructor);
1060 1100
1061 List<HInstruction> compiledArguments = new List<HInstruction>(); 1101 List<HInstruction> compiledArguments = new List<HInstruction>();
1062 bool succeeded = addStaticSendArgumentsToList(selector, 1102 bool succeeded = addStaticSendArgumentsToList(selector,
1063 arguments, 1103 arguments,
1064 constructor, 1104 constructor,
1065 compiledArguments); 1105 compiledArguments);
1066 if (!succeeded) { 1106 if (!succeeded) {
1067 // Non-matching super and redirects are compile-time errors and thus 1107 // Non-matching super and redirects are compile-time errors and thus
1068 // checked by the resolver. 1108 // checked by the resolver.
(...skipping 23 matching lines...) Expand all
1092 buildInitializers(constructor, constructors, fieldValues); 1132 buildInitializers(constructor, constructors, fieldValues);
1093 elements = oldElements; 1133 elements = oldElements;
1094 } 1134 }
1095 1135
1096 /** 1136 /**
1097 * Run through the initializers and inline all field initializers. Recursively 1137 * Run through the initializers and inline all field initializers. Recursively
1098 * inlines super initializers. 1138 * inlines super initializers.
1099 * 1139 *
1100 * The constructors of the inlined initializers is added to [constructors] 1140 * The constructors of the inlined initializers is added to [constructors]
1101 * with sub constructors having a lower index than super constructors. 1141 * with sub constructors having a lower index than super constructors.
1142 *
1143 * Invariant: The [constructor] and elements in [constructors] must all be
1144 * implementation elements.
1102 */ 1145 */
1103 void buildInitializers(FunctionElement constructor, 1146 void buildInitializers(FunctionElement constructor,
1104 List<FunctionElement> constructors, 1147 List<FunctionElement> constructors,
1105 Map<Element, HInstruction> fieldValues) { 1148 Map<Element, HInstruction> fieldValues) {
1149 assert(invariant(constructor, constructor.isImplementation));
1106 FunctionExpression functionNode = constructor.parseNode(compiler); 1150 FunctionExpression functionNode = constructor.parseNode(compiler);
1107 1151
1108 bool foundSuperOrRedirect = false; 1152 bool foundSuperOrRedirect = false;
1109 1153
1110 if (functionNode.initializers !== null) { 1154 if (functionNode.initializers !== null) {
1111 Link<Node> initializers = functionNode.initializers.nodes; 1155 Link<Node> initializers = functionNode.initializers.nodes;
1112 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) { 1156 for (Link<Node> link = initializers; !link.isEmpty(); link = link.tail) {
1113 assert(link.head is Send); 1157 assert(link.head is Send);
1114 if (link.head is !SendSet) { 1158 if (link.head is !SendSet) {
1115 // A super initializer or constructor redirection. 1159 // A super initializer or constructor redirection.
(...skipping 17 matching lines...) Expand all
1133 fieldValues[elements[init]] = pop(); 1177 fieldValues[elements[init]] = pop();
1134 } 1178 }
1135 } 1179 }
1136 } 1180 }
1137 1181
1138 if (!foundSuperOrRedirect) { 1182 if (!foundSuperOrRedirect) {
1139 // No super initializer found. Try to find the default constructor if 1183 // No super initializer found. Try to find the default constructor if
1140 // the class is not Object. 1184 // the class is not Object.
1141 ClassElement enclosingClass = constructor.getEnclosingClass(); 1185 ClassElement enclosingClass = constructor.getEnclosingClass();
1142 ClassElement superClass = enclosingClass.superclass; 1186 ClassElement superClass = enclosingClass.superclass;
1143 if (enclosingClass != compiler.objectClass) { 1187 if (!enclosingClass.isObject(compiler)) {
1144 assert(superClass !== null); 1188 assert(superClass !== null);
1145 assert(superClass.resolutionState == STATE_DONE); 1189 assert(superClass.resolutionState == STATE_DONE);
1146 Selector selector = 1190 Selector selector =
1147 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0); 1191 new Selector.call(superClass.name, enclosingClass.getLibrary(), 0);
1148 FunctionElement target = superClass.lookupConstructor(superClass.name); 1192 FunctionElement target = superClass.lookupConstructor(superClass.name);
1149 if (target === null) { 1193 if (target === null) {
1150 compiler.internalError("no default constructor available"); 1194 compiler.internalError("no default constructor available");
1151 } 1195 }
1152 inlineSuperOrRedirect(target, 1196 inlineSuperOrRedirect(target.implementation,
1153 selector, 1197 selector,
1154 const EmptyLink<Node>(), 1198 const EmptyLink<Node>(),
1155 constructors, 1199 constructors,
1156 fieldValues); 1200 fieldValues);
1157 } 1201 }
1158 } 1202 }
1159 } 1203 }
1160 1204
1161 /** 1205 /**
1162 * Run through the fields of [cls] and add their potential 1206 * Run through the fields of [cls] and add their potential
1163 * initializers. 1207 * initializers.
1208 *
1209 * Invariant: [classElement] must be a declaration element.
1164 */ 1210 */
1165 void buildFieldInitializers(ClassElement classElement, 1211 void buildFieldInitializers(ClassElement classElement,
1166 Map<Element, HInstruction> fieldValues) { 1212 Map<Element, HInstruction> fieldValues) {
1213 assert(invariant(classElement, classElement.isDeclaration));
1167 classElement.forEachInstanceField( 1214 classElement.forEachInstanceField(
1168 includeBackendMembers: true, 1215 includeBackendMembers: true,
1169 includeSuperMembers: false, 1216 includeSuperMembers: false,
1170 f: (ClassElement enclosingClass, Element member) { 1217 f: (ClassElement enclosingClass, Element member) {
1171 TreeElements definitions = compiler.analyzeElement(member); 1218 TreeElements definitions = compiler.analyzeElement(member);
1172 Node node = member.parseNode(compiler); 1219 Node node = member.parseNode(compiler);
1173 SendSet assignment = node.asSendSet(); 1220 SendSet assignment = node.asSendSet();
1174 HInstruction value; 1221 HInstruction value;
1175 if (assignment === null) { 1222 if (assignment === null) {
1176 value = graph.addConstantNull(constantSystem); 1223 value = graph.addConstantNull(constantSystem);
(...skipping 11 matching lines...) Expand all
1188 1235
1189 1236
1190 /** 1237 /**
1191 * Build the factory function corresponding to the constructor 1238 * Build the factory function corresponding to the constructor
1192 * [functionElement]: 1239 * [functionElement]:
1193 * - Initialize fields with the values of the field initializers of the 1240 * - Initialize fields with the values of the field initializers of the
1194 * current constructor and super constructors or constructors redirected 1241 * current constructor and super constructors or constructors redirected
1195 * to, starting from the current constructor. 1242 * to, starting from the current constructor.
1196 * - Call the the constructor bodies, starting from the constructor(s) in the 1243 * - Call the the constructor bodies, starting from the constructor(s) in the
1197 * super class(es). 1244 * super class(es).
1245 *
1246 * Invariants: [classElement] must be a declaration element, and
1247 * [functionElement] must be an implementation element.
1198 */ 1248 */
1199 HGraph buildFactory(ClassElement classElement, 1249 HGraph buildFactory(ClassElement classElement,
1200 FunctionElement functionElement) { 1250 FunctionElement functionElement) {
1251 assert(invariant(classElement, classElement.isDeclaration));
1252 assert(invariant(functionElement, functionElement.isImplementation));
1201 FunctionExpression function = functionElement.parseNode(compiler); 1253 FunctionExpression function = functionElement.parseNode(compiler);
1202 // Note that constructors (like any other static function) do not need 1254 // 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 1255 // to deal with optional arguments. It is the callers job to provide all
1204 // arguments as if they were positional. 1256 // arguments as if they were positional.
1205 1257
1206 // The initializer list could contain closures. 1258 // The initializer list could contain closures.
1207 openFunction(functionElement, function); 1259 openFunction(functionElement, function);
1208 1260
1209 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); 1261 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
1210 1262
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 if (compiler.world.needsRti(classElement)) { 1300 if (compiler.world.needsRti(classElement)) {
1249 classElement.typeVariables.forEach((TypeVariableType typeVariable) { 1301 classElement.typeVariables.forEach((TypeVariableType typeVariable) {
1250 inputs.add(localsHandler.directLocals[typeVariable.element]); 1302 inputs.add(localsHandler.directLocals[typeVariable.element]);
1251 }); 1303 });
1252 callSetRuntimeTypeInfo(classElement, inputs, newObject); 1304 callSetRuntimeTypeInfo(classElement, inputs, newObject);
1253 } 1305 }
1254 1306
1255 // Generate calls to the constructor bodies. 1307 // Generate calls to the constructor bodies.
1256 for (int index = constructors.length - 1; index >= 0; index--) { 1308 for (int index = constructors.length - 1; index >= 0; index--) {
1257 FunctionElement constructor = constructors[index]; 1309 FunctionElement constructor = constructors[index];
1310 assert(invariant(functionElement, constructor.isImplementation));
1258 ConstructorBodyElement body = getConstructorBody(constructor); 1311 ConstructorBodyElement body = getConstructorBody(constructor);
1259 if (body === null) continue; 1312 if (body === null) continue;
1260 List bodyCallInputs = <HInstruction>[]; 1313 List bodyCallInputs = <HInstruction>[];
1261 bodyCallInputs.add(newObject); 1314 bodyCallInputs.add(newObject);
1262 int arity = body.functionSignature.parameterCount; 1315 FunctionSignature functionSignature = body.computeSignature(compiler);
1263 body.functionSignature.forEachParameter((parameter) { 1316 int arity = functionSignature.parameterCount;
1317 functionSignature.forEachParameter((parameter) {
1264 bodyCallInputs.add(localsHandler.readLocal(parameter)); 1318 bodyCallInputs.add(localsHandler.readLocal(parameter));
1265 }); 1319 });
1266 // TODO(ahe): The constructor name is statically resolved. See 1320 // TODO(ahe): The constructor name is statically resolved. See
1267 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner 1321 // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner
1268 // way to do this? 1322 // way to do this?
1269 SourceString name = new SourceString(backend.namer.getName(body)); 1323 SourceString name =
1324 new SourceString(backend.namer.getName(body.declaration));
1270 // TODO(kasperl): This seems fishy. We shouldn't be inventing all 1325 // TODO(kasperl): This seems fishy. We shouldn't be inventing all
1271 // these selectors. Maybe the resolver can do more of the work 1326 // these selectors. Maybe the resolver can do more of the work
1272 // for us here? 1327 // for us here?
1273 LibraryElement library = body.getLibrary(); 1328 LibraryElement library = body.getLibrary();
1274 Selector selector = new Selector.call(name, library, arity); 1329 Selector selector = new Selector.call(name, library, arity);
1275 add(new HInvokeDynamicMethod(selector, bodyCallInputs)); 1330 add(new HInvokeDynamicMethod(selector, bodyCallInputs));
1276 } 1331 }
1277 close(new HReturn(newObject)).addSuccessor(graph.exit); 1332 close(new HReturn(newObject)).addSuccessor(graph.exit);
1278 return closeFunction(); 1333 return closeFunction();
1279 } 1334 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 1372
1318 // Create the instruction that parameter checks will use. 1373 // Create the instruction that parameter checks will use.
1319 check = new HNot(check); 1374 check = new HNot(check);
1320 add(check); 1375 add(check);
1321 1376
1322 ClosureClassMap closureData = localsHandler.closureData; 1377 ClosureClassMap closureData = localsHandler.closureData;
1323 Element checkResultElement = closureData.parametersWithSentinel[element]; 1378 Element checkResultElement = closureData.parametersWithSentinel[element];
1324 localsHandler.updateLocal(checkResultElement, check); 1379 localsHandler.updateLocal(checkResultElement, check);
1325 } 1380 }
1326 1381
1382 /**
1383 * Documentation wanted -- johnniwinther
1384 *
1385 * Invariant: [functionElement] must be the implementation element.
1386 */
1327 void openFunction(FunctionElement functionElement, 1387 void openFunction(FunctionElement functionElement,
1328 FunctionExpression node) { 1388 FunctionExpression node) {
1389 assert(invariant(functionElement, functionElement.isImplementation));
1329 HBasicBlock block = graph.addNewBlock(); 1390 HBasicBlock block = graph.addNewBlock();
1330 open(graph.entry); 1391 open(graph.entry);
1331 1392
1332 localsHandler.startFunction(functionElement, node); 1393 localsHandler.startFunction(functionElement, node);
1333 close(new HGoto()).addSuccessor(block); 1394 close(new HGoto()).addSuccessor(block);
1334 1395
1335 open(block); 1396 open(block);
1336 1397
1337 FunctionSignature params = functionElement.computeSignature(compiler); 1398 FunctionSignature params = functionElement.computeSignature(compiler);
1338 params.forEachParameter((Element element) { 1399 params.forEachParameter((Element element) {
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 if (element.isField() && !element.isAssignable()) { 2114 if (element.isField() && !element.isAssignable()) {
2054 // A static final or const. Get its constant value and inline it if 2115 // A static final or const. Get its constant value and inline it if
2055 // the value can be compiled eagerly. 2116 // the value can be compiled eagerly.
2056 value = compiler.compileVariable(element); 2117 value = compiler.compileVariable(element);
2057 } 2118 }
2058 if (value != null) { 2119 if (value != null) {
2059 stack.add(graph.addConstant(value)); 2120 stack.add(graph.addConstant(value));
2060 } else if (element.isField() && compiler.isLazilyInitialized(element)) { 2121 } else if (element.isField() && compiler.isLazilyInitialized(element)) {
2061 push(new HLazyStatic(element)); 2122 push(new HLazyStatic(element));
2062 } else { 2123 } else {
2063 push(new HStatic(element)); 2124 // TODO(5346): Try to avoid the need for calling [declaration] before
2125 // creating an [HStatic].
2126 push(new HStatic(element.declaration));
2064 if (element.isGetter()) { 2127 if (element.isGetter()) {
2065 push(new HInvokeStatic(<HInstruction>[pop()])); 2128 push(new HInvokeStatic(<HInstruction>[pop()]));
2066 } 2129 }
2067 } 2130 }
2068 } else if (Elements.isInstanceSend(send, elements)) { 2131 } else if (Elements.isInstanceSend(send, elements)) {
2069 HInstruction receiver = generateInstanceSendReceiver(send); 2132 HInstruction receiver = generateInstanceSendReceiver(send);
2070 generateInstanceGetterWithCompiledReceiver(send, receiver); 2133 generateInstanceGetterWithCompiledReceiver(send, receiver);
2071 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2134 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2072 push(new HStatic(element)); 2135 // TODO(5346): Try to avoid the need for calling [declaration] before
2136 // creating an [HStatic].
2137 push(new HStatic(element.declaration));
2073 // TODO(ahe): This should be registered in codegen. 2138 // TODO(ahe): This should be registered in codegen.
2074 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2139 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2075 } else if (Elements.isErroneousElement(element)) { 2140 } else if (Elements.isErroneousElement(element)) {
2076 // An erroneous element indicates an unresolved static getter. 2141 // An erroneous element indicates an unresolved static getter.
2077 generateThrowNoSuchMethod(send, 2142 generateThrowNoSuchMethod(send,
2078 getTargetName(element, 'get'), 2143 getTargetName(element, 'get'),
2079 const EmptyLink<Node>()); 2144 const EmptyLink<Node>());
2080 } else { 2145 } else {
2081 stack.add(localsHandler.readLocal(element)); 2146 stack.add(localsHandler.readLocal(element));
2082 } 2147 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2282 // selectors with the same named arguments. 2347 // selectors with the same named arguments.
2283 List<SourceString> orderedNames = selector.getOrderedNamedArguments(); 2348 List<SourceString> orderedNames = selector.getOrderedNamedArguments();
2284 for (SourceString name in orderedNames) { 2349 for (SourceString name in orderedNames) {
2285 list.add(instructions[name]); 2350 list.add(instructions[name]);
2286 } 2351 }
2287 } 2352 }
2288 } 2353 }
2289 2354
2290 /** 2355 /**
2291 * Returns true if the arguments were compatible with the function signature. 2356 * Returns true if the arguments were compatible with the function signature.
2357 *
2358 * Invariant: [element] must be an implementation element.
2292 */ 2359 */
2293 bool addStaticSendArgumentsToList(Selector selector, 2360 bool addStaticSendArgumentsToList(Selector selector,
2294 Link<Node> arguments, 2361 Link<Node> arguments,
2295 FunctionElement element, 2362 FunctionElement element,
2296 List<HInstruction> list) { 2363 List<HInstruction> list) {
2364 assert(invariant(element, element.isImplementation));
2365
2297 HInstruction compileArgument(Node argument) { 2366 HInstruction compileArgument(Node argument) {
2298 visit(argument); 2367 visit(argument);
2299 return pop(); 2368 return pop();
2300 } 2369 }
2301 2370
2302 HInstruction compileConstant(Element parameter) { 2371 HInstruction compileConstant(Element parameter) {
2303 Constant constant; 2372 Constant constant;
2304 TreeElements calleeElements = 2373 TreeElements calleeElements =
2305 compiler.enqueuer.resolution.getCachedElements(element); 2374 compiler.enqueuer.resolution.getCachedElements(element);
2306 if (calleeElements.isParameterChecked(parameter)) { 2375 if (calleeElements.isParameterChecked(parameter)) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2513 node: node.argumentsNode); 2582 node: node.argumentsNode);
2514 } 2583 }
2515 Node closure = node.arguments.head; 2584 Node closure = node.arguments.head;
2516 Element element = elements[closure]; 2585 Element element = elements[closure];
2517 if (!Elements.isStaticOrTopLevelFunction(element)) { 2586 if (!Elements.isStaticOrTopLevelFunction(element)) {
2518 compiler.cancel( 2587 compiler.cancel(
2519 'JS_TO_CLOSURE requires a static or top-level method', 2588 'JS_TO_CLOSURE requires a static or top-level method',
2520 node: closure); 2589 node: closure);
2521 } 2590 }
2522 FunctionElement function = element; 2591 FunctionElement function = element;
2523 FunctionSignature params = function.computeSignature(compiler); 2592 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
2593 // and implementation signatures. Currently it is need because the
2594 // signatures have different elements for parameters.
2595 FunctionSignature params
2596 = function.implementation.computeSignature(compiler);
2524 if (params.optionalParameterCount !== 0) { 2597 if (params.optionalParameterCount !== 0) {
2525 compiler.cancel( 2598 compiler.cancel(
2526 'JS_TO_CLOSURE does not handle closure with optional parameters', 2599 'JS_TO_CLOSURE does not handle closure with optional parameters',
2527 node: closure); 2600 node: closure);
2528 } 2601 }
2529 visit(closure); 2602 visit(closure);
2530 List<HInstruction> inputs = <HInstruction>[pop()]; 2603 List<HInstruction> inputs = <HInstruction>[pop()];
2531 String invocationName = backend.namer.closureInvocationName( 2604 String invocationName = backend.namer.closureInvocationName(
2532 new Selector.callClosure(params.requiredParameterCount)); 2605 new Selector.callClosure(params.requiredParameterCount));
2533 push(new HForeign(new DartString.literal('#.$invocationName'), 2606 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) { 2653 if (element !== null && element === work.element) {
2581 graph.isRecursiveMethod = true; 2654 graph.isRecursiveMethod = true;
2582 } 2655 }
2583 super.visitSend(node); 2656 super.visitSend(node);
2584 } 2657 }
2585 2658
2586 visitSuperSend(Send node) { 2659 visitSuperSend(Send node) {
2587 Selector selector = elements.getSelector(node); 2660 Selector selector = elements.getSelector(node);
2588 Element element = elements[node]; 2661 Element element = elements[node];
2589 if (element === null) return generateSuperNoSuchMethodSend(node); 2662 if (element === null) return generateSuperNoSuchMethodSend(node);
2590 HInstruction target = new HStatic(element); 2663 // TODO(5346): Try to avoid the need for calling [declaration] before
2664 // creating an [HStatic].
2665 HInstruction target = new HStatic(element.declaration);
2591 HInstruction context = localsHandler.readThis(); 2666 HInstruction context = localsHandler.readThis();
2592 add(target); 2667 add(target);
2593 var inputs = <HInstruction>[target, context]; 2668 var inputs = <HInstruction>[target, context];
2594 if (node.isPropertyAccess) { 2669 if (node.isPropertyAccess) {
2595 push(new HInvokeSuper(inputs)); 2670 push(new HInvokeSuper(inputs));
2596 } else if (element.isFunction() || element.isGenerativeConstructor()) { 2671 } else if (element.isFunction() || element.isGenerativeConstructor()) {
2672 // TODO(5347): Try to avoid the need for calling [implementation] before
2673 // calling [addStaticSendArgumentsToList].
2597 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2674 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2598 element, inputs); 2675 element.implementation,
2676 inputs);
2599 if (!succeeded) { 2677 if (!succeeded) {
2600 // TODO(ngeoffray): Match the VM behavior and throw an 2678 // TODO(ngeoffray): Match the VM behavior and throw an
2601 // exception at runtime. 2679 // exception at runtime.
2602 compiler.cancel('Unimplemented non-matching static call', node); 2680 compiler.cancel('Unimplemented non-matching static call', node);
2603 } 2681 }
2604 push(new HInvokeSuper(inputs)); 2682 push(new HInvokeSuper(inputs));
2605 } else { 2683 } else {
2606 target = new HInvokeSuper(inputs); 2684 target = new HInvokeSuper(inputs);
2607 add(target); 2685 add(target);
2608 inputs = <HInstruction>[target]; 2686 inputs = <HInstruction>[target];
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 } 2804 }
2727 } 2805 }
2728 2806
2729 Element constructor = elements[node]; 2807 Element constructor = elements[node];
2730 Selector selector = elements.getSelector(node); 2808 Selector selector = elements.getSelector(node);
2731 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) { 2809 if (compiler.enqueuer.resolution.getCachedElements(constructor) === null) {
2732 compiler.internalError("Unresolved element: $constructor", node: node); 2810 compiler.internalError("Unresolved element: $constructor", node: node);
2733 } 2811 }
2734 FunctionElement functionElement = constructor; 2812 FunctionElement functionElement = constructor;
2735 constructor = functionElement.defaultImplementation; 2813 constructor = functionElement.defaultImplementation;
2736 HInstruction target = new HStatic(constructor); 2814 // TODO(5346): Try to avoid the need for calling [declaration] before
2815 // creating an [HStatic].
2816 HInstruction target = new HStatic(constructor.declaration);
2737 add(target); 2817 add(target);
2738 var inputs = <HInstruction>[]; 2818 var inputs = <HInstruction>[];
2739 inputs.add(target); 2819 inputs.add(target);
2820 // TODO(5347): Try to avoid the need for calling [implementation] before
2821 // calling [addStaticSendArgumentsToList].
2740 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2822 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2741 constructor, inputs); 2823 constructor.implementation,
2824 inputs);
2742 if (!succeeded) { 2825 if (!succeeded) {
2743 // TODO(ngeoffray): Match the VM behavior and throw an 2826 // TODO(ngeoffray): Match the VM behavior and throw an
2744 // exception at runtime. 2827 // exception at runtime.
2745 compiler.cancel('Unimplemented non-matching static call', node: node); 2828 compiler.cancel('Unimplemented non-matching static call', node: node);
2746 } 2829 }
2747 2830
2748 TypeAnnotation annotation = node.getTypeAnnotation(); 2831 TypeAnnotation annotation = node.getTypeAnnotation();
2749 if (annotation == null) { 2832 if (annotation == null) {
2750 compiler.internalError("malformed send in new expression"); 2833 compiler.internalError("malformed send in new expression");
2751 } 2834 }
(...skipping 23 matching lines...) Expand all
2775 if (element.isErroneous()) { 2858 if (element.isErroneous()) {
2776 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); 2859 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
2777 return; 2860 return;
2778 } 2861 }
2779 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2862 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2780 stack.add(graph.addConstantNull(constantSystem)); 2863 stack.add(graph.addConstantNull(constantSystem));
2781 return; 2864 return;
2782 } 2865 }
2783 compiler.ensure(!element.isGenerativeConstructor()); 2866 compiler.ensure(!element.isGenerativeConstructor());
2784 if (element.isFunction()) { 2867 if (element.isFunction()) {
2785 if (tryInlineMethod(element, selector, node.arguments)) return; 2868 if (tryInlineMethod(element, selector, node.arguments)) {
2869 return;
2870 }
2786 2871
2787 HInstruction target = new HStatic(element); 2872 HInstruction target = new HStatic(element);
2788 add(target); 2873 add(target);
2789 var inputs = <HInstruction>[target]; 2874 var inputs = <HInstruction>[target];
2875 // TODO(5347): Try to avoid the need for calling [implementation] before
2876 // calling [addStaticSendArgumentsToList].
2790 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2877 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2791 element, inputs); 2878 element.implementation,
2879 inputs);
2792 if (!succeeded) { 2880 if (!succeeded) {
2793 // TODO(ngeoffray): Match the VM behavior and throw an 2881 // TODO(ngeoffray): Match the VM behavior and throw an
2794 // exception at runtime. 2882 // exception at runtime.
2795 compiler.cancel('Unimplemented non-matching static call', node: node); 2883 compiler.cancel('Unimplemented non-matching static call', node: node);
2796 } 2884 }
2797 HInvokeStatic instruction = new HInvokeStatic(inputs); 2885 HInvokeStatic instruction = new HInvokeStatic(inputs);
2798 // TODO(ngeoffray): Only do this if knowing the return type is 2886 // TODO(ngeoffray): Only do this if knowing the return type is
2799 // useful. 2887 // useful.
2800 HType returnType = 2888 HType returnType =
2801 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( 2889 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3987 void visitTryStatement(Node node) { 4075 void visitTryStatement(Node node) {
3988 tooDifficult = true; 4076 tooDifficult = true;
3989 } 4077 }
3990 4078
3991 void visitThrow(Node node) { 4079 void visitThrow(Node node) {
3992 tooDifficult = true; 4080 tooDifficult = true;
3993 } 4081 }
3994 } 4082 }
3995 4083
3996 class InliningState { 4084 class InliningState {
4085 /**
4086 * Documentation wanted -- johnniwinther
4087 *
4088 * Invariant: [function] must be an implementation element.
4089 */
3997 final PartialFunctionElement function; 4090 final PartialFunctionElement function;
3998 final Element oldReturnElement; 4091 final Element oldReturnElement;
3999 final TreeElements oldElements; 4092 final TreeElements oldElements;
4000 final List<HInstruction> oldStack; 4093 final List<HInstruction> oldStack;
4001 4094
4002 InliningState(this.function, 4095 InliningState(this.function,
4003 this.oldReturnElement, 4096 this.oldReturnElement,
4004 this.oldElements, 4097 this.oldElements,
4005 this.oldStack); 4098 this.oldStack) {
4099 assert(function.isImplementation);
4100 }
4006 } 4101 }
4007 4102
4008 class SsaBranch { 4103 class SsaBranch {
4009 final SsaBranchBuilder branchBuilder; 4104 final SsaBranchBuilder branchBuilder;
4010 final HBasicBlock block; 4105 final HBasicBlock block;
4011 LocalsHandler startLocals; 4106 LocalsHandler startLocals;
4012 LocalsHandler exitLocals; 4107 LocalsHandler exitLocals;
4013 SubGraph graph; 4108 SubGraph graph;
4014 4109
4015 SsaBranch(this.branchBuilder) : block = new HBasicBlock(); 4110 SsaBranch(this.branchBuilder) : block = new HBasicBlock();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4232 new HSubGraphBlockInformation(elseBranch.graph)); 4327 new HSubGraphBlockInformation(elseBranch.graph));
4233 4328
4234 HBasicBlock conditionStartBlock = conditionBranch.block; 4329 HBasicBlock conditionStartBlock = conditionBranch.block;
4235 conditionStartBlock.setBlockFlow(info, joinBlock); 4330 conditionStartBlock.setBlockFlow(info, joinBlock);
4236 SubGraph conditionGraph = conditionBranch.graph; 4331 SubGraph conditionGraph = conditionBranch.graph;
4237 HIf branch = conditionGraph.end.last; 4332 HIf branch = conditionGraph.end.last;
4238 assert(branch is HIf); 4333 assert(branch is HIf);
4239 branch.blockInformation = conditionStartBlock.blockFlow; 4334 branch.blockInformation = conditionStartBlock.blockFlow;
4240 } 4335 }
4241 } 4336 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/scanner/token.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698