Missing native methods are reported through diagnostics. Better

rendering of problem stack trace.
This commit is contained in:
Alexey Andreev 2015-01-16 18:36:11 +04:00
parent 9154f4eff9
commit d55bd862d0
2 changed files with 47 additions and 4 deletions

View File

@ -59,7 +59,7 @@ public final class TeaVMProblemRenderer {
if (location == null) {
return;
}
sb.append("\n at ");
sb.append("\n at ");
renderCallLocation(location.getMethod(), location.getSourceLocation(), sb);
if (location.getMethod() != null) {
CallGraphNode node = cg.getNode(location.getMethod());
@ -69,7 +69,7 @@ public final class TeaVMProblemRenderer {
break;
}
CallSite callSite = callSites.next();
sb.append("\n at ");
sb.append("\n at ");
renderCallLocation(callSite.getCaller().getMethod(), callSite.getLocation(), sb);
node = callSite.getCaller();
}
@ -78,11 +78,10 @@ public final class TeaVMProblemRenderer {
private static void renderCallLocation(MethodReference method, InstructionLocation location, StringBuilder sb) {
if (method != null) {
sb.append(method);
sb.append(method.getClassName() + "." + method.getName());
} else {
sb.append("unknown method");
}
sb.append(' ');
if (location != null) {
sb.append("(");
String fileName = location.getFileName();

View File

@ -26,9 +26,12 @@ import org.teavm.diagnostics.AccumulationDiagnostics;
import org.teavm.diagnostics.ProblemProvider;
import org.teavm.javascript.*;
import org.teavm.javascript.ast.ClassNode;
import org.teavm.javascript.ni.GeneratedBy;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.InjectedBy;
import org.teavm.javascript.ni.Injector;
import org.teavm.model.*;
import org.teavm.model.instructions.*;
import org.teavm.model.util.*;
import org.teavm.optimization.*;
import org.teavm.vm.spi.RendererListener;
@ -537,6 +540,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
ClassHolder cls = classes.get(className);
for (MethodHolder method : cls.getMethods()) {
processMethod(method);
preprocessNativeMethod(method);
if (bytecodeLogging) {
logMethodBytecode(bytecodeLogger, method);
}
@ -550,6 +554,46 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
return classNodes;
}
private void preprocessNativeMethod(MethodHolder method) {
if (!method.getModifiers().contains(ElementModifier.NATIVE) ||
methodGenerators.get(method.getReference()) != null ||
methodInjectors.get(method.getReference()) != null ||
method.getAnnotations().get(GeneratedBy.class.getName()) != null ||
method.getAnnotations().get(InjectedBy.class.getName()) != null) {
return;
}
method.getModifiers().remove(ElementModifier.NATIVE);
Program program = new Program();
method.setProgram(program);
BasicBlock block = program.createBasicBlock();
Variable exceptionVar = program.createVariable();
ConstructInstruction newExceptionInsn = new ConstructInstruction();
newExceptionInsn.setType(NoSuchMethodError.class.getName());
newExceptionInsn.setReceiver(exceptionVar);
block.getInstructions().add(newExceptionInsn);
Variable constVar = program.createVariable();
StringConstantInstruction constInsn = new StringConstantInstruction();
constInsn.setConstant("Native method implementation not found: " + method.getReference());
constInsn.setReceiver(constVar);
block.getInstructions().add(constInsn);
InvokeInstruction initExceptionInsn = new InvokeInstruction();
initExceptionInsn.setInstance(exceptionVar);
initExceptionInsn.setMethod(new MethodReference(NoSuchMethodError.class, "<init>", String.class, void.class));
initExceptionInsn.setType(InvocationType.SPECIAL);
initExceptionInsn.getArguments().add(constVar);
block.getInstructions().add(initExceptionInsn);
RaiseInstruction raiseInsn = new RaiseInstruction();
raiseInsn.setException(exceptionVar);
block.getInstructions().add(raiseInsn);
diagnostics.error(new CallLocation(method.getReference()), "Native method {{m0}} has no implementation",
method.getReference());
}
private void processMethod(MethodHolder method) {
if (method.getProgram() == null) {
return;