Sfoglia il codice sorgente

fix: CGAdapter: passing long arguments

Mariusz Sieroń 6 anni fa
parent
commit
d61660b4df

+ 10 - 2
assira/src/main/java/net/ranides/assira/reflection/impl/CGAdapter.java

@@ -287,10 +287,14 @@ public class CGAdapter {
             m.push(oargs.size());
             m.newObject(IClass.typeinfo(Object[].class));
 
+            int offset = 1;
+
             for (int i = 0, n = iargs.size(); i < n; i++) {
                 m.dup();
                 m.push(i);
-                m.load(iargs.get(i), i + 1);
+                m.load(iargs.get(i), offset);
+                offset += AsmSupport.sizeof(iargs.get(i));
+
                 if(iargs.get(i).annotation(Meta.Adapter.class).isPresent()) {
                     m.invokeVirtual(M_THAT);
                 }
@@ -303,8 +307,12 @@ public class CGAdapter {
         }
 
         private void invokeDirect() {
+            int offset = 1;
+
             for(int i=0, n=iargs.size(); i<n; i++) {
-                m.load(iargs.get(i), i+1);
+                m.load(iargs.get(i), offset);
+                offset += AsmSupport.sizeof(iargs.get(i));
+
                 if(iargs.get(i).annotation(Meta.Adapter.class).isPresent()) {
                     m.invokeVirtual(M_THAT);
                 }

+ 11 - 0
assira/src/test/java/net/ranides/assira/reflection/AdapterFactoryTest.java

@@ -13,6 +13,8 @@ import net.ranides.assira.reflection.adapter.model2.Image2error;
 import net.ranides.assira.reflection.adapter.model2.Screen2;
 import net.ranides.assira.reflection.adapter.model3.Image3;
 import net.ranides.assira.reflection.adapter.model3.Screen3;
+import net.ranides.assira.reflection.adapter.example.LongInterface;
+import net.ranides.assira.reflection.adapter.example.LongMock;
 import org.junit.Test;
 
 import java.io.IOException;
@@ -177,5 +179,14 @@ public class AdapterFactoryTest {
         assertEquals("Adapter{Internal{168:72} => IRecord2}", target2.toString());
     }
 
+    @Test
+    public void testUnsafe() {
+        LongMock mock = new LongMock();
+        LongInterface adapter = AdapterFactory.getSystem().cast(IClass.typeinfo(LongInterface.class), mock);
+
+        adapter.putNumbers("name", 1200L, "-", -5L);
+        assertEquals(33L, adapter.parseMe("33"));
 
+        assertEquals(Arrays.asList("putNumbers name:1200:-:-5", "parseMe 33"), mock.calls);
+    }
 }

+ 13 - 0
assira/src/test/java/net/ranides/assira/reflection/adapter/example/LongInterface.java

@@ -0,0 +1,13 @@
+package net.ranides.assira.reflection.adapter.example;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+public interface LongInterface {
+
+    void putNumbers(Object a, long b, String c, long d);
+
+    long parseMe(String arg);
+
+}

+ 20 - 0
assira/src/test/java/net/ranides/assira/reflection/adapter/example/LongMock.java

@@ -0,0 +1,20 @@
+package net.ranides.assira.reflection.adapter.example;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LongMock {
+
+    public final List<String> calls = new ArrayList<>();
+
+    public void putNumbers(Object a, long b, String c, long d) {
+        calls.add("putNumbers " + a + ":" + b + ":" + c + ":" + d);
+    }
+
+    public long parseMe(String arg) {
+        calls.add("parseMe " + arg);
+        return Long.parseLong(arg);
+    }
+
+}