Skip to content

Commit ee7c221

Browse files
committed
Increase maximum supported fixed args on varargs calls from 3 to 255
1 parent 54fc662 commit ee7c221

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ Features
1111
Bug Fixes
1212
---------
1313
* [#1501](https://github.com/java-native-access/jna/pull/1501): `Library.OPTION_STRING_ENCODING` is ignore for string arguments function calls - [@matthiasblaesing](https://github.com/matthiasblaesing).
14+
* [#1504](https://github.com/java-native-access/jna/pull/1504): Increase maximum supported fixed args on varargs calls from 3 to 255 - [@andrew-nowak](https://github.com/andrew-nowak).
15+
16+
Important Changes
17+
-----------------
18+
* The interfaces between Java and native code have changed, so `libjnidispatch`
19+
must be rebuilt to be compatible with this release.
1420

1521
Release (5.13.0)
1622
================

native/dispatch.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ extern "C" {
144144
PSTART(); memset(D,C,L); PEND(ENV); \
145145
} while(0)
146146

147-
#define MASK_CC com_sun_jna_Function_MASK_CC
148-
#define THROW_LAST_ERROR com_sun_jna_Function_THROW_LAST_ERROR
149-
#define USE_VARARGS com_sun_jna_Function_USE_VARARGS
147+
#define MASK_CC com_sun_jna_Function_MASK_CC
148+
#define THROW_LAST_ERROR com_sun_jna_Function_THROW_LAST_ERROR
149+
#define USE_VARARGS com_sun_jna_Function_USE_VARARGS
150+
#define USE_VARARGS_SHIFT com_sun_jna_Function_USE_VARARGS_SHIFT
150151

151152
/* Cached class, field and method IDs */
152153
static jclass classObject;
@@ -480,7 +481,7 @@ dispatch(JNIEnv *env, void* func, jint flags, jobjectArray args,
480481
callconv_t callconv = flags & MASK_CC;
481482
const char* volatile throw_type = NULL;
482483
const char* volatile throw_msg = NULL;
483-
int fixed_args = (flags & USE_VARARGS) >> 7;
484+
int fixed_args = (flags >> USE_VARARGS_SHIFT) & USE_VARARGS;
484485

485486
nargs = (*env)->GetArrayLength(env, args);
486487

native/testlib.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,19 @@ addVarArgs(const char *fmt, ...) {
908908
return sum;
909909
}
910910

911+
EXPORT int32_t
912+
addSeveralFixedArgsAndVarArgs(int a, int b, int c, int d, int n_varargs, ...) {
913+
va_list ap;
914+
int32_t sum = a + b + c + d;
915+
va_start(ap, n_varargs);
916+
917+
for (int i = 0; i < n_varargs; i++) {
918+
sum += va_arg(ap, int32_t);
919+
}
920+
va_end(ap);
921+
return sum;
922+
}
923+
911924
EXPORT void
912925
modifyStructureVarArgs(const char* fmt, ...) {
913926
struct _ss {

src/com/sun/jna/Function.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,12 @@ public interface PostCallRead {
7676
/** Whether to throw an exception if last error is non-zero after call. */
7777
@java.lang.annotation.Native
7878
public static final int THROW_LAST_ERROR = 0x40;
79-
/** Mask for number of fixed args (1-3) for varargs calls. */
79+
/** Mask for number of fixed args (max 255) for varargs calls. */
8080
@java.lang.annotation.Native
81-
public static final int USE_VARARGS = 0x180;
81+
public static final int USE_VARARGS = 0xFF;
82+
/** Offset of USE_VARARGS in call flags */
83+
@java.lang.annotation.Native
84+
public static final int USE_VARARGS_SHIFT = 7;
8285

8386
static final Integer INTEGER_TRUE = Integer.valueOf(-1);
8487
static final Integer INTEGER_FALSE = Integer.valueOf(0);
@@ -410,7 +413,7 @@ Object invoke(Object[] args, Class<?> returnType, boolean allowObjects) {
410413
/* @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */
411414
Object invoke(Object[] args, Class<?> returnType, boolean allowObjects, int fixedArgs) {
412415
Object result = null;
413-
int callFlags = this.callFlags | ((fixedArgs & 0x3) << 7);
416+
int callFlags = this.callFlags | ((fixedArgs & USE_VARARGS) << USE_VARARGS_SHIFT);
414417
if (returnType == null || returnType==void.class || returnType==Void.class) {
415418
Native.invokeVoid(this, this.peer, callFlags, args);
416419
result = null;

test/com/sun/jna/VarArgsTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ protected List<String> getFieldOrder() {
4141
}
4242
}
4343
public int addVarArgs(String fmt, Number... args);
44+
public int addSeveralFixedArgsAndVarArgs(int a, int b, int c, int d, int nArgs, Integer... args);
4445
public String returnStringVarArgs(String fmt, Object... args);
4546
public void modifyStructureVarArgs(String fmt, Object... args);
4647
public String returnStringVarArgs2(String fmt, String... args);
@@ -102,6 +103,22 @@ public void testStringVarArgsFull() {
102103
lib.returnStringVarArgs2("", "Test"));
103104
}
104105

106+
public void testSeveralFixedAndVarArgs() {
107+
int fixedarg1 = 1;
108+
int fixedarg2 = 2;
109+
int fixedarg3 = 3;
110+
int fixedarg4 = 4;
111+
int vararg1 = 100;
112+
int vararg2 = 200;
113+
114+
int expected = fixedarg1 + fixedarg2 + fixedarg3 + fixedarg4 + vararg1 + vararg2;
115+
int result = lib.addSeveralFixedArgsAndVarArgs(fixedarg1, fixedarg2, fixedarg3, fixedarg4,
116+
2, vararg1, vararg2);
117+
118+
assertEquals("varargs not passed correctly with multiple fixed args",
119+
expected, result);
120+
}
121+
105122
public void testAppendNullToVarargs() {
106123
Number[] args = new Number[] { Integer.valueOf(1) };
107124
assertEquals("No trailing NULL was appended to varargs list",

0 commit comments

Comments
 (0)