@@ -43,6 +43,78 @@ public BridgeCompiler(MethodHandles.Lookup lookup, String owner, MethodType sour
4343 }
4444
4545 public Class <?> createClass ()
46+ throws IllegalAccessException {
47+ final Class <?>[] arguments = source .parameterArray ();
48+ final Class <?>[] parameters = target .getParameterTypes ();
49+ final Class <?> expected = source .returnType ();
50+ final Class <?> result = target .getReturnType ();
51+ if (arguments .length != parameters .length && !target .isVarArgs ())
52+ throw new ScriptRuntimeError ("Function argument count did not match target parameter count." );
53+ final ClassWriter writer = new ClassWriter (0 );
54+ writer .visit (Skript .JAVA_VERSION , 0x0001 | 0x1000 , location , null , "java/lang/Object" , null );
55+ final MethodVisitor visitor ;
56+ final Type [] types = new Type [arguments .length ];
57+ for (int i = 0 ; i < arguments .length ; i ++) types [i ] = Type .getType (arguments [i ]);
58+ visitor = writer .visitMethod (0x0001 | 0x0008 | 0x0040 | 0x1000 , "bridge" , Type .getMethodDescriptor (Type .getType (expected ), types ), null , null );
59+ visitor .visitCode ();
60+ final int length ;
61+ if (target .isVarArgs ()) length = parameters .length - 1 ;
62+ else length = arguments .length ;
63+ this .extractSimpleArguments (length , arguments , parameters , visitor );
64+ this .extractVarArguments (arguments , parameters , visitor , length );
65+ this .invoke (visitor );
66+ if (result == void .class ) {
67+ visitor .visitInsn (1 );
68+ visitor .visitInsn (176 );
69+ } else {
70+ this .box (visitor , result );
71+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getWrapperType (expected )));
72+ visitor .visitInsn (171 + this .instructionOffset (expected ));
73+ }
74+ final int stack ;
75+ if (target .isVarArgs ())
76+ stack = Math .max (parameters .length + 1 + this .wideIndexOffset (parameters , result ), 1 ) + 4 ;
77+ else stack = Math .max (parameters .length + 1 + this .wideIndexOffset (parameters , result ), 1 );
78+ visitor .visitMaxs (stack , arguments .length );
79+ visitor .visitEnd ();
80+ writer .visitEnd ();
81+ this .generated = lookup .defineClass (writer .toByteArray ());
82+ return generated ;
83+ }
84+
85+ private void extractVarArguments (Class <?>[] arguments , Class <?>[] parameters , MethodVisitor visitor , int length ) {
86+ if (!target .isVarArgs ()) return ;
87+ final int remaining = arguments .length - length ;
88+ final Class <?> array = parameters [parameters .length - 1 ];
89+ final Class <?> parameter = array .getComponentType ();
90+ visitor .visitIntInsn (16 , remaining );
91+ visitor .visitTypeInsn (189 , Type .getInternalName (parameter ));
92+ for (int i = 0 ; i < remaining ; i ++) {
93+ visitor .visitInsn (89 );
94+ visitor .visitIntInsn (16 , i );
95+ final Class <?> argument = arguments [i ];
96+ visitor .visitVarInsn (20 + this .instructionOffset (argument ), i );
97+ this .boxAtomic (visitor , parameter );
98+ this .conform (visitor , parameter );
99+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getUnboxingType (parameter )));
100+ this .unbox (visitor , parameter );
101+ visitor .visitInsn (83 );
102+ }
103+ }
104+
105+ private void extractSimpleArguments (int length , Class <?>[] arguments , Class <?>[] parameters , MethodVisitor visitor ) {
106+ for (int i = 0 ; i < length ; i ++) { // assume no fat arguments ?
107+ final Class <?> argument = arguments [i ];
108+ final Class <?> parameter = parameters [i ];
109+ visitor .visitVarInsn (20 + this .instructionOffset (argument ), i );
110+ this .boxAtomic (visitor , parameter );
111+ this .conform (visitor , parameter );
112+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getUnboxingType (parameter )));
113+ this .unbox (visitor , parameter );
114+ }
115+ }
116+
117+ public Class <?> createClass0 ()
46118 throws IllegalAccessException {
47119 final Class <?>[] arguments = source .parameterArray ();
48120 final Class <?>[] parameters = target .getParameterTypes ();
0 commit comments