From 07c5c3a820c29a3c9497eb096faaf3db993bdebb Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 25 Aug 2017 18:22:32 +0300 Subject: [PATCH 1/5] Fix asm int to boolean conversion --- .../java/jnr/ffi/provider/jffi/NumberUtil.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java index 3ca02c51c..f212c02c2 100644 --- a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java +++ b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java @@ -20,6 +20,7 @@ import jnr.ffi.NativeType; import jnr.ffi.provider.SigType; +import org.objectweb.asm.Label; public final class NumberUtil { private NumberUtil() {} @@ -158,9 +159,18 @@ public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) { mv.i2c(); } else if (boolean.class == to) { - // Ensure only 0x0 and 0x1 values are used for boolean + /* Equivalent to + return resilt == 0 ? true : false; + */ + Label zero = new Label(); + Label ret = new Label(); + mv.iconst_0(); + mv.if_icmpeq(zero); mv.iconst_1(); - mv.iand(); + mv.go_to(ret); + mv.label(zero); + mv.iconst_0(); + mv.label(ret); } } } From c5a2104c2b308ce41ccba0ab6ba583b77aba75df Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 25 Aug 2017 19:03:22 +0300 Subject: [PATCH 2/5] Add test for LongLong to boolean convertion --- src/test/java/jnr/ffi/NumberTest.java | 28 +++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/test/java/jnr/ffi/NumberTest.java b/src/test/java/jnr/ffi/NumberTest.java index 10f1c506f..48ff2d93e 100644 --- a/src/test/java/jnr/ffi/NumberTest.java +++ b/src/test/java/jnr/ffi/NumberTest.java @@ -18,16 +18,16 @@ package jnr.ffi; +import jnr.ffi.annotations.LongLong; +import jnr.ffi.types.int32_t; +import jnr.ffi.types.pid_t; +import jnr.ffi.types.u_int32_t; +import org.junit.*; + import java.util.Random; -import jnr.ffi.annotations.LongLong; -import jnr.ffi.types.*; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * @@ -35,6 +35,8 @@ */ public class NumberTest { + public static final long LONG_WITH_ONLY_SECOND_BYTE_POSITIVE = 0xFF00000000L; + public NumberTest() { } @@ -70,6 +72,7 @@ public static interface TestLib { public static interface TestBoolean { public boolean ret_int32_t(int l); + public @LongLong boolean ret_int64_t(@LongLong long l); } static TestBoolean testboolean; @@ -357,4 +360,13 @@ public long n(long i1, long i2) { assertEquals(true, testboolean.ret_int32_t(1)); assertEquals(true, testboolean.ret_int32_t(2)); } + + @Test public void testBooleanFromLong() throws Exception { + assertEquals(false, testboolean.ret_int64_t(0)); + assertEquals(true, testboolean.ret_int64_t(-1)); + assertEquals(true, testboolean.ret_int64_t(-5)); + assertEquals(true, testboolean.ret_int64_t(1)); + assertEquals(true, testboolean.ret_int64_t(2)); + assertEquals(true, testboolean.ret_int64_t(LONG_WITH_ONLY_SECOND_BYTE_POSITIVE)); + } } From 3039a593af291c41a0ba129543039ed0a8bf4d75 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 25 Aug 2017 19:06:37 +0300 Subject: [PATCH 3/5] Fix LongLong to boolean conversion If LongLong is converted to boolean, result must be true when the value is greater than 0x1_00_00_00_00 --- .../jnr/ffi/provider/jffi/NumberUtil.java | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java index f212c02c2..c94e9f2cb 100644 --- a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java +++ b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java @@ -145,32 +145,40 @@ public static void widen(SkinnyMethodAdapter mv, Class from, Class to, NativeTyp public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) { if (!from.equals(to)) { if (byte.class == to || short.class == to || char.class == to || int.class == to || boolean.class == to) { - if (long.class == from) { - mv.l2i(); - } + if (boolean.class == to) { + if (long.class == from) { + mv.lconst_0(); + mv.lcmp(); + + } else { + /* Equivalent to + return result == 0 ? true : false; + */ + Label zero = new Label(); + Label ret = new Label(); + mv.iconst_0(); + mv.if_icmpeq(zero); + mv.iconst_1(); + mv.go_to(ret); + mv.label(zero); + mv.iconst_0(); + mv.label(ret); + } + } else { + if (long.class == from) { + mv.l2i(); + } - if (byte.class == to) { - mv.i2b(); - - } else if (short.class == to) { - mv.i2s(); - - } else if (char.class == to) { - mv.i2c(); - - } else if (boolean.class == to) { - /* Equivalent to - return resilt == 0 ? true : false; - */ - Label zero = new Label(); - Label ret = new Label(); - mv.iconst_0(); - mv.if_icmpeq(zero); - mv.iconst_1(); - mv.go_to(ret); - mv.label(zero); - mv.iconst_0(); - mv.label(ret); + if (byte.class == to) { + mv.i2b(); + + } else if (short.class == to) { + mv.i2s(); + + } else if (char.class == to) { + mv.i2c(); + + } } } } From 6a3aa2189cb9c95b2611b3ac5a782d650210ba1e Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 25 Aug 2017 19:19:49 +0300 Subject: [PATCH 4/5] Fix LongLong to boolean conversion for ReflectionLibraryLoader --- src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java b/src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java index 3a04907b3..c64135185 100644 --- a/src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java +++ b/src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java @@ -506,6 +506,9 @@ public final Object invoke(Runtime runtime, Function function, HeapInvocationBuf static class BooleanInvoker extends BaseInvoker { static FunctionInvoker INSTANCE = new BooleanInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { + if (function.getReturnType().size() == 8) { + return invoker.invokeLong(function, buffer) != 0; + } return invoker.invokeInt(function, buffer) != 0; } } From 74246ab63e0f8d1a9623a9e9956acca08b621871 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 25 Aug 2017 19:23:37 +0300 Subject: [PATCH 5/5] Fix typo in test class --- src/test/java/jnr/ffi/NumberTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/jnr/ffi/NumberTest.java b/src/test/java/jnr/ffi/NumberTest.java index 48ff2d93e..353ad9bfe 100644 --- a/src/test/java/jnr/ffi/NumberTest.java +++ b/src/test/java/jnr/ffi/NumberTest.java @@ -35,7 +35,7 @@ */ public class NumberTest { - public static final long LONG_WITH_ONLY_SECOND_BYTE_POSITIVE = 0xFF00000000L; + public static final long LONG_WITH_ONLY_THIRD_WORD_NOT_ZERO = 0xFF00000000L; public NumberTest() { } @@ -367,6 +367,6 @@ public long n(long i1, long i2) { assertEquals(true, testboolean.ret_int64_t(-5)); assertEquals(true, testboolean.ret_int64_t(1)); assertEquals(true, testboolean.ret_int64_t(2)); - assertEquals(true, testboolean.ret_int64_t(LONG_WITH_ONLY_SECOND_BYTE_POSITIVE)); + assertEquals(true, testboolean.ret_int64_t(LONG_WITH_ONLY_THIRD_WORD_NOT_ZERO)); } }