11package cz .neumimto .nts .bytecode ;
22
3+ import cz .neumimto .nts .Scope ;
4+ import cz .neumimto .nts .ScriptContext ;
35import net .bytebuddy .description .type .TypeDescription ;
46import net .bytebuddy .implementation .Implementation ;
57import net .bytebuddy .implementation .bytecode .StackManipulation ;
1214import java .lang .invoke .LambdaMetafactory ;
1315import java .lang .invoke .MethodHandles ;
1416import java .lang .invoke .MethodType ;
17+ import java .util .List ;
18+ import java .util .Map ;
1519import java .util .stream .Collectors ;
1620
1721public class InvokeDynamic implements StackManipulation {
1822
23+ private final Map <String , Variable > fnVars ;
24+ private ScriptContext scriptContext ;
25+
26+ public InvokeDynamic (ScriptContext scriptContext , Map <String , Variable > fnVars ) {
27+ this .scriptContext = scriptContext ;
28+ this .fnVars = fnVars ;
29+ }
1930
2031 @ Override
2132 public boolean isValid () {
@@ -24,24 +35,26 @@ public boolean isValid() {
2435
2536 @ Override
2637 public Size apply (MethodVisitor methodVisitor , Implementation .Context implementationContext ) {
27- // String descriptor = "(%s)Ljava/lang/Runnable;";
28- // String k = ctx.localVariables().values().stream().map(a-> new TypeDescription.ForLoadedType(a.aClass).getDescriptor()).collect(Collectors.joining());
29- // descriptor = descriptor.replaceAll("%s",ctx.thisType().getDescriptor() + k);
30- //
31- // methodVisitor.visitInvokeDynamicInsn("run",
32- // descriptor,
33- // new Handle(Opcodes.H_INVOKESTATIC,
34- // new TypeDescription.ForLoadedType(LambdaMetafactory.class).getInternalName(),
35- // "metafactory",
36- // MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, Object[].class).toMethodDescriptorString(),
37- // false),
38- // Type.VOID_TYPE,
39- // new Handle(Opcodes.H_INVOKESPECIAL,
40- // this.ctx.thisType().getInternalName(),
41- // methodName,
42- // "("+k+")V",
43- // false),
44- // Type.VOID_TYPE);
38+ String descriptor = "(%s)Ljava/lang/Runnable;" ;
39+ String k = fnVars .values ().stream ()
40+ .map (a -> new TypeDescription .ForLoadedType (a .getRuntimeType ()).getDescriptor ())
41+ .collect (Collectors .joining ());
42+ descriptor = descriptor .replaceAll ("%s" ,scriptContext .getInsnType ().getDescriptor () + k );
43+
44+ methodVisitor .visitInvokeDynamicInsn ("run" ,
45+ descriptor ,
46+ new Handle (Opcodes .H_INVOKESTATIC ,
47+ new TypeDescription .ForLoadedType (LambdaMetafactory .class ).getInternalName (),
48+ "metafactory" ,
49+ MethodType .methodType (CallSite .class , MethodHandles .Lookup .class , String .class , MethodType .class , String .class , Object [].class ).toMethodDescriptorString (),
50+ false ),
51+ Type .VOID_TYPE ,
52+ new Handle (Opcodes .H_INVOKESPECIAL ,
53+ scriptContext .getInsnType ().getInternalName (),
54+ Scope .LAMBDA_METHOD_NAME .apply (scriptContext .getScopes ().size () - 1 ),
55+ "(" +k +")V" ,
56+ false ),
57+ Type .VOID_TYPE );
4558 return null ;
4659 }
4760}
0 commit comments