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

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: Address 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 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 1957
1958 HInstruction generateInstanceSendReceiver(Send send) { 1958 HInstruction generateInstanceSendReceiver(Send send) {
1959 assert(Elements.isInstanceSend(send, elements)); 1959 assert(Elements.isInstanceSend(send, elements));
1960 if (send.receiver == null) { 1960 if (send.receiver == null) {
1961 return localsHandler.readThis(); 1961 return localsHandler.readThis();
1962 } 1962 }
1963 visit(send.receiver); 1963 visit(send.receiver);
1964 return pop(); 1964 return pop();
1965 } 1965 }
1966 1966
1967 String getTargetName(ErroneousElement error, [String prefix]) {
1968 String targetName = error.errorMessage.arguments[0].toString();
1969 if (prefix != null) {
1970 return prefix.concat(targetName);
1971 }
1972 return targetName;
1973 }
1974
1967 void generateInstanceGetterWithCompiledReceiver(Send send, 1975 void generateInstanceGetterWithCompiledReceiver(Send send,
1968 HInstruction receiver) { 1976 HInstruction receiver) {
1969 assert(Elements.isInstanceSend(send, elements)); 1977 assert(Elements.isInstanceSend(send, elements));
1970 // TODO(kasperl): This is a convoluted way of checking if we're 1978 // TODO(kasperl): This is a convoluted way of checking if we're
1971 // generating code for a compound assignment. If we are, we need 1979 // generating code for a compound assignment. If we are, we need
1972 // to get the selector from the mapping for the AST selector node. 1980 // to get the selector from the mapping for the AST selector node.
1973 Selector selector = (send.asSendSet() === null) 1981 Selector selector = (send.asSendSet() === null)
1974 ? elements.getSelector(send) 1982 ? elements.getSelector(send)
1975 : elements.getSelector(send.selector); 1983 : elements.getSelector(send.selector);
1976 assert(selector.isGetter()); 1984 assert(selector.isGetter());
(...skipping 24 matching lines...) Expand all
2001 push(new HInvokeStatic(<HInstruction>[pop()])); 2009 push(new HInvokeStatic(<HInstruction>[pop()]));
2002 } 2010 }
2003 } 2011 }
2004 } else if (Elements.isInstanceSend(send, elements)) { 2012 } else if (Elements.isInstanceSend(send, elements)) {
2005 HInstruction receiver = generateInstanceSendReceiver(send); 2013 HInstruction receiver = generateInstanceSendReceiver(send);
2006 generateInstanceGetterWithCompiledReceiver(send, receiver); 2014 generateInstanceGetterWithCompiledReceiver(send, receiver);
2007 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2015 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2008 push(new HStatic(element)); 2016 push(new HStatic(element));
2009 // TODO(ahe): This should be registered in codegen. 2017 // TODO(ahe): This should be registered in codegen.
2010 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2018 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2019 } else if (element != null && Element.isInvalid(element)) {
2020 // An erroneous element indicates an unresolved static getter.
2021 generateThrowNoSuchMethod(send,
2022 getTargetName(element, 'get '),
2023 const EmptyLink<Node>());
2011 } else { 2024 } else {
2012 stack.add(localsHandler.readLocal(element)); 2025 stack.add(localsHandler.readLocal(element));
2013 } 2026 }
2014 } 2027 }
2015 2028
2016 void generateInstanceSetterWithCompiledReceiver(Send send, 2029 void generateInstanceSetterWithCompiledReceiver(Send send,
2017 HInstruction receiver, 2030 HInstruction receiver,
2018 HInstruction value) { 2031 HInstruction value) {
2019 assert(Elements.isInstanceSend(send, elements)); 2032 assert(Elements.isInstanceSend(send, elements));
2020 Selector selector = elements.getSelector(send); 2033 Selector selector = elements.getSelector(send);
(...skipping 20 matching lines...) Expand all
2041 HStatic target = new HStatic(element); 2054 HStatic target = new HStatic(element);
2042 add(target); 2055 add(target);
2043 add(new HInvokeStatic(<HInstruction>[target, value])); 2056 add(new HInvokeStatic(<HInstruction>[target, value]));
2044 } else { 2057 } else {
2045 add(new HStaticStore(element, value)); 2058 add(new HStaticStore(element, value));
2046 } 2059 }
2047 stack.add(value); 2060 stack.add(value);
2048 } else if (element === null || Elements.isInstanceField(element)) { 2061 } else if (element === null || Elements.isInstanceField(element)) {
2049 HInstruction receiver = generateInstanceSendReceiver(send); 2062 HInstruction receiver = generateInstanceSendReceiver(send);
2050 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 2063 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
2064 } else if (element != null && Element.isInvalid(element)) {
2065 // An erroneous element indicates an unresolved static setter.
2066 generateThrowNoSuchMethod(send,
2067 getTargetName(element, 'set '),
2068 send.arguments);
2051 } else { 2069 } else {
2052 stack.add(value); 2070 stack.add(value);
2053 // If the value does not already have a name, give it here. 2071 // If the value does not already have a name, give it here.
2054 if (value.sourceElement === null) { 2072 if (value.sourceElement === null) {
2055 value.sourceElement = element; 2073 value.sourceElement = element;
2056 } 2074 }
2057 HInstruction checked = potentiallyCheckType(value, element); 2075 HInstruction checked = potentiallyCheckType(value, element);
2058 if (checked !== value) { 2076 if (checked !== value) {
2059 pop(); 2077 pop();
2060 stack.add(checked); 2078 stack.add(checked);
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 }); 2619 });
2602 2620
2603 HType elementType = computeType(constructor); 2621 HType elementType = computeType(constructor);
2604 HInstruction newInstance = new HInvokeStatic(inputs, elementType); 2622 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
2605 pushWithPosition(newInstance, node); 2623 pushWithPosition(newInstance, node);
2606 } 2624 }
2607 2625
2608 visitStaticSend(Send node) { 2626 visitStaticSend(Send node) {
2609 Selector selector = elements.getSelector(node); 2627 Selector selector = elements.getSelector(node);
2610 Element element = elements[node]; 2628 Element element = elements[node];
2629 if (element.isErroneous()) {
2630 generateThrowNoSuchMethod(node, getTargetName(element), node.arguments);
2631 return;
2632 }
2611 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2633 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2612 stack.add(graph.addConstantNull()); 2634 stack.add(graph.addConstantNull());
2613 return; 2635 return;
2614 } 2636 }
2615 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); 2637 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR);
2616 2638
2617 if (tryInlineMethod(element, selector, node.arguments)) return; 2639 if (tryInlineMethod(element, selector, node.arguments)) return;
2618 2640
2619 HInstruction target = new HStatic(element); 2641 HInstruction target = new HStatic(element);
2620 add(target); 2642 add(target);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 compiler.internalError(reason, node: node); 2678 compiler.internalError(reason, node: node);
2657 } 2679 }
2658 2680
2659 void generateRuntimeError(Node node, String message) { 2681 void generateRuntimeError(Node node, String message) {
2660 DartString messageObject = new DartString.literal(message); 2682 DartString messageObject = new DartString.literal(message);
2661 HInstruction errorMessage = graph.addConstantString(messageObject, node); 2683 HInstruction errorMessage = graph.addConstantString(messageObject, node);
2662 Element helper = interceptors.getThrowRuntimeError(); 2684 Element helper = interceptors.getThrowRuntimeError();
2663 pushInvokeHelper1(helper, errorMessage); 2685 pushInvokeHelper1(helper, errorMessage);
2664 } 2686 }
2665 2687
2688 void generateThrowNoSuchMethod(Node diagnosticNode,
2689 String methodName,
2690 [Link<Node> argumentNodes,
2691 List<HInstruction> argumentValues]) {
2692 Element helper =
2693 compiler.findHelper(const SourceString('throwNoSuchMethod'));
2694 HInstruction receiver =
2695 graph.addConstantString(new DartString.empty(), diagnosticNode);
2696 DartString dartString = new DartString.literal(methodName);
2697 HInstruction name = graph.addConstantString(dartString, diagnosticNode);
2698 if (argumentValues == null) {
2699 argumentValues = <HInstruction>[];
kasperl 2012/09/05 11:16:01 Could this be done using argumentNodes.map?
karlklose 2012/09/05 14:53:42 No, this is a Link, which does not have map.
2700 argumentNodes.forEach((argumentNode) {
2701 visit(argumentNode);
2702 HInstruction value = pop();
2703 argumentValues.add(value);
2704 });
2705 }
2706 HInstruction arguments = new HLiteralList(argumentValues);
2707 add(arguments);
2708 pushInvokeHelper3(helper, receiver, name, arguments);
2709 }
2710
2666 visitNewExpression(NewExpression node) { 2711 visitNewExpression(NewExpression node) {
2667 Element element = elements[node.send]; 2712 Element element = elements[node.send];
2668 if (element != null && element.isErroneous()) { 2713 if (element != null && element.isErroneous()) {
2669 ErroneousElement error = element; 2714 ErroneousElement error = element;
2670 Message message = error.errorMessage; 2715 Message message = error.errorMessage;
2671 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { 2716 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) {
2672 Element helper =
2673 compiler.findHelper(const SourceString('throwNoSuchMethod'));
2674 DartString receiverLiteral = new DartString.literal('');
2675 HInstruction receiver = graph.addConstantString(receiverLiteral, node);
2676 String constructorName = 'constructor ${message.arguments[0]}'; 2717 String constructorName = 'constructor ${message.arguments[0]}';
2677 DartString nameLiteral = new DartString.literal(constructorName); 2718 generateThrowNoSuchMethod(node.send,
2678 HInstruction name = graph.addConstantString(nameLiteral, node.send); 2719 getTargetName(error, 'constructor'),
2679 List<HInstruction> inputs = <HInstruction>[]; 2720 node.send.arguments);
2680 node.send.arguments.forEach((argumentNode) {
2681 visit(argumentNode);
2682 HInstruction value = pop();
2683 inputs.add(value);
2684 });
2685 HInstruction arguments = new HLiteralList(inputs);
2686 add(arguments);
2687 pushInvokeHelper3(helper, receiver, name, arguments);
2688 } else if (message.kind === MessageKind.CANNOT_RESOLVE) { 2721 } else if (message.kind === MessageKind.CANNOT_RESOLVE) {
2689 generateRuntimeError(node.send, message.message); 2722 generateRuntimeError(node.send, message.message);
2690 } else { 2723 } else {
2691 compiler.internalError('unexpected unresolved constructor call', 2724 compiler.internalError('unexpected unresolved constructor call',
2692 node: node); 2725 node: node);
2693 } 2726 }
2694 } else if (node.isConst()) { 2727 } else if (node.isConst()) {
2695 // TODO(karlklose): add type representation 2728 // TODO(karlklose): add type representation
2696 ConstantHandler handler = compiler.constantHandler; 2729 ConstantHandler handler = compiler.constantHandler;
2697 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2730 Constant constant = handler.compileNodeWithDefinitions(node, elements);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
3047 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); 3080 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator]));
3048 3081
3049 Element variable; 3082 Element variable;
3050 if (node.declaredIdentifier.asSend() !== null) { 3083 if (node.declaredIdentifier.asSend() !== null) {
3051 variable = elements[node.declaredIdentifier]; 3084 variable = elements[node.declaredIdentifier];
3052 } else { 3085 } else {
3053 assert(node.declaredIdentifier.asVariableDefinitions() !== null); 3086 assert(node.declaredIdentifier.asVariableDefinitions() !== null);
3054 VariableDefinitions variableDefinitions = node.declaredIdentifier; 3087 VariableDefinitions variableDefinitions = node.declaredIdentifier;
3055 variable = elements[variableDefinitions.definitions.nodes.head]; 3088 variable = elements[variableDefinitions.definitions.nodes.head];
3056 } 3089 }
3057 localsHandler.updateLocal(variable, pop()); 3090 HInstruction oldVariable = pop();
3091 if (variable == null) {
3092 // Do nothing.
3093 } else if (variable.isErroneous()) {
3094 generateThrowNoSuchMethod(node,
3095 getTargetName(variable, 'set '),
3096 argumentValues: <HInstruction>[oldVariable]);
3097 pop();
3098 } else {
3099 localsHandler.updateLocal(variable, oldVariable);
3100 }
3058 3101
3059 visit(node.body); 3102 visit(node.body);
3060 } 3103 }
3061 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); 3104 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
3062 } 3105 }
3063 3106
3064 visitLabel(Label node) { 3107 visitLabel(Label node) {
3065 compiler.internalError('SsaBuilder.visitLabel', node: node); 3108 compiler.internalError('SsaBuilder.visitLabel', node: node);
3066 } 3109 }
3067 3110
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 new HSubGraphBlockInformation(elseBranch.graph)); 4044 new HSubGraphBlockInformation(elseBranch.graph));
4002 4045
4003 HBasicBlock conditionStartBlock = conditionBranch.block; 4046 HBasicBlock conditionStartBlock = conditionBranch.block;
4004 conditionStartBlock.setBlockFlow(info, joinBlock); 4047 conditionStartBlock.setBlockFlow(info, joinBlock);
4005 SubGraph conditionGraph = conditionBranch.graph; 4048 SubGraph conditionGraph = conditionBranch.graph;
4006 HIf branch = conditionGraph.end.last; 4049 HIf branch = conditionGraph.end.last;
4007 assert(branch is HIf); 4050 assert(branch is HIf);
4008 branch.blockInformation = conditionStartBlock.blockFlow; 4051 branch.blockInformation = conditionStartBlock.blockFlow;
4009 } 4052 }
4010 } 4053 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698