Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index b5d0b128082b5e8944a8cda3db67fb12e656ea36..149d0ee71172d14cf1a9d0da8cbce554178b35c6 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -1964,6 +1964,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| return pop(); |
| } |
| + String getTargetName(ErroneousElement error, [String prefix]) { |
| + String targetName = error.errorMessage.arguments[0].toString(); |
|
ngeoffray
2012/09/05 11:46:45
I would put the information in the ErroneousElemen
karlklose
2012/09/05 14:53:42
Done.
|
| + if (prefix != null) { |
| + return prefix.concat(targetName); |
| + } |
| + return targetName; |
| + } |
| + |
| void generateInstanceGetterWithCompiledReceiver(Send send, |
| HInstruction receiver) { |
| assert(Elements.isInstanceSend(send, elements)); |
| @@ -2008,6 +2016,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| push(new HStatic(element)); |
| // TODO(ahe): This should be registered in codegen. |
| compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| + } else if (element != null && Element.isInvalid(element)) { |
| + // An erroneous element indicates an unresolved static getter. |
| + generateThrowNoSuchMethod(send, |
| + getTargetName(element, 'get '), |
| + const EmptyLink<Node>()); |
| } else { |
| stack.add(localsHandler.readLocal(element)); |
| } |
| @@ -2048,6 +2061,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } else if (element === null || Elements.isInstanceField(element)) { |
| HInstruction receiver = generateInstanceSendReceiver(send); |
| generateInstanceSetterWithCompiledReceiver(send, receiver, value); |
| + } else if (element != null && Element.isInvalid(element)) { |
|
ngeoffray
2012/09/05 11:46:45
This null check feels quite annoying. Could we hav
karlklose
2012/09/05 14:53:42
I renamed isInvalid to isUnresolved and added isEr
|
| + // An erroneous element indicates an unresolved static setter. |
| + generateThrowNoSuchMethod(send, |
| + getTargetName(element, 'set '), |
| + send.arguments); |
| } else { |
| stack.add(value); |
| // If the value does not already have a name, give it here. |
| @@ -2608,6 +2626,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| visitStaticSend(Send node) { |
| Selector selector = elements.getSelector(node); |
| Element element = elements[node]; |
| + if (element.isErroneous()) { |
| + generateThrowNoSuchMethod(node, getTargetName(element), node.arguments); |
| + return; |
| + } |
| if (element === compiler.assertMethod && !compiler.enableUserAssertions) { |
| stack.add(graph.addConstantNull()); |
| return; |
| @@ -2663,28 +2685,39 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| pushInvokeHelper1(helper, errorMessage); |
| } |
| + void generateThrowNoSuchMethod(Node diagnosticNode, |
| + String methodName, |
| + [Link<Node> argumentNodes, |
| + List<HInstruction> argumentValues]) { |
| + Element helper = |
| + compiler.findHelper(const SourceString('throwNoSuchMethod')); |
| + HInstruction receiver = |
| + graph.addConstantString(new DartString.empty(), diagnosticNode); |
| + DartString dartString = new DartString.literal(methodName); |
| + HInstruction name = graph.addConstantString(dartString, diagnosticNode); |
| + if (argumentValues == null) { |
| + argumentValues = <HInstruction>[]; |
| + argumentNodes.forEach((argumentNode) { |
| + visit(argumentNode); |
| + HInstruction value = pop(); |
| + argumentValues.add(value); |
| + }); |
| + } |
| + HInstruction arguments = new HLiteralList(argumentValues); |
| + add(arguments); |
| + pushInvokeHelper3(helper, receiver, name, arguments); |
| + } |
| + |
| visitNewExpression(NewExpression node) { |
| Element element = elements[node.send]; |
| if (element != null && element.isErroneous()) { |
| ErroneousElement error = element; |
| Message message = error.errorMessage; |
| if (message.kind === MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| - Element helper = |
| - compiler.findHelper(const SourceString('throwNoSuchMethod')); |
| - DartString receiverLiteral = new DartString.literal(''); |
| - HInstruction receiver = graph.addConstantString(receiverLiteral, node); |
| String constructorName = 'constructor ${message.arguments[0]}'; |
| - DartString nameLiteral = new DartString.literal(constructorName); |
| - HInstruction name = graph.addConstantString(nameLiteral, node.send); |
| - List<HInstruction> inputs = <HInstruction>[]; |
| - node.send.arguments.forEach((argumentNode) { |
| - visit(argumentNode); |
| - HInstruction value = pop(); |
| - inputs.add(value); |
| - }); |
| - HInstruction arguments = new HLiteralList(inputs); |
| - add(arguments); |
| - pushInvokeHelper3(helper, receiver, name, arguments); |
| + generateThrowNoSuchMethod(node.send, |
| + getTargetName(error, 'constructor'), |
| + node.send.arguments); |
| } else if (message.kind === MessageKind.CANNOT_RESOLVE) { |
| generateRuntimeError(node.send, message.message); |
| } else { |
| @@ -3054,7 +3087,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| variable = elements[variableDefinitions.definitions.nodes.head]; |
| } |
| - localsHandler.updateLocal(variable, pop()); |
| + HInstruction oldVariable = pop(); |
| + if (variable.isErroneous()) { |
| + generateThrowNoSuchMethod(node, |
| + getTargetName(variable, 'set '), |
| + argumentValues: <HInstruction>[oldVariable]); |
| + pop(); |
| + } else { |
| + localsHandler.updateLocal(variable, oldVariable); |
| + } |
| visit(node.body); |
| } |