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 8d6c163875223f6a40e72eb8db446ab1be043565..86d4ab7085692154482dde68e2dd4d3ea67b5dad 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -1989,6 +1989,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| return pop(); |
| } |
| + 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.
|
| + String targetName = error.targetName.slowToString(); |
| + if (prefix != null) { |
| + return prefix.concat(targetName); |
| + } |
| + return targetName; |
| + } |
| + |
| void generateInstanceGetterWithCompiledReceiver(Send send, |
| HInstruction receiver) { |
| assert(Elements.isInstanceSend(send, elements)); |
| @@ -2039,6 +2047,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.isErroneousElement(element)) { |
| + // An erroneous element indicates an unresolved static getter. |
| + generateThrowNoSuchMethod(send, |
| + getTargetName(element, 'get '), |
| + const EmptyLink<Node>()); |
| } else { |
| stack.add(localsHandler.readLocal(element)); |
| } |
| @@ -2079,6 +2092,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.isErroneousElement(element)) { |
| + // 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. |
| @@ -2638,6 +2656,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; |
| @@ -2688,28 +2710,38 @@ 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()) { |
| + if (Element.isErroneousElement(element)) { |
| 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 { |
| @@ -3079,7 +3111,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); |
| } |