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

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

Issue 11273034: Make unmatched static call a runtime error. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Refactored resolution code. Created 8 years, 1 month 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 part of ssa; 5 part of ssa;
6 6
7 class Interceptors { 7 class Interceptors {
8 Compiler compiler; 8 Compiler compiler;
9 Interceptors(Compiler this.compiler); 9 Interceptors(Compiler this.compiler);
10 10
(...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 2291
2292 void pushInvokeHelper3(Element helper, HInstruction a0, HInstruction a1, 2292 void pushInvokeHelper3(Element helper, HInstruction a0, HInstruction a1,
2293 HInstruction a2) { 2293 HInstruction a2) {
2294 HInstruction reference = new HStatic(helper); 2294 HInstruction reference = new HStatic(helper);
2295 add(reference); 2295 add(reference);
2296 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; 2296 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2];
2297 HInstruction result = new HInvokeStatic(inputs); 2297 HInstruction result = new HInvokeStatic(inputs);
2298 push(result); 2298 push(result);
2299 } 2299 }
2300 2300
2301 void pushInvokeHelper4(Element helper, HInstruction a0, HInstruction a1,
2302 HInstruction a2, HInstruction a3) {
2303 HInstruction reference = new HStatic(helper);
2304 add(reference);
2305 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3];
2306 HInstruction result = new HInvokeStatic(inputs);
2307 push(result);
2308 }
2309
2301 visitOperatorSend(node) { 2310 visitOperatorSend(node) {
2302 assert(node.selector is Operator); 2311 assert(node.selector is Operator);
2303 if (!methodInterceptionEnabled) { 2312 if (!methodInterceptionEnabled) {
2304 visitDynamicSend(node); 2313 visitDynamicSend(node);
2305 return; 2314 return;
2306 } 2315 }
2307 2316
2308 Operator op = node.selector; 2317 Operator op = node.selector;
2309 if (const SourceString("[]") == op.source) { 2318 if (const SourceString("[]") == op.source) {
2310 HStatic target = new HStatic(interceptors.getIndexInterceptor()); 2319 HStatic target = new HStatic(interceptors.getIndexInterceptor());
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 // creating an [HStatic]. 2733 // creating an [HStatic].
2725 HInstruction target = new HStatic(element.declaration); 2734 HInstruction target = new HStatic(element.declaration);
2726 HInstruction context = localsHandler.readThis(); 2735 HInstruction context = localsHandler.readThis();
2727 add(target); 2736 add(target);
2728 var inputs = <HInstruction>[target, context]; 2737 var inputs = <HInstruction>[target, context];
2729 if (node.isPropertyAccess) { 2738 if (node.isPropertyAccess) {
2730 push(new HInvokeSuper(inputs)); 2739 push(new HInvokeSuper(inputs));
2731 } else if (element.isFunction() || element.isGenerativeConstructor()) { 2740 } else if (element.isFunction() || element.isGenerativeConstructor()) {
2732 // TODO(5347): Try to avoid the need for calling [implementation] before 2741 // TODO(5347): Try to avoid the need for calling [implementation] before
2733 // calling [addStaticSendArgumentsToList]. 2742 // calling [addStaticSendArgumentsToList].
2743 FunctionElement function = element.implementation;
2734 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2744 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2735 element.implementation, 2745 function, inputs);
2736 inputs);
2737 if (!succeeded) { 2746 if (!succeeded) {
2738 // TODO(ngeoffray): Match the VM behavior and throw an 2747 generateWrongArgumentCountError(node, element, node.arguments);
2739 // exception at runtime. 2748 } else {
2740 compiler.cancel('Unimplemented non-matching static call', node: node); 2749 push(new HInvokeSuper(inputs));
2741 } 2750 }
2742 push(new HInvokeSuper(inputs));
2743 } else { 2751 } else {
2744 target = new HInvokeSuper(inputs); 2752 target = new HInvokeSuper(inputs);
2745 add(target); 2753 add(target);
2746 inputs = <HInstruction>[target]; 2754 inputs = <HInstruction>[target];
2747 addDynamicSendArgumentsToList(node, inputs); 2755 addDynamicSendArgumentsToList(node, inputs);
2748 push(new HInvokeClosure(selector, inputs)); 2756 push(new HInvokeClosure(selector, inputs));
2749 } 2757 }
2750 } 2758 }
2751 2759
2752 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { 2760 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 HInstruction target = new HStatic(constructor.declaration); 2939 HInstruction target = new HStatic(constructor.declaration);
2932 add(target); 2940 add(target);
2933 var inputs = <HInstruction>[]; 2941 var inputs = <HInstruction>[];
2934 inputs.add(target); 2942 inputs.add(target);
2935 // TODO(5347): Try to avoid the need for calling [implementation] before 2943 // TODO(5347): Try to avoid the need for calling [implementation] before
2936 // calling [addStaticSendArgumentsToList]. 2944 // calling [addStaticSendArgumentsToList].
2937 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2945 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2938 constructor.implementation, 2946 constructor.implementation,
2939 inputs); 2947 inputs);
2940 if (!succeeded) { 2948 if (!succeeded) {
2941 // TODO(ngeoffray): Match the VM behavior and throw an 2949 generateWrongArgumentCountError(node, constructor, node.arguments);
2942 // exception at runtime. 2950 return;
2943 compiler.cancel('Unimplemented non-matching static call', node: node);
2944 } 2951 }
2945 2952
2946 TypeAnnotation annotation = node.getTypeAnnotation(); 2953 TypeAnnotation annotation = node.getTypeAnnotation();
2947 if (annotation == null) { 2954 if (annotation == null) {
2948 compiler.internalError("malformed send in new expression"); 2955 compiler.internalError("malformed send in new expression");
2949 } 2956 }
2950 InterfaceType type = elements.getType(annotation); 2957 InterfaceType type = elements.getType(annotation);
2951 if (type.element.modifiers.isAbstract() && 2958 if (type.element.modifiers.isAbstract() &&
2952 constructor.isGenerativeConstructor()) { 2959 constructor.isGenerativeConstructor()) {
2953 generateAbstractClassInstantiationError(node, type.name.slowToString()); 2960 generateAbstractClassInstantiationError(node, type.name.slowToString());
(...skipping 20 matching lines...) Expand all
2974 2981
2975 visitStaticSend(Send node) { 2982 visitStaticSend(Send node) {
2976 Selector selector = elements.getSelector(node); 2983 Selector selector = elements.getSelector(node);
2977 Element element = elements[node]; 2984 Element element = elements[node];
2978 if (element.isErroneous()) { 2985 if (element.isErroneous()) {
2979 generateThrowNoSuchMethod(node, 2986 generateThrowNoSuchMethod(node,
2980 getTargetName(element), 2987 getTargetName(element),
2981 argumentNodes: node.arguments); 2988 argumentNodes: node.arguments);
2982 return; 2989 return;
2983 } 2990 }
2984 if (identical(element, compiler.assertMethod) && !compiler.enableUserAsserti ons) { 2991 if (identical(element, compiler.assertMethod)
2992 && !compiler.enableUserAssertions) {
2985 stack.add(graph.addConstantNull(constantSystem)); 2993 stack.add(graph.addConstantNull(constantSystem));
2986 return; 2994 return;
2987 } 2995 }
2988 compiler.ensure(!element.isGenerativeConstructor()); 2996 compiler.ensure(!element.isGenerativeConstructor());
2989 if (element.isFunction()) { 2997 if (element.isFunction()) {
2990 if (tryInlineMethod(element, selector, node.arguments)) { 2998 if (tryInlineMethod(element, selector, node.arguments)) {
2991 return; 2999 return;
2992 } 3000 }
2993 3001
2994 HInstruction target = new HStatic(element); 3002 HInstruction target = new HStatic(element);
2995 add(target); 3003 add(target);
2996 var inputs = <HInstruction>[target]; 3004 var inputs = <HInstruction>[target];
2997 // TODO(5347): Try to avoid the need for calling [implementation] before 3005 // TODO(5347): Try to avoid the need for calling [implementation] before
2998 // calling [addStaticSendArgumentsToList]. 3006 // calling [addStaticSendArgumentsToList].
2999 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 3007 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
3000 element.implementation, 3008 element.implementation,
3001 inputs); 3009 inputs);
3002 if (!succeeded) { 3010 if (!succeeded) {
3003 // TODO(ngeoffray): Match the VM behavior and throw an 3011 generateWrongArgumentCountError(node, element, node.arguments);
3004 // exception at runtime. 3012 return;
3005 compiler.cancel('Unimplemented non-matching static call', node: node);
3006 } 3013 }
3007 3014
3008 // TODO(kasperl): Try to use the general inlining infrastructure for 3015 // TODO(kasperl): Try to use the general inlining infrastructure for
3009 // inlining the identical function. 3016 // inlining the identical function.
3010 if (identical(element, compiler.identicalFunction)) { 3017 if (identical(element, compiler.identicalFunction)) {
3011 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node); 3018 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node);
3012 return; 3019 return;
3013 } 3020 }
3014 3021
3015 HInvokeStatic instruction = new HInvokeStatic(inputs); 3022 HInvokeStatic instruction = new HInvokeStatic(inputs);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3051 3058
3052 void generateAbstractClassInstantiationError(Node node, String message) { 3059 void generateAbstractClassInstantiationError(Node node, String message) {
3053 generateError(node, 3060 generateError(node,
3054 message, 3061 message,
3055 interceptors.getThrowAbstractClassInstantiationError()); 3062 interceptors.getThrowAbstractClassInstantiationError());
3056 } 3063 }
3057 3064
3058 void generateThrowNoSuchMethod(Node diagnosticNode, 3065 void generateThrowNoSuchMethod(Node diagnosticNode,
3059 String methodName, 3066 String methodName,
3060 {Link<Node> argumentNodes, 3067 {Link<Node> argumentNodes,
3061 List<HInstruction> argumentValues}) { 3068 List<HInstruction> argumentValues,
3069 List<String> existingArguments}) {
3062 Element helper = 3070 Element helper =
3063 compiler.findHelper(const SourceString('throwNoSuchMethod')); 3071 compiler.findHelper(const SourceString('throwNoSuchMethod'));
3064 Constant receiverConstant = 3072 Constant receiverConstant =
3065 constantSystem.createString(new DartString.empty(), diagnosticNode); 3073 constantSystem.createString(new DartString.empty(), diagnosticNode);
3066 HInstruction receiver = graph.addConstant(receiverConstant); 3074 HInstruction receiver = graph.addConstant(receiverConstant);
3067 DartString dartString = new DartString.literal(methodName); 3075 DartString dartString = new DartString.literal(methodName);
3068 Constant nameConstant = 3076 Constant nameConstant =
3069 constantSystem.createString(dartString, diagnosticNode); 3077 constantSystem.createString(dartString, diagnosticNode);
3070 HInstruction name = graph.addConstant(nameConstant); 3078 HInstruction name = graph.addConstant(nameConstant);
3071 if (argumentValues == null) { 3079 if (argumentValues == null) {
3072 argumentValues = <HInstruction>[]; 3080 argumentValues = <HInstruction>[];
3073 argumentNodes.forEach((argumentNode) { 3081 argumentNodes.forEach((argumentNode) {
3074 visit(argumentNode); 3082 visit(argumentNode);
3075 HInstruction value = pop(); 3083 HInstruction value = pop();
3076 argumentValues.add(value); 3084 argumentValues.add(value);
3077 }); 3085 });
3078 } 3086 }
3079 HInstruction arguments = new HLiteralList(argumentValues); 3087 HInstruction arguments = new HLiteralList(argumentValues);
3080 add(arguments); 3088 add(arguments);
3081 pushInvokeHelper3(helper, receiver, name, arguments); 3089 HInstruction existingNamesList;
3090 if (existingArguments != null) {
3091 List<HInstruction> existingNames = <HInstruction>[];
3092 for (String name in existingArguments) {
3093 HInstruction nameConstant =
3094 graph.addConstantString(new DartString.literal(name),
3095 diagnosticNode, constantSystem);
3096 existingNames.add(nameConstant);
3097 }
3098 existingNamesList = new HLiteralList(existingNames);
3099 add(existingNamesList);
3100 } else {
3101 existingNamesList = graph.addConstantNull(constantSystem);
3102 }
3103 pushInvokeHelper4(helper, receiver, name, arguments, existingNamesList);
3104 }
3105
3106 /**
3107 * Generate code to throw a [NoSuchMethodError] exception for calling a
3108 * method with a wrong number of arguments or mismatching named optional
3109 * arguments.
3110 */
3111 void generateWrongArgumentCountError(Node diagnosticNode,
3112 FunctionElement function,
3113 Link<Node> argumentNodes) {
3114 List<String> existingArguments = <String>[];
3115 FunctionSignature signature = function.computeSignature(compiler);
3116 signature.forEachParameter((Element parameter) {
3117 existingArguments.add(parameter.name.slowToString());
3118 });
3119 generateThrowNoSuchMethod(diagnosticNode,
3120 function.name.slowToString(),
3121 argumentNodes: argumentNodes,
3122 existingArguments: existingArguments);
3082 } 3123 }
3083 3124
3084 visitNewExpression(NewExpression node) { 3125 visitNewExpression(NewExpression node) {
3085 Element element = elements[node.send]; 3126 Element element = elements[node.send];
3086 if (Elements.isErroneousElement(element)) { 3127 if (Elements.isErroneousElement(element)) {
3087 ErroneousElement error = element; 3128 ErroneousElement error = element;
3088 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { 3129 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
3089 generateThrowNoSuchMethod(node.send, 3130 generateThrowNoSuchMethod(node.send,
3090 getTargetName(error, 'constructor'), 3131 getTargetName(error, 'constructor'),
3091 argumentNodes: node.send.arguments); 3132 argumentNodes: node.send.arguments);
(...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after
4507 new HSubGraphBlockInformation(elseBranch.graph)); 4548 new HSubGraphBlockInformation(elseBranch.graph));
4508 4549
4509 HBasicBlock conditionStartBlock = conditionBranch.block; 4550 HBasicBlock conditionStartBlock = conditionBranch.block;
4510 conditionStartBlock.setBlockFlow(info, joinBlock); 4551 conditionStartBlock.setBlockFlow(info, joinBlock);
4511 SubGraph conditionGraph = conditionBranch.graph; 4552 SubGraph conditionGraph = conditionBranch.graph;
4512 HIf branch = conditionGraph.end.last; 4553 HIf branch = conditionGraph.end.last;
4513 assert(branch is HIf); 4554 assert(branch is HIf);
4514 branch.blockInformation = conditionStartBlock.blockFlow; 4555 branch.blockInformation = conditionStartBlock.blockFlow;
4515 } 4556 }
4516 } 4557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698