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

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 1990 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 push(new HInvokeStatic(<HInstruction>[pop()])); 2001 push(new HInvokeStatic(<HInstruction>[pop()]));
2002 } 2002 }
2003 } 2003 }
2004 } else if (Elements.isInstanceSend(send, elements)) { 2004 } else if (Elements.isInstanceSend(send, elements)) {
2005 HInstruction receiver = generateInstanceSendReceiver(send); 2005 HInstruction receiver = generateInstanceSendReceiver(send);
2006 generateInstanceGetterWithCompiledReceiver(send, receiver); 2006 generateInstanceGetterWithCompiledReceiver(send, receiver);
2007 } else if (Elements.isStaticOrTopLevelFunction(element)) { 2007 } else if (Elements.isStaticOrTopLevelFunction(element)) {
2008 push(new HStatic(element)); 2008 push(new HStatic(element));
2009 // TODO(ahe): This should be registered in codegen. 2009 // TODO(ahe): This should be registered in codegen.
2010 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); 2010 compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
2011 } else if (element != null && Element.isInvalid(element)) {
2012 // An erroneous element indicates an unresolved static getter.
kasperl 2012/09/05 09:29:45 Introduce new helper for this? Moar code sharing f
karlklose 2012/09/05 11:10:47 Done.
2013 ErroneousElement error = element;
2014 Message message = error.errorMessage;
2015 String name = 'get ${message.arguments[0]}';
2016 generateThrowNoSuchMethod(send, name, const EmptyLink<Node>());
2011 } else { 2017 } else {
2012 stack.add(localsHandler.readLocal(element)); 2018 stack.add(localsHandler.readLocal(element));
2013 } 2019 }
2014 } 2020 }
2015 2021
2016 void generateInstanceSetterWithCompiledReceiver(Send send, 2022 void generateInstanceSetterWithCompiledReceiver(Send send,
2017 HInstruction receiver, 2023 HInstruction receiver,
2018 HInstruction value) { 2024 HInstruction value) {
2019 assert(Elements.isInstanceSend(send, elements)); 2025 assert(Elements.isInstanceSend(send, elements));
2020 Selector selector = elements.getSelector(send); 2026 Selector selector = elements.getSelector(send);
(...skipping 20 matching lines...) Expand all
2041 HStatic target = new HStatic(element); 2047 HStatic target = new HStatic(element);
2042 add(target); 2048 add(target);
2043 add(new HInvokeStatic(<HInstruction>[target, value])); 2049 add(new HInvokeStatic(<HInstruction>[target, value]));
2044 } else { 2050 } else {
2045 add(new HStaticStore(element, value)); 2051 add(new HStaticStore(element, value));
2046 } 2052 }
2047 stack.add(value); 2053 stack.add(value);
2048 } else if (element === null || Elements.isInstanceField(element)) { 2054 } else if (element === null || Elements.isInstanceField(element)) {
2049 HInstruction receiver = generateInstanceSendReceiver(send); 2055 HInstruction receiver = generateInstanceSendReceiver(send);
2050 generateInstanceSetterWithCompiledReceiver(send, receiver, value); 2056 generateInstanceSetterWithCompiledReceiver(send, receiver, value);
2057 } else if (element != null && Element.isInvalid(element)) {
2058 // An erroneous element indicates an unresolved static getter.
2059 ErroneousElement error = element;
2060 Message message = error.errorMessage;
2061 String name = 'set ${message.arguments[0]}';
2062 generateThrowNoSuchMethod(send, name, send.arguments);
2051 } else { 2063 } else {
2052 stack.add(value); 2064 stack.add(value);
2053 // If the value does not already have a name, give it here. 2065 // If the value does not already have a name, give it here.
2054 if (value.sourceElement === null) { 2066 if (value.sourceElement === null) {
2055 value.sourceElement = element; 2067 value.sourceElement = element;
2056 } 2068 }
2057 HInstruction checked = potentiallyCheckType(value, element); 2069 HInstruction checked = potentiallyCheckType(value, element);
2058 if (checked !== value) { 2070 if (checked !== value) {
2059 pop(); 2071 pop();
2060 stack.add(checked); 2072 stack.add(checked);
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 }); 2613 });
2602 2614
2603 HType elementType = computeType(constructor); 2615 HType elementType = computeType(constructor);
2604 HInstruction newInstance = new HInvokeStatic(inputs, elementType); 2616 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
2605 pushWithPosition(newInstance, node); 2617 pushWithPosition(newInstance, node);
2606 } 2618 }
2607 2619
2608 visitStaticSend(Send node) { 2620 visitStaticSend(Send node) {
2609 Selector selector = elements.getSelector(node); 2621 Selector selector = elements.getSelector(node);
2610 Element element = elements[node]; 2622 Element element = elements[node];
2623 if (element.isErroneous()) {
2624 ErroneousElement error = element;
2625 String name = error.errorMessage.arguments[0].toString();
2626 generateThrowNoSuchMethod(node, name, node.arguments);
2627 return;
2628 }
2611 if (element === compiler.assertMethod && !compiler.enableUserAssertions) { 2629 if (element === compiler.assertMethod && !compiler.enableUserAssertions) {
2612 stack.add(graph.addConstantNull()); 2630 stack.add(graph.addConstantNull());
2613 return; 2631 return;
2614 } 2632 }
2615 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR); 2633 compiler.ensure(element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR);
2616 2634
2617 if (tryInlineMethod(element, selector, node.arguments)) return; 2635 if (tryInlineMethod(element, selector, node.arguments)) return;
2618 2636
2619 HInstruction target = new HStatic(element); 2637 HInstruction target = new HStatic(element);
2620 add(target); 2638 add(target);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 compiler.internalError(reason, node: node); 2674 compiler.internalError(reason, node: node);
2657 } 2675 }
2658 2676
2659 void generateRuntimeError(Node node, String message) { 2677 void generateRuntimeError(Node node, String message) {
2660 DartString messageObject = new DartString.literal(message); 2678 DartString messageObject = new DartString.literal(message);
2661 HInstruction errorMessage = graph.addConstantString(messageObject, node); 2679 HInstruction errorMessage = graph.addConstantString(messageObject, node);
2662 Element helper = interceptors.getThrowRuntimeError(); 2680 Element helper = interceptors.getThrowRuntimeError();
2663 pushInvokeHelper1(helper, errorMessage); 2681 pushInvokeHelper1(helper, errorMessage);
2664 } 2682 }
2665 2683
2684 void generateThrowNoSuchMethod(Node diagnosticNode,
2685 String methodName,
2686 [Link<Node> argumentNodes,
2687 List<HInstruction> argumentValues]) {
2688 Element helper =
2689 compiler.findHelper(const SourceString('throwNoSuchMethod'));
2690 HInstruction receiver =
2691 graph.addConstantString(new DartString.empty(), diagnosticNode);
2692 DartString dartString = new DartString.literal(methodName);
2693 HInstruction name = graph.addConstantString(dartString, diagnosticNode);
2694 if (argumentValues == null) {
2695 argumentValues = <HInstruction>[];
2696 argumentNodes.forEach((argumentNode) {
2697 visit(argumentNode);
2698 HInstruction value = pop();
2699 argumentValues.add(value);
2700 });
2701 }
2702 HInstruction arguments = new HLiteralList(argumentValues);
2703 add(arguments);
2704 pushInvokeHelper3(helper, receiver, name, arguments);
2705 }
2706
2666 visitNewExpression(NewExpression node) { 2707 visitNewExpression(NewExpression node) {
2667 Element element = elements[node.send]; 2708 Element element = elements[node.send];
2668 if (element != null && element.isErroneous()) { 2709 if (element != null && element.isErroneous()) {
2669 ErroneousElement error = element; 2710 ErroneousElement error = element;
2670 Message message = error.errorMessage; 2711 Message message = error.errorMessage;
2671 if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { 2712 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]}'; 2713 String constructorName = 'constructor ${message.arguments[0]}';
2677 DartString nameLiteral = new DartString.literal(constructorName); 2714 generateThrowNoSuchMethod(node.send, constructorName,
2678 HInstruction name = graph.addConstantString(nameLiteral, node.send); 2715 node.send.arguments);
2679 List<HInstruction> inputs = <HInstruction>[];
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) { 2716 } else if (message.kind === MessageKind.CANNOT_RESOLVE) {
2689 generateRuntimeError(node.send, message.message); 2717 generateRuntimeError(node.send, message.message);
2690 } else { 2718 } else {
2691 compiler.internalError('unexpected unresolved constructor call', 2719 compiler.internalError('unexpected unresolved constructor call',
2692 node: node); 2720 node: node);
2693 } 2721 }
2694 } else if (node.isConst()) { 2722 } else if (node.isConst()) {
2695 // TODO(karlklose): add type representation 2723 // TODO(karlklose): add type representation
2696 ConstantHandler handler = compiler.constantHandler; 2724 ConstantHandler handler = compiler.constantHandler;
2697 Constant constant = handler.compileNodeWithDefinitions(node, elements); 2725 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])); 3075 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator]));
3048 3076
3049 Element variable; 3077 Element variable;
3050 if (node.declaredIdentifier.asSend() !== null) { 3078 if (node.declaredIdentifier.asSend() !== null) {
3051 variable = elements[node.declaredIdentifier]; 3079 variable = elements[node.declaredIdentifier];
3052 } else { 3080 } else {
3053 assert(node.declaredIdentifier.asVariableDefinitions() !== null); 3081 assert(node.declaredIdentifier.asVariableDefinitions() !== null);
3054 VariableDefinitions variableDefinitions = node.declaredIdentifier; 3082 VariableDefinitions variableDefinitions = node.declaredIdentifier;
3055 variable = elements[variableDefinitions.definitions.nodes.head]; 3083 variable = elements[variableDefinitions.definitions.nodes.head];
3056 } 3084 }
3057 localsHandler.updateLocal(variable, pop()); 3085 HInstruction oldVariable = pop();
3086 if (variable == null) {
3087 } else if (variable.isErroneous()) {
kasperl 2012/09/05 09:29:45 Add a comment in the empty braces to make it clear
karlklose 2012/09/05 11:10:47 Done.
3088 ErroneousElement error = variable;
3089 String name = 'setter ${error.errorMessage.arguments[0]}';
3090 generateThrowNoSuchMethod(node, name,
3091 argumentValues: <HInstruction>[oldVariable]);
3092 pop();
3093 } else {
3094 localsHandler.updateLocal(variable, oldVariable);
3095 }
3058 3096
3059 visit(node.body); 3097 visit(node.body);
3060 } 3098 }
3061 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody); 3099 handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
3062 } 3100 }
3063 3101
3064 visitLabel(Label node) { 3102 visitLabel(Label node) {
3065 compiler.internalError('SsaBuilder.visitLabel', node: node); 3103 compiler.internalError('SsaBuilder.visitLabel', node: node);
3066 } 3104 }
3067 3105
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 new HSubGraphBlockInformation(elseBranch.graph)); 4039 new HSubGraphBlockInformation(elseBranch.graph));
4002 4040
4003 HBasicBlock conditionStartBlock = conditionBranch.block; 4041 HBasicBlock conditionStartBlock = conditionBranch.block;
4004 conditionStartBlock.setBlockFlow(info, joinBlock); 4042 conditionStartBlock.setBlockFlow(info, joinBlock);
4005 SubGraph conditionGraph = conditionBranch.graph; 4043 SubGraph conditionGraph = conditionBranch.graph;
4006 HIf branch = conditionGraph.end.last; 4044 HIf branch = conditionGraph.end.last;
4007 assert(branch is HIf); 4045 assert(branch is HIf);
4008 branch.blockInformation = conditionStartBlock.blockFlow; 4046 branch.blockInformation = conditionStartBlock.blockFlow;
4009 } 4047 }
4010 } 4048 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698