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

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

Powered by Google App Engine
This is Rietveld 408576698