[Soot-list] invokedynamic/lambda support

Brian Alliet balliet at grammatech.com
Tue Nov 15 15:29:25 EST 2016


I've been having some trouble getting Soot to process any file 
containing lambdas. Even the most trivial example:

public class Lambda {
// intentionally avoiding any external dependencies on java.util.function
     @FunctionalInterface
     public interface IntPredicate { public boolean test(int value); }
     public static boolean even(int x) {
         return ((IntPredicate) (y -> y  % 2 == 0)).test(x);
     }
};

fails with:

soot.SootMethodRefImpl$ClassResolutionFailedException: Class 
soot.dummy.InvokeDynamic doesn't have method test([]) : 
Lambda$IntPredicate; failed to resolve in superclasses and interfaces
Looking in soot.dummy.InvokeDynamic which has methods []

I managed to hack around this by doing:

>                             SootMethod dummy = new SootMethod(insn.name,
>                                     parameterTypes,
>                                     returnType,
>                                     soot.Modifier.ABSTRACT | 
> soot.Modifier.STATIC);
> if(!bclass.declaresMethod(dummy.getSubSignature()))
>                                 bclass.addMethod(dummy);


In AsmMethodSource's convertInvokeDynamicInsn (bclass is 
SootClass.INVOKEDYNAMIC_DUMMY_CLASS here). This actually allows it to 
mostly succeed, however I realize just randomly adding abstract methods 
to soot.dummy.InvokeDynamic is probably wrong and certainly won't get me 
the right semantics.  -allow-phantom-refs also seems to push the example 
though (although I get the impression that may have other bad side effects).

Is this expected to work? Am I doing something wrong?

Additionally, the Jasmin backend seems to choke on the invokedynamic 
instructions:

Jasmin:21: Warning - Syntax error.
     invokedynamic "test" ()LLambda$IntPredicate; 
java/lang/invoke/LambdaMetafactory/metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;((Ljava/lang/Class;)class\blank"(I)Z",(Ljava/lang/invoke/MethodHandle;)handle:\

Using -asm-backend, seems to work though.

Thanks for any help,

-Brian



More information about the Soot-list mailing list