# HG changeset patch # User Carnë Draug # Date 1429572772 -3600 # Node ID 8261c4a112507a3dca3659c4bc626e12d96a3e71 # Parent 81fcf4aa9e03f0f250c87bf9275de0db40a5b867 Convert octave integer scalars into closest java type (bug #44882) * libinterp/octave-value/ov-java.cc (unbox): when calling a java method, octave core types should be converted automatically into equivalent java types. In the case of integers, we must pick the closest one but at the moment all were being converted to Integer (int32_t). This fixes it, even if it meas to lose data (as is the case in some of the added tests). Also reduce some code duplication by using macros since the code is similar to the code for float and doubles. diff -r 81fcf4aa9e03 -r 8261c4a11250 libinterp/octave-value/ov-java.cc --- a/libinterp/octave-value/ov-java.cc Mon Apr 20 17:40:39 2015 +0100 +++ b/libinterp/octave-value/ov-java.cc Tue Apr 21 00:32:52 2015 +0100 @@ -1309,44 +1309,32 @@ #undef IF_UNBOX_PRIMITIVE_ARRAY } - else if (val.is_real_scalar ()) + else if (val.is_real_scalar () || val.is_bool_scalar ()) { - if (val.is_double_type ()) - { - double dval = val.double_value (); - jclass_ref dcls (jni_env, jni_env->FindClass ("java/lang/Double")); - jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;"); - jmethodID mid = jni_env->GetMethodID (dcls, "", "(D)V"); - jcls = reinterpret_cast (jni_env->GetStaticObjectField (dcls, fid)); - jobj = jni_env->NewObject (dcls, mid, dval); - } - else if (val.is_bool_type ()) - { - bool bval = val.bool_value (); - jclass_ref bcls (jni_env, jni_env->FindClass ("java/lang/Boolean")); - jfieldID fid = jni_env->GetStaticFieldID (bcls, "TYPE", "Ljava/lang/Class;"); - jmethodID mid = jni_env->GetMethodID (bcls, "", "(Z)V"); - jcls = reinterpret_cast (jni_env->GetStaticObjectField (bcls, fid)); - jobj = jni_env->NewObject (bcls, mid, bval); - } - else - { - float fval = val.float_scalar_value (); - jclass_ref fcls (jni_env, jni_env->FindClass ("java/lang/Float")); - jfieldID fid = jni_env->GetStaticFieldID (fcls, "TYPE", "Ljava/lang/Class;"); - jmethodID mid = jni_env->GetMethodID (fcls, "", "(F)V"); - jcls = reinterpret_cast (jni_env->GetStaticObjectField (fcls, fid)); - jobj = jni_env->NewObject (fcls, mid, fval); - } - } - else if (val.is_integer_type () && val.is_scalar_type ()) - { - int32_t ival = val.int32_scalar_value (); - jclass_ref icls (jni_env, jni_env->FindClass ("java/lang/Integer")); - jfieldID fid = jni_env->GetStaticFieldID (icls, "TYPE", "Ljava/lang/Class;"); - jmethodID mid = jni_env->GetMethodID (icls, "", "(I)V"); - jcls = reinterpret_cast (jni_env->GetStaticObjectField (icls, fid)); - jobj = jni_env->NewObject (icls, mid, ival); +#define IF_UNBOX_PRIMITIVE_SCALAR(CHECK_TYPE, OCTAVE_TYPE, METHOD_TYPE, JAVA_TYPE, JAVA_CON) \ + if (val.is_ ## CHECK_TYPE ## _type ()) \ + { \ + const OCTAVE_TYPE ov = val.METHOD_TYPE ## _value (); \ + jclass_ref dcls (jni_env, jni_env->FindClass (JAVA_TYPE)); \ + const jfieldID fid = jni_env->GetStaticFieldID (dcls, "TYPE", "Ljava/lang/Class;"); \ + const jmethodID mid = jni_env->GetMethodID (dcls, "", JAVA_CON); \ + jcls = reinterpret_cast (jni_env->GetStaticObjectField (dcls, fid)); \ + jobj = jni_env->NewObject (dcls, mid, ov); \ + } + + IF_UNBOX_PRIMITIVE_SCALAR(double, double, double, "java/lang/Double", "(D)V") + else IF_UNBOX_PRIMITIVE_SCALAR(float, float, float, "java/lang/Float", "(F)V") + else IF_UNBOX_PRIMITIVE_SCALAR(bool, bool, bool, "java/lang/Boolean", "(Z)V") + else IF_UNBOX_PRIMITIVE_SCALAR(int8, int8_t, int8_scalar, "java/lang/Byte", "(B)V") + else IF_UNBOX_PRIMITIVE_SCALAR(uint8, uint8_t, uint8_scalar, "java/lang/Byte", "(B)V") + else IF_UNBOX_PRIMITIVE_SCALAR(int16, int16_t, int16_scalar, "java/lang/Short", "(S)V") + else IF_UNBOX_PRIMITIVE_SCALAR(uint16, uint16_t, uint16_scalar, "java/lang/Short", "(S)V") + else IF_UNBOX_PRIMITIVE_SCALAR(int32, int32_t, int32_scalar, "java/lang/Int", "(I)V") + else IF_UNBOX_PRIMITIVE_SCALAR(uint32, uint32_t, uint32_scalar, "java/lang/Int", "(I)V") + else IF_UNBOX_PRIMITIVE_SCALAR(int64, int64_t, int64_scalar, "java/lang/Long", "(L)V") + else IF_UNBOX_PRIMITIVE_SCALAR(uint64, uint64_t, uint64_scalar, "java/lang/Long", "(L)V") + +#undef IF_UNBOX_PRIMITIVE_SCALAR } else if (val.is_empty ()) { @@ -2485,4 +2473,12 @@ ## Check automatic conversion of java primitive arrays into octave types %!assert (javaObject ("java.lang.String", "hello").getBytes (), %! int8 ([104 101 108 108 111]')) + +## Check automatic conversion of octave types into java primitive arrays +## Note that uint8 are casted into int8 +%!assert (javaMethod ("binarySearch", "java.util.Arrays", [90 100 255], 255), 2) +%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 255]), uint8 (255)) < 0) +%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 128]), uint8 (128)) < 0) +%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint8 ([90 100 127]), uint8 (127)), 2) +%!assert (javaMethod ("binarySearch", "java.util.Arrays", uint16 ([90 100 128]), uint16 (128)), 2) */