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

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: 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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2721 // TODO(5346): Try to avoid the need for calling [declaration] before 2730 // TODO(5346): Try to avoid the need for calling [declaration] before
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] and
2741 // [generateWrongArgumentCoundError].
ngeoffray 2012/10/25 11:24:09 generateWrongArgumentCoundError doesn't use functi
karlklose 2012/10/25 13:55:44 Done.
2742 FunctionElement function = element.implementation;
2732 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2743 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2733 element.implementation, 2744 function, inputs);
2734 inputs);
2735 if (!succeeded) { 2745 if (!succeeded) {
2736 // TODO(ngeoffray): Match the VM behavior and throw an 2746 generateWrongArgumentCountError(node, element,
2737 // exception at runtime. 2747 argumentNodes: node.arguments);
2738 compiler.cancel('Unimplemented non-matching static call', node: node); 2748 } else {
2749 push(new HInvokeSuper(inputs));
2739 } 2750 }
2740 push(new HInvokeSuper(inputs));
2741 } else { 2751 } else {
2742 target = new HInvokeSuper(inputs); 2752 target = new HInvokeSuper(inputs);
2743 add(target); 2753 add(target);
2744 inputs = <HInstruction>[target]; 2754 inputs = <HInstruction>[target];
2745 addDynamicSendArgumentsToList(node, inputs); 2755 addDynamicSendArgumentsToList(node, inputs);
2746 push(new HInvokeClosure(selector, inputs)); 2756 push(new HInvokeClosure(selector, inputs));
2747 } 2757 }
2748 } 2758 }
2749 2759
2750 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
2929 HInstruction target = new HStatic(constructor.declaration); 2939 HInstruction target = new HStatic(constructor.declaration);
2930 add(target); 2940 add(target);
2931 var inputs = <HInstruction>[]; 2941 var inputs = <HInstruction>[];
2932 inputs.add(target); 2942 inputs.add(target);
2933 // TODO(5347): Try to avoid the need for calling [implementation] before 2943 // TODO(5347): Try to avoid the need for calling [implementation] before
2934 // calling [addStaticSendArgumentsToList]. 2944 // calling [addStaticSendArgumentsToList].
2935 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 2945 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2936 constructor.implementation, 2946 constructor.implementation,
2937 inputs); 2947 inputs);
2938 if (!succeeded) { 2948 if (!succeeded) {
2939 // TODO(ngeoffray): Match the VM behavior and throw an 2949 generateWrongArgumentCountError(node, constructor,
2940 // exception at runtime. 2950 argumentNodes: node.arguments);
2941 compiler.cancel('Unimplemented non-matching static call', node: node); 2951 return;
2942 } 2952 }
2943 2953
2944 TypeAnnotation annotation = node.getTypeAnnotation(); 2954 TypeAnnotation annotation = node.getTypeAnnotation();
2945 if (annotation == null) { 2955 if (annotation == null) {
2946 compiler.internalError("malformed send in new expression"); 2956 compiler.internalError("malformed send in new expression");
2947 } 2957 }
2948 InterfaceType type = elements.getType(annotation); 2958 InterfaceType type = elements.getType(annotation);
2949 if (type.element.modifiers.isAbstract() && 2959 if (type.element.modifiers.isAbstract() &&
2950 constructor.isGenerativeConstructor()) { 2960 constructor.isGenerativeConstructor()) {
2951 generateAbstractClassInstantiationError(node, type.name.slowToString()); 2961 generateAbstractClassInstantiationError(node, type.name.slowToString());
(...skipping 20 matching lines...) Expand all
2972 2982
2973 visitStaticSend(Send node) { 2983 visitStaticSend(Send node) {
2974 Selector selector = elements.getSelector(node); 2984 Selector selector = elements.getSelector(node);
2975 Element element = elements[node]; 2985 Element element = elements[node];
2976 if (element.isErroneous()) { 2986 if (element.isErroneous()) {
2977 generateThrowNoSuchMethod(node, 2987 generateThrowNoSuchMethod(node,
2978 getTargetName(element), 2988 getTargetName(element),
2979 argumentNodes: node.arguments); 2989 argumentNodes: node.arguments);
2980 return; 2990 return;
2981 } 2991 }
2982 if (identical(element, compiler.assertMethod) && !compiler.enableUserAsserti ons) { 2992 if (identical(element, compiler.assertMethod)
2993 && !compiler.enableUserAssertions) {
2983 stack.add(graph.addConstantNull(constantSystem)); 2994 stack.add(graph.addConstantNull(constantSystem));
2984 return; 2995 return;
2985 } 2996 }
2986 compiler.ensure(!element.isGenerativeConstructor()); 2997 compiler.ensure(!element.isGenerativeConstructor());
2987 if (element.isFunction()) { 2998 if (element.isFunction()) {
2988 if (tryInlineMethod(element, selector, node.arguments)) { 2999 if (tryInlineMethod(element, selector, node.arguments)) {
2989 return; 3000 return;
2990 } 3001 }
2991 3002
2992 HInstruction target = new HStatic(element); 3003 HInstruction target = new HStatic(element);
2993 add(target); 3004 add(target);
2994 var inputs = <HInstruction>[target]; 3005 var inputs = <HInstruction>[target];
2995 // TODO(5347): Try to avoid the need for calling [implementation] before 3006 // TODO(5347): Try to avoid the need for calling [implementation] before
2996 // calling [addStaticSendArgumentsToList]. 3007 // calling [addStaticSendArgumentsToList].
2997 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, 3008 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments,
2998 element.implementation, 3009 element.implementation,
2999 inputs); 3010 inputs);
3000 if (!succeeded) { 3011 if (!succeeded) {
3001 // TODO(ngeoffray): Match the VM behavior and throw an 3012 generateWrongArgumentCountError(node, element,
3002 // exception at runtime. 3013 argumentNodes: node.arguments);
3003 compiler.cancel('Unimplemented non-matching static call', node: node); 3014 return;
3004 } 3015 }
3005 3016
3006 // TODO(kasperl): Try to use the general inlining infrastructure for 3017 // TODO(kasperl): Try to use the general inlining infrastructure for
3007 // inlining the identical function. 3018 // inlining the identical function.
3008 if (identical(element, compiler.identicalFunction)) { 3019 if (identical(element, compiler.identicalFunction)) {
3009 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node); 3020 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node);
3010 return; 3021 return;
3011 } 3022 }
3012 3023
3013 HInvokeStatic instruction = new HInvokeStatic(inputs); 3024 HInvokeStatic instruction = new HInvokeStatic(inputs);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 3060
3050 void generateAbstractClassInstantiationError(Node node, String message) { 3061 void generateAbstractClassInstantiationError(Node node, String message) {
3051 generateError(node, 3062 generateError(node,
3052 message, 3063 message,
3053 interceptors.getThrowAbstractClassInstantiationError()); 3064 interceptors.getThrowAbstractClassInstantiationError());
3054 } 3065 }
3055 3066
3056 void generateThrowNoSuchMethod(Node diagnosticNode, 3067 void generateThrowNoSuchMethod(Node diagnosticNode,
3057 String methodName, 3068 String methodName,
3058 {Link<Node> argumentNodes, 3069 {Link<Node> argumentNodes,
3059 List<HInstruction> argumentValues}) { 3070 List<HInstruction> argumentValues,
3071 List<String> existingArguments}) {
3060 Element helper = 3072 Element helper =
3061 compiler.findHelper(const SourceString('throwNoSuchMethod')); 3073 compiler.findHelper(const SourceString('throwNoSuchMethod'));
3062 Constant receiverConstant = 3074 Constant receiverConstant =
3063 constantSystem.createString(new DartString.empty(), diagnosticNode); 3075 constantSystem.createString(new DartString.empty(), diagnosticNode);
3064 HInstruction receiver = graph.addConstant(receiverConstant); 3076 HInstruction receiver = graph.addConstant(receiverConstant);
3065 DartString dartString = new DartString.literal(methodName); 3077 DartString dartString = new DartString.literal(methodName);
3066 Constant nameConstant = 3078 Constant nameConstant =
3067 constantSystem.createString(dartString, diagnosticNode); 3079 constantSystem.createString(dartString, diagnosticNode);
3068 HInstruction name = graph.addConstant(nameConstant); 3080 HInstruction name = graph.addConstant(nameConstant);
3069 if (argumentValues == null) { 3081 if (argumentValues == null) {
3070 argumentValues = <HInstruction>[]; 3082 argumentValues = <HInstruction>[];
3071 argumentNodes.forEach((argumentNode) { 3083 argumentNodes.forEach((argumentNode) {
3072 visit(argumentNode); 3084 visit(argumentNode);
3073 HInstruction value = pop(); 3085 HInstruction value = pop();
3074 argumentValues.add(value); 3086 argumentValues.add(value);
3075 }); 3087 });
3076 } 3088 }
3077 HInstruction arguments = new HLiteralList(argumentValues); 3089 HInstruction arguments = new HLiteralList(argumentValues);
3078 add(arguments); 3090 add(arguments);
3079 pushInvokeHelper3(helper, receiver, name, arguments); 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 HInstruction existingNamesList = new HLiteralList(existingNames);
3100 add(existingNamesList);
3101 pushInvokeHelper4(helper, receiver, name, arguments, existingNamesList);
3102 } else {
3103 pushInvokeHelper3(helper, receiver, name, arguments);
3104 }
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 13:34:04 Why do you need optional arguments here?
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