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

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

Issue 10920089: Generate a warning and a runtime error for calls to nonexistent static calls, getters and setters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 1971 matching lines...) Expand 10 before | Expand all | Expand 10 after
1982 1982
1983 HInstruction generateInstanceSendReceiver(Send send) { 1983 HInstruction generateInstanceSendReceiver(Send send) {
1984 assert(Elements.isInstanceSend(send, elements)); 1984 assert(Elements.isInstanceSend(send, elements));
1985 if (send.receiver == null) { 1985 if (send.receiver == null) {
1986 return localsHandler.readThis(); 1986 return localsHandler.readThis();
1987 } 1987 }
1988 visit(send.receiver); 1988 visit(send.receiver);
1989 return pop(); 1989 return pop();
1990 } 1990 }
1991 1991
1992 String getTargetName(ErroneousElement error, [String prefix]) {
ngeoffray 2012/09/07 08:12:46 How about String getTargetName(error, [String pre
karlklose 2012/09/07 09:24:01 Done.
1993 String targetName = error.targetName.slowToString();
1994 if (prefix != null) {
1995 return prefix.concat(targetName);
1996 }
1997 return targetName;
1998 }
1999
1992 void generateInstanceGetterWithCompiledReceiver(Send send, 2000 void generateInstanceGetterWithCompiledReceiver(Send send,
1993 HInstruction receiver) { 2001 HInstruction receiver) {
1994 assert(Elements.isInstanceSend(send, elements)); 2002 assert(Elements.isInstanceSend(send, elements));
1995 // TODO(kasperl): This is a convoluted way of checking if we're 2003 // TODO(kasperl): This is a convoluted way of checking if we're
1996 // generating code for a compound assignment. If we are, we need 2004 // generating code for a compound assignment. If we are, we need
1997 // to get the selector from the mapping for the AST selector node. 2005 // to get the selector from the mapping for the AST selector node.
1998 Selector selector = (send.asSendSet() === null) 2006 Selector selector = (send.asSendSet() === null)
1999 ? elements.getSelector(send) 2007 ? elements.getSelector(send)
2000 : elements.getSelector(send.selector); 2008 : elements.getSelector(send.selector);
2001 assert(selector.isGetter()); 2009 assert(selector.isGetter());
(...skipping 30 matching lines...) Expand all
2032 push(new HInvokeStatic(<HInstruction>[pop()])); 2040 push(new HInvokeStatic(<HInstruction>[pop()]));
2033 } 2041 }
2034 } 2042 }
2035 } else if (Elements.isInstanceSend(send, elements)) { 2043 } else if (Elements.isInstanceSend(send, elements)) {
2036 HInstruction receiver = generateInstanceSendReceiver(send); 2044 HInstruction receiver = generateInstanceSendReceiver(send);
2037 generateInstanceGetterWithCompiledReceiver(send, receiver); 2045 generateInstanceGetterWithCompiledReceiver(send, receiver);
2038 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2046 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2039 push(new HStatic(element)); 2047 push(new HStatic(element));
2040 // TODO(ahe): This should be registered in codegen. 2048 // TODO(ahe): This should be registered in codegen.
2041 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2049 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2050 } else if (Element.isErroneousElement(element)) {
2051 // An erroneous element indicates an unresolved static getter.
2052 generateThrowNoSuchMethod(send,
2053 getTargetName(element, 'get '),
2054 const EmptyLink<Node>());
2042 } else { 2055 } else {
2043 stack.add(localsHandler.readLocal(element)); 2056 stack.add(localsHandler.readLocal(element));
2044 } 2057 }
2045 } 2058 }
2046 2059
2047 void generateInstanceSetterWithCompiledReceiver(Send send, 2060 void generateInstanceSetterWithCompiledReceiver(Send send,
2048 HInstruction receiver, 2061 HInstruction receiver,
2049 HInstruction value) { 2062 HInstruction value) {
2050 assert(Elements.isInstanceSend(send, elements)); 2063 assert(Elements.isInstanceSend(send, elements));
2051 Selector selector = elements.getSelector(send); 2064 Selector selector = elements.getSelector(send);
(...skipping 20 matching lines...) Expand all
2072 HStatic target = new HStatic(element); 2085 HStatic target = new HStatic(element);
2073 add(target); 2086 add(target);
2074 add(new HInvokeStatic(<HInstruction>[target, value])); 2087 add(new HInvokeStatic(<HInstruction>[target, value]));
2075 } else { 2088 } else {
2076 add(new HStaticStore(element, value)); 2089 add(new HStaticStore(element, value));
2077 } 2090 }
2078 stack.add(value); 2091 stack.add(value);
2079 } else if (element === null || Elements.isInstanceField(element)) { 2092 } else if (element === null || Elements.isInstanceField(element)) {
2080 HInstruction receiver = generateInstanceSendReceiver(send); 2093 HInstruction receiver = generateInstanceSendReceiver(send);
2081 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 2094 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
2095 } else if (Element.isErroneousElement(element)) {
2096 // An erroneous element indicates an unresolved static setter.
2097 generateThrowNoSuchMethod(send,
2098 getTargetName(element, 'set '),
2099 send.arguments);
2082 } else { 2100 } else {
2083 stack.add(value); 2101 stack.add(value);
2084 // If the value does not already have a name, give it here. 2102 // If the value does not already have a name, give it here.
2085 if (value.sourceElement === null) { 2103 if (value.sourceElement === null) {
2086 value.sourceElement = element; 2104 value.sourceElement = element;
2087 } 2105 }
2088 HInstruction checked = potentiallyCheckType(value, element); 2106 HInstruction checked = potentiallyCheckType(value, element);
2089 if (checked !== value) { 2107 if (checked !== value) {
2090 pop(); 2108 pop();
2091 stack.add(checked); 2109 stack.add(checked);
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 }); 2649 });
2632 2650
2633 HType elementType = computeType(constructor); 2651 HType elementType = computeType(constructor);
2634 HInstruction newInstance = new HInvokeStatic(inputs, elementType); 2652 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
2635 pushWithPosition(newInstance, node); 2653 pushWithPosition(newInstance, node);
2636 } 2654 }
2637 2655
2638 visitStaticSend(Send node) { 2656 visitStaticSend(Send node) {
2639 Selector selector = elements.getSelector(node); 2657 Selector selector = elements.getSelector(node);
2640 Element element = elements[node]; 2658 Element element = elements[node];
2659 if (element.isErroneous()) {
2660 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
2661 return;
2662 }
2641 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2663 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2642 stack.add(graph.addConstantNull()); 2664 stack.add(graph.addConstantNull());
2643 return; 2665 return;
2644 } 2666 }
2645 compiler.ensure(!element.isGenerativeConstructor()); 2667 compiler.ensure(!element.isGenerativeConstructor());
2646 if (element.isFunction()) { 2668 if (element.isFunction()) {
2647 if (tryInlineMethod(element, selector, node.arguments)) return; 2669 if (tryInlineMethod(element, selector, node.arguments)) return;
2648 2670
2649 HInstruction target = new HStatic(element); 2671 HInstruction target = new HStatic(element);
2650 add(target); 2672 add(target);
(...skipping 30 matching lines...) Expand all
2681 compiler.internalError(reason, node: node); 2703 compiler.internalError(reason, node: node);
2682 } 2704 }
2683 2705
2684 void generateRuntimeError(Node node, String message) { 2706 void generateRuntimeError(Node node, String message) {
2685 DartString messageObject = new DartString.literal(message); 2707 DartString messageObject = new DartString.literal(message);
2686 HInstruction errorMessage = graph.addConstantString(messageObject, node); 2708 HInstruction errorMessage = graph.addConstantString(messageObject, node);
2687 Element helper = interceptors.getThrowRuntimeError(); 2709 Element helper = interceptors.getThrowRuntimeError();
2688 pushInvokeHelper1(helper, errorMessage); 2710 pushInvokeHelper1(helper, errorMessage);
2689 } 2711 }
2690 2712
2713 void generateThrowNoSuchMethod(Node diagnosticNode,
2714 String methodName,
2715 [Link<Node> argumentNodes,
2716 List<HInstruction> argumentValues]) {
2717 Element helper =
2718 compiler.findHelper(const SourceString('throwNoSuchMethod'));
2719 HInstruction receiver =
2720 graph.addConstantString(new DartString.empty(), diagnosticNode);
2721 DartString dartString = new DartString.literal(methodName);
2722 HInstruction name = graph.addConstantString(dartString, diagnosticNode);
2723 if (argumentValues == null) {
2724 argumentValues = <HInstruction>[];
2725 argumentNodes.forEach((argumentNode) {
2726 visit(argumentNode);
2727 HInstruction value = pop();
2728 argumentValues.add(value);
2729 });
2730 }
2731 HInstruction arguments = new HLiteralList(argumentValues);
2732 add(arguments);
2733 pushInvokeHelper3(helper, receiver, name, arguments);
2734 }
2735
2691 visitNewExpression(NewExpression node) { 2736 visitNewExpression(NewExpression node) {
2692 Element element = elements[node.send]; 2737 Element element = elements[node.send];
2693 if (element != null && element.isErroneous()) { 2738 if (Element.isErroneousElement(element)) {
2694 ErroneousElement error = element; 2739 ErroneousElement error = element;
2695 Message message = error.errorMessage; 2740 Message message = error.errorMessage;
2696 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { 2741 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) {
2697 Element helper = 2742 generateThrowNoSuchMethod(node.send,
2698 compiler.findHelper(const SourceString('throwNoSuchMethod')); 2743 getTargetName(error, 'constructor'),
2699 DartString receiverLiteral = new DartString.literal(''); 2744 node.send.arguments);
2700 HInstruction receiver = graph.addConstantString(receiverLiteral, node);
2701 String constructorName = 'constructor ${message.arguments[0]}';
2702 DartString nameLiteral = new DartString.literal(constructorName);
2703 HInstruction name = graph.addConstantString(nameLiteral, node.send);
2704 List<HInstruction> inputs = <HInstruction>[];
2705 node.send.arguments.forEach((argumentNode) {
2706 visit(argumentNode);
2707 HInstruction value = pop();
2708 inputs.add(value);
2709 });
2710 HInstruction arguments = new HLiteralList(inputs);
2711 add(arguments);
2712 pushInvokeHelper3(helper, receiver, name, arguments);
2713 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { 2745 } else if (message.kind === MessageKind.CANNOT_RESOLVE) {
2714 generateRuntimeError(node.send, message.message); 2746 generateRuntimeError(node.send, message.message);
2715 } else { 2747 } else {
2716 compiler.internalError('unexpected unresolved constructor call', 2748 compiler.internalError('unexpected unresolved constructor call',
2717 node: node); 2749 node: node);
2718 } 2750 }
2719 } else if (node.isConst()) { 2751 } else if (node.isConst()) {
2720 // TODO(karlklose): add type representation 2752 // TODO(karlklose): add type representation
2721 ConstantHandler handler = compiler.constantHandler; 2753 ConstantHandler handler = compiler.constantHandler;
2722 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2754 Constant constant = handler.compileNodeWithDefinitions(node, elements);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
3072 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); 3104 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator]));
3073 3105
3074 Element variable; 3106 Element variable;
3075 if (node.declaredIdentifier.asSend() !== null) { 3107 if (node.declaredIdentifier.asSend() !== null) {
3076 variable = elements[node.declaredIdentifier]; 3108 variable = elements[node.declaredIdentifier];
3077 } else { 3109 } else {
3078 assert(node.declaredIdentifier.asVariableDefinitions() !== null); 3110 assert(node.declaredIdentifier.asVariableDefinitions() !== null);
3079 VariableDefinitions variableDefinitions = node.declaredIdentifier; 3111 VariableDefinitions variableDefinitions = node.declaredIdentifier;
3080 variable = elements[variableDefinitions.definitions.nodes.head]; 3112 variable = elements[variableDefinitions.definitions.nodes.head];
3081 } 3113 }
3082 localsHandler.updateLocal(variable, pop()); 3114 HInstruction oldVariable = pop();
3115 if (variable.isErroneous()) {
3116 generateThrowNoSuchMethod(node,
3117 getTargetName(variable, 'set '),
3118 argumentValues: <HInstruction>[oldVariable]);
3119 pop();
3120 } else {
3121 localsHandler.updateLocal(variable, oldVariable);
3122 }
3083 3123
3084 visit(node.body); 3124 visit(node.body);
3085 } 3125 }
3086 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); 3126 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
3087 } 3127 }
3088 3128
3089 visitLabel(Label node) { 3129 visitLabel(Label node) {
3090 compiler.internalError('SsaBuilder.visitLabel', node: node); 3130 compiler.internalError('SsaBuilder.visitLabel', node: node);
3091 } 3131 }
3092 3132
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 new HSubGraphBlockInformation(elseBranch.graph)); 4066 new HSubGraphBlockInformation(elseBranch.graph));
4027 4067
4028 HBasicBlock conditionStartBlock = conditionBranch.block; 4068 HBasicBlock conditionStartBlock = conditionBranch.block;
4029 conditionStartBlock.setBlockFlow(info, joinBlock); 4069 conditionStartBlock.setBlockFlow(info, joinBlock);
4030 SubGraph conditionGraph = conditionBranch.graph; 4070 SubGraph conditionGraph = conditionBranch.graph;
4031 HIf branch = conditionGraph.end.last; 4071 HIf branch = conditionGraph.end.last;
4032 assert(branch is HIf); 4072 assert(branch is HIf);
4033 branch.blockInformation = conditionStartBlock.blockFlow; 4073 branch.blockInformation = conditionStartBlock.blockFlow;
4034 } 4074 }
4035 } 4075 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698