Skip to content

Commit

Permalink
Merge pull request #110 from Ladicek/fix-primitive-arrays
Browse files Browse the repository at this point in the history
Fix reading from int[] and writing to long[]
  • Loading branch information
stuartwdouglas authored May 4, 2022
2 parents b85aae8 + 1370f9f commit 1048fce
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/main/java/io/quarkus/gizmo/BytecodeCreatorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ public void writeBytecode(MethodVisitor methodVisitor) {
loadResultHandle(methodVisitor, resolvedIndex, BytecodeCreatorImpl.this, "I");
switch (result.getType()) {
case "I":
methodVisitor.visitInsn(Opcodes.AALOAD);
methodVisitor.visitInsn(Opcodes.IALOAD);
break;
case "J":
methodVisitor.visitInsn(Opcodes.LALOAD);
Expand Down Expand Up @@ -642,7 +642,7 @@ public void writeBytecode(MethodVisitor methodVisitor) {
methodVisitor.visitInsn(Opcodes.IASTORE);
} else if (arrayType.equals("C")) {
methodVisitor.visitInsn(Opcodes.CASTORE);
} else if (arrayType.equals("L")) {
} else if (arrayType.equals("J")) {
methodVisitor.visitInsn(Opcodes.LASTORE);
} else if (arrayType.equals("F")) {
methodVisitor.visitInsn(Opcodes.FASTORE);
Expand Down
201 changes: 200 additions & 1 deletion src/test/java/io/quarkus/gizmo/ArrayTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,151 @@ public void testNewArray() throws Exception {
}

@Test
public void testWriteArray() throws Exception {
public void testWriteArrayBoolean() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(boolean.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load(true));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(boolean[].class, o.getClass());
boolean[] res = (boolean[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(true, res[0]);
}

@Test
public void testWriteArrayByte() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(byte.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load((byte) 42));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(byte[].class, o.getClass());
byte[] res = (byte[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42, res[0]);
}

@Test
public void testWriteArrayShort() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(short.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load((short) 42));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(short[].class, o.getClass());
short[] res = (short[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42, res[0]);
}

@Test
public void testWriteArrayInt() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(int.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load(42));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(int[].class, o.getClass());
int[] res = (int[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42, res[0]);
}

@Test
public void testWriteArrayLong() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(long.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load(42L));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(long[].class, o.getClass());
long[] res = (long[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42L, res[0]);
}

@Test
public void testWriteArrayFloat() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(float.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load(42.0F));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(float[].class, o.getClass());
float[] res = (float[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42.0F, res[0], 0.0);
}

@Test
public void testWriteArrayDouble() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(double.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load(42.0));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(double[].class, o.getClass());
double[] res = (double[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals(42.0, res[0], 0.0);
}

@Test
public void testWriteArrayChar() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
ResultHandle arrayHandle = method.newArray(char.class, 1);
method.writeArrayValue(arrayHandle, method.load(0), method.load('a'));
method.returnValue(arrayHandle);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Supplier myInterface = (Supplier) clazz.getDeclaredConstructor().newInstance();
Object o = myInterface.get();
Assert.assertEquals(char[].class, o.getClass());
char[] res = (char[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals('a', res[0], 0.0);
}

@Test
public void testWriteArrayObject() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Supplier.class).build()) {
MethodCreator method = creator.getMethodCreator("get", Object.class);
Expand All @@ -58,7 +202,44 @@ public void testWriteArray() throws Exception {
String[] res = (String[]) o;
Assert.assertEquals(1, res.length);
Assert.assertEquals("hello", res[0]);
}

@Test
public void testReadArrayBoolean() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Function.class).build()) {
MethodCreator method = creator.getMethodCreator("apply", Object.class, Object.class);
ResultHandle arrayHandle = method.checkCast(method.getMethodParam(0), boolean[].class);
ResultHandle ret = method.readArrayValue(arrayHandle, 0);
method.returnValue(ret);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Function myInterface = (Function) clazz.getDeclaredConstructor().newInstance();
boolean[] array = new boolean[1];
array[0] = true;
Object o = myInterface.apply(array);
Assert.assertEquals(Boolean.class, o.getClass());
boolean val = (Boolean) o;
Assert.assertEquals(true, val);
}

@Test
public void testReadArrayChar() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Function.class).build()) {
MethodCreator method = creator.getMethodCreator("apply", Object.class, Object.class);
ResultHandle arrayHandle = method.checkCast(method.getMethodParam(0), char[].class);
ResultHandle ret = method.readArrayValue(arrayHandle, 0);
method.returnValue(ret);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Function myInterface = (Function) clazz.getDeclaredConstructor().newInstance();
char[] array = new char[1];
array[0] = 'a';
Object o = myInterface.apply(array);
Assert.assertEquals(Character.class, o.getClass());
char val = (Character) o;
Assert.assertEquals('a', val);
}

@Test
Expand Down Expand Up @@ -135,6 +316,24 @@ public void testReadArrayShort() throws Exception {
Assert.assertEquals(26, (short) o);
}

@Test
public void testReadArrayInt() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
try (ClassCreator creator = ClassCreator.builder().classOutput(cl).className("com.MyTest").interfaces(Function.class).build()) {
MethodCreator method = creator.getMethodCreator("apply", Object.class, Object.class);
ResultHandle arrayHandle = method.checkCast(method.getMethodParam(0), int[].class);
ResultHandle ret = method.readArrayValue(arrayHandle, 0);
method.returnValue(ret);
}
Class<?> clazz = cl.loadClass("com.MyTest");
Function myInterface = (Function) clazz.getDeclaredConstructor().newInstance();
int[] array = new int[1];
array[0] = 26;
Object o = myInterface.apply(array);
Assert.assertEquals(Integer.class, o.getClass());
Assert.assertEquals(26, (int) o);
}

@Test
public void testReadArrayLong() throws Exception {
TestClassLoader cl = new TestClassLoader(getClass().getClassLoader());
Expand Down

0 comments on commit 1048fce

Please sign in to comment.