Skip to content

Commit aa3ac58

Browse files
committed
anonymous fn 2
1 parent 307f05f commit aa3ac58

File tree

5 files changed

+91
-66
lines changed

5 files changed

+91
-66
lines changed

src/main/java/cz/neumimto/nts/NTScript.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.lang.annotation.Annotation;
3333
import java.lang.reflect.Method;
3434
import java.lang.reflect.Parameter;
35+
import java.lang.reflect.Type;
3536
import java.nio.file.Files;
3637
import java.nio.file.Path;
3738
import java.util.*;
@@ -148,7 +149,15 @@ public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVis
148149
for (int i = scopes.size()-1; i > 0; i--) {
149150
Scope scope = scopes.get(i);
150151

151-
bb = bb.defineMethod(Scope.LAMBDA_METHOD_NAME.apply(i), void.class, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC)
152+
List<TypeDescription> params = new ArrayList<>();
153+
TypeDescription typeDefinitions = bb.toTypeDescription();
154+
params.add(typeDefinitions);
155+
for (Variable value : scope.variables.values()) {
156+
params.add(new TypeDescription.ForLoadedType(value.getRuntimeType()));
157+
}
158+
159+
bb = bb.defineMethod(Scope.LAMBDA_METHOD_NAME.apply(i - 1), void.class, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC)
160+
.withParameters(params)
152161
.intercept(new Implementation() {
153162
@Override
154163
public ByteCodeAppender appender(Target implementationTarget) {

src/main/java/cz/neumimto/nts/ScriptContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ protected MethodVariableAccess getRalReturnType(ntsParser.Assignment_valuesConte
101101
return MethodVariableAccess.INTEGER;
102102
} else if (rval.type_comparison() != null) {
103103
return MethodVariableAccess.INTEGER;
104+
} else if (rval.variable_reference() != null) {
105+
return MethodVariableAccess.of(new TypeDescription.ForLoadedType(currentScope().variables.get(rval.getText()).getRuntimeType()));
104106
}
105107
throw new RuntimeException("Unknown type " + rval.getText());
106108
}

src/main/java/cz/neumimto/nts/bytecode/InvokeDynamic.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
import net.bytebuddy.description.type.TypeDescription;
66
import net.bytebuddy.implementation.Implementation;
77
import net.bytebuddy.implementation.bytecode.StackManipulation;
8+
import net.bytebuddy.implementation.bytecode.StackSize;
89
import net.bytebuddy.jar.asm.Handle;
910
import net.bytebuddy.jar.asm.MethodVisitor;
1011
import net.bytebuddy.jar.asm.Opcodes;
1112
import net.bytebuddy.jar.asm.Type;
1213

13-
import java.lang.invoke.CallSite;
14-
import java.lang.invoke.LambdaMetafactory;
15-
import java.lang.invoke.MethodHandles;
16-
import java.lang.invoke.MethodType;
14+
import java.lang.invoke.*;
15+
import java.lang.reflect.Method;
1716
import java.util.List;
1817
import java.util.Map;
1918
import java.util.stream.Collectors;
@@ -23,6 +22,15 @@ public class InvokeDynamic implements StackManipulation {
2322
private final Map<String, Variable> fnVars;
2423
private ScriptContext scriptContext;
2524

25+
private static Method metaFactory;
26+
static {
27+
try {
28+
metaFactory = LambdaMetafactory.class.getDeclaredMethod("metafactory", MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
29+
} catch (NoSuchMethodException e) {
30+
e.printStackTrace();
31+
}
32+
}
33+
2634
public InvokeDynamic(ScriptContext scriptContext, Map<String, Variable> fnVars) {
2735
this.scriptContext = scriptContext;
2836
this.fnVars = fnVars;
@@ -41,20 +49,31 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementa
4149
.collect(Collectors.joining());
4250
descriptor = descriptor.replaceAll("%s",scriptContext.getInsnType().getDescriptor() + k);
4351

44-
methodVisitor.visitInvokeDynamicInsn("run",
52+
53+
54+
// methodVisitor.visitInvokeDynamicInsn("run",
55+
// "(Lcz/neumimto/nts/DecompileTest;IZ)Ljava/lang/Runnable;",
56+
// new Handle(Opcodes.H_INVOKESTATIC, "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;", false),
57+
// Type.getType("()V"),
58+
// new Handle(Opcodes.H_INVOKEVIRTUAL, "cz/neumimto/nts/DecompileTest", "lambda$a$0", "(IZ)V", false),
59+
// Type.getType("()V"));
60+
//
61+
62+
63+
64+
methodVisitor.visitInvokeDynamicInsn("run",
4565
descriptor,
46-
new Handle(Opcodes.H_INVOKESTATIC,
47-
new TypeDescription.ForLoadedType(LambdaMetafactory.class).getInternalName(),
66+
new Handle(Opcodes.H_INVOKESTATIC, new TypeDescription.ForLoadedType(LambdaMetafactory.class).getInternalName(),
4867
"metafactory",
49-
MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, Object[].class).toMethodDescriptorString(),
68+
Type.getMethodDescriptor(metaFactory),
5069
false),
51-
Type.VOID_TYPE,
52-
new Handle(Opcodes.H_INVOKESPECIAL,
70+
Type.getType("()V"),
71+
new Handle(Opcodes.H_INVOKEVIRTUAL,
5372
scriptContext.getInsnType().getInternalName(),
54-
Scope.LAMBDA_METHOD_NAME.apply(scriptContext.getScopes().size() - 1),
73+
Scope.LAMBDA_METHOD_NAME.apply(scriptContext.getScopes().size() - 2),
5574
"("+k+")V",
5675
false),
57-
Type.VOID_TYPE);
58-
return null;
76+
Type.getType("()V"));
77+
return new StackManipulation.Size(1, 1);
5978
}
6079
}

src/test/java/cz/neumimto/nts/DecompileTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,15 @@ public Tests.Result a() {
1313
// boolean b = false;
1414
// boolean a = true;
1515
int ldc = 70000;
16-
int b = 55000;
1716
String o = ";";
1817

19-
boolean c = ldc < 70000;
2018

2119
Runnable r = () -> {
2220
int w = ldc;
23-
boolean a =c;
2421
A.a(null,null);
2522
String k = "inside";
2623
};
2724
String w = "after";
28-
int k = 0;
29-
MP.mp(r);
3025

3126
// int i = (int) (1 * Math.random());
3227
// int b = 30;

src/test/java/cz/neumimto/nts/Tests.java

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,54 @@ public Result test(){
2020
@org.junit.jupiter.api.Test
2121
public void test() throws Exception {
2222
String k = """
23-
@text = "test"
24-
@bool_t = t
25-
@bool_f = false
23+
# @text = "test"
24+
# @bool_t = t
25+
# @bool_f = false
2626
@int = 10000
2727
28-
#C O M M E N T
29-
30-
@param = call{string=@text, func=method{int=50}}
31-
32-
IF test{int= @int, string=call{string=@text}}
33-
@int2 = 5000
34-
END
35-
36-
@text="re-assigment"
37-
print{val=@text}
38-
39-
IF @bool_f
40-
@int3=700000
41-
END
42-
43-
@x = list{size=3}
44-
FOREACH @entity IN @x
45-
print{val=@entity}
46-
END
47-
48-
print{val="POP NEXT"}
49-
list{size=50}
50-
51-
FOREACH @entity IN list{size=5}
52-
print{val=@entity}
53-
END
54-
55-
print{val="XXXX"}
56-
57-
FOREACH @entity IN @x
58-
IF True
59-
print{val="CCC"}
60-
END
61-
END
62-
63-
IF @int <= 70000
64-
print{val="@int <= 70000"}
65-
END
28+
# #C O M M E N T
29+
#
30+
# @param = call{string=@text, func=method{int=50}}
31+
#
32+
# IF test{int= @int, string=call{string=@text}}
33+
# @int2 = 5000
34+
# END
35+
#
36+
# @text="re-assigment"
37+
# print{val=@text}
38+
#
39+
# IF @bool_f
40+
# @int3=700000
41+
# END
42+
#
43+
# @x = list{size=3}
44+
# FOREACH @entity IN @x
45+
# print{val=@entity}
46+
# END
47+
#
48+
# print{val="POP NEXT"}
49+
# list{size=50}
50+
#
51+
# FOREACH @entity IN list{size=5}
52+
# print{val=@entity}
53+
# END
54+
#
55+
# print{val="XXXX"}
56+
#
57+
# FOREACH @entity IN @x
58+
# IF True
59+
# print{val="CCC"}
60+
# END
61+
# END
62+
#
63+
# IF @int <= 70000
64+
# print{val="@int <= 70000"}
65+
# END
6666
6767
@lesser = @int <= 70000
6868
6969
@function = fn @int @lesser
70-
print{val="FN"}
70+
@k = @int
7171
END
7272
7373
@@ -88,12 +88,12 @@ public void test() throws Exception {
8888
Class aClass = script.parseScript(k);
8989
Object o = aClass.newInstance();
9090
try {
91-
o.getClass().getDeclaredField("A").set(o, new A());
92-
o.getClass().getDeclaredField("B").set(o, new B());
93-
o.getClass().getDeclaredField("C").set(o, new C());
94-
o.getClass().getDeclaredField("L").set(o, new L());
91+
// o.getClass().getDeclaredField("A").set(o, new A());
92+
// o.getClass().getDeclaredField("B").set(o, new B());
93+
// o.getClass().getDeclaredField("C").set(o, new C());
94+
// o.getClass().getDeclaredField("L").set(o, new L());
9595
o.getClass().getDeclaredField("P").set(o, new P());
96-
o.getClass().getDeclaredMethod("test").invoke(o);
96+
// o.getClass().getDeclaredMethod("test").invoke(o);
9797
} catch (Throwable t) {
9898
t.printStackTrace();
9999
}

0 commit comments

Comments
 (0)