Archie Cobbs wrote:
> public class Bar {
> public static void main(String[] args) {
> new soot.jimple.internal.JimpleLocalBox(null).setValue(null);
> }
> }
>
> I get this crash:
>
> assertion "_svmf_is_assignable_from (env, instance->vtable->type, _svmf_cast_type_class (method->class_info))" failed: file "instructions_preparation_direct_threaded.c", line 17953
The problem seems to be this... the soot-1.2.4 classes are compiled
with a Java compiler (I don't know which one) that uses INVOKEVIRTUAL
when calling a method M in a subclass B that extends an abstract
class A that implements an interface I, where M is not implemented in
A (and therefore abstract in A) but is implemented in B.
Above, A = AbstractValueBox, B = JimpleLocalBox, I = ValueBox, and
M = canContainValue(). The code for JimpleLocalBox.setValue() invokes
the method "AbstractValueBox.canContainValue()" using INVOKEVIRTUAL.
The problem with SableVM is that it calls _svmf_resolve_CONSTANT_Methodref()
to resolve the INVOKEVIRUTAL method reference, but it's possible for
_svmf_resolve_CONSTANT_Methodref() to return an interface method. That's
what happens in the above example.
But the code for PREPARE_INVOKEVIRTUAL does not handle that; it expects
a non-interface method and so when the method_id is some huge value we
get a crash.
I'm not sure how to fix this.. the code for INVOKEINTERFACE calls
_svmf_resolve_CONSTANT_InterfaceMethodref() to resolve the interface
method, but it seems redundant now. Or perhaps INVOKEVIRTUAL needs to
check if the returned method is an interface method and act accordingly.
-Archie
__________________________________________________________________________
Archie Cobbs * Packet Design * http://www.packetdesign.com
|