diff --git a/runtime/tests/clinkerffi/CMakeLists.txt b/runtime/tests/clinkerffi/CMakeLists.txt
index 4f4978b6d7b..6a203680743 100644
--- a/runtime/tests/clinkerffi/CMakeLists.txt
+++ b/runtime/tests/clinkerffi/CMakeLists.txt
@@ -23,6 +23,8 @@
set(OMR_ENHANCED_WARNINGS OFF)
j9vm_add_library(clinkerffitests SHARED
downcall.c
+ upcall.c
+ valist.c
)
target_link_libraries(clinkerffitests
PRIVATE
@@ -42,9 +44,6 @@ omr_add_exports(clinkerffitests
add2Longs
add2Floats
add2Doubles
- addIntsFromVaList
- addLongsFromVaList
- addDoublesFromVaList
addIntAndIntFromPointer
addBoolAndBoolFromPointerWithOr
createNewCharFromCharAndCharFromPointer
@@ -165,6 +164,245 @@ omr_add_exports(clinkerffitests
add2DoubleStructs_returnStruct
add2DoubleStructs_returnStructPointer
add3DoubleStructs_returnStruct
+ add2BoolsWithOrByUpcallMH
+ addBoolAndBoolFromPointerWithOrByUpcallMH
+ addBoolAndBoolFromNativePtrWithOrByUpcallMH
+ addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH
+ createNewCharFrom2CharsByUpcallMH
+ createNewCharFromCharAndCharFromPointerByUpcallMH
+ createNewCharFromCharAndCharFromNativePtrByUpcallMH
+ createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH
+ add2BytesByUpcallMH
+ addByteAndByteFromPointerByUpcallMH
+ addByteAndByteFromNativePtrByUpcallMH
+ addByteAndByteFromPtr_RetPtr_ByUpcallMH
+ add2ShortsByUpcallMH
+ addShortAndShortFromPointerByUpcallMH
+ addShortAndShortFromNativePtrByUpcallMH
+ addShortAndShortFromPtr_RetPtr_ByUpcallMH
+ add2IntsByUpcallMH
+ addIntAndIntFromPointerByUpcallMH
+ addIntAndIntFromNativePtrByUpcallMH
+ addIntAndIntFromPtr_RetPtr_ByUpcallMH
+ add3IntsByUpcallMH
+ addIntAndCharByUpcallMH
+ add2IntsReturnVoidByUpcallMH
+ add2LongsByUpcallMH
+ addLongAndLongFromPointerByUpcallMH
+ addLongAndLongFromNativePtrByUpcallMH
+ addLongAndLongFromPtr_RetPtr_ByUpcallMH
+ add2FloatsByUpcallMH
+ addFloatAndFloatFromPointerByUpcallMH
+ addFloatAndFloatFromNativePtrByUpcallMH
+ addFloatAndFloatFromPtr_RetPtr_ByUpcallMH
+ add2DoublesByUpcallMH
+ addDoubleAndDoubleFromPointerByUpcallMH
+ addDoubleAndDoubleFromNativePtrByUpcallMH
+ addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH
+ addBoolAndBoolsFromStructWithXorByUpcallMH
+ addBoolAnd20BoolsFromStructWithXorByUpcallMH
+ addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH
+ addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH
+ addBoolAndBoolsFromStructPointerWithXorByUpcallMH
+ addBoolAndBoolsFromNestedStructWithXorByUpcallMH
+ addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH
+ addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH
+ addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH
+ addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH
+ addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2BoolStructsWithXor_returnStructByUpcallMH
+ add2BoolStructsWithXor_returnStructPointerByUpcallMH
+ add3BoolStructsWithXor_returnStructByUpcallMH
+ addByteAndBytesFromStructByUpcallMH
+ addByteAnd20BytesFromStructByUpcallMH
+ addByteFromPointerAndBytesFromStructByUpcallMH
+ addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH
+ addByteAndBytesFromStructPointerByUpcallMH
+ addByteAndBytesFromNestedStructByUpcallMH
+ addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH
+ addByteAndBytesFromStructWithNestedByteArrayByUpcallMH
+ addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH
+ addByteAndBytesFromStructWithNestedStructArrayByUpcallMH
+ addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add1ByteStructs_returnStructByUpcallMH
+ add2ByteStructs_returnStructByUpcallMH
+ add2ByteStructs_returnStructPointerByUpcallMH
+ add3ByteStructs_returnStructByUpcallMH
+ addCharAndCharsFromStructByUpcallMH
+ addCharFromPointerAndCharsFromStructByUpcallMH
+ addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH
+ addCharAndCharsFromStructPointerByUpcallMH
+ addCharAndCharsFromNestedStructByUpcallMH
+ addCharAnd10CharsFromStructByUpcallMH
+ addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH
+ addCharAndCharsFromStructWithNestedCharArrayByUpcallMH
+ addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH
+ addCharAndCharsFromStructWithNestedStructArrayByUpcallMH
+ addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2CharStructs_returnStructByUpcallMH
+ add2CharStructs_returnStructPointerByUpcallMH
+ add3CharStructs_returnStructByUpcallMH
+ addShortAndShortsFromStructByUpcallMH
+ addShortAnd10ShortsFromStructByUpcallMH
+ addShortFromPointerAndShortsFromStructByUpcallMH
+ addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH
+ addShortAndShortsFromStructPointerByUpcallMH
+ addShortAndShortsFromNestedStructByUpcallMH
+ addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH
+ addShortAndShortsFromStructWithNestedShortArrayByUpcallMH
+ addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH
+ addShortAndShortsFromStructWithNestedStructArrayByUpcallMH
+ addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2ShortStructs_returnStructByUpcallMH
+ add2ShortStructs_returnStructPointerByUpcallMH
+ add3ShortStructs_returnStructByUpcallMH
+ addIntAndIntsFromStructByUpcallMH
+ addIntAnd5IntsFromStructByUpcallMH
+ addIntFromPointerAndIntsFromStructByUpcallMH
+ addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH
+ addIntAndIntsFromStructPointerByUpcallMH
+ addIntAndIntsFromNestedStructByUpcallMH
+ addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH
+ addIntAndIntsFromStructWithNestedIntArrayByUpcallMH
+ addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH
+ addIntAndIntsFromStructWithNestedStructArrayByUpcallMH
+ addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2IntStructs_returnStructByUpcallMH
+ add2IntStructs_returnStructPointerByUpcallMH
+ add3IntStructs_returnStructByUpcallMH
+ addLongAndLongsFromStructByUpcallMH
+ addLongFromPointerAndLongsFromStructByUpcallMH
+ addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH
+ addLongAndLongsFromStructPointerByUpcallMH
+ addLongAndLongsFromNestedStructByUpcallMH
+ addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH
+ addLongAndLongsFromStructWithNestedLongArrayByUpcallMH
+ addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH
+ addLongAndLongsFromStructWithNestedStructArrayByUpcallMH
+ addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2LongStructs_returnStructByUpcallMH
+ add2LongStructs_returnStructPointerByUpcallMH
+ add3LongStructs_returnStructByUpcallMH
+ addFloatAndFloatsFromStructByUpcallMH
+ addFloatAnd5FloatsFromStructByUpcallMH
+ addFloatFromPointerAndFloatsFromStructByUpcallMH
+ addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH
+ addFloatAndFloatsFromStructPointerByUpcallMH
+ addFloatAndFloatsFromNestedStructByUpcallMH
+ addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH
+ addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH
+ addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH
+ addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH
+ addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2FloatStructs_returnStructByUpcallMH
+ add2FloatStructs_returnStructPointerByUpcallMH
+ add3FloatStructs_returnStructByUpcallMH
+ addDoubleAndDoublesFromStructByUpcallMH
+ addDoubleFromPointerAndDoublesFromStructByUpcallMH
+ addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH
+ addDoubleAndDoublesFromStructPointerByUpcallMH
+ addDoubleAndDoublesFromNestedStructByUpcallMH
+ addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH
+ addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH
+ addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH
+ addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH
+ addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH
+ add2DoubleStructs_returnStructByUpcallMH
+ add2DoubleStructs_returnStructPointerByUpcallMH
+ add3DoubleStructs_returnStructByUpcallMH
+ addIntAndIntShortFromStructByUpcallMH
+ addIntAndShortIntFromStructByUpcallMH
+ addIntAndIntLongFromStructByUpcallMH
+ addIntAndLongIntFromStructByUpcallMH
+ addDoubleAndDoubleIntFromStructByUpcallMH
+ addDoubleAndIntDoubleFromStructByUpcallMH
+ addDoubleAndFloatDoubleFromStructByUpcallMH
+ addDoubleAndDoubleFloatFromStructByUpcallMH
+ addDoubleAnd2FloatsDoubleFromStructByUpcallMH
+ addDoubleAndDouble2FloatsFromStructByUpcallMH
+ addFloatAndInt2FloatsFromStructByUpcallMH
+ addFloatAndFloatIntFloatFromStructByUpcallMH
+ addDoubleAndIntFloatDoubleFromStructByUpcallMH
+ addDoubleAndFloatIntDoubleFromStructByUpcallMH
+ addDoubleAndLongDoubleFromStructByUpcallMH
+ addFloatAndInt3FloatsFromStructByUpcallMH
+ addLongAndLong2FloatsFromStructByUpcallMH
+ addFloatAnd3FloatsIntFromStructByUpcallMH
+ addLongAndFloatLongFromStructByUpcallMH
+ addDoubleAndDoubleFloatIntFromStructByUpcallMH
+ addDoubleAndDoubleLongFromStructByUpcallMH
+ addLongAnd2FloatsLongFromStructByUpcallMH
+ addShortAnd3ShortsCharFromStructByUpcallMH
+ addFloatAndIntFloatIntFloatFromStructByUpcallMH
+ addDoubleAndIntDoubleFloatFromStructByUpcallMH
+ addDoubleAndFloatDoubleIntFromStructByUpcallMH
+ addDoubleAndIntDoubleIntFromStructByUpcallMH
+ addDoubleAndFloatDoubleFloatFromStructByUpcallMH
+ addDoubleAndIntDoubleLongFromStructByUpcallMH
+ return254BytesFromStructByUpcallMH
+ return4KBytesFromStructByUpcallMH
+ addIntsFromVaList
+ addLongsFromVaList
+ addDoublesFromVaList
+ addMixedArgsFromVaList
+ addMoreMixedArgsFromVaList
+ addIntsByPtrFromVaList
+ addLongsByPtrFromVaList
+ addDoublesByPtrFromVaList
+ add1ByteOfStructsFromVaList
+ add2BytesOfStructsFromVaList
+ add3BytesOfStructsFromVaList
+ add5BytesOfStructsFromVaList
+ add7BytesOfStructsFromVaList
+ add1ShortOfStructsFromVaList
+ add2ShortsOfStructsFromVaList
+ add3ShortsOfStructsFromVaList
+ add1IntOfStructsFromVaList
+ add2IntsOfStructsFromVaList
+ add3IntsOfStructsFromVaList
+ add2LongsOfStructsFromVaList
+ add1FloatOfStructsFromVaList
+ add2FloatsOfStructsFromVaList
+ add3FloatsOfStructsFromVaList
+ add1DoubleOfStructsFromVaList
+ add2DoublesOfStructsFromVaList
+ addIntShortOfStructsFromVaList
+ addShortIntOfStructsFromVaList
+ addIntLongOfStructsFromVaList
+ addLongIntOfStructsFromVaList
+ addFloatDoubleOfStructsFromVaList
+ addDoubleFloatOfStructsFromVaList
+ addIntsFromVaListByUpcallMH
+ addLongsFromVaListByUpcallMH
+ addDoublesFromVaListByUpcallMH
+ addMixedArgsFromVaListByUpcallMH
+ addMoreMixedArgsFromVaListByUpcallMH
+ addIntsByPtrFromVaListByUpcallMH
+ addLongsByPtrFromVaListByUpcallMH
+ addDoublesByPtrFromVaListByUpcallMH
+ add1ByteOfStructsFromVaListByUpcallMH
+ add2BytesOfStructsFromVaListByUpcallMH
+ add3BytesOfStructsFromVaListByUpcallMH
+ add5BytesOfStructsFromVaListByUpcallMH
+ add7BytesOfStructsFromVaListByUpcallMH
+ add1ShortOfStructsFromVaListByUpcallMH
+ add2ShortsOfStructsFromVaListByUpcallMH
+ add3ShortsOfStructsFromVaListByUpcallMH
+ add1IntOfStructsFromVaListByUpcallMH
+ add2IntsOfStructsFromVaListByUpcallMH
+ add3IntsOfStructsFromVaListByUpcallMH
+ add2LongsOfStructsFromVaListByUpcallMH
+ add1FloatOfStructsFromVaListByUpcallMH
+ add2FloatsOfStructsFromVaListByUpcallMH
+ add3FloatsOfStructsFromVaListByUpcallMH
+ add1DoubleOfStructsFromVaListByUpcallMH
+ add2DoublesOfStructsFromVaListByUpcallMH
+ addIntShortOfStructsFromVaListByUpcallMH
+ addShortIntOfStructsFromVaListByUpcallMH
+ addIntLongOfStructsFromVaListByUpcallMH
+ addLongIntOfStructsFromVaListByUpcallMH
+ addFloatDoubleOfStructsFromVaListByUpcallMH
+ addDoubleFloatOfStructsFromVaListByUpcallMH
)
install(
diff --git a/runtime/tests/clinkerffi/downcall.c b/runtime/tests/clinkerffi/downcall.c
index 8fee504cc32..65131f1f741 100644
--- a/runtime/tests/clinkerffi/downcall.c
+++ b/runtime/tests/clinkerffi/downcall.c
@@ -21,8 +21,11 @@
*******************************************************************************/
/**
- * This file contains the native code used by the test cases in
- * org.openj9.test.jep389.downcall via a Clinker FFI DownCall.
+ * This file contains the native code used by the test cases via a Clinker FFI DownCall in java,
+ * which come from:
+ * org.openj9.test.jep389.downcall (JDK16/17)
+ * org.openj9.test.jep419.downcall (JDK18)
+ * org.openj9.test.jep424.downcall (JDK19+)
*
* Created by jincheng@ca.ibm.com
*/
@@ -72,24 +75,6 @@ add3Ints(int intArg1, int intArg2, int intArg3)
return intSum;
}
-/**
- * Add integers from the va_list with the specified count
- *
- * @param intCount the count of the integers
- * @param intArgList the integer va_list
- * @return the sum of integers from the va_list
- */
-int
-addIntsFromVaList(int intCount, va_list intVaList)
-{
- int intSum = 0;
- while (intCount > 0) {
- intSum += va_arg(intVaList, int);
- intCount--;
- }
- return intSum;
-}
-
/**
* Add an integer and a character.
*
@@ -267,24 +252,6 @@ addLongAndLongFromPointer(LONG *longArg1, LONG longArg2)
return longSum;
}
-/**
- * Add long integers from the va_list with the specified count
- *
- * @param longCount the count of the long integers
- * @param longArgList the long va_list
- * @return the sum of long integers from the va_list
- */
-LONG
-addLongsFromVaList(int longCount, va_list longVaList)
-{
- LONG longSum = 0;
- while (longCount > 0) {
- longSum += va_arg(longVaList, LONG);
- longCount--;
- }
- return longSum;
-}
-
/**
* Add two floats.
*
@@ -341,24 +308,6 @@ addDoubleAndDoubleFromPointer(double *doubleArg1, double doubleArg2)
return doubleSum;
}
-/**
- * Add doubles from the va_list with the specified count
- *
- * @param doubleCount the count of the double arguments
- * @param doubleArgList the double va_list
- * @return the sum of doubles from the va_list
- */
-double
-addDoublesFromVaList(int doubleCount, va_list doubleVaList)
-{
- double doubleSum = 0;
- while (doubleCount > 0) {
- doubleSum += va_arg(doubleVaList, double);
- doubleCount--;
- }
- return doubleSum;
-}
-
/**
* Add a boolean and all boolean elements of a struct with the XOR (^) operator.
*
@@ -1255,7 +1204,7 @@ addIntAndIntsFromNestedStruct(int arg1, stru_NestedStruct_Int arg2)
*
* @param arg1 an integer
* @param arg2 a struct with an integer and a nested struct
- * @return the sum of these ints
+ * @return the sum of these integers
*/
int
addIntAndIntsFromNestedStruct_reverseOrder(int arg1, stru_Int_NestedStruct arg2)
diff --git a/runtime/tests/clinkerffi/downcall.h b/runtime/tests/clinkerffi/downcall.h
index eff640631b3..6dc94d8038f 100644
--- a/runtime/tests/clinkerffi/downcall.h
+++ b/runtime/tests/clinkerffi/downcall.h
@@ -21,8 +21,11 @@
*******************************************************************************/
/**
- * This file contains the structs required in the native code used by org.openj9.test.jep389.downcall.StructTests
- * via a Clinker FFI DownCall.
+ * This file contains the structs required in the native code via a Clinker FFI DownCall & Upcall in java,
+ * which come from:
+ * org.openj9.test.jep389.downcall/upcall (JDK16/17)
+ * org.openj9.test.jep419.downcall/upcall (JDK18)
+ * org.openj9.test.jep424.downcall/upcall (JDK19+)
*
* Created by jincheng@ca.ibm.com
*/
@@ -48,6 +51,29 @@ typedef struct stru_Bool_Bool_Bool {
bool elem3;
} stru_Bool_Bool_Bool;
+typedef struct stru_20_Bools {
+ bool elem1;
+ bool elem2;
+ bool elem3;
+ bool elem4;
+ bool elem5;
+ bool elem6;
+ bool elem7;
+ bool elem8;
+ bool elem9;
+ bool elem10;
+ bool elem11;
+ bool elem12;
+ bool elem13;
+ bool elem14;
+ bool elem15;
+ bool elem16;
+ bool elem17;
+ bool elem18;
+ bool elem19;
+ bool elem20;
+} stru_20_Bools;
+
typedef struct stru_NestedStruct_Bool {
stru_Bool_Bool elem1;
bool elem2;
@@ -78,6 +104,10 @@ typedef struct stru_Bool_NestedStruArray {
stru_Bool_Bool elem2[2];
} stru_Bool_NestedStruArray;
+typedef struct stru_Byte {
+ char elem1;
+} stru_Byte;
+
typedef struct stru_Byte_Byte {
char elem1;
char elem2;
@@ -89,6 +119,55 @@ typedef struct stru_Byte_Byte_Byte {
char elem3;
} stru_Byte_Byte_Byte;
+typedef struct stru_5_Bytes {
+ char elem1;
+ char elem2;
+ char elem3;
+ char elem4;
+ char elem5;
+} stru_5_Bytes;
+
+typedef struct stru_7_Bytes {
+ char elem1;
+ char elem2;
+ char elem3;
+ char elem4;
+ char elem5;
+ char elem6;
+ char elem7;
+} stru_7_Bytes;
+
+typedef struct stru_20_Bytes {
+ char elem1;
+ char elem2;
+ char elem3;
+ char elem4;
+ char elem5;
+ char elem6;
+ char elem7;
+ char elem8;
+ char elem9;
+ char elem10;
+ char elem11;
+ char elem12;
+ char elem13;
+ char elem14;
+ char elem15;
+ char elem16;
+ char elem17;
+ char elem18;
+ char elem19;
+ char elem20;
+} stru_20_Bytes;
+
+typedef struct stru_254_Bytes {
+ char elem[254];
+} stru_254_Bytes;
+
+typedef struct stru_4K_Bytes {
+ char elem[4096];
+} stru_4K_Bytes;
+
typedef struct stru_NestedStruct_Byte {
stru_Byte_Byte elem1;
char elem2;
@@ -130,6 +209,19 @@ typedef struct stru_Char_Char_Char {
short elem3;
} stru_Char_Char_Char;
+typedef struct stru_10_Chars {
+ short elem1;
+ short elem2;
+ short elem3;
+ short elem4;
+ short elem5;
+ short elem6;
+ short elem7;
+ short elem8;
+ short elem9;
+ short elem10;
+} stru_10_Chars;
+
typedef struct stru_NestedStruct_Char {
stru_Char_Char elem1;
short elem2;
@@ -160,6 +252,10 @@ typedef struct stru_Char_NestedStruArray {
stru_Char_Char elem2[2];
} stru_Char_NestedStruArray;
+typedef struct stru_Short {
+ short elem1;
+} stru_Short;
+
typedef struct stru_Short_Short {
short elem1;
short elem2;
@@ -171,6 +267,19 @@ typedef struct stru_Short_Short_Short {
short elem3;
} stru_Short_Short_Short;
+typedef struct stru_10_Shorts {
+ short elem1;
+ short elem2;
+ short elem3;
+ short elem4;
+ short elem5;
+ short elem6;
+ short elem7;
+ short elem8;
+ short elem9;
+ short elem10;
+} stru_10_Shorts;
+
typedef struct stru_NestedStruct_Short {
stru_Short_Short elem1;
short elem2;
@@ -201,6 +310,10 @@ typedef struct stru_Short_NestedStruArray {
stru_Short_Short elem2[2];
} stru_Short_NestedStruArray;
+typedef struct stru_Int {
+ int elem1;
+} stru_Int;
+
typedef struct stru_Int_Int {
int elem1;
int elem2;
@@ -212,15 +325,13 @@ typedef struct stru_Int_Int_Int {
int elem3;
} stru_Int_Int_Int;
-typedef struct stru_Int_Short {
+typedef struct stru_5_Ints {
int elem1;
- short elem2;
-} stru_Int_Short;
-
-typedef struct stru_Short_Int {
- short elem1;
int elem2;
-} stru_Short_Int;
+ int elem3;
+ int elem4;
+ int elem5;
+} stru_5_Ints;
typedef struct stru_NestedStruct_Int {
stru_Int_Int elem1;
@@ -263,16 +374,6 @@ typedef struct stru_Long_Long_Long {
LONG elem3;
} stru_Long_Long_Long;
-typedef struct stru_Int_Long {
- int elem1;
- LONG elem2;
-} stru_Int_Long;
-
-typedef struct stru_Long_Int {
- LONG elem1;
- int elem2;
-} stru_Long_Int;
-
typedef struct stru_NestedStruct_Long {
stru_Long_Long elem1;
LONG elem2;
@@ -303,6 +404,10 @@ typedef struct stru_Long_NestedStruArray {
stru_Long_Long elem2[2];
} stru_Long_NestedStruArray;
+typedef struct stru_Float {
+ float elem1;
+} stru_Float;
+
typedef struct stru_Float_Float {
float elem1;
float elem2;
@@ -314,6 +419,14 @@ typedef struct stru_Float_Float_Float {
float elem3;
} stru_Float_Float_Float;
+typedef struct stru_5_Floats {
+ float elem1;
+ float elem2;
+ float elem3;
+ float elem4;
+ float elem5;
+} stru_5_Floats;
+
typedef struct stru_NestedStruct_Float {
stru_Float_Float elem1;
float elem2;
@@ -344,6 +457,10 @@ typedef struct stru_Float_NestedStruArray {
stru_Float_Float elem2[2];
} stru_Float_NestedStruArray;
+typedef struct stru_Double {
+ double elem1;
+} stru_Double;
+
typedef struct stru_Double_Double {
double elem1;
double elem2;
@@ -355,26 +472,6 @@ typedef struct stru_Double_Double_Double {
double elem3;
} stru_Double_Double_Double;
-typedef struct stru_Float_Double {
- float elem1;
- double elem2;
-} stru_Float_Double;
-
-typedef struct stru_Int_Double {
- int elem1;
- double elem2;
-} stru_Int_Double;
-
-typedef struct stru_Double_Float {
- double elem1;
- float elem2;
-} stru_Double_Float;
-
-typedef struct stru_Double_Int {
- double elem1;
- int elem2;
-} stru_Double_Int;
-
typedef struct stru_NestedStruct_Double {
stru_Double_Double elem1;
double elem2;
@@ -405,4 +502,169 @@ typedef struct stru_Double_NestedStruArray {
stru_Double_Double elem2[2];
} stru_Double_NestedStruArray;
+typedef struct stru_Int_Short {
+ int elem1;
+ short elem2;
+} stru_Int_Short;
+
+typedef struct stru_Short_Int {
+ short elem1;
+ int elem2;
+} stru_Short_Int;
+
+typedef struct stru_Int_Long {
+ int elem1;
+ LONG elem2;
+} stru_Int_Long;
+
+typedef struct stru_Long_Int {
+ LONG elem1;
+ int elem2;
+} stru_Long_Int;
+
+typedef struct stru_Int_Double {
+ int elem1;
+ double elem2;
+} stru_Int_Double;
+
+typedef struct stru_Double_Int {
+ double elem1;
+ int elem2;
+} stru_Double_Int;
+
+typedef struct stru_Float_Double {
+ float elem1;
+ double elem2;
+} stru_Float_Double;
+
+typedef struct stru_Double_Float {
+ double elem1;
+ float elem2;
+} stru_Double_Float;
+
+typedef struct stru_Float_Float_Double {
+ float elem1;
+ float elem2;
+ double elem3;
+} stru_Float_Float_Double;
+
+typedef struct stru_Double_Float_Float {
+ double elem1;
+ float elem2;
+ float elem3;
+} stru_Double_Float_Float;
+
+typedef struct stru_Int_Float_Float {
+ int elem1;
+ float elem2;
+ float elem3;
+} stru_Int_Float_Float;
+
+typedef struct stru_Float_Int_Float {
+ float elem1;
+ int elem2;
+ float elem3;
+} stru_Float_Int_Float;
+
+typedef struct stru_Int_Float_Double {
+ int elem1;
+ float elem2;
+ double elem3;
+} stru_Int_Float_Double;
+
+typedef struct stru_Float_Int_Double {
+ float elem1;
+ int elem2;
+ double elem3;
+} stru_Float_Int_Double;
+
+typedef struct stru_Long_Double {
+ LONG elem1;
+ double elem2;
+} stru_Long_Double;
+
+typedef struct stru_Int_3_Floats {
+ int elem1;
+ float elem2;
+ float elem3;
+ float elem4;
+} stru_Int_3_Floats;
+
+typedef struct stru_Long_2_Floats {
+ LONG elem1;
+ float elem2;
+ float elem3;
+} stru_Long_2_Floats;
+
+typedef struct stru_3_Floats_Int {
+ float elem1;
+ float elem2;
+ float elem3;
+ int elem4;
+} stru_3_Floats_Int;
+
+typedef struct stru_Float_Long {
+ float elem1;
+ LONG elem2;
+} stru_Float_Long;
+
+typedef struct stru_Double_Float_Int {
+ double elem1;
+ float elem2;
+ int elem3;
+} stru_Double_Float_Int;
+
+typedef struct stru_Double_Long {
+ double elem1;
+ LONG elem2;
+} stru_Double_Long;
+
+typedef struct stru_Float_Float_Long {
+ float elem1;
+ float elem2;
+ LONG elem3;
+} stru_Float_Float_Long;
+
+typedef struct stru_3_Shorts_Char {
+ short elem1[3];
+ short elem2; // intended for the char type in java
+} stru_3_Shorts_Char;
+
+typedef struct stru_Int_Float_Int_Float {
+ int elem1;
+ float elem2;
+ int elem3;
+ float elem4;
+} stru_Int_Float_Int_Float;
+
+typedef struct stru_Int_Double_Float {
+ int elem1;
+ double elem2;
+ float elem3;
+} stru_Int_Double_Float;
+
+typedef struct stru_Float_Double_Int {
+ float elem1;
+ double elem2;
+ int elem3;
+} stru_Float_Double_Int;
+
+typedef struct stru_Int_Double_Int {
+ int elem1;
+ double elem2;
+ int elem3;
+} stru_Int_Double_Int;
+
+typedef struct stru_Float_Double_Float {
+ float elem1;
+ double elem2;
+ float elem3;
+} stru_Float_Double_Float;
+
+typedef struct stru_Int_Double_Long {
+ int elem1;
+ double elem2;
+ LONG elem3;
+} stru_Int_Double_Long;
+
#endif /* DOWNCALL_H */
diff --git a/runtime/tests/clinkerffi/module.xml b/runtime/tests/clinkerffi/module.xml
index 9c355104980..c641cfd1e5a 100644
--- a/runtime/tests/clinkerffi/module.xml
+++ b/runtime/tests/clinkerffi/module.xml
@@ -35,9 +35,6 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-excepti
-
-
-
@@ -158,6 +155,245 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-excepti
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/runtime/tests/clinkerffi/upcall.c b/runtime/tests/clinkerffi/upcall.c
new file mode 100644
index 00000000000..2c6bb939b15
--- /dev/null
+++ b/runtime/tests/clinkerffi/upcall.c
@@ -0,0 +1,2849 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+
+/**
+ * This file contains the native code used by the test cases via a Clinker FFI Upcall in java,
+ * which come from:
+ * org.openj9.test.jep389.upcall (JDK16/17)
+ * org.openj9.test.jep419.upcall (JDK18)
+ * org.openj9.test.jep424.upcall (JDK19+)
+ *
+ * Created by jincheng@ca.ibm.com
+ */
+
+#include
+#include
+#include
+#include "downcall.h"
+
+/**
+ * Add two booleans with the OR (||) operator by invoking an upcall method.
+ *
+ * @param boolArg1 the 1st boolean
+ * @param boolArg2 the 2nd boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the result value
+ */
+bool
+add2BoolsWithOrByUpcallMH(bool boolArg1, bool boolArg2, bool (*upcallMH)(bool, bool))
+{
+ bool result = (*upcallMH)(boolArg1, boolArg2);
+ return result;
+}
+
+/**
+ * Add two booleans with the OR (||) operator (the 2nd one is dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param boolArg1 a boolean
+ * @param boolArg2 a pointer to boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the result value
+ */
+bool
+addBoolAndBoolFromPointerWithOrByUpcallMH(bool boolArg1, bool *boolArg2, bool (*upcallMH)(bool, bool *))
+{
+ bool result = (*upcallMH)(boolArg1, boolArg2);
+ return result;
+}
+
+/**
+ * Add two booleans (the 2nd one assigned in native) with
+ * the OR (||) operator by invoking an upcall method.
+ *
+ * @param boolArg1 the 1st boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the result value
+ */
+bool
+addBoolAndBoolFromNativePtrWithOrByUpcallMH(bool boolArg1, bool (*upcallMH)(bool, bool *))
+{
+ bool boolArg2 = 1;
+ bool result = (*upcallMH)(boolArg1, &boolArg2);
+ return result;
+}
+
+/**
+ * Add two booleans with the OR (||) operator (the 2nd one is dereferenced from a pointer)
+ * by invoking an upcall method and return a pointer to the XOR result of booleans.
+ *
+ * @param boolArg1 the 1st boolean
+ * @param boolArg2 a pointer to the 2nd boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the resulting pointer to boolean
+ */
+bool *
+addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH(bool boolArg1, bool *boolArg2, bool *(*upcallMH)(bool, bool *))
+{
+ bool *resultPtr = (*upcallMH)(boolArg1, boolArg2);
+ return resultPtr;
+}
+
+/**
+ * Add two bytes by invoking an upcall method.
+ * Note:
+ * the passed-in arguments are byte given the byte size
+ * in Java is the same size as the char in C code.
+ *
+ * @param byteArg1 the 1st byte
+ * @param byteArg2 the 2nd byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add2BytesByUpcallMH(char byteArg1, char byteArg2, char (*upcallMH)(char, char))
+{
+ char byteSum = (*upcallMH)(byteArg1, byteArg2);
+ return byteSum;
+}
+
+/**
+ * Add two bytes (the 2nd one is dereferenced from a pointer)
+ * by invoking an upcall method.
+ * Note:
+ * the passed-in arguments are byte given the byte size
+ * in Java is the same size as the char in C code.
+ *
+ * @param byteArg1 the 1st byte
+ * @param byteArg2 a pointer to the 2nd byte in char size
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndByteFromPointerByUpcallMH(char byteArg1, char *byteArg2, char (*upcallMH)(char, char *))
+{
+ char byteSum = (*upcallMH)(byteArg1, byteArg2);
+ return byteSum;
+}
+
+/**
+ * Add two bytes (the 2nd one assigned in native) by invoking an upcall method.
+ * Note: the passed-in arguments are byte given the byte size
+ * in Java is the same size as the char in C code.
+ *
+ * @param byteArg1 the 1st byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndByteFromNativePtrByUpcallMH(char byteArg1, char (*upcallMH)(char, char *))
+{
+ char byteArg2 = 55;
+ char byteSum = (*upcallMH)(byteArg1, &byteArg2);
+ return byteSum;
+}
+
+/**
+ * Add two bytes (the 2nd one is dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ * Note:
+ * the passed-in arguments are byte given the byte size
+ * in Java is the same size as the char in C code.
+ *
+ * @param byteArg1 the 1st byte
+ * @param byteArg2 a pointer to the 2nd byte in char size
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+char *
+addByteAndByteFromPtr_RetPtr_ByUpcallMH(char byteArg1, char *byteArg2, char *(*upcallMH)(char, char *))
+{
+ char *byteSum = (*upcallMH)(byteArg1, byteArg2);
+ return byteSum;
+}
+
+/**
+ * Generate a new char by manipulating two chars by invoking an upcall method.
+ *
+ * @param charArg1 the 1st char
+ * @param charArg2 the 2nd char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the resulting char
+ */
+short
+createNewCharFrom2CharsByUpcallMH(short charArg1, short charArg2, short (*upcallMH)(short, short))
+{
+ short result = (*upcallMH)(charArg1, charArg2);
+ return result;
+}
+
+/**
+ * Generate a new char by manipulating two chars (the 1st one dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param charArg1 a pointer to the 1st char
+ * @param charArg2 the 2nd char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the resulting char
+ */
+short
+createNewCharFromCharAndCharFromPointerByUpcallMH(short *charArg1, short charArg2, short (*upcallMH)(short *, short))
+{
+ short result = (*upcallMH)(charArg1, charArg2);
+ return result;
+}
+
+/**
+ * Generate a new char by manipulating two chars (the 1st one is assigned in native)
+ * via invoking an upcall method.
+ *
+ * @param charArg2 the 2nd char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the resulting char
+ */
+short
+createNewCharFromCharAndCharFromNativePtrByUpcallMH(short charArg2, short (*upcallMH)(short *, short))
+{
+ short charArg1 = 'B';
+ short result = (*upcallMH)(&charArg1, charArg2);
+ return result;
+}
+
+/**
+ * Generate a new char by manipulating two chars (the 1st one dereferenced from a pointer)
+ * by invoking an upcall method and return a pointer to a new char.
+ *
+ * @param charArg1 a pointer to the 1st char
+ * @param charArg2 the 2nd char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the resulting pointer to a new char
+ */
+short *
+createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH(short *charArg1, short charArg2, short *(*upcallMH)(short *, short))
+{
+ short *resultPtr = (*upcallMH)(charArg1, charArg2);
+ return resultPtr;
+}
+
+/**
+ * Add two shorts by invoking an upcall method.
+ *
+ * @param shortArg1 the 1st short
+ * @param shortArg2 the 2nd short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+add2ShortsByUpcallMH(short shortArg1, short shortArg2, short (*upcallMH)(short, short))
+{
+ short shortSum = (*upcallMH)(shortArg1, shortArg2);
+ return shortSum;
+}
+
+/**
+ * Add two shorts (the 1st one dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param shortArg1 a pointer to the 1st short
+ * @param shortArg2 the 2nd short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortFromPointerByUpcallMH(short *shortArg1, short shortArg2, short (*upcallMH)(short *, short))
+{
+ short shortSum = (*upcallMH)(shortArg1, shortArg2);
+ return shortSum;
+}
+
+/**
+ * Add two shorts (the 1st one is assigned in native) by invoking an upcall method.
+ *
+ * @param shortArg2 the 2nd short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortFromNativePtrByUpcallMH(short shortArg2, short (*upcallMH)(short *, short))
+{
+ short shortArg1 = 456;
+ short shortSum = (*upcallMH)(&shortArg1, shortArg2);
+ return shortSum;
+}
+
+/**
+ * Add two shorts (the 1st one dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ *
+ * @param shortArg1 a pointer to the 1st short
+ * @param shortArg2 the 2nd short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+short *
+addShortAndShortFromPtr_RetPtr_ByUpcallMH(short *shortArg1, short shortArg2, short *(*upcallMH)(short *, short))
+{
+ short *shortSum = (*upcallMH)(shortArg1, shortArg2);
+ return shortSum;
+}
+
+/**
+ * Add two ints by invoking an upcall method.
+ *
+ * @param intArg1 the 1st int
+ * @param intArg2 the 2nd int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+add2IntsByUpcallMH(int intArg1, int intArg2, int (*upcallMH)(int, int))
+{
+ int intSum = (*upcallMH)(intArg1, intArg2);
+ return intSum;
+}
+
+/**
+ * Add two ints (the 2nd one is dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param intArg1 the 1st int
+ * @param intArg2 a pointer to the 2nd int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntFromPointerByUpcallMH(int intArg1, int *intArg2, int (*upcallMH)(int, int *))
+{
+ int intSum = (*upcallMH)(intArg1, intArg2);
+ return intSum;
+}
+
+/**
+ * Add two ints (the 2nd one is assigned in native) by invoking an upcall method.
+ *
+ * @param intArg1 the 1st int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntFromNativePtrByUpcallMH(int intArg1, int (*upcallMH)(int, int *))
+{
+ int intArg2 = 444444;
+ int intSum = (*upcallMH)(intArg1, &intArg2);
+ return intSum;
+}
+
+/**
+ * Add two ints (the 1st one is dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ *
+ * @param intArg1 the 1st int
+ * @param intArg2 a pointer to the 2nd int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+int *
+addIntAndIntFromPtr_RetPtr_ByUpcallMH(int intArg1, int *intArg2, int *(*upcallMH)(int, int *))
+{
+ int *intSum = (*upcallMH)(intArg1, intArg2);
+ return intSum;
+}
+
+/**
+ * Add three ints by invoking an upcall method.
+ *
+ * @param intArg1 the 1st int
+ * @param intArg2 the 2nd int
+ * @param intArg3 the 3rd int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+add3IntsByUpcallMH(int intArg1, int intArg2, int intArg3, int (*upcallMH)(int, int, int))
+{
+ int intSum = (*upcallMH)(intArg1, intArg2, intArg3);
+ return intSum;
+}
+
+/**
+ * Add an int and a char by invoking an upcall method.
+ *
+ * @param intArg an int
+ * @param charArg a char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndCharByUpcallMH(int intArg, char charArg, int (*upcallMH)(int, char))
+{
+ int sum = (*upcallMH)(intArg, charArg);
+ return sum;
+}
+
+/**
+ * Add two ints without return value by invoking an upcall method.
+ *
+ * @param intArg1 the 1st int
+ * @param intArg2 the 2nd int
+ * @param upcallMH the function pointer to the upcall method
+ * @return void
+ */
+void
+add2IntsReturnVoidByUpcallMH(int intArg1, int intArg2, int (*upcallMH)(int, int))
+{
+ (*upcallMH)(intArg1, intArg2);
+}
+
+/**
+ * Add two longs by invoking an upcall method.
+ *
+ * @param longArg1 the 1st long
+ * @param longArg2 the 2nd long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+add2LongsByUpcallMH(LONG longArg1, LONG longArg2, LONG (*upcallMH)(LONG, LONG))
+{
+ LONG longSum = (*upcallMH)(longArg1, longArg2);
+ return longSum;
+}
+
+/**
+ * Add two longs (the 1st one dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param longArg1 a pointer to the 1stlong
+ * @param longArg2 the 2nd long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongFromPointerByUpcallMH(LONG *longArg1, LONG longArg2, LONG (*upcallMH)(LONG *, LONG))
+{
+ LONG longSum = (*upcallMH)(longArg1, longArg2);
+ return longSum;
+}
+
+/**
+ * Add two longs (the 1st one is assigned in native) by invoking an upcall method.
+ *
+ * @param longArg2 the 2nd long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongFromNativePtrByUpcallMH(LONG longArg2, LONG (*upcallMH)(LONG *, LONG))
+{
+ LONG longArg1 = 3333333333;
+ LONG longSum = (*upcallMH)(&longArg1, longArg2);
+ return longSum;
+}
+
+/**
+ * Add two longs (the 1st one dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ *
+ * @param longArg1 a pointer to the 1st long
+ * @param longArg2 the 2nd long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+LONG *
+addLongAndLongFromPtr_RetPtr_ByUpcallMH(LONG *longArg1, LONG longArg2, LONG *(*upcallMH)(LONG *, LONG))
+{
+ LONG *longSum = (*upcallMH)(longArg1, longArg2);
+ return longSum;
+}
+
+/**
+ * Add two floats by invoking an upcall method.
+ *
+ * @param floatArg1 the 1st float
+ * @param floatArg2 the 2nd float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+add2FloatsByUpcallMH(float floatArg1, float floatArg2, float (*upcallMH)(float, float))
+{
+ float floatSum = (*upcallMH)(floatArg1, floatArg2);
+ return floatSum;
+}
+
+/**
+ * Add two floats (the 2nd one is dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param floatArg1 the 1st float
+ * @param floatArg2 a pointer to the 2nd float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatFromPointerByUpcallMH(float floatArg1, float *floatArg2, float (*upcallMH)(float, float *))
+{
+ float floatSum = (*upcallMH)(floatArg1, floatArg2);
+ return floatSum;
+}
+
+/**
+ * Add two floats (the 2nd one is assigned in native) by invoking an upcall method.
+ *
+ * @param floatArg1 the 1st float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatFromNativePtrByUpcallMH(float floatArg1, float (*upcallMH)(float, float *))
+{
+ float floatArg2 = 6.79F;
+ float floatSum = (*upcallMH)(floatArg1, &floatArg2);
+ return floatSum;
+}
+
+/**
+ * Add two floats (the 2nd one is dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ *
+ * @param floatArg1 the 1st float
+ * @param floatArg2 a pointer to the 2nd float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+float *
+addFloatAndFloatFromPtr_RetPtr_ByUpcallMH(float floatArg1, float *floatArg2, float *(*upcallMH)(float, float *))
+{
+ float *floatSum = (*upcallMH)(floatArg1, floatArg2);
+ return floatSum;
+}
+
+/**
+ * Add two doubles by invoking an upcall method.
+ *
+ * @param doubleArg1 the 1st double
+ * @param doubleArg2 the 2nd double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+add2DoublesByUpcallMH(double doubleArg1, double doubleArg2, double (*upcallMH)(double, double))
+{
+ double doubleSum = (*upcallMH)(doubleArg1, doubleArg2);
+ return doubleSum;
+}
+
+/**
+ * Add two doubles (the 1st one dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param doubleArg1 a pointer to the 1st double
+ * @param doubleArg2 the 2nd double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleFromPointerByUpcallMH(double *doubleArg1, double doubleArg2, double (*upcallMH)(double *, double))
+{
+ double doubleSum = (*upcallMH)(doubleArg1, doubleArg2);
+ return doubleSum;
+}
+
+/**
+ * Add two doubles (the 1st one is assigned in native) by invoking an upcall method.
+ *
+ * @param doubleArg2 the 2nd double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleFromNativePtrByUpcallMH(double doubleArg2, double (*upcallMH)(double *, double))
+{
+ double doubleArg1 = 1159.748;
+ double doubleSum = (*upcallMH)(&doubleArg1, doubleArg2);
+ return doubleSum;
+}
+
+/**
+ * Add two doubles (the 1st one dereferenced from a pointer) by invoking an upcall method
+ * and return a pointer to the sum.
+ *
+ * @param doubleArg1 a pointer to the 1st double
+ * @param doubleArg2 the 2nd double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the pointer to the sum
+ */
+double *
+addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH(double *doubleArg1, double doubleArg2, double *(*upcallMH)(double *, double))
+{
+ double *doubleSum = (*upcallMH)(doubleArg1, doubleArg2);
+ return doubleSum;
+}
+
+/**
+ * Add a boolean and two booleans of a struct with the XOR (^) operator
+ * by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructWithXorByUpcallMH(bool arg1, stru_Bool_Bool arg2, bool (*upcallMH)(bool, stru_Bool_Bool))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and 20 booleans of a struct with the XOR (^) operator
+ * by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with 20 booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAnd20BoolsFromStructWithXorByUpcallMH(bool arg1, stru_20_Bools arg2, bool (*upcallMH)(bool, stru_20_Bools))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean (dereferenced from a pointer) and all booleans of
+ * a struct with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a pointer to boolean
+ * @param arg2 a struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH(bool *arg1, stru_Bool_Bool arg2, bool (*upcallMH)(bool *, stru_Bool_Bool))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Get a pointer to boolean by adding a boolean (dereferenced from a pointer) and all booleans
+ * of a struct with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a pointer to boolean
+ * @param arg2 a struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the XOR result of booleans
+ */
+bool *
+addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH(bool *arg1, stru_Bool_Bool arg2, bool * (*upcallMH)(bool *, stru_Bool_Bool))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a boolean and two booleans of a struct (dereferenced from a pointer)
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a pointer to struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructPointerWithXorByUpcallMH(bool arg1, stru_Bool_Bool *arg2, bool (*upcallMH)(bool, stru_Bool_Bool *))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a nested struct and a boolean
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a nested struct and a boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromNestedStructWithXorByUpcallMH(bool arg1, stru_NestedStruct_Bool arg2, bool (*upcallMH)(bool, stru_NestedStruct_Bool))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a boolean and a nested struct (in reverse order)
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a boolean and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH(bool arg1, stru_Bool_NestedStruct arg2, bool (*upcallMH)(bool, stru_Bool_NestedStruct))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a nested array and a boolean
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a nested array and a boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH(bool arg1, stru_NestedBoolArray_Bool arg2, bool (*upcallMH)(bool, stru_NestedBoolArray_Bool))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a boolean and a nested array (in reverse order)
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a boolean and a nested array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH(bool arg1, stru_Bool_NestedBoolArray arg2, bool (*upcallMH)(bool, stru_Bool_NestedBoolArray))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a nested struct array and a boolean
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a nested struct array and a boolean
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH(bool arg1, stru_NestedStruArray_Bool arg2, bool (*upcallMH)(bool, stru_NestedStruArray_Bool))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Add a boolean and all booleans of a struct with a boolean and a nested struct array
+ * (in reverse order) with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a boolean
+ * @param arg2 a struct with a boolean and a nested struct array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the XOR result of booleans
+ */
+bool
+addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH(bool arg1, stru_Bool_NestedStruArray arg2, bool (*upcallMH)(bool, stru_Bool_NestedStruArray))
+{
+ bool boolSum = (*upcallMH)(arg1, arg2);
+ return boolSum;
+}
+
+/**
+ * Get a new struct by adding each boolean of two structs
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two booleans
+ * @param arg2 the 2nd struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two booleans
+ */
+stru_Bool_Bool
+add2BoolStructsWithXor_returnStructByUpcallMH(stru_Bool_Bool arg1, stru_Bool_Bool arg2, stru_Bool_Bool (*upcallMH)(stru_Bool_Bool, stru_Bool_Bool))
+{
+ stru_Bool_Bool boolStruct = (*upcallMH)(arg1, arg2);
+ return boolStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each boolean of two structs
+ * with the XOR (^) operator by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two booleans
+ * @param arg2 the 2nd struct with two booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two booleans
+ */
+stru_Bool_Bool *
+add2BoolStructsWithXor_returnStructPointerByUpcallMH(stru_Bool_Bool *arg1, stru_Bool_Bool arg2, stru_Bool_Bool * (*upcallMH)(stru_Bool_Bool *, stru_Bool_Bool))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Get a new struct by adding each boolean of two structs with
+ * three booleans by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three booleans
+ * @param arg2 the 2nd struct with three booleans
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three booleans
+ */
+stru_Bool_Bool_Bool
+add3BoolStructsWithXor_returnStructByUpcallMH(stru_Bool_Bool_Bool arg1, stru_Bool_Bool_Bool arg2, stru_Bool_Bool_Bool (*upcallMH)(stru_Bool_Bool_Bool, stru_Bool_Bool_Bool))
+{
+ stru_Bool_Bool_Bool boolStruct = (*upcallMH)(arg1, arg2);
+ return boolStruct;
+}
+
+/**
+ * Add a byte and two bytes of a struct by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructByUpcallMH(char arg1, stru_Byte_Byte arg2, char (*upcallMH)(char, stru_Byte_Byte))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and 20 bytes of a struct by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with 20 bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAnd20BytesFromStructByUpcallMH(char arg1, stru_20_Bytes arg2, char (*upcallMH)(char, stru_20_Bytes))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte (dereferenced from a pointer) and two bytes
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to byte
+ * @param arg2 a struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteFromPointerAndBytesFromStructByUpcallMH(char *arg1, stru_Byte_Byte arg2, char (*upcallMH)(char *, stru_Byte_Byte))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Get a pointer to byte by adding a byte (dereferenced from a pointer)
+ * and two bytes of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to byte
+ * @param arg2 a struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+char *
+addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH(char *arg1, stru_Byte_Byte arg2, char * (*upcallMH)(char *, stru_Byte_Byte))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a byte and two bytes of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a pointer to struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructPointerByUpcallMH(char arg1, stru_Byte_Byte *arg2, char (*upcallMH)(char, stru_Byte_Byte *))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all bytes of a struct with a nested struct
+ * and a byte by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a nested struct and a byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromNestedStructByUpcallMH(char arg1, stru_NestedStruct_Byte arg2, char (*upcallMH)(char, stru_NestedStruct_Byte))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all bytes of a struct with a byte and a nested struct
+ * (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a byte and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH(char arg1, stru_Byte_NestedStruct arg2, char (*upcallMH)(char, stru_Byte_NestedStruct))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all byte elements of a struct with a nested byte array
+ * and a byte by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a nested byte array and a byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructWithNestedByteArrayByUpcallMH(char arg1, stru_NestedByteArray_Byte arg2, char (*upcallMH)(char, stru_NestedByteArray_Byte))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all byte elements of a struct with a byte and a nested byte array
+ * (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a byte and a nested byte array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH(char arg1, stru_Byte_NestedByteArray arg2, char (*upcallMH)(char, stru_Byte_NestedByteArray))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all byte elements of a struct with a nested struct array
+ * and a byte by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a nested struct array and a byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructWithNestedStructArrayByUpcallMH(char arg1, stru_NestedStruArray_Byte arg2, char (*upcallMH)(char, stru_NestedStruArray_Byte))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Add a byte and all byte elements of a struct with a byte and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a byte
+ * @param arg2 a struct with a byte and a nested byte array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH(char arg1, stru_Byte_NestedStruArray arg2, char (*upcallMH)(char, stru_Byte_NestedStruArray))
+{
+ char byteSum = (*upcallMH)(arg1, arg2);
+ return byteSum;
+}
+
+/**
+ * Get a new struct by adding each byte element of two structs with
+ * two byte elements by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with one byte
+ * @param arg2 the 2nd struct with one byte
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with one byte
+ */
+stru_Byte
+add1ByteStructs_returnStructByUpcallMH(stru_Byte arg1, stru_Byte arg2, stru_Byte (*upcallMH)(stru_Byte, stru_Byte))
+{
+ stru_Byte byteStruct = (*upcallMH)(arg1, arg2);
+ return byteStruct;
+}
+
+/**
+ * Get a new struct by adding each byte element of two structs with
+ * two byte elements by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two bytes
+ * @param arg2 the 2nd struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two bytes
+ */
+stru_Byte_Byte
+add2ByteStructs_returnStructByUpcallMH(stru_Byte_Byte arg1, stru_Byte_Byte arg2, stru_Byte_Byte (*upcallMH)(stru_Byte_Byte, stru_Byte_Byte))
+{
+ stru_Byte_Byte byteStruct = (*upcallMH)(arg1, arg2);
+ return byteStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each byte element of two structs
+ * with two byte elements by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two bytes
+ * @param arg2 the 2nd struct with two bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two bytes
+ */
+stru_Byte_Byte *
+add2ByteStructs_returnStructPointerByUpcallMH(stru_Byte_Byte *arg1, stru_Byte_Byte arg2, stru_Byte_Byte * (*upcallMH)(stru_Byte_Byte *, stru_Byte_Byte))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Get a new struct by adding each byte element of two structs with
+ * three byte elements by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three bytes
+ * @param arg2 the 2nd struct with three bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three bytes
+ */
+stru_Byte_Byte_Byte
+add3ByteStructs_returnStructByUpcallMH(stru_Byte_Byte_Byte arg1, stru_Byte_Byte_Byte arg2, stru_Byte_Byte_Byte (*upcallMH)(stru_Byte_Byte_Byte, stru_Byte_Byte_Byte))
+{
+ stru_Byte_Byte_Byte byteStruct = (*upcallMH)(arg1, arg2);
+ return byteStruct;
+}
+
+/**
+ * Generate a new char by adding a char and two chars of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructByUpcallMH(short arg1, stru_Char_Char arg2, short (*upcallMH)(short, stru_Char_Char))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and 10 chars of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with 10 chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAnd10CharsFromStructByUpcallMH(short arg1, stru_10_Chars arg2, short (*upcallMH)(short, stru_10_Chars))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+
+/**
+ * Generate a new char by adding a char (dereferenced from a pointer)
+ * and two chars of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to char
+ * @param arg2 a struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharFromPointerAndCharsFromStructByUpcallMH(short *arg1, stru_Char_Char arg2, short (*upcallMH)(short *, stru_Char_Char))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Get a pointer to char by adding a char (dereferenced from a pointer)
+ * and two chars of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to char
+ * @param arg2 a struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to a new char
+ */
+short *
+addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH(short *arg1, stru_Char_Char arg2, short * (*upcallMH)(short *, stru_Char_Char))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Generate a new char by adding a char and two chars of struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a pointer to struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructPointerByUpcallMH(short arg1, stru_Char_Char *arg2, short (*upcallMH)(short, stru_Char_Char *))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct
+ * with a nested struct and a char by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromNestedStructByUpcallMH(short arg1, stru_NestedStruct_Char arg2, short (*upcallMH)(short, stru_NestedStruct_Char))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct with a char
+ * and a nested struct (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a char and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH(short arg1, stru_Char_NestedStruct arg2, short (*upcallMH)(short, stru_Char_NestedStruct))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct with
+ * a nested char array and a char by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a nested char array and a char
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructWithNestedCharArrayByUpcallMH(short arg1, stru_NestedCharArray_Char arg2, short (*upcallMH)(short, stru_NestedCharArray_Char))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct with a char
+ * and a nested char array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a char and a nested char array
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH(short arg1, stru_Char_NestedCharArray arg2, short (*upcallMH)(short, stru_Char_NestedCharArray))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct with
+ * a nested struct array and a char by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a nested char array and a char
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructWithNestedStructArrayByUpcallMH(short arg1, stru_NestedStruArray_Char arg2, short (*upcallMH)(short, stru_NestedStruArray_Char))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Generate a new char by adding a char and all char elements of a struct with a char
+ * and a nested struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a char
+ * @param arg2 a struct with a char and a nested char array
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new char
+ */
+short
+addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH(short arg1, stru_Char_NestedStruArray arg2, short (*upcallMH)(short, stru_Char_NestedStruArray))
+{
+ short result = (*upcallMH)(arg1, arg2);
+ return result;
+}
+
+/**
+ * Create a new struct by adding each char element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two chars
+ * @param arg2 the 2nd struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new struct of with two chars
+ */
+stru_Char_Char
+add2CharStructs_returnStructByUpcallMH(stru_Char_Char arg1, stru_Char_Char arg2, stru_Char_Char (*upcallMH)(stru_Char_Char, stru_Char_Char))
+{
+ stru_Char_Char charStruct = (*upcallMH)(arg1, arg2);
+ return charStruct;
+}
+
+/**
+ * Get a pointer to a struct by adding each element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two chars
+ * @param arg2 the 2nd struct with two chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to a struct of with two chars
+ */
+stru_Char_Char *
+add2CharStructs_returnStructPointerByUpcallMH(stru_Char_Char *arg1, stru_Char_Char arg2, stru_Char_Char * (*upcallMH)(stru_Char_Char *, stru_Char_Char))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Create a new struct by adding each char element of two structs
+ * with three chars by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three chars
+ * @param arg2 the 2nd struct with three chars
+ * @param upcallMH the function pointer to the upcall method
+ * @return a new struct of with three chars
+ */
+stru_Char_Char_Char
+add3CharStructs_returnStructByUpcallMH(stru_Char_Char_Char arg1, stru_Char_Char_Char arg2, stru_Char_Char_Char (*upcallMH)(stru_Char_Char_Char, stru_Char_Char_Char))
+{
+ stru_Char_Char_Char charStruct = (*upcallMH)(arg1, arg2);
+ return charStruct;
+}
+
+/**
+ * Add a short and two shorts of a struct by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructByUpcallMH(short arg1, stru_Short_Short arg2, short (*upcallMH)(short, stru_Short_Short))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and 10 shorts of a struct by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with 10 shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAnd10ShortsFromStructByUpcallMH(short arg1, stru_10_Shorts arg2, short (*upcallMH)(short, stru_10_Shorts))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short (dereferenced from a pointer) and two shorts of
+ * a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to short
+ * @param arg2 a struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortFromPointerAndShortsFromStructByUpcallMH(short *arg1, stru_Short_Short arg2, short (*upcallMH)(short *, stru_Short_Short))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short (dereferenced from a pointer) and two shorts
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to short
+ * @param arg2 a struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+short *
+addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH(short *arg1, stru_Short_Short arg2, short * (*upcallMH)(short *, stru_Short_Short))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a short and two shorts of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a pointer to struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructPointerByUpcallMH(short arg1, stru_Short_Short *arg2, short (*upcallMH)(short, stru_Short_Short *))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a nested struct
+ * and a short by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a nested struct and a short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromNestedStructByUpcallMH(short arg1, stru_NestedStruct_Short arg2, short (*upcallMH)(short, stru_NestedStruct_Short))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a short and a nested struct
+ * (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a short and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH(short arg1, stru_Short_NestedStruct arg2, short (*upcallMH)(short, stru_Short_NestedStruct))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a nested short array
+ * and a short by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a nested short array and a short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructWithNestedShortArrayByUpcallMH(short arg1, stru_NestedShortArray_Short arg2, short (*upcallMH)(short, stru_NestedShortArray_Short))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a short and a nested
+ * short array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a short and a nested short array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH(short arg1, stru_Short_NestedShortArray arg2, short (*upcallMH)(short, stru_Short_NestedShortArray))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a nested struct
+ * array and a short by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a nested short array and a short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructWithNestedStructArrayByUpcallMH(short arg1, stru_NestedStruArray_Short arg2, short (*upcallMH)(short, stru_NestedStruArray_Short))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a short and all short elements of a struct with a short and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with a short and a nested short array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH(short arg1, stru_Short_NestedStruArray arg2, short (*upcallMH)(short, stru_Short_NestedStruArray))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Get a new struct by adding each short element of two structs
+ * with two short elements by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two shorts
+ * @param arg2 the 2nd struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two shorts
+ */
+stru_Short_Short
+add2ShortStructs_returnStructByUpcallMH(stru_Short_Short arg1, stru_Short_Short arg2, stru_Short_Short (*upcallMH)(stru_Short_Short, stru_Short_Short))
+{
+ stru_Short_Short shortStruct = (*upcallMH)(arg1, arg2);
+ return shortStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each short element of two structs
+ * with two short elements by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two shorts
+ * @param arg2 the 2nd struct with two shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two shorts
+ */
+stru_Short_Short *
+add2ShortStructs_returnStructPointerByUpcallMH(stru_Short_Short *arg1, stru_Short_Short arg2, stru_Short_Short * (*upcallMH)(stru_Short_Short *, stru_Short_Short))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Get a new struct by adding each short element of two structs with
+ * three short elements by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three shorts
+ * @param arg2 the 2nd struct with three shorts
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three shorts
+ */
+stru_Short_Short_Short
+add3ShortStructs_returnStructByUpcallMH(stru_Short_Short_Short arg1, stru_Short_Short_Short arg2, stru_Short_Short_Short (*upcallMH)(stru_Short_Short_Short, stru_Short_Short_Short))
+{
+ stru_Short_Short_Short shortStruct = (*upcallMH)(arg1, arg2);
+ return shortStruct;
+}
+
+/**
+ * Add an int and two ints of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructByUpcallMH(int arg1, stru_Int_Int arg2, int (*upcallMH)(int, stru_Int_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and 5 ints of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with 5 ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAnd5IntsFromStructByUpcallMH(int arg1, stru_5_Ints arg2, int (*upcallMH)(int, stru_5_Ints))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int (dereferenced from a pointer) and two ints
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to int
+ * @param arg2 a struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntFromPointerAndIntsFromStructByUpcallMH(int *arg1, stru_Int_Int arg2, int (*upcallMH)(int *, stru_Int_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int (dereferenced from a pointer) and two ints
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to int
+ * @param arg2 a struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+int *
+addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH(int *arg1, stru_Int_Int arg2, int *(*upcallMH)(int *, stru_Int_Int))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add an int and two ints of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a pointer to struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructPointerByUpcallMH(int arg1, stru_Int_Int *arg2, int (*upcallMH)(int, stru_Int_Int *))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with a nested struct
+ * and an int by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with a nested struct and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromNestedStructByUpcallMH(int arg1, stru_NestedStruct_Int arg2, int (*upcallMH)(int, stru_NestedStruct_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with an int and
+ * a nested struct (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with an int and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH(int arg1, stru_Int_NestedStruct arg2, int (*upcallMH)(int, stru_Int_NestedStruct))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with a nested int array
+ * and an int by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with a nested int array and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructWithNestedIntArrayByUpcallMH(int arg1, stru_NestedIntArray_Int arg2, int (*upcallMH)(int, stru_NestedIntArray_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with an int and a
+ * nested int array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with an int and a nested int array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH(int arg1, stru_Int_NestedIntArray arg2, int (*upcallMH)(int, stru_Int_NestedIntArray))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with a nested struct array
+ * and an int by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with a nested int array and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructWithNestedStructArrayByUpcallMH(int arg1, stru_NestedStruArray_Int arg2, int (*upcallMH)(int, stru_NestedStruArray_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all int elements of a struct with an int and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with an int and a nested int array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH(int arg1, stru_Int_NestedStruArray arg2, int (*upcallMH)(int, stru_Int_NestedStruArray))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Get a new struct by adding each int element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two ints
+ * @param arg2 the 2nd struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two ints
+ */
+stru_Int_Int
+add2IntStructs_returnStructByUpcallMH(stru_Int_Int arg1, stru_Int_Int arg2, stru_Int_Int (*upcallMH)(stru_Int_Int, stru_Int_Int))
+{
+ stru_Int_Int intStruct = (*upcallMH)(arg1, arg2);
+ return intStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each int element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two ints
+ * @param arg2 the 2nd struct with two ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two ints
+ */
+stru_Int_Int *
+add2IntStructs_returnStructPointerByUpcallMH(stru_Int_Int *arg1, stru_Int_Int arg2, stru_Int_Int * (*upcallMH)(stru_Int_Int *, stru_Int_Int))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Get a new struct by adding each int element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three ints
+ * @param arg2 the 2nd struct with three ints
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three ints
+ */
+stru_Int_Int_Int
+add3IntStructs_returnStructByUpcallMH(stru_Int_Int_Int arg1, stru_Int_Int_Int arg2, stru_Int_Int_Int (*upcallMH)(stru_Int_Int_Int, stru_Int_Int_Int))
+{
+ stru_Int_Int_Int intStruct = (*upcallMH)(arg1, arg2);
+ return intStruct;
+}
+
+/**
+ * Add a long and two longs of a struct by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructByUpcallMH(LONG arg1, stru_Long_Long arg2, LONG (*upcallMH)(LONG, stru_Long_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long (dereferenced from a pointer) and two longs
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to long
+ * @param arg2 a struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongFromPointerAndLongsFromStructByUpcallMH(LONG *arg1, stru_Long_Long arg2, LONG (*upcallMH)(LONG *, stru_Long_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long (dereferenced from a pointer) and two longs
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to long
+ * @param arg2 a struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+LONG *
+addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH(LONG *arg1, stru_Long_Long arg2, LONG * (*upcallMH)(LONG *, stru_Long_Long))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a long and two longs of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a pointer to struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructPointerByUpcallMH(LONG arg1, stru_Long_Long *arg2, LONG (*upcallMH)(LONG, stru_Long_Long *))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a nested struct
+ * and a long by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a nested struct and long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromNestedStructByUpcallMH(LONG arg1, stru_NestedStruct_Long arg2, LONG (*upcallMH)(LONG, stru_NestedStruct_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a long and a nested
+ * struct (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a long and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH(LONG arg1, stru_Long_NestedStruct arg2, LONG (*upcallMH)(LONG, stru_Long_NestedStruct))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a nested long
+ * array and a long by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a nested long array and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructWithNestedLongArrayByUpcallMH(LONG arg1, stru_NestedLongArray_Long arg2, LONG (*upcallMH)(LONG, stru_NestedLongArray_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a long and a nested
+ * long array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a long and a nested long array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH(LONG arg1, stru_Long_NestedLongArray arg2, LONG (*upcallMH)(LONG, stru_Long_NestedLongArray))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a nested struct
+ * array and a long by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a nested long array and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructWithNestedStructArrayByUpcallMH(LONG arg1, stru_NestedStruArray_Long arg2, LONG (*upcallMH)(LONG, stru_NestedStruArray_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a long and all long elements of a struct with a long and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a long and a nested long array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH(LONG arg1, stru_Long_NestedStruArray arg2, LONG (*upcallMH)(LONG, stru_Long_NestedStruArray))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Get a new struct by adding each long element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two longs
+ * @param arg2 the 2nd struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two longs
+ */
+stru_Long_Long
+add2LongStructs_returnStructByUpcallMH(stru_Long_Long arg1, stru_Long_Long arg2, stru_Long_Long (*upcallMH)(stru_Long_Long, stru_Long_Long))
+{
+ stru_Long_Long longStruct = (*upcallMH)(arg1, arg2);
+ return longStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each long element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two longs
+ * @param arg2 the 2nd struct with two longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two longs
+ */
+stru_Long_Long *
+add2LongStructs_returnStructPointerByUpcallMH(stru_Long_Long *arg1, stru_Long_Long arg2, stru_Long_Long * (*upcallMH)(stru_Long_Long *, stru_Long_Long))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Get a new struct by adding each long element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three longs
+ * @param arg2 the 2nd struct with three longs
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three longs
+ */
+stru_Long_Long_Long
+add3LongStructs_returnStructByUpcallMH(stru_Long_Long_Long arg1, stru_Long_Long_Long arg2, stru_Long_Long_Long (*upcallMH)(stru_Long_Long_Long, stru_Long_Long_Long))
+{
+ stru_Long_Long_Long longStruct = (*upcallMH)(arg1, arg2);
+ return longStruct;
+}
+
+/**
+ * Add a float and two floats of a struct by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructByUpcallMH(float arg1, stru_Float_Float arg2, float (*upcallMH)(float, stru_Float_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and 5 floats of a struct by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with 5 floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAnd5FloatsFromStructByUpcallMH(float arg1, stru_5_Floats arg2, float (*upcallMH)(float, stru_5_Floats))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float (dereferenced from a pointer) and two floats
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to float
+ * @param arg2 a struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatFromPointerAndFloatsFromStructByUpcallMH(float *arg1, stru_Float_Float arg2, float (*upcallMH)(float *, stru_Float_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float (dereferenced from a pointer) and two floats
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to float
+ * @param arg2 a struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+float *
+addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH(float *arg1, stru_Float_Float arg2, float * (*upcallMH)(float *, stru_Float_Float))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a float and two floats of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a pointer to struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructPointerByUpcallMH(float arg1, stru_Float_Float *arg2, float (*upcallMH)(float, stru_Float_Float *))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a nested
+ * struct and a float by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a nested struct and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromNestedStructByUpcallMH(float arg1, stru_NestedStruct_Float arg2, float (*upcallMH)(float, stru_NestedStruct_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a float and a nested struct
+ * (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a float and a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH(float arg1, stru_Float_NestedStruct arg2, float (*upcallMH)(float, stru_Float_NestedStruct))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a nested
+ * float array and a float by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a nested float array and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH(float arg1, stru_NestedFloatArray_Float arg2, float (*upcallMH)(float, stru_NestedFloatArray_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a float and a nested
+ * float array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a float and a nested float array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH(float arg1, stru_Float_NestedFloatArray arg2, float (*upcallMH)(float, stru_Float_NestedFloatArray))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a nested
+ * struct array and a float by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a nested float array and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH(float arg1, stru_NestedStruArray_Float arg2, float (*upcallMH)(float, stru_NestedStruArray_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all float elements of a struct with a float and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a float and a nested float array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH(float arg1, stru_Float_NestedStruArray arg2, float (*upcallMH)(float, stru_Float_NestedStruArray))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Create a new struct by adding each float element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two floats
+ * @param arg2 the 2nd struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two floats
+ */
+stru_Float_Float
+add2FloatStructs_returnStructByUpcallMH(stru_Float_Float arg1, stru_Float_Float arg2, stru_Float_Float (*upcallMH)(stru_Float_Float, stru_Float_Float))
+{
+ stru_Float_Float floatStruct = (*upcallMH)(arg1, arg2);
+ return floatStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each float element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two floats
+ * @param arg2 the 2nd struct with two floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two floats
+ */
+stru_Float_Float *
+add2FloatStructs_returnStructPointerByUpcallMH(stru_Float_Float *arg1, stru_Float_Float arg2, stru_Float_Float * (*upcallMH)(stru_Float_Float *, stru_Float_Float))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Create a new struct by adding each float element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three floats
+ * @param arg2 the 2nd struct with three floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three floats
+ */
+stru_Float_Float_Float
+add3FloatStructs_returnStructByUpcallMH(stru_Float_Float_Float arg1, stru_Float_Float_Float arg2, stru_Float_Float_Float (*upcallMH)(stru_Float_Float_Float, stru_Float_Float_Float))
+{
+ stru_Float_Float_Float floatStruct = (*upcallMH)(arg1, arg2);
+ return floatStruct;
+}
+
+/**
+ * Add a double and two doubles of a struct by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructByUpcallMH(double arg1, stru_Double_Double arg2, double (*upcallMH)(double, stru_Double_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double (dereferenced from a pointer) and two doubles
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to double
+ * @param arg2 a struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleFromPointerAndDoublesFromStructByUpcallMH(double *arg1, stru_Double_Double arg2, double (*upcallMH)(double *, stru_Double_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double (dereferenced from a pointer) and two doubles
+ * of a struct by invoking an upcall method.
+ *
+ * @param arg1 a pointer to double
+ * @param arg2 a struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to the sum
+ */
+double *
+addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH(double *arg1, stru_Double_Double arg2, double * (*upcallMH)(double *, stru_Double_Double))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Add a double and two doubles of a struct (dereferenced from a pointer)
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a pointer to struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructPointerByUpcallMH(double arg1, stru_Double_Double *arg2, double (*upcallMH)(double, stru_Double_Double *))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all doubles of a struct with a nested struct
+ * and a double by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a nested struct and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromNestedStructByUpcallMH(double arg1, stru_NestedStruct_Double arg2, double (*upcallMH)(double, stru_NestedStruct_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all doubles of a struct with a double and a nested struct
+ * (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double a nested struct
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH(double arg1, stru_Double_NestedStruct arg2, double (*upcallMH)(double, stru_Double_NestedStruct))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all double elements of a struct with a nested
+ * double array and a double by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a nested double array and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH(double arg1, stru_NestedDoubleArray_Double arg2, double (*upcallMH)(double, stru_NestedDoubleArray_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all double elements of a struct with a double and a nested
+ * double array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and a nested double array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH(double arg1, stru_Double_NestedDoubleArray arg2, double (*upcallMH)(double, stru_Double_NestedDoubleArray))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all double elements of a struct with a nested struct array
+ * and a double by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a nested double array and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH(double arg1, stru_NestedStruArray_Double arg2, double (*upcallMH)(double, stru_NestedStruArray_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all double elements of a struct with a double and a nested
+ * struct array (in reverse order) by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and a nested double array
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH(double arg1, stru_Double_NestedStruArray arg2, double (*upcallMH)(double, stru_Double_NestedStruArray))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Create a new struct by adding each double element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with two doubles
+ * @param arg2 the 2nd struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with two doubles
+ */
+stru_Double_Double
+add2DoubleStructs_returnStructByUpcallMH(stru_Double_Double arg1, stru_Double_Double arg2, stru_Double_Double (*upcallMH)(stru_Double_Double, stru_Double_Double))
+{
+ stru_Double_Double doubleStruct = (*upcallMH)(arg1, arg2);
+ return doubleStruct;
+}
+
+/**
+ * Get a pointer to struct by adding each double element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 a pointer to the 1st struct with two doubles
+ * @param arg2 the 2nd struct with two doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return a pointer to struct with two doubles
+ */
+stru_Double_Double *
+add2DoubleStructs_returnStructPointerByUpcallMH(stru_Double_Double *arg1, stru_Double_Double arg2, stru_Double_Double * (*upcallMH)(stru_Double_Double *, stru_Double_Double))
+{
+ arg1 = (*upcallMH)(arg1, arg2);
+ return arg1;
+}
+
+/**
+ * Create a new struct by adding each double element of two structs
+ * by invoking an upcall method.
+ *
+ * @param arg1 the 1st struct with three doubles
+ * @param arg2 the 2nd struct with three doubles
+ * @param upcallMH the function pointer to the upcall method
+ * @return a struct with three doubles
+ */
+stru_Double_Double_Double
+add3DoubleStructs_returnStructByUpcallMH(stru_Double_Double_Double arg1, stru_Double_Double_Double arg2, stru_Double_Double_Double (*upcallMH)(stru_Double_Double_Double, stru_Double_Double_Double))
+{
+ stru_Double_Double_Double doubleStruct = (*upcallMH)(arg1, arg2);
+ return doubleStruct;
+}
+
+/**
+ * Add an int and all elements (int & short) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with an int and a short
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndIntShortFromStructByUpcallMH(int arg1, stru_Int_Short arg2, int (*upcallMH)(int, stru_Int_Short))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all elements (short & int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with a short and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntAndShortIntFromStructByUpcallMH(int arg1, stru_Short_Int arg2, int (*upcallMH)(int, stru_Short_Int))
+{
+ int intSum = (*upcallMH)(arg1, arg2);
+ return intSum;
+}
+
+/**
+ * Add an int and all elements (int & long) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with an int and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addIntAndIntLongFromStructByUpcallMH(int arg1, stru_Int_Long arg2, LONG (*upcallMH)(int, stru_Int_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add an int and all elements (long & int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 an int
+ * @param arg2 a struct with a long and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addIntAndLongIntFromStructByUpcallMH(int arg1, stru_Long_Int arg2, LONG (*upcallMH)(int, stru_Long_Int))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a double and all elements (double & int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleIntFromStructByUpcallMH(double arg1, stru_Double_Int arg2, double (*upcallMH)(double, stru_Double_Int))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (int & double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with an int and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndIntDoubleFromStructByUpcallMH(double arg1, stru_Int_Double arg2, double (*upcallMH)(double, stru_Int_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (float & double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a float and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndFloatDoubleFromStructByUpcallMH(double arg1, stru_Float_Double arg2, double (*upcallMH)(double, stru_Float_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (double & float) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleFloatFromStructByUpcallMH(double arg1, stru_Double_Float arg2, double (*upcallMH)(double, stru_Double_Float))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (2 floats & a double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with 2 floats and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAnd2FloatsDoubleFromStructByUpcallMH(double arg1, stru_Float_Float_Double arg2, double (*upcallMH)(double, stru_Float_Float_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (a double & 2 floats) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and 2 floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDouble2FloatsFromStructByUpcallMH(double arg1, stru_Double_Float_Float arg2, double (*upcallMH)(double, stru_Double_Float_Float))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a float and all elements (int & 2 floats) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with an int and 2 floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndInt2FloatsFromStructByUpcallMH(float arg1, stru_Int_Float_Float arg2, float (*upcallMH)(float, stru_Int_Float_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a float and all elements (float, int and float) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with a float, an int and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndFloatIntFloatFromStructByUpcallMH(float arg1, stru_Float_Int_Float arg2, float (*upcallMH)(float, stru_Float_Int_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a double and all elements (int, float & double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with an int, a float and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndIntFloatDoubleFromStructByUpcallMH(double arg1, stru_Int_Float_Double arg2, double (*upcallMH)(double, stru_Int_Float_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (float, int & double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a float, an int and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndFloatIntDoubleFromStructByUpcallMH(double arg1, stru_Float_Int_Double arg2, double (*upcallMH)(double, stru_Float_Int_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (long & double) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a long and a double
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndLongDoubleFromStructByUpcallMH(double arg1, stru_Long_Double arg2, double (*upcallMH)(double, stru_Long_Double))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a float and all elements (int & 3 floats) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with an int and 3 floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndInt3FloatsFromStructByUpcallMH(float arg1, stru_Int_3_Floats arg2, float (*upcallMH)(float, stru_Int_3_Floats))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a long and all elements (long & 2 floats) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a long and 2 floats
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndLong2FloatsFromStructByUpcallMH(LONG arg1, stru_Long_2_Floats arg2, LONG (*upcallMH)(LONG, stru_Long_2_Floats))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a float and all elements (3 floats & int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with 3 floats and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAnd3FloatsIntFromStructByUpcallMH(float arg1, stru_3_Floats_Int arg2, float (*upcallMH)(float, stru_3_Floats_Int))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a long and all elements (float & long) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with a float and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAndFloatLongFromStructByUpcallMH(LONG arg1, stru_Float_Long arg2, LONG (*upcallMH)(LONG, stru_Float_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a double and all elements (double, float & int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double, a float and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleFloatIntFromStructByUpcallMH(double arg1, stru_Double_Float_Int arg2, double (*upcallMH)(double, stru_Double_Float_Int))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (double & long) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a double and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndDoubleLongFromStructByUpcallMH(double arg1, stru_Double_Long arg2, double (*upcallMH)(double, stru_Double_Long))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a long and all elements (2 floats & a long) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a long
+ * @param arg2 a struct with 2 floats and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongAnd2FloatsLongFromStructByUpcallMH(LONG arg1, stru_Float_Float_Long arg2, LONG (*upcallMH)(LONG, stru_Float_Float_Long))
+{
+ LONG longSum = (*upcallMH)(arg1, arg2);
+ return longSum;
+}
+
+/**
+ * Add a short and all elements (an array of 3 shorts & a char) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a short
+ * @param arg2 a struct with an array of 3 shorts & a char
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+addShortAnd3ShortsCharFromStructByUpcallMH(short arg1, stru_3_Shorts_Char arg2, short (*upcallMH)(short, stru_3_Shorts_Char))
+{
+ short shortSum = (*upcallMH)(arg1, arg2);
+ return shortSum;
+}
+
+/**
+ * Add a float and all elements (int, float, int & float) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a float
+ * @param arg2 a struct with an int, a float, an int and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+addFloatAndIntFloatIntFloatFromStructByUpcallMH(float arg1, stru_Int_Float_Int_Float arg2, float (*upcallMH)(float, stru_Int_Float_Int_Float))
+{
+ float floatSum = (*upcallMH)(arg1, arg2);
+ return floatSum;
+}
+
+/**
+ * Add a double and all elements (int, double, float) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with an int, a double and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndIntDoubleFloatFromStructByUpcallMH(double arg1, stru_Int_Double_Float arg2, double (*upcallMH)(double, stru_Int_Double_Float))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (float, double, int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a float, a double and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndFloatDoubleIntFromStructByUpcallMH(double arg1, stru_Float_Double_Int arg2, double (*upcallMH)(double, stru_Float_Double_Int))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (int, double, int) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with an int, a double and an int
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndIntDoubleIntFromStructByUpcallMH(double arg1, stru_Int_Double_Int arg2, double (*upcallMH)(double, stru_Int_Double_Int))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (float, double, float) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with a float, a double and a float
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndFloatDoubleFloatFromStructByUpcallMH(double arg1, stru_Float_Double_Float arg2, double (*upcallMH)(double, stru_Float_Double_Float))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Add a double and all elements (int, double and long) of a struct
+ * by invoking an upcall method.
+ *
+ * @param arg1 a double
+ * @param arg2 a struct with an int, a double and a long
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoubleAndIntDoubleLongFromStructByUpcallMH(double arg1, stru_Int_Double_Long arg2, double (*upcallMH)(double, stru_Int_Double_Long))
+{
+ double doubleSum = (*upcallMH)(arg1, arg2);
+ return doubleSum;
+}
+
+/**
+ * Return a struct with 254 bytes by invoking an upcall method.
+ *
+ * @param arg a struct with 254 bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the struct
+ */
+stru_254_Bytes
+return254BytesFromStructByUpcallMH(stru_254_Bytes (*upcallMH)())
+{
+ return (*upcallMH)();
+}
+
+/**
+ * Return a struct with 4K bytes by invoking an upcall method.
+ *
+ * @param arg a struct with 4K bytes
+ * @param upcallMH the function pointer to the upcall method
+ * @return the struct
+ */
+stru_4K_Bytes
+return4KBytesFromStructByUpcallMH(stru_4K_Bytes (*upcallMH)())
+{
+ return (*upcallMH)();
+}
diff --git a/runtime/tests/clinkerffi/valist.c b/runtime/tests/clinkerffi/valist.c
new file mode 100644
index 00000000000..f8f08f9214a
--- /dev/null
+++ b/runtime/tests/clinkerffi/valist.c
@@ -0,0 +1,1109 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+
+/**
+ * This file contains the native code used by the VaList specific test cases
+ * via a Clinker FFI Downcall & Upcall in java, which come from:
+ * org.openj9.test.jep389.valist (JDK16/17)
+ * org.openj9.test.jep419.valist (JDK18)
+ * org.openj9.test.jep424.valist (JDK19+)
+ *
+ * Created by jincheng@ca.ibm.com
+ */
+
+#include
+#include
+#include
+#include "downcall.h"
+
+/**
+ * Add ints from the va_list with the specified count
+ *
+ * @param argCount the count of the ints
+ * @param intArgList the integer va_list
+ * @return the sum of ints from the va_list
+ */
+int
+addIntsFromVaList(int argCount, va_list intVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ intSum += va_arg(intVaList, int);
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add longs from the va_list with the specified count
+ *
+ * @param argCount the count of longs
+ * @param longArgList the long va_list
+ * @return the sum of longs from the va_list
+ */
+LONG
+addLongsFromVaList(int argCount, va_list longVaList)
+{
+ LONG longSum = 0;
+ while (argCount > 0) {
+ longSum += va_arg(longVaList, LONG);
+ argCount--;
+ }
+ return longSum;
+}
+
+/**
+ * Add doubles from the va_list with the specified count
+ *
+ * @param argCount the count of the doubles
+ * @param doubleArgList the double va_list
+ * @return the sum of doubles from the va_list
+ */
+double
+addDoublesFromVaList(int argCount, va_list doubleVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ doubleSum += va_arg(doubleVaList, double);
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add arguments with different types from the va_list
+ *
+ * @param argVaList the va_list with mixed arguments
+ * @return the sum of arguments from the va_list
+ */
+double
+addMixedArgsFromVaList(va_list argVaList)
+{
+ double argSum = va_arg(argVaList, int) + va_arg(argVaList, long) + va_arg(argVaList, double);
+ return argSum;
+}
+
+/**
+ * Add more arguments with different types from the va_list
+ *
+ * @param argVaList the va_list with mixed arguments
+ * @return the sum of arguments from the va_list
+ */
+double
+addMoreMixedArgsFromVaList(va_list argVaList)
+{
+ double argSum = va_arg(argVaList, int) + va_arg(argVaList, long) + va_arg(argVaList, int)
+ + va_arg(argVaList, long) + va_arg(argVaList, int) + va_arg(argVaList, long)
+ + va_arg(argVaList, int) + va_arg(argVaList, double) + va_arg(argVaList, int)
+ + va_arg(argVaList, double) + va_arg(argVaList, int) + va_arg(argVaList, double)
+ + va_arg(argVaList, int) + va_arg(argVaList, double) + va_arg(argVaList, int)
+ + va_arg(argVaList, double);
+ return argSum;
+}
+
+/**
+ * Add ints (accessed by pointers) from the va_list
+ *
+ * @param argCount the count of integer pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the integer pointers
+ * @return the sum of ints
+ */
+int
+addIntsByPtrFromVaList(int argCount, va_list ptrVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ intSum += *va_arg(ptrVaList, int *);
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add longs (accessed by pointers) from the va_list
+ *
+ * @param argCount the count of long pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the long pointers
+ * @return the sum of longs
+ */
+LONG
+addLongsByPtrFromVaList(int argCount, va_list ptrVaList)
+{
+ LONG longSum = 0;
+ while (argCount > 0) {
+ longSum += *va_arg(ptrVaList, LONG *);
+ argCount--;
+ }
+ return longSum;
+}
+
+/**
+ * Add doubles (accessed by pointers) from the va_list
+ *
+ * @param argCount the count of double pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the double pointers
+ * @return the sum of doubles
+ */
+double
+addDoublesByPtrFromVaList(int argCount, va_list ptrVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ doubleSum += *va_arg(ptrVaList, double *);
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add the only one element(byte) of structs from the va_list
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+char
+add1ByteOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ char byteSum = 0;
+ while (argCount > 0) {
+ stru_Byte struArg = va_arg(struVaList, stru_Byte);
+ byteSum += struArg.elem1;
+ argCount--;
+ }
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with two elements from the va_list
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+char
+add2BytesOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ char byteSum = 0;
+ while (argCount > 0) {
+ stru_Byte_Byte struArg = va_arg(struVaList, stru_Byte_Byte);
+ byteSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with three elements from the va_list
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+char
+add3BytesOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ char byteSum = 0;
+ while (argCount > 0) {
+ stru_Byte_Byte_Byte struArg = va_arg(struVaList, stru_Byte_Byte_Byte);
+ byteSum += struArg.elem1 + struArg.elem2 + struArg.elem3;
+ argCount--;
+ }
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with five elements from the va_list
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+char
+add5BytesOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ char byteSum = 0;
+ while (argCount > 0) {
+ stru_5_Bytes struArg = va_arg(struVaList, stru_5_Bytes);
+ byteSum += struArg.elem1 + struArg.elem2 + struArg.elem3 + struArg.elem4 + struArg.elem5;
+ argCount--;
+ }
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with seven elements from the va_list
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+char
+add7BytesOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ char byteSum = 0;
+ while (argCount > 0) {
+ stru_7_Bytes struArg = va_arg(struVaList, stru_7_Bytes);
+ byteSum += struArg.elem1 + struArg.elem2 + struArg.elem3
+ + struArg.elem4 + struArg.elem5 + struArg.elem6 + struArg.elem7;
+ argCount--;
+ }
+ return byteSum;
+}
+
+/**
+ * Add the only one element(short) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+short
+add1ShortOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ short shortSum = 0;
+ while (argCount > 0) {
+ stru_Short struArg = va_arg(struVaList, stru_Short);
+ shortSum += struArg.elem1;
+ argCount--;
+ }
+ return shortSum;
+}
+
+/**
+ * Add shorts of structs with two elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+short
+add2ShortsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ short shortSum = 0;
+ while (argCount > 0) {
+ stru_Short_Short struArg = va_arg(struVaList, stru_Short_Short);
+ shortSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return shortSum;
+}
+
+/**
+ * Add shorts of structs with three elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+short
+add3ShortsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ short shortSum = 0;
+ while (argCount > 0) {
+ stru_Short_Short_Short struArg = va_arg(struVaList, stru_Short_Short_Short);
+ shortSum += struArg.elem1 + struArg.elem2 + struArg.elem3;
+ argCount--;
+ }
+ return shortSum;
+}
+
+/**
+ * Add the only one element(int) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+int
+add1IntOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ stru_Int struArg = va_arg(struVaList, stru_Int);
+ intSum += struArg.elem1;
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add ints of structs with two elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of ints
+ */
+int
+add2IntsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ stru_Int_Int struArg = va_arg(struVaList, stru_Int_Int);
+ intSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add ints of structs with three elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of ints
+ */
+int
+add3IntsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ stru_Int_Int_Int struArg = va_arg(struVaList, stru_Int_Int_Int);
+ intSum += struArg.elem1 + struArg.elem2 + struArg.elem3;
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add longs of structs with two elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of longs
+ */
+LONG
+add2LongsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ LONG longSum = 0;
+ while (argCount > 0) {
+ stru_Long_Long struArg = va_arg(struVaList, stru_Long_Long);
+ longSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return longSum;
+}
+
+/**
+ * Add the only one element(float) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+float
+add1FloatOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ float floatSum = 0;
+ while (argCount > 0) {
+ stru_Float struArg = va_arg(struVaList, stru_Float);
+ floatSum += struArg.elem1;
+ argCount--;
+ }
+ return floatSum;
+}
+
+/**
+ * Add floats of structs with two elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of floats
+ */
+float
+add2FloatsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ float floatSum = 0;
+ while (argCount > 0) {
+ stru_Float_Float struArg = va_arg(struVaList, stru_Float_Float);
+ floatSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return floatSum;
+}
+
+/**
+ * Add floats of structs with three elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of floats
+ */
+float
+add3FloatsOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ float floatSum = 0;
+ while (argCount > 0) {
+ stru_Float_Float_Float struArg = va_arg(struVaList, stru_Float_Float_Float);
+ floatSum += struArg.elem1 + struArg.elem2 + struArg.elem3;
+ argCount--;
+ }
+ return floatSum;
+}
+
+/**
+ * Add the only one element(double) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+double
+add1DoubleOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ stru_Double struArg = va_arg(struVaList, stru_Double);
+ doubleSum += struArg.elem1;
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add doubles of structs with two elements from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum of doubles
+ */
+double
+add2DoublesOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ stru_Double_Double struArg = va_arg(struVaList, stru_Double_Double);
+ doubleSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add the elements(int & short) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+int
+addIntShortOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ stru_Int_Short struArg = va_arg(struVaList, stru_Int_Short);
+ intSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add the elements(short & int) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+int
+addShortIntOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ int intSum = 0;
+ while (argCount > 0) {
+ stru_Short_Int struArg = va_arg(struVaList, stru_Short_Int);
+ intSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return intSum;
+}
+
+/**
+ * Add the elements(int & long) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+LONG
+addIntLongOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ LONG longSum = 0;
+ while (argCount > 0) {
+ stru_Int_Long struArg = va_arg(struVaList, stru_Int_Long);
+ longSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return longSum;
+}
+
+/**
+ * Add the elements(long & int) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+LONG
+addLongIntOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ LONG longSum = 0;
+ while (argCount > 0) {
+ stru_Long_Int struArg = va_arg(struVaList, stru_Long_Int);
+ longSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return longSum;
+}
+
+/**
+ * Add the elements(float & double) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+double
+addFloatDoubleOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ stru_Float_Double struArg = va_arg(struVaList, stru_Float_Double);
+ doubleSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add the elements(double & float) of structs from the va_list
+ *
+ * @param argCount the count of structs in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @return the sum
+ */
+double
+addDoubleFloatOfStructsFromVaList(int argCount, va_list struVaList)
+{
+ double doubleSum = 0;
+ while (argCount > 0) {
+ stru_Double_Float struArg = va_arg(struVaList, stru_Double_Float);
+ doubleSum += struArg.elem1 + struArg.elem2;
+ argCount--;
+ }
+ return doubleSum;
+}
+
+/**
+ * Add ints from the va_list with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of the ints
+ * @param intArgList the int va_list
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntsFromVaListByUpcallMH(int argCount, va_list intVaList, int (*upcallMH)(int, va_list))
+{
+ int arg1 = va_arg(intVaList, int);
+ int intSum = arg1 + (*upcallMH)(argCount - 1, intVaList);
+ return intSum;
+}
+
+/**
+ * Add longs from the va_list with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of the longs
+ * @param longArgList the long va_list
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongsFromVaListByUpcallMH(int argCount, va_list longVaList, LONG (*upcallMH)(int, va_list))
+{
+ LONG longSum = (*upcallMH)(argCount, longVaList);
+ return longSum;
+}
+
+/**
+ * Add doubles from the va_list with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of the double arguments
+ * @param doubleArgList the double va_list
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoublesFromVaListByUpcallMH(int argCount, va_list doubleVaList, double (*upcallMH)(int, va_list))
+{
+ double arg1 = va_arg(doubleVaList, double);
+ double doubleSum = arg1 + (*upcallMH)(argCount - 1, doubleVaList);
+ return doubleSum;
+}
+
+/**
+ * Add arguments with different types from the va_list
+ * by invoking an upcall method.
+ *
+ * @param argVaList the va_list with mixed arguments
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addMixedArgsFromVaListByUpcallMH(va_list argVaList, double (*upcallMH)(va_list))
+{
+ double argSum = (*upcallMH)(argVaList);
+ return argSum;
+}
+
+/**
+ * Add more arguments with different types from the va_list
+ * by invoking an upcall method.
+ *
+ * @param argVaList the va_list with mixed arguments
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addMoreMixedArgsFromVaListByUpcallMH(va_list argVaList, double (*upcallMH)(va_list))
+{
+ double argSum = (*upcallMH)(argVaList);
+ return argSum;
+}
+
+/**
+ * Add ints (accessed via MemoryAddress in java) from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of integer pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the int pointers
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntsByPtrFromVaListByUpcallMH(int argCount, va_list ptrVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, ptrVaList);
+ return intSum;
+}
+
+/**
+ * Add longs (accessed via MemoryAddress in java) from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of integer pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the long pointers
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongsByPtrFromVaListByUpcallMH(int argCount, va_list ptrVaList, LONG (*upcallMH)(int, va_list))
+{
+ LONG longSum = (*upcallMH)(argCount, ptrVaList);
+ return longSum;
+}
+
+/**
+ * Add doubles (accessed via MemoryAddress in java) from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of integer pointers in the va_list
+ * @param ptrVaList the passed-in va_list containing the double pointers
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+addDoublesByPtrFromVaListByUpcallMH(int argCount, va_list ptrVaList, double (*upcallMH)(int, va_list))
+{
+ double doubleSum = (*upcallMH)(argCount, ptrVaList);
+ return doubleSum;
+}
+
+/**
+ * Add the only one element(byte) of structs with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add1ByteOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, char (*upcallMH)(int, va_list))
+{
+ char byteSum = (*upcallMH)(argCount, struVaList);
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add2BytesOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, char (*upcallMH)(int, va_list))
+{
+ char byteSum = (*upcallMH)(argCount, struVaList);
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with three elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add3BytesOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, char (*upcallMH)(int, va_list))
+{
+ char byteSum = (*upcallMH)(argCount, struVaList);
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with five elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add5BytesOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, char (*upcallMH)(int, va_list))
+{
+ char byteSum = (*upcallMH)(argCount, struVaList);
+ return byteSum;
+}
+
+/**
+ * Add bytes of structs with seven elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+char
+add7BytesOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, char (*upcallMH)(int, va_list))
+{
+ char byteSum = (*upcallMH)(argCount, struVaList);
+ return byteSum;
+}
+
+/**
+ * Add the only one element(short) of structs with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+add1ShortOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, short (*upcallMH)(int, va_list))
+{
+ short shortSum = (*upcallMH)(argCount, struVaList);
+ return shortSum;
+}
+
+/**
+ * Add shorts of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+add2ShortsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, short (*upcallMH)(int, va_list))
+{
+ short shortSum = (*upcallMH)(argCount, struVaList);
+ return shortSum;
+}
+
+/**
+ * Add shorts of structs with three elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+short
+add3ShortsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, short (*upcallMH)(int, va_list))
+{
+ short shortSum = (*upcallMH)(argCount, struVaList);
+ return shortSum;
+}
+
+/**
+ * Add the only one element(int) of structs with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+add1IntOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, struVaList);
+ return intSum;
+}
+
+/**
+ * Add ints of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+add2IntsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, struVaList);
+ return intSum;
+}
+
+/**
+ * Add ints of structs with three elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+add3IntsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, struVaList);
+ return intSum;
+}
+
+/**
+ * Add longs of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+add2LongsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, LONG (*upcallMH)(int, va_list))
+{
+ LONG longSum = (*upcallMH)(argCount, struVaList);
+ return longSum;
+}
+
+/**
+ * Add the only one element(float) of structs with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+add1FloatOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, float (*upcallMH)(int, va_list))
+{
+ float floatSum = (*upcallMH)(argCount, struVaList);
+ return floatSum;
+}
+
+/**
+ * Add floats of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+add2FloatsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, float (*upcallMH)(int, va_list))
+{
+ float floatSum = (*upcallMH)(argCount, struVaList);
+ return floatSum;
+}
+
+/**
+ * Add floats of structs with three elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+float
+add3FloatsOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, float (*upcallMH)(int, va_list))
+{
+ float floatSum = (*upcallMH)(argCount, struVaList);
+ return floatSum;
+}
+
+/**
+ * Add the only one element(double) of structs with the specified count
+ * by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+add1DoubleOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, double (*upcallMH)(int, va_list))
+{
+ double doubleSum = (*upcallMH)(argCount, struVaList);
+ return doubleSum;
+}
+
+/**
+ * Add doubles of structs with two elements from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+double
+add2DoublesOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, double (*upcallMH)(int, va_list))
+{
+ double doubleSum = (*upcallMH)(argCount, struVaList);
+ return doubleSum;
+}
+
+/**
+ * Add the elements(int & short) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addIntShortOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, struVaList);
+ return intSum;
+}
+
+/**
+ * Add the elements(short & int) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+int
+addShortIntOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, int (*upcallMH)(int, va_list))
+{
+ int intSum = (*upcallMH)(argCount, struVaList);
+ return intSum;
+}
+
+/**
+ * Add the elements(int & long) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addIntLongOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, LONG (*upcallMH)(int, va_list))
+{
+ LONG longSum = (*upcallMH)(argCount, struVaList);
+ return longSum;
+}
+
+/**
+ * Add the elements(long & int) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pointer to the upcall method
+ * @return the sum
+ */
+LONG
+addLongIntOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, LONG (*upcallMH)(int, va_list))
+{
+ LONG longSum = (*upcallMH)(argCount, struVaList);
+ return longSum;
+}
+
+/**
+ * Add the elements(float & double) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pofloater to the upcall method
+ * @return the sum
+ */
+double
+addFloatDoubleOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, double (*upcallMH)(int, va_list))
+{
+ double doubleSum = (*upcallMH)(argCount, struVaList);
+ return doubleSum;
+}
+
+/**
+ * Add the elements(double & float) of structs from the va_list
+ * with the specified count by invoking an upcall method.
+ *
+ * @param argCount the count of struct in the va_list
+ * @param struVaList the passed-in va_list containing structs
+ * @param upcallMH the function pofloater to the upcall method
+ * @return the sum
+ */
+double
+addDoubleFloatOfStructsFromVaListByUpcallMH(int argCount, va_list struVaList, double (*upcallMH)(int, va_list))
+{
+ double doubleSum = (*upcallMH)(argCount, struVaList);
+ return doubleSum;
+}
diff --git a/test/functional/Java17andUp/playlist.xml b/test/functional/Java17andUp/playlist.xml
index 8fd3519cb7d..977b3c3d5e0 100644
--- a/test/functional/Java17andUp/playlist.xml
+++ b/test/functional/Java17andUp/playlist.xml
@@ -43,7 +43,7 @@
-excludegroups $(DEFAULT_EXCLUDE); \
$(TEST_STATUS)
- bits.64,^arch.x86,^arch.aarch64,^arch.ppc,^arch.390,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
sanity
@@ -57,6 +57,37 @@
17
+
+
+ Jep389Tests_testClinkerFfi_UpCall
+
+ --enable-preview
+
+ $(ADD_JVM_LIB_DIR_TO_LIBPATH) $(JAVA_COMMAND) $(JVM_OPTIONS) \
+ --add-modules jdk.incubator.foreign \
+ --enable-native-access=ALL-UNNAMED \
+ -Dforeign.restricted=permit \
+ -cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)GeneralTest.jar$(Q) \
+ org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng_170.xml$(Q) -testnames Jep389Tests_testClinkerFfi_UpCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 17
+
+
+
Jep389Tests_testClinkerFfi_VaList
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/InvalidDownCallTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/InvalidDownCallTests.java
index c37ec8166f5..16bd73dbad2 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/InvalidDownCallTests.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/InvalidDownCallTests.java
@@ -57,7 +57,7 @@ public class InvalidDownCallTests {
System.loadLibrary("clinkerffitests");
}
private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
- private static final SymbolLookup defaultLibLookup = (!isAixOS) ? CLinker.systemLookup() : null;
+ private static final SymbolLookup defaultLibLookup = CLinker.systemLookup();
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "The return type must be .*")
public void test_invalidBooleanTypeOnReturn() throws Throwable {
@@ -358,19 +358,11 @@ public void test_invalidMemoryLayoutForIntType() throws Throwable {
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "ValueLayout is expected.*")
public void test_invalidMemoryLayoutForMemoryAddress() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (isAixOS) {
- throw new IllegalArgumentException("ValueLayout is expected");
- } else {
- Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, MemoryLayout.paddingLayout(64));
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, MemoryLayout.paddingLayout(64));
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Mismatched size .*")
@@ -384,19 +376,11 @@ public void test_mismatchedLayoutSizeForIntType() throws Throwable {
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Mismatched size .*")
public void test_mismatchedLayoutSizeForMemoryAddress() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (isAixOS) {
- throw new IllegalArgumentException("Mismatched size ");
- } else {
- Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, MemoryLayouts.BITS_16_LE);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- fail("Failed to throw out IllegalArgumentException in the case of the mismatched layout size");
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, MemoryLayouts.BITS_16_LE);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the mismatched layout size");
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = ".* neither primitive nor .*")
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests1.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests1.java
index 167b2c3c179..140791cf7b8 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests1.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests1.java
@@ -31,12 +31,16 @@
import jdk.incubator.foreign.CLinker;
import static jdk.incubator.foreign.CLinker.*;
import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.SymbolLookup;
/**
* Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in downcall,
- * which verifies the downcalls with the same layout & argument and return types in multithreading.
+ * which verifies the downcalls with the same downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests1 implements Thread.UncaughtExceptionHandler {
@@ -55,44 +59,57 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithSameFuncDescriptor() throws Throwable {
+ public void test_twoThreadsWithSameFuncDesc_SameDowncallHandler() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(112, 123);
- Assert.assertEquals(result, 235);
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MethodType mt = MethodType.methodType(int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ MemorySegment intSegmt = MemorySegment.allocateNative(C_INT, scope);
+ MemoryAccess.setInt(intSegmt, 215);
+ int result = (int)mh.invokeExact(321, intSegmt.address());
+ Assert.assertEquals(result, 536);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
};
- thr1.setUncaughtExceptionHandler(this);
- thr1.start();
Thread thr2 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(235, 439);
- Assert.assertEquals(result, 674);
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MethodType mt = MethodType.methodType(int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ MemorySegment intSegmt = MemorySegment.allocateNative(C_INT, scope);
+ MemoryAccess.setInt(intSegmt, 215);
+ int result = (int)mh.invokeExact(322, intSegmt.address());
+ Assert.assertEquals(result, 537);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
};
+
+ thr1.setUncaughtExceptionHandler(this);
thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
thr2.start();
thr1.join();
thr2.join();
+
if (initException != null){
throw new RuntimeException(initException);
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests2.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests2.java
index b7a3ea24789..9fded4ad86b 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests2.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests2.java
@@ -24,29 +24,41 @@
import org.testng.annotations.Test;
import org.testng.Assert;
import org.testng.AssertJUnit;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
import jdk.incubator.foreign.Addressable;
import jdk.incubator.foreign.CLinker;
import static jdk.incubator.foreign.CLinker.*;
import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
/**
* Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in downcall,
- * which verifies the downcalls with the diffrent layouts and arguments/return types in multithreading.
+ * which verifies the downcalls with the shared downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests2 implements Thread.UncaughtExceptionHandler {
private volatile Throwable initException;
- private static CLinker clinker = CLinker.getInstance();
static {
System.loadLibrary("clinkerffitests");
}
- private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ private static final MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class);
+ private static final FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ private static final Addressable functionSymbol = SymbolLookup.loaderLookup().lookup("add2IntStructs_returnStruct").get();
+ private static final MethodHandle mh = CLinker.getInstance().downcallHandle(mt, fd);
@Test(enabled=false)
@Override
@@ -55,16 +67,26 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithDiffFuncDescriptor() throws Throwable {
+ public void test_twoThreadsWithSameFuncDesc_SharedDowncallHandler() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(112, 123);
- Assert.assertEquals(result, 235);
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -74,12 +96,22 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(112, 123, 235);
- Assert.assertEquals(result, 470);
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001123);
+ intHandle2.set(structSegmt2, 33445567);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224467);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113355);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests3.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests3.java
index 84baab16283..f89dfc7b55a 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests3.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests3.java
@@ -36,7 +36,7 @@
/**
* Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in downcall,
- * which verifies the downcalls with the diffrent return types in multithreading.
+ * which verifies the downcalls with the diffrent layouts and arguments/return types in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests3 implements Thread.UncaughtExceptionHandler {
@@ -55,7 +55,7 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithDiffReturnType() throws Throwable {
+ public void test_twoThreadsWithDiffFuncDescriptor() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
@@ -74,11 +74,12 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(void.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- mh.invokeExact(454, 398);
+ int result = (int)mh.invokeExact(112, 123, 235);
+ Assert.assertEquals(result, 470);
} catch (Throwable t) {
throw new RuntimeException(t);
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests4.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests4.java
index f2736dec7be..d6e83835cf6 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests4.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests4.java
@@ -36,7 +36,7 @@
/**
* Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in downcall,
- * which verifies multiple downcalls combined with the diffrent layouts/arguments/return types in multithreading.
+ * which verifies the downcalls with the diffrent return types in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests4 implements Thread.UncaughtExceptionHandler {
@@ -55,7 +55,7 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_multiThreadsWithMixedFuncDescriptors() throws Throwable {
+ public void test_twoThreadsWithDiffReturnType() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
@@ -63,8 +63,8 @@ public void run() {
FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(128, 246);
- Assert.assertEquals(result, 374);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -74,72 +74,11 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodType mt = MethodType.methodType(void.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(112, 642, 971);
- Assert.assertEquals(result, 1725);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr3 = new Thread(){
- public void run() {
- try {
- MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR);
- Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- boolean result = (boolean)mh.invokeExact(true, false);
- Assert.assertEquals(result, true);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr4 = new Thread(){
- public void run() {
- try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(416, 728);
- Assert.assertEquals(result, 1144);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr5 = new Thread(){
- public void run() {
- try {
- MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
- Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- int result = (int)mh.invokeExact(1012, 1023, 2035);
- Assert.assertEquals(result, 4070);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr6 = new Thread(){
- public void run() {
- try {
- MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR);
- Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- boolean result = (boolean)mh.invokeExact(false, false);
- Assert.assertEquals(result, false);
+ mh.invokeExact(454, 398);
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -148,24 +87,12 @@ public void run() {
thr1.setUncaughtExceptionHandler(this);
thr2.setUncaughtExceptionHandler(this);
- thr3.setUncaughtExceptionHandler(this);
- thr4.setUncaughtExceptionHandler(this);
- thr5.setUncaughtExceptionHandler(this);
- thr6.setUncaughtExceptionHandler(this);
thr1.start();
thr2.start();
- thr3.start();
- thr4.start();
- thr5.start();
- thr6.start();
- thr6.join();
- thr5.join();
- thr4.join();
- thr3.join();
- thr2.join();
thr1.join();
+ thr2.join();
if (initException != null){
throw new RuntimeException(initException);
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests5.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests5.java
new file mode 100644
index 00000000000..9b6d64dff95
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/MultiThreadingTests5.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SymbolLookup;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in downcall,
+ * which verifies multiple downcalls combined with the diffrent layouts/arguments/return types in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests5 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiThreadsWithMixedFuncDescriptors() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ int result = (int)mh.invokeExact(128, 246);
+ Assert.assertEquals(result, 374);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ int result = (int)mh.invokeExact(112, 642, 971);
+ Assert.assertEquals(result, 1725);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ boolean result = (boolean)mh.invokeExact(true, false);
+ Assert.assertEquals(result, true);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr4 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ int result = (int)mh.invokeExact(416, 728);
+ Assert.assertEquals(result, 1144);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr5 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ int result = (int)mh.invokeExact(1012, 1023, 2035);
+ Assert.assertEquals(result, 4070);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr6 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ boolean result = (boolean)mh.invokeExact(false, false);
+ Assert.assertEquals(result, false);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+ thr3.setUncaughtExceptionHandler(this);
+ thr4.setUncaughtExceptionHandler(this);
+ thr5.setUncaughtExceptionHandler(this);
+ thr6.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+ thr3.start();
+ thr4.start();
+ thr5.start();
+ thr6.start();
+
+ thr6.join();
+ thr5.join();
+ thr4.join();
+ thr3.join();
+ thr2.join();
+ thr1.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests1.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests1.java
index 4fd78a19205..7a8de880ea0 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests1.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests1.java
@@ -61,7 +61,7 @@ public class PrimitiveTypeTests1 {
System.loadLibrary("clinkerffitests");
}
private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
- private static final SymbolLookup defaultLibLookup = (!isAixOS) ? CLinker.systemLookup() : null;
+ private static final SymbolLookup defaultLibLookup = CLinker.systemLookup();
@Test
public void test_addTwoBoolsWithOr_1() throws Throwable {
@@ -407,134 +407,92 @@ public void test_addTwoDoubles_fromMemAddr_1() throws Throwable {
@Test
public void test_strlenFromDefaultLibWithMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(strlenSymbol, mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(strlenSymbol, mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_strlenFromDefaultLibWithMemAddr_fromMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MemoryAddress memAddr = strlenSymbol.address();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(memAddr, mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MemoryAddress memAddr = strlenSymbol.address();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(memAddr, mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_fromMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocMemAddrFromSymbol, allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MemoryAddress freeMemAddr = freeSymbol.address();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeMemAddr, freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocMemAddrFromSymbol, allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MemoryAddress freeMemAddr = freeSymbol.address();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeMemAddr, freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromCLinkerMethod_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 49);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
- CLinker.freeMemory(allocMemAddr);
- }
+ MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 49);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
+ CLinker.freeMemory(allocMemAddr);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(formatMemSegment.address(), 15, 27, 42);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_fromMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MemoryAddress memAddr = functionSymbol.address();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(memAddr, mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MemoryAddress memAddr = functionSymbol.address();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(memAddr, mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(formatMemSegment.address(), 15, 27, 42);
}
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests2.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests2.java
index 35542535f4d..8c40c30ad3e 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests2.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests2.java
@@ -62,7 +62,7 @@ public class PrimitiveTypeTests2 {
System.loadLibrary("clinkerffitests");
}
private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
- private static final SymbolLookup defaultLibLookup = (!isAixOS) ? CLinker.systemLookup() : null;
+ private static final SymbolLookup defaultLibLookup = CLinker.systemLookup();
@Test
public void test_addTwoBoolsWithOr_2() throws Throwable {
@@ -408,134 +408,92 @@ public void test_addTwoDoubles_fromMemAddr_2() throws Throwable {
@Test
public void test_strlenFromDefaultLibWithMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(strlenSymbol, allocator, mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(strlenSymbol, allocator, mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_strlenFromDefaultLibWithMemAddr_fromMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MemoryAddress memAddr = strlenSymbol.address();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(memAddr, allocator, mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MemoryAddress memAddr = strlenSymbol.address();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(memAddr, allocator, mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocator, allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, allocator, freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocator, allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, allocator, freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_fromMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocMemAddrFromSymbol, allocator, allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MemoryAddress freeMemAddr = freeSymbol.address();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeMemAddr, allocator, freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocMemAddrFromSymbol, allocator, allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MemoryAddress freeMemAddr = freeSymbol.address();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeMemAddr, allocator, freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromCLinkerMethod_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 49);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
- CLinker.freeMemory(allocMemAddr);
- }
+ MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 49);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
+ CLinker.freeMemory(allocMemAddr);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(formatMemSegment.address(), 15, 27, 42);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_fromMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MemoryAddress memAddr = functionSymbol.address();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(memAddr, allocator, mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MemoryAddress memAddr = functionSymbol.address();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(memAddr, allocator, mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(formatMemSegment.address(), 15, 27, 42);
}
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests3.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests3.java
index 9a3e62007ed..352be9b3e66 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests3.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/PrimitiveTypeTests3.java
@@ -62,7 +62,7 @@ public class PrimitiveTypeTests3 {
System.loadLibrary("clinkerffitests");
}
private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
- private static final SymbolLookup defaultLibLookup = (!isAixOS) ? CLinker.systemLookup() : null;
+ private static final SymbolLookup defaultLibLookup = CLinker.systemLookup();
@Test
public void test_addTwoBoolsWithOr_3() throws Throwable {
@@ -398,132 +398,90 @@ public void test_addTwoDoubles_fromMemAddr_3() throws Throwable {
@Test
public void test_strlenFromDefaultLibWithMemAddr_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(strlenSymbol, funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(strlenSymbol, funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_strlenFromDefaultLibWithMemAddr_fromMemAddr_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
- MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
- MethodHandle mh = clinker.downcallHandle(mt, fd);
- MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
- long strLength = (long)mh.invokeExact(strlenSymbol, funcMemSegment.address());
- Assert.assertEquals(strLength, 27);
- }
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER);
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment funcMemSegment = CLinker.toCString("JEP389 DOWNCALL TEST SUITES", resourceScope);
+ long strLength = (long)mh.invokeExact(strlenSymbol, funcMemSegment.address());
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(freeSymbol, allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(freeSymbol, allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_fromMemAddr_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
- MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
- MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
- MethodHandle allocHandle = clinker.downcallHandle(allocMethodType, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 15);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
-
- Addressable freeSymbol = defaultLibLookup.lookup("free").get();
- MemoryAddress freeMemAddr = freeSymbol.address();
- MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
- MethodHandle freeHandle = clinker.downcallHandle(freeMethodType, freeFuncDesc);
- freeHandle.invokeExact(freeSymbol, allocMemAddr);
- }
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ MemoryAddress allocMemAddrFromSymbol = allocSymbol.address();
+ MethodType allocMethodType = MethodType.methodType(MemoryAddress.class, long.class);
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(C_POINTER, longLayout);
+ MethodHandle allocHandle = clinker.downcallHandle(allocMethodType, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 15);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ MemoryAddress freeMemAddr = freeSymbol.address();
+ MethodType freeMethodType = MethodType.methodType(void.class, MemoryAddress.class);
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(C_POINTER);
+ MethodHandle freeHandle = clinker.downcallHandle(freeMethodType, freeFuncDesc);
+ freeHandle.invokeExact(freeSymbol, allocMemAddr);
}
@Test
public void test_memoryAllocFreeFromCLinkerMethod_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
- MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
- MemoryAccess.setIntAtOffset(memSeg, 0, 49);
- Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
- CLinker.freeMemory(allocMemAddr);
- }
+ MemoryAddress allocMemAddr = CLinker.allocateMemory(10L);
+ MemorySegment memSeg = allocMemAddr.asSegment(10L, resourceScope);
+ MemoryAccess.setIntAtOffset(memSeg, 0, 49);
+ Assert.assertEquals(MemoryAccess.getIntAtOffset(memSeg, 0), 49);
+ CLinker.freeMemory(allocMemAddr);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(functionSymbol, formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(functionSymbol, formatMemSegment.address(), 15, 27, 42);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_fromMemAddr_3() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
- MethodHandle mh = clinker.downcallHandle(mt, fd);
- MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
- mh.invoke(functionSymbol, formatMemSegment.address(), 15, 27, 42);
- }
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, int.class, int.class, int.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_INT, C_INT);
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment formatMemSegment = CLinker.toCString("\n%d + %d = %d\n", resourceScope);
+ mh.invoke(functionSymbol, formatMemSegment.address(), 15, 27, 42);
}
}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests1.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests1.java
index bd10a3d2920..6f985c54c52 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests1.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests1.java
@@ -170,7 +170,8 @@ public void test_addBoolAndBoolsFromStructPointerWithXor_1() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
@@ -213,7 +214,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_1() throws
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
@@ -278,7 +280,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_1() t
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_1() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
@@ -350,7 +353,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_1()
public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(C_CHAR, C_CHAR);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
@@ -555,7 +559,8 @@ public void test_addByteAndBytesFromStructPointer_1() throws Throwable {
@Test
public void test_addByteAndBytesFromNestedStruct_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
@@ -598,7 +603,8 @@ public void test_addByteAndBytesFromNestedStruct_reverseOrder_1() throws Throwab
@Test
public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
@@ -663,7 +669,8 @@ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_1() t
@Test
public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_1() throws Throwable {
SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(byteArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
@@ -735,7 +742,8 @@ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_1()
public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR, C_CHAR);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
@@ -940,7 +948,8 @@ public void test_addCharAndCharsFromStructPointer_1() throws Throwable {
@Test
public void test_addCharAndCharsFromNestedStruct_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(C_SHORT.bitSize()));
MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
@@ -1174,7 +1183,8 @@ public void test_add2CharStructs_returnStructPointer_1() throws Throwable {
@Test
public void test_add3CharStructs_returnStruct_1() throws Throwable {
- GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"), C_SHORT.withName("elem3"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(C_SHORT.bitSize()));
VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
VarHandle charHandle3 = structLayout.varHandle(char.class, PathElement.groupElement("elem3"));
@@ -1345,7 +1355,8 @@ public void test_addShortAndShortsFromNestedStruct_reverseOrder_1() throws Throw
@Test
public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT, C_SHORT);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_SHORT,
+ MemoryLayout.paddingLayout(C_SHORT.bitSize()));
MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
@@ -2839,34 +2850,25 @@ public void test_addDoubleAndDoublesFromStruct_1() throws Throwable {
@Test
public void test_addDoubleAndFloatDoubleFromStruct_1() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(C_FLOAT.bitSize()), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
-
- /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- MemoryAccess.setFloatAtOffset(structSegmt, 0, 18.444F);
- MemoryAccess.setDoubleAtOffset(structSegmt, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
- MemoryLayout.paddingLayout(C_FLOAT.bitSize()), C_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18.444F);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
- Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(113.567D, structSegmt);
Assert.assertEquals(result, 751.788D, 0.001D);
@@ -2875,34 +2877,25 @@ public void test_addDoubleAndFloatDoubleFromStruct_1() throws Throwable {
@Test
public void test_addDoubleAndIntDoubleFromStruct_1() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(C_INT.bitSize()), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
-
- /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- MemoryAccess.setIntAtOffset(structSegmt, 0, 18);
- MemoryAccess.setDoubleAtOffset(structSegmt, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
- MemoryLayout.paddingLayout(C_INT.bitSize()), C_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
- Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(113.567D, structSegmt);
Assert.assertEquals(result, 751.344D, 0.001D);
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests2.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests2.java
index d921575c52f..93114de729b 100644
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests2.java
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/downcall/StructTests2.java
@@ -168,7 +168,8 @@ public void test_addBoolAndBoolsFromStructPointerWithXor_2() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
@@ -211,7 +212,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_2() throws
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
@@ -276,7 +278,7 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_2() t
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_2() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, C_CHAR, MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
@@ -348,7 +350,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_2()
public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(C_CHAR, C_CHAR);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
@@ -553,7 +556,8 @@ public void test_addByteAndBytesFromStructPointer_2() throws Throwable {
@Test
public void test_addByteAndBytesFromNestedStruct_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
@@ -596,7 +600,8 @@ public void test_addByteAndBytesFromNestedStruct_reverseOrder_2() throws Throwab
@Test
public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
@@ -661,7 +666,8 @@ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_2() t
@Test
public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_2() throws Throwable {
SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
- GroupLayout structLayout = MemoryLayout.structLayout(byteArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize()));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
@@ -733,7 +739,8 @@ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_2()
public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR, C_CHAR);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, C_CHAR,
+ MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
@@ -938,7 +945,8 @@ public void test_addCharAndCharsFromStructPointer_2() throws Throwable {
@Test
public void test_addCharAndCharsFromNestedStruct_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(C_SHORT.bitSize()));
MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
@@ -1172,7 +1180,8 @@ public void test_add2CharStructs_returnStructPointer_2() throws Throwable {
@Test
public void test_add3CharStructs_returnStruct_2() throws Throwable {
- GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"), C_SHORT.withName("elem3"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(C_SHORT.bitSize()));
VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
VarHandle charHandle3 = structLayout.varHandle(char.class, PathElement.groupElement("elem3"));
@@ -1343,7 +1352,8 @@ public void test_addShortAndShortsFromNestedStruct_reverseOrder_2() throws Throw
@Test
public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT, C_SHORT);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, C_SHORT,
+ MemoryLayout.paddingLayout(C_SHORT.bitSize()));
MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class);
FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout);
Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
@@ -2837,34 +2847,25 @@ public void test_addDoubleAndDoublesFromStruct_2() throws Throwable {
@Test
public void test_addDoubleAndFloatDoubleFromStruct_2() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(C_FLOAT.bitSize()), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
-
- /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- MemoryAccess.setFloatAtOffset(structSegmt, 0, 18.444F);
- MemoryAccess.setDoubleAtOffset(structSegmt, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
- MemoryLayout.paddingLayout(C_FLOAT.bitSize()), C_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18.444F);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
- Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
Assert.assertEquals(result, 751.788D, 0.001D);
@@ -2873,34 +2874,25 @@ public void test_addDoubleAndFloatDoubleFromStruct_2() throws Throwable {
@Test
public void test_addDoubleAndIntDoubleFromStruct_2() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(C_INT.bitSize()), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(mt, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
-
- /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- MemoryAccess.setIntAtOffset(structSegmt, 0, 18);
- MemoryAccess.setDoubleAtOffset(structSegmt, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
- MemoryLayout.paddingLayout(C_INT.bitSize()), C_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout);
- Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(mt, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
Assert.assertEquals(result, 751.344D, 0.001D);
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallMHTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallMHTests.java
new file mode 100644
index 00000000000..56be08e532e
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallMHTests.java
@@ -0,0 +1,606 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) in upcall intended for
+ * the situations when the multiple primitive specific upcalls happen within
+ * the same resource scope or from different resource scopes.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallMHTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
+ private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ boolean result = (boolean)mh.invokeExact(true, false, upcallFuncAddr1);
+ Assert.assertEquals(result, true);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ result = (boolean)mh.invokeExact(true, false, upcallFuncAddr2);
+ Assert.assertEquals(result, true);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ result = (boolean)mh.invokeExact(true, false, upcallFuncAddr3);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ boolean result = (boolean)mh.invokeExact(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ boolean result = (boolean)mh.invokeExact(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ boolean result = (boolean)mh.invokeExact(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(char.class, MemoryAddress.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ char result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr2);
+ Assert.assertEquals(result, 'C');
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr3);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(char.class, MemoryAddress.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ char result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ char result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ char result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ byte result = (byte)mh.invokeExact((byte)33, upcallFuncAddr1);
+ Assert.assertEquals(result, (byte)88);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ result = (byte)mh.invokeExact((byte)33, upcallFuncAddr2);
+ Assert.assertEquals(result, (byte)88);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ result = (byte)mh.invokeExact((byte)33, upcallFuncAddr3);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ byte result = (byte)mh.invokeExact((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ byte result = (byte)mh.invokeExact((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ byte result = (byte)mh.invokeExact((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr1);
+ short result = MemoryAccess.getShort(resultAddr1.asSegment(C_SHORT.byteSize(), resultAddr1.scope()));
+ Assert.assertEquals(result, (short)999);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr2);
+ result = MemoryAccess.getShort(resultAddr2.asSegment(C_SHORT.byteSize(), resultAddr2.scope()));
+ Assert.assertEquals(result, (short)999);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr3);
+ result = MemoryAccess.getShort(resultAddr3.asSegment(C_SHORT.byteSize(), resultAddr3.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr);
+ short result = MemoryAccess.getShort(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr);
+ short result = MemoryAccess.getShort(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr);
+ short result = MemoryAccess.getShort(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr1);
+ Assert.assertEquals(result, 222235);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr2);
+ Assert.assertEquals(result, 222235);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr3);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr1);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr2);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr3);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(111454, 111398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ long result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr1);
+ Assert.assertEquals(result, 12409155659L);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr2);
+ Assert.assertEquals(result, 12409155659L);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr3);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ long result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ long result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ long result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(float.class, float.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ float result = (float)mh.invokeExact(5.74F, upcallFuncAddr1);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ result = (float)mh.invokeExact(5.74F, upcallFuncAddr2);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ result = (float)mh.invokeExact(5.74F, upcallFuncAddr3);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(float.class, float.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ float result = (float)mh.invokeExact(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ float result = (float)mh.invokeExact(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ float result = (float)mh.invokeExact(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_SameScope() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+
+ MemoryAddress upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748d);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr1);
+ double result = MemoryAccess.getDouble(resultAddr1.asSegment(C_DOUBLE.byteSize(), resultAddr1.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+
+ MemoryAddress upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr2);
+ result = MemoryAccess.getDouble(resultAddr2.asSegment(C_DOUBLE.byteSize(), resultAddr2.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+
+ MemoryAddress upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr3);
+ result = MemoryAccess.getDouble(resultAddr3.asSegment(C_DOUBLE.byteSize(), resultAddr3.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_DiffScope() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748d);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr);
+ double result = MemoryAccess.getDouble(resultAddr.asSegment(C_DOUBLE.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748d);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr);
+ double result = MemoryAccess.getDouble(resultAddr.asSegment(C_DOUBLE.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748d);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795d, upcallFuncAddr);
+ double result = MemoryAccess.getDouble(resultAddr.asSegment(C_DOUBLE.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 2422.543d, 0.001d);
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests1.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests1.java
new file mode 100644
index 00000000000..9147800ab80
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests1.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within different resource scopes, in which case the upcall
+ * metadata and the generated thunk are allocated separately.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests1 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithDiffScopes() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests2.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests2.java
new file mode 100644
index 00000000000..ceaea1ca751
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/MultiUpcallThrdsMHTests2.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within the same resource scope, in which case the upcall
+ * metadata and the generated thunk are only allocated once and shared among
+ * these threads.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests2 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.getInstance();
+ private static ResourceScope resourceScope = ResourceScope.newImplicitScope();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithSameScope() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), resourceScope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), resourceScope);
+ int result = (int)mh.invokeExact(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), resourceScope);
+ int result = (int)mh.invokeExact(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithMixedSigStruTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithMixedSigStruTests.java
new file mode 100644
index 00000000000..eb3c2c36d7b
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithMixedSigStruTests.java
@@ -0,0 +1,934 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.nio.ByteOrder;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryHandles;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) for the mixed native signatures
+ * in argument/return struct in upcall.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithMixedSigStruTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
+ private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addIntAndIntShortFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntShortFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntShortFromStruct,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, (short)32766);
+
+ int result = (int)mh.invokeExact(22334455, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33590565);
+ }
+ }
+
+ @Test
+ public void test_addIntAndShortIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), C_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndShortIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndShortIntFromStruct,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, (short)32766);
+ elemHandle2.set(structSegmt, 22446688);
+
+ int result = (int)mh.invokeExact(11335577, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33815031);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntLongFromStruct,
+ FunctionDescriptor.of(longLayout, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, 667788990011L);
+
+ long result = (long)mh.invokeExact(22446688, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667822660043L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndLongIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"),
+ C_INT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndLongIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndLongIntFromStruct,
+ FunctionDescriptor.of(longLayout, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 667788990011L);
+ elemHandle2.set(structSegmt, 11223344);
+
+ long result = (long)mh.invokeExact(1234567, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667801447922L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invokeExact(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111844.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleIntFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 111111111);
+
+ double result = (double)mh.invokeExact(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111546.221D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invokeExact(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 751.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invokeExact(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatPlusPaddingFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"),
+ C_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invokeExact(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAnd2FloatsDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAnd2FloatsDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAnd2FloatsDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invokeExact(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDouble2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDouble2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDouble2FloatsFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ double result = (double)mh.invokeExact(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndInt2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt2FloatsFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invokeExact(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_INT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatIntFloatFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 111111);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invokeExact(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntFloatDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntFloatDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invokeExact(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatIntDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_INT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatIntDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22.33F);
+ elemHandle2.set(structSegmt, 111111111);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invokeExact(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndLongDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndLongDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndLongDoubleFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22222222222222L);
+ elemHandle2.set(structSegmt, 33333.444D);
+
+ double result = (double)mh.invokeExact(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 22222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt3FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"), C_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndInt3FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt3FloatsFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 77777777);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+ elemHandle4.set(structSegmt, 44.55F);
+
+ float result = (float)mh.invokeExact(66.678F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.778F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLong2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLong2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLong2FloatsFromStruct,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 777777777777L);
+ elemHandle2.set(structSegmt, 11.25F);
+ elemHandle3.set(structSegmt, 22.75F);
+
+ long result = (long)mh.invokeExact(555555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1333333333365L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd3FloatsIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"), C_INT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(int.class, PathElement.groupElement("elem4"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAnd3FloatsIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAnd3FloatsIntFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 44.55F);
+ elemHandle4.set(structSegmt, 77777777);
+
+ float result = (float)mh.invokeExact(66.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.556F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndFloatLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndFloatLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndFloatLongFromStruct,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 55.11F);
+ elemHandle2.set(structSegmt, 150000000000L);
+
+ long result = (long)mh.invokeExact(5555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 155555555610L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatIntFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 111111111);
+
+ double result = (double)mh.invokeExact(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.341D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleLongFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33333.444D);
+ elemHandle2.set(structSegmt, 222222222222L);
+
+ double result = (double)mh.invokeExact(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addLongAnd2FloatsLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAnd2FloatsLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAnd2FloatsLongFromStruct,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.11F);
+ elemHandle2.set(structSegmt, 22.11F);
+ elemHandle3.set(structSegmt, 4444444444L);
+
+ long result = (long)mh.invokeExact(11111111111L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15555555588L);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd3ShortsCharFromStructByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(3, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray, C_SHORT);
+
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAnd3ShortsCharFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAnd3ShortsCharFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)1000);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)2000);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)3000);
+ MemoryAccess.setCharAtOffset(structSegmt, 6, 'A');
+
+ short result = (short)mh.invokeExact((short)4000, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 10065);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndIntFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_INT.withName("elem3"), C_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndIntFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndIntFloatIntFloatFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 555555555);
+ elemHandle2.set(structSegmt, 11.222F);
+ elemHandle3.set(structSegmt, 666666666);
+ elemHandle4.set(structSegmt, 33.444F);
+
+ float result = (float)mh.invokeExact(77.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1222222343.122F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFloatFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(C_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFloatFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 7777);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"))
+ : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"),
+ C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleIntFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33.444F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"))
+ : MemoryLayout.structLayout(C_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleIntFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 6666);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15217.122D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFloatFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(C_FLOAT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFloatFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.222F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 818.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleLongFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), longLayout.withName("elem3")) : MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleLongFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+ elemHandle3.set(structSegmt, 888888888888L);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 889000000732.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_return254BytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("return254BytesFromStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_return254BytesFromStruct,
+ FunctionDescriptor.of(structLayout), scope);
+
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(upcallFuncAddr);
+ for (int i = 0; i < 254; i++) {
+ Assert.assertEquals(MemoryAccess.getByteAtOffset(byteArrStruSegment, i), (byte)i);
+ }
+ }
+ }
+
+ @Test
+ public void test_return4KBytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("return4KBytesFromStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_return4KBytesFromStruct,
+ FunctionDescriptor.of(structLayout), scope);
+
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(upcallFuncAddr);
+ for (int i = 0; i < 4096; i++) {
+ Assert.assertEquals(MemoryAccess.getByteAtOffset(byteArrStruSegment, i), (byte)i);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithPrimTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithPrimTests.java
new file mode 100644
index 00000000000..9499a515712
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithPrimTests.java
@@ -0,0 +1,821 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) for primitive types in upcall.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithPrimTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
+ private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = CLinker.systemLookup();
+
+ @Test(enabled=false)
+ public static boolean byteToBool(byte value) {
+ return (value != 0);
+ }
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, boolean.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ boolean result = (boolean)mh.invokeExact(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPointerWithOrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPointerWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment boolSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(boolSegmt, (byte)1);
+ boolean result = (boolean)mh.invokeExact(false, boolSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromNativePtrWithOrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromNativePtrWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ boolean result = (boolean)mh.invokeExact(false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, boolean.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment boolSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(boolSegmt, (byte)1);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(false, boolSegmt.address(), upcallFuncAddr);
+ byte result = MemoryAccess.getByte(resultAddr.asSegment(C_CHAR.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(byteToBool(result), true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, boolean.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment boolSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(boolSegmt, (byte)1);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(false, boolSegmt.address(), upcallFuncAddr);
+ byte result = MemoryAccess.getByte(resultAddr.asSegment(C_CHAR.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(byteToBool(result), true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBytesByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(byte.class, byte.class, byte.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BytesByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Bytes,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_CHAR), scope);
+ byte result = (byte)mh.invokeExact((byte)6, (byte)3, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)9);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment charSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(charSegmt, (byte)7);
+ byte result = (byte)mh.invokeExact((byte)8, charSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, (byte)15);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ byte result = (byte)mh.invokeExact((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, byte.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment charSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(charSegmt, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact((byte)47, charSegmt.address(), upcallFuncAddr);
+ byte result = MemoryAccess.getByte(resultAddr.asSegment(C_CHAR.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (byte)82);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, byte.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment charSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(charSegmt, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact((byte)47, charSegmt.address(), upcallFuncAddr);
+ byte result = MemoryAccess.getByte(resultAddr.asSegment(C_CHAR.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (byte)82);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFrom2CharsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(char.class, char.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFrom2CharsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFrom2Chars,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, C_SHORT), scope);
+ char result = (char)mh.invokeExact('B', 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(char.class, MemoryAddress.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ char result = (char)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(char.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ char result = (char)mh.invokeExact('D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr);
+ char result = MemoryAccess.getChar(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(shortSegmt, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), 'D', upcallFuncAddr);
+ char result = MemoryAccess.getChar(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_addTwoShortsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(short.class, short.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Shorts,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, C_SHORT), scope);
+ short result = (short)mh.invokeExact((short)1111, (short)2222, upcallFuncAddr);
+ Assert.assertEquals(result, (short)3333);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(short.class, MemoryAddress.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)2222);
+ short result = (short)mh.invokeExact(shortSegmt.address(), (short)3333, upcallFuncAddr);
+ Assert.assertEquals(result, (short)5555);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(short.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, C_SHORT), scope);
+ short result = (short)mh.invokeExact((short)789, upcallFuncAddr);
+ Assert.assertEquals(result, (short)1245);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr);
+ short result = MemoryAccess.getShort(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, short.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), (short)555, upcallFuncAddr);
+ short result = MemoryAccess.getShort(resultAddr.asSegment(C_SHORT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, (short)999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(C_INT, C_INT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment intSegmt = allocator.allocate(C_INT);
+ MemoryAccess.setInt(intSegmt, 222215);
+ int result = (int)mh.invokeExact(333321, intSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(C_INT, C_INT, C_POINTER), scope);
+ int result = (int)mh.invokeExact(222222, upcallFuncAddr);
+ Assert.assertEquals(result, 666666);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, int.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_INT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_INT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment intSegmt = allocator.allocate(C_INT);
+ MemoryAccess.setInt(intSegmt, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(333321, intSegmt.address(), upcallFuncAddr);
+ int result = MemoryAccess.getInt(resultAddr.asSegment(C_INT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, int.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_INT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_INT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment intSegmt = allocator.allocate(C_INT);
+ MemoryAccess.setInt(intSegmt, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(333321, intSegmt.address(), upcallFuncAddr);
+ int result = MemoryAccess.getInt(resultAddr.asSegment(C_INT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 555536);
+ }
+ }
+
+ @Test
+ public void test_add3IntsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3Ints,
+ FunctionDescriptor.of(C_INT, C_INT, C_INT, C_INT), scope);
+ int result = (int)mh.invokeExact(111112, 111123, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 333359);
+ }
+ }
+
+ @Test
+ public void test_addIntAndCharByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(int.class, int.class, char.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_SHORT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndCharByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndChar,
+ FunctionDescriptor.of(C_INT, C_INT, C_SHORT), scope);
+ int result = (int)mh.invokeExact(555558, 'A', upcallFuncAddr);
+ Assert.assertEquals(result, 555623);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(C_INT, C_INT), scope);
+ mh.invokeExact(44454, 333398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addTwoLongsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(long.class, long.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Longs,
+ FunctionDescriptor.of(longLayout, longLayout, longLayout), scope);
+ long result = (long)mh.invokeExact(333333222222L, 111111555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 444444777777L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ long result = (long)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(long.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(longLayout, C_POINTER, longLayout), scope);
+ long result = (long)mh.invokeExact(5555555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 8888888888L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ long result = MemoryAccess.getLong(resultAddr.asSegment(longLayout.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, long.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, longLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, longLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(longSegmt.address(), 6666698235L, upcallFuncAddr);
+ long result = MemoryAccess.getLong(resultAddr.asSegment(longLayout.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addTwoFloatsByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(float.class, float.class, float.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_FLOAT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Floats,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_FLOAT), scope);
+ float result = (float)mh.invokeExact(15.74F, 16.79F, upcallFuncAddr);
+ Assert.assertEquals(result, 32.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(float.class, float.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment floatSegmt = allocator.allocate(C_FLOAT);
+ MemoryAccess.setFloat(floatSegmt, 6.79F);
+ float result = (float)mh.invokeExact(5.74F, floatSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(float.class, float.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ float result = (float)mh.invokeExact(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, float.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_FLOAT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_FLOAT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment floatSegmt = allocator.allocate(C_FLOAT);
+ MemoryAccess.setFloat(floatSegmt, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(5.74F, floatSegmt.address(), upcallFuncAddr);
+ float result = MemoryAccess.getFloat(resultAddr.asSegment(C_FLOAT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, float.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_FLOAT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_FLOAT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment floatSegmt = allocator.allocate(C_FLOAT);
+ MemoryAccess.setFloat(floatSegmt, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(5.74F, floatSegmt.address(), upcallFuncAddr);
+ float result = MemoryAccess.getFloat(resultAddr.asSegment(C_FLOAT.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2DoublesByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(double.class, double.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoublesByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Doubles,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, C_DOUBLE), scope);
+ double result = (double)mh.invokeExact(159.748D, 262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPointerByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(double.class, MemoryAddress.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_POINTER, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(C_DOUBLE, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748D);
+ double result = (double)mh.invokeExact(doubleSegmt.address(), 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromNativePtrByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(double.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(C_DOUBLE, C_POINTER, C_DOUBLE), scope);
+ double result = (double)mh.invokeExact(1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795D, upcallFuncAddr);
+ double result = MemoryAccess.getDouble(resultAddr.asSegment(C_DOUBLE.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, double.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetArgPtr,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, C_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), 1262.795D, upcallFuncAddr);
+ double result = MemoryAccess.getDouble(resultAddr.asSegment(C_DOUBLE.byteSize(), resultAddr.scope()));
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_qsortByUpcallMH() throws Throwable {
+ int expectedArray[] = {11, 12, 13, 14, 15, 16, 17};
+ int expectedArrayLength = expectedArray.length;
+
+ MethodType mt = MethodType.methodType(void.class, MemoryAddress.class, int.class, int.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_POINTER, C_INT, C_INT, C_POINTER);
+ Addressable functionSymbol = defaultLibLookup.lookup("qsort").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_compare,
+ FunctionDescriptor.of(C_INT, C_POINTER, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment arraySegmt = allocator.allocateArray(C_INT, new int[]{17, 14, 13, 16, 15, 12, 11});
+ mh.invokeExact(arraySegmt.address(), 7, 4, upcallFuncAddr);
+ int[] sortedArray = arraySegmt.toIntArray();
+ for (int index = 0; index < expectedArrayLength; index++) {
+ Assert.assertEquals(sortedArray[index], expectedArray[index]);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithStructTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithStructTests.java
new file mode 100644
index 00000000000..2a1b48d4d87
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMHWithStructTests.java
@@ -0,0 +1,3069 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.nio.ByteOrder;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.Addressable;
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryHandles;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) for argument/return struct in upcall.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithStructTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ /* The padding of struct is not required on Linux/s390x and Windows/x64 */
+ private static boolean isStructPaddingNotRequired = isWinOS && (arch.equals("amd64") || arch.equals("x86_64"))
+ || osName.contains("linux") && arch.equals("s390x");
+ /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
+ private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
+ private static CLinker clinker = CLinker.getInstance();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ public static boolean byteToBool(byte value) {
+ return (value != 0);
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, (byte)0);
+ boolHandle2.set(structSegmt, (byte)1);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAnd20BoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR,
+ C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR,
+ C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR);
+
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAnd20BoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAnd20BoolsFromStructWithXor,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 5, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 6, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 7, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 8, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 9, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 10, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 11, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 12, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 13, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 14, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 15, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 16, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 17, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 18, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 19, (byte)1);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(boolean.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(C_CHAR, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment boolSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(boolSegmt, (byte)1);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, (byte)0);
+ boolHandle2.set(structSegmt, (byte)1);
+
+ boolean result = (boolean)mh.invokeExact(boolSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR);
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment boolSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(boolSegmt, (byte)0);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(boolSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_CHAR.byteSize(), scope);
+ boolean result = byteToBool(MemoryAccess.getByte(resultSegmt));
+ Assert.assertEquals(result, true);
+ Assert.assertEquals(resultAddr.toRawLongValue(), boolSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructPointerWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructPointerWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructPointerWithXor,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, (byte)1);
+ boolHandle2.set(structSegmt, (byte)0);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)1);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)1);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)0);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ intArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)0);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)0);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+ MethodType mt = MethodType.methodType(boolean.class, boolean.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)0);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)0);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, (byte)1);
+ boolHandle2.set(structSegmt1, (byte)0);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, (byte)1);
+ boolHandle2.set(structSegmt2, (byte)1);
+
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(byteToBool((byte)boolHandle1.get(resultSegmt)), false);
+ Assert.assertEquals(byteToBool((byte)boolHandle2.get(resultSegmt)), true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, (byte)1);
+ boolHandle2.set(structSegmt1, (byte)0);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, (byte)1);
+ boolHandle2.set(structSegmt2, (byte)1);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals(byteToBool((byte)boolHandle1.get(resultSegmt)), false);
+ Assert.assertEquals(byteToBool((byte)boolHandle2.get(resultSegmt)), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3")) : MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BoolStructsWithXor_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, (byte)1);
+ boolHandle2.set(structSegmt1, (byte)0);
+ boolHandle3.set(structSegmt1, (byte)1);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, (byte)1);
+ boolHandle2.set(structSegmt2, (byte)1);
+ boolHandle3.set(structSegmt2, (byte)0);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(byteToBool((byte)boolHandle1.get(resultSegmt)), false);
+ Assert.assertEquals(byteToBool((byte)boolHandle2.get(resultSegmt)), true);
+ Assert.assertEquals(byteToBool((byte)boolHandle3.get(resultSegmt)), true);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStruct,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)8);
+ byteHandle2.set(structSegmt, (byte)9);
+
+ byte result = (byte)mh.invokeExact((byte)6, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addByteAnd20BytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR,
+ C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR,
+ C_CHAR, C_CHAR, C_CHAR, C_CHAR, C_CHAR);
+
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAnd20BytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAnd20BytesFromStruct,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)2);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)3);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)4);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)5);
+ MemoryAccess.setByteAtOffset(structSegmt, 5, (byte)6);
+ MemoryAccess.setByteAtOffset(structSegmt, 6, (byte)7);
+ MemoryAccess.setByteAtOffset(structSegmt, 7, (byte)8);
+ MemoryAccess.setByteAtOffset(structSegmt, 8, (byte)9);
+ MemoryAccess.setByteAtOffset(structSegmt, 9, (byte)10);
+ MemoryAccess.setByteAtOffset(structSegmt, 10, (byte)1);
+ MemoryAccess.setByteAtOffset(structSegmt, 11, (byte)2);
+ MemoryAccess.setByteAtOffset(structSegmt, 12, (byte)3);
+ MemoryAccess.setByteAtOffset(structSegmt, 13, (byte)4);
+ MemoryAccess.setByteAtOffset(structSegmt, 14, (byte)5);
+ MemoryAccess.setByteAtOffset(structSegmt, 15, (byte)6);
+ MemoryAccess.setByteAtOffset(structSegmt, 16, (byte)7);
+ MemoryAccess.setByteAtOffset(structSegmt, 17, (byte)8);
+ MemoryAccess.setByteAtOffset(structSegmt, 18, (byte)9);
+ MemoryAccess.setByteAtOffset(structSegmt, 19, (byte)10);
+
+ byte result = (byte)mh.invokeExact((byte)11, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 121);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(byte.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct,
+ FunctionDescriptor.of(C_CHAR, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment byteSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(byteSegmt, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)18);
+ byteHandle2.set(structSegmt, (byte)19);
+
+ byte result = (byte)mh.invokeExact(byteSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct_returnBytePointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment byteSegmt = allocator.allocate(C_CHAR);
+ MemoryAccess.setByte(byteSegmt, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)14);
+ byteHandle2.set(structSegmt, (byte)16);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(byteSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_CHAR.byteSize(), scope);
+ VarHandle byteHandle = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder());
+ byte result = (byte)byteHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 42);
+ Assert.assertEquals(resultAddr.toRawLongValue(), byteSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructPointer,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)11);
+ byteHandle2.set(structSegmt, (byte)12);
+
+ byte result = (byte)mh.invokeExact((byte)13, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 36);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)11);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)22);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)33);
+
+ byte result = (byte)mh.invokeExact((byte)46, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")): MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)12);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)24);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)36);
+
+ byte result = (byte)mh.invokeExact((byte)48, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 120);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArrayByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ C_CHAR.withName("elem2")): MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)11);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)12);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)13);
+
+ byte result = (byte)mh.invokeExact((byte)14, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 50);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ byteArray.withName("array_elem2")): MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(8));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)12);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)14);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)16);
+
+ byte result = (byte)mh.invokeExact((byte)18, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 60);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)11);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)12);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)13);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)14);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)15);
+
+ byte result = (byte)mh.invokeExact((byte)16, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+ MethodType mt = MethodType.methodType(byte.class, byte.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_CHAR, C_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setByteAtOffset(structSegmt, 0, (byte)12);
+ MemoryAccess.setByteAtOffset(structSegmt, 1, (byte)14);
+ MemoryAccess.setByteAtOffset(structSegmt, 2, (byte)16);
+ MemoryAccess.setByteAtOffset(structSegmt, 3, (byte)18);
+ MemoryAccess.setByteAtOffset(structSegmt, 4, (byte)20);
+
+ byte result = (byte)mh.invokeExact((byte)22, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 102);
+ }
+ }
+
+ @Test
+ public void test_add1ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ByteStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add1ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3")) : MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ByteStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ byteHandle3.set(structSegmt1, (byte)12);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+ byteHandle3.set(structSegmt2, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt), (byte)28);
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'A');
+ charHandle2.set(structSegmt, 'B');
+
+ char result = (char)mh.invokeExact('C', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'D');
+ }
+ }
+
+ @Test
+ public void test_addCharAnd10CharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT, C_SHORT, C_SHORT, C_SHORT,
+ C_SHORT, C_SHORT, C_SHORT, C_SHORT, C_SHORT, C_SHORT);
+
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAnd10CharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAnd10CharsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'A');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'A');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'B');
+ MemoryAccess.setCharAtOffset(structSegmt, 6, 'B');
+ MemoryAccess.setCharAtOffset(structSegmt, 8, 'C');
+ MemoryAccess.setCharAtOffset(structSegmt, 10, 'C');
+ MemoryAccess.setCharAtOffset(structSegmt, 12, 'D');
+ MemoryAccess.setCharAtOffset(structSegmt, 14, 'D');
+ MemoryAccess.setCharAtOffset(structSegmt, 16, 'E');
+ MemoryAccess.setCharAtOffset(structSegmt, 18, 'E');
+
+ char result = (char)mh.invokeExact('A', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'U');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(char.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment charSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(charSegmt, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ char result = (char)mh.invokeExact(charSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'M');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct_returnCharPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment charSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setChar(charSegmt, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(charSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_SHORT.byteSize(), scope);
+ VarHandle charHandle = MemoryHandles.varHandle(char.class, ByteOrder.nativeOrder());
+ char result = (char)charHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 'M');
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), charSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(char.class, char.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructPointer,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'H');
+ charHandle2.set(structSegmt, 'I');
+
+ char result = (char)mh.invokeExact('G', structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 'V');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'E');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'F');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'G');
+
+ char result = (char)mh.invokeExact('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'E');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'F');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'G');
+
+ char result = (char)mh.invokeExact('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArrayByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ C_SHORT.withName("elem2")) : MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'A');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'B');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'C');
+
+ char result = (char)mh.invokeExact('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ charArray.withName("array_elem2")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'A');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'B');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'C');
+
+ char result = (char)mh.invokeExact('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_SHORT.withName("elem2"));
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'E');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'F');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'G');
+ MemoryAccess.setCharAtOffset(structSegmt, 6, 'H');
+ MemoryAccess.setCharAtOffset(structSegmt, 8, 'I');
+
+ char result = (char)mh.invokeExact('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(char.class, char.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setCharAtOffset(structSegmt, 0, 'E');
+ MemoryAccess.setCharAtOffset(structSegmt, 2, 'F');
+ MemoryAccess.setCharAtOffset(structSegmt, 4, 'G');
+ MemoryAccess.setCharAtOffset(structSegmt, 6, 'H');
+ MemoryAccess.setCharAtOffset(structSegmt, 8, 'I');
+
+ char result = (char)mh.invokeExact('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(char.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3CharStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ charHandle3.set(structSegmt1, 'C');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'B');
+ charHandle2.set(structSegmt2, 'C');
+ charHandle3.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt), 'F');
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)888);
+ shortHandle2.set(structSegmt, (short)999);
+
+ short result = (short)mh.invokeExact((short)777, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2664);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd10ShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT, C_SHORT, C_SHORT, C_SHORT,
+ C_SHORT, C_SHORT, C_SHORT, C_SHORT, C_SHORT, C_SHORT);
+
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAnd10ShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAnd10ShortsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)10);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)20);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)30);
+ MemoryAccess.setShortAtOffset(structSegmt, 6, (short)40);
+ MemoryAccess.setShortAtOffset(structSegmt, 8, (short)50);
+ MemoryAccess.setShortAtOffset(structSegmt, 10, (short)60);
+ MemoryAccess.setShortAtOffset(structSegmt, 12, (short)70);
+ MemoryAccess.setShortAtOffset(structSegmt, 14, (short)80);
+ MemoryAccess.setShortAtOffset(structSegmt, 16, (short)90);
+ MemoryAccess.setShortAtOffset(structSegmt, 18, (short)100);
+
+ short result = (short)mh.invokeExact((short)110, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 660);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(short.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct,
+ FunctionDescriptor.of(C_SHORT, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ short result = (short)mh.invokeExact(shortSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 3349);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct_returnShortPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment shortSegmt = allocator.allocate(C_SHORT);
+ MemoryAccess.setShort(shortSegmt, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(shortSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_SHORT.byteSize(), scope);
+ VarHandle shortHandle = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder());
+ short result = (short)shortHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 3349);
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), shortSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(short.class, short.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructPointer,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)2222);
+ shortHandle2.set(structSegmt, (short)4444);
+
+ short result = (short)mh.invokeExact((short)6666, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 13332);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)331);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)333);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)335);
+
+ short result = (short)mh.invokeExact((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)331);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)333);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)335);
+
+ short result = (short)mh.invokeExact((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArrayByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ C_SHORT.withName("elem2")) : MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)1111);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)2222);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)3333);
+
+ short result = (short)mh.invokeExact((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)1111);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)2222);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)3333);
+
+ short result = (short)mh.invokeExact((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), C_SHORT.withName("elem2"));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)1111);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)2222);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)3333);
+ MemoryAccess.setShortAtOffset(structSegmt, 6, (short)4444);
+ MemoryAccess.setShortAtOffset(structSegmt, 8, (short)5555);
+
+ short result = (short)mh.invokeExact((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+ MethodType mt = MethodType.methodType(short.class, short.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_SHORT, C_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setShortAtOffset(structSegmt, 0, (short)1111);
+ MemoryAccess.setShortAtOffset(structSegmt, 2, (short)2222);
+ MemoryAccess.setShortAtOffset(structSegmt, 4, (short)3333);
+ MemoryAccess.setShortAtOffset(structSegmt, 6, (short)4444);
+ MemoryAccess.setShortAtOffset(structSegmt, 8, (short)5555);
+
+ short result = (short)mh.invokeExact((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)734);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)712);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)734);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)712);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3")) : MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(short.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)325);
+ shortHandle2.set(structSegmt1, (short)326);
+ shortHandle3.set(structSegmt1, (short)327);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)334);
+ shortHandle2.set(structSegmt2, (short)335);
+ shortHandle3.set(structSegmt2, (short)336);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)659);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)661);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt), (short)663);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStruct,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1122334);
+ intHandle2.set(structSegmt, 1234567);
+
+ int result = (int)mh.invokeExact(2244668, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 4601569);
+ }
+ }
+
+ @Test
+ public void test_addIntAnd5IntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"),
+ C_INT.withName("elem3"), C_INT.withName("elem4"), C_INT.withName("elem5"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+ VarHandle intHandle4 = structLayout.varHandle(int.class, PathElement.groupElement("elem4"));
+ VarHandle intHandle5 = structLayout.varHandle(int.class, PathElement.groupElement("elem5"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAnd5IntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAnd5IntsFromStruct,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1111111);
+ intHandle2.set(structSegmt, 2222222);
+ intHandle3.set(structSegmt, 3333333);
+ intHandle4.set(structSegmt, 2222222);
+ intHandle5.set(structSegmt, 1111111);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 14444443);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct,
+ FunctionDescriptor.of(C_INT, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment intSegmt = allocator.allocate(C_INT);
+ MemoryAccess.setInt(intSegmt, 7654321);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1234567);
+ intHandle2.set(structSegmt, 2468024);
+
+ int result = (int)mh.invokeExact(intSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11356912);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct_returnIntPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment intSegmt = allocator.allocate(C_INT);
+ MemoryAccess.setInt(intSegmt, 1122333);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 4455666);
+ intHandle2.set(structSegmt, 7788999);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(intSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_INT.byteSize(), scope);
+ VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
+ int result = (int)intHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 13366998);
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), intSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructPointer,
+ FunctionDescriptor.of(C_INT, C_INT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 11121314);
+ intHandle2.set(structSegmt, 15161718);
+
+ int result = (int)mh.invokeExact(19202122, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 45485154);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_INT.withName("elem2"));
+
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 21222324);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 25262728);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 29303132);
+
+ int result = (int)mh.invokeExact(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 21222324);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 25262728);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 29303132);
+
+ int result = (int)mh.invokeExact(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArrayByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), C_INT.withName("elem2"));
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 1111111);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 2222222);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 3333333);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), intArray.withName("array_elem2"));
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 1111111);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 2222222);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 3333333);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_INT.withName("elem2"));
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 1111111);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 2222222);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 3333333);
+ MemoryAccess.setIntAtOffset(structSegmt, 12, 4444444);
+ MemoryAccess.setIntAtOffset(structSegmt, 16, 5555555);
+
+ int result = (int)mh.invokeExact(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ MethodType mt = MethodType.methodType(int.class, int.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_INT, C_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setIntAtOffset(structSegmt, 0, 1111111);
+ MemoryAccess.setIntAtOffset(structSegmt, 4, 2222222);
+ MemoryAccess.setIntAtOffset(structSegmt, 8, 3333333);
+ MemoryAccess.setIntAtOffset(structSegmt, 12, 4444444);
+ MemoryAccess.setIntAtOffset(structSegmt, 16, 5555555);
+
+ int result = (int)mh.invokeExact(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add3IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ intHandle3.set(structSegmt1, 99001122);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 33445566);
+ intHandle2.set(structSegmt2, 77889900);
+ intHandle3.set(structSegmt2, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt), 143333333);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStruct,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 1234567890L);
+ longHandle2.set(structSegmt, 9876543210L);
+
+ long result = (long)mh.invokeExact(2468024680L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 13579135780L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct,
+ FunctionDescriptor.of(longLayout, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 1111111111L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 3333333333L);
+ longHandle2.set(structSegmt, 5555555555L);
+
+ long result = (long)mh.invokeExact(longSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 9999999999L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct_returnLongPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment longSegmt = allocator.allocate(longLayout);
+ MemoryAccess.setLong(longSegmt, 1122334455L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 6677889900L);
+ longHandle2.set(structSegmt, 1234567890L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(longSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(longLayout.byteSize(), scope);
+ VarHandle longHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
+ long result = (long)longHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 9034792245L);
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), longSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(long.class, long.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructPointer,
+ FunctionDescriptor.of(longLayout, longLayout, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 224466880022L);
+ longHandle2.set(structSegmt, 446688002244L);
+
+ long result = (long)mh.invokeExact(668800224466L, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 1339955106732L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 135791357913L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 246802468024L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 135791357913L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 246802468024L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArrayByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, longLayout);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), longLayout.withName("elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 11111111111L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 22222222222L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16, 33333333333L);
+
+ long result = (long)mh.invokeExact(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, longLayout);
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longArray.withName("array_elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 11111111111L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 22222222222L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16, 33333333333L);
+
+ long result = (long)mh.invokeExact(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), longLayout.withName("elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 11111111111L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 22222222222L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16, 33333333333L);
+ MemoryAccess.setLongAtOffset(structSegmt, 24, 44444444444L);
+ MemoryAccess.setLongAtOffset(structSegmt, 32, 55555555555L);
+
+ long result = (long)mh.invokeExact(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), structArray.withName("struct_array_elem2"));
+ MethodType mt = MethodType.methodType(long.class, long.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(longLayout, longLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(longLayout, longLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setLongAtOffset(structSegmt, 0, 11111111111L);
+ MemoryAccess.setLongAtOffset(structSegmt, 8, 22222222222L);
+ MemoryAccess.setLongAtOffset(structSegmt, 16, 33333333333L);
+ MemoryAccess.setLongAtOffset(structSegmt, 24, 44444444444L);
+ MemoryAccess.setLongAtOffset(structSegmt, 32, 55555555555L);
+
+ long result = (long)mh.invokeExact(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 5566778899L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 9900112233L);
+ longHandle2.set(structSegmt2, 3344556677L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 11022446688L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 8911335576L);
+ }
+ }
+
+ @Test
+ public void test_add3LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3LongStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ longHandle3.set(structSegmt1, 112233445566L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+ longHandle3.set(structSegmt2, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt), 891132446688L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 8.12F);
+ floatHandle2.set(structSegmt, 9.24F);
+
+ float result = (float)mh.invokeExact(6.56F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23.92F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd5FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"),
+ C_FLOAT.withName("elem3"), C_FLOAT.withName("elem4"), C_FLOAT.withName("elem5"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle floatHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+ VarHandle floatHandle5 = structLayout.varHandle(float.class, PathElement.groupElement("elem5"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAnd5FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAnd5FloatsFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 1.01F);
+ floatHandle2.set(structSegmt, 1.02F);
+ floatHandle3.set(structSegmt, 1.03F);
+ floatHandle4.set(structSegmt, 1.04F);
+ floatHandle5.set(structSegmt, 1.05F);
+
+ float result = (float)mh.invokeExact(1.06F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 6.21F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(float.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct,
+ FunctionDescriptor.of(C_FLOAT, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment floatSegmt = allocator.allocate(C_FLOAT);
+ MemoryAccess.setFloat(floatSegmt, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ float result = (float)mh.invokeExact(floatSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment floatSegmt = allocator.allocate(C_FLOAT);
+ MemoryAccess.setFloat(floatSegmt, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(floatSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_FLOAT.byteSize(), scope);
+ VarHandle floatHandle = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder());
+ float result = (float)floatHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), floatSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(float.class, float.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructPointer,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 35.11F);
+ floatHandle2.set(structSegmt, 46.22F);
+
+ float result = (float)mh.invokeExact(79.33F, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 160.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_FLOAT.withName("elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 31.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 33.44F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 31.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 33.44F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, C_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), C_FLOAT.withName("elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 111.11F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 222.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, C_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 111.11F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 222.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_FLOAT.withName("elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 111.11F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 222.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 333.33F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 12, 444.44F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ MethodType mt = MethodType.methodType(float.class, float.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_FLOAT, C_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setFloatAtOffset(structSegmt, 0, 111.11F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 4, 222.22F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 8, 333.33F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 12, 444.44F);
+ MemoryAccess.setFloatAtOffset(structSegmt, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ floatHandle3.set(structSegmt1, 45.67F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+ floatHandle3.set(structSegmt2, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt), 115.39, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 2228.111D);
+ doubleHandle2.set(structSegmt, 2229.221D);
+
+ double result = (double)mh.invokeExact(3336.333D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 7793.665D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 112.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 118.456D);
+ doubleHandle2.set(structSegmt, 119.789D);
+
+ double result = (double)mh.invokeExact(doubleSegmt.address(), structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 350.368D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment doubleSegmt = allocator.allocate(C_DOUBLE);
+ MemoryAccess.setDouble(doubleSegmt, 212.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 218.456D);
+ doubleHandle2.set(structSegmt, 219.789D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(doubleSegmt.address(), structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(C_DOUBLE.byteSize(), scope);
+ VarHandle doubleHandle = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder());
+ double result = (double)doubleHandle.get(resultSegmt, 0);
+ Assert.assertEquals(result, 650.368D, 0.001D);
+ Assert.assertEquals(resultSegmt.address().toRawLongValue(), doubleSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemoryAddress.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, C_POINTER, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructPointer,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, C_POINTER), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 22.111D);
+ doubleHandle2.set(structSegmt, 44.222D);
+
+ double result = (double)mh.invokeExact(66.333D, structSegmt.address(), upcallFuncAddr);
+ Assert.assertEquals(result, 132.666D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_DOUBLE.withName("elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 31.789D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 33.456D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 31.789D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 33.456D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, C_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), C_DOUBLE.withName("elem2"));
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 111.111D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 222.222D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, C_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 111.111D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 222.222D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_DOUBLE.withName("elem2"));
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 111.111D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 222.222D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 333.333D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 24, 444.444D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ MethodType mt = MethodType.methodType(double.class, double.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(C_DOUBLE, C_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 0, 111.111D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 8, 222.222D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 16, 333.333D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 24, 444.444D);
+ MemoryAccess.setDoubleAtOffset(structSegmt, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MethodType mt = MethodType.methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStructPointer,
+ FunctionDescriptor.of(C_POINTER, C_POINTER, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invokeExact(structSegmt1.address(), structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.asSegment(structLayout.byteSize(), scope);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add3DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemoryAddress.class);
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, C_POINTER);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3DoubleStructs_returnStructByUpcallMH").get();
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.ofScope(scope);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, allocator, mt, fd);
+ MemoryAddress upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ doubleHandle3.set(structSegmt1, 33.123D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+ doubleHandle3.set(structSegmt2, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMethodHandles.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMethodHandles.java
new file mode 100644
index 00000000000..74e16a9b71a
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/upcall/UpcallMethodHandles.java
@@ -0,0 +1,2624 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.upcall;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import static java.lang.invoke.MethodType.methodType;
+import java.lang.invoke.VarHandle;
+
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.CLinker.VaList;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * The helper class that contains all upcall method handles with primitive types or struct as arguments.
+ */
+public class UpcallMethodHandles {
+ private static final Lookup lookup = MethodHandles.lookup();
+ private static ResourceScope scope = ResourceScope.newImplicitScope();
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
+ private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
+
+ static final MethodType MT_Bool_Bool_MemSegmt = methodType(boolean.class, boolean.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_Bool_MemAddr = methodType(MemoryAddress.class, boolean.class, MemoryAddress.class);
+ static final MethodType MT_Char_Char_MemSegmt = methodType(char.class, char.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_MemAddr_Char = methodType(MemoryAddress.class, MemoryAddress.class, char.class);
+ static final MethodType MT_Byte_Byte_MemSegmt = methodType(byte.class, byte.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_Byte_MemAddr = methodType(MemoryAddress.class, byte.class, MemoryAddress.class);
+ static final MethodType MT_Short_Short_MemSegmt = methodType(short.class, short.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_MemAddr_Short = methodType(MemoryAddress.class, MemoryAddress.class, short.class);
+ static final MethodType MT_Int_Int_MemSegmt = methodType(int.class, int.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_Int_MemAddr = methodType(MemoryAddress.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Long_Long_MemSegmt = methodType(long.class, long.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_MemAddr_Long = methodType(MemoryAddress.class, MemoryAddress.class, long.class);
+ static final MethodType MT_Long_Int_MemSegmt = methodType(long.class, int.class, MemorySegment.class);
+ static final MethodType MT_Float_Float_MemSegmt = methodType(float.class, float.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_Float_MemAddr = methodType(MemoryAddress.class, float.class, MemoryAddress.class);
+ static final MethodType MT_Double_Double_MemSegmt = methodType(double.class, double.class, MemorySegment.class);
+ static final MethodType MT_MemAddr_MemAddr_Double = methodType(MemoryAddress.class, MemoryAddress.class, double.class);
+ static final MethodType MT_MemAddr_MemAddr_MemSegmt = methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt_MemSegmt_MemSegmt = methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt = methodType(MemorySegment.class);
+
+ public static final MethodHandle MH_add2BoolsWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPointerWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetPtr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetArgPtr;
+ public static final MethodHandle MH_createNewCharFrom2Chars;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPointer;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetPtr;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Bytes;
+ public static final MethodHandle MH_addByteAndByteFromPointer;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetPtr;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Shorts;
+ public static final MethodHandle MH_addShortAndShortFromPointer;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetPtr;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Ints;
+ public static final MethodHandle MH_addIntAndIntFromPointer;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetPtr;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add3Ints;
+ public static final MethodHandle MH_addIntAndChar;
+ public static final MethodHandle MH_add2IntsReturnVoid;
+ public static final MethodHandle MH_add2Longs;
+ public static final MethodHandle MH_addLongAndLongFromPointer;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetPtr;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Floats;
+ public static final MethodHandle MH_addFloatAndFloatFromPointer;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetPtr;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Doubles;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPointer;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetPtr;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetArgPtr;
+ public static final MethodHandle MH_compare;
+
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolAnd20BoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructPointerWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStruct;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStructPointer;
+ public static final MethodHandle MH_add3BoolStructsWithXor_returnStruct;
+
+ public static final MethodHandle MH_addByteAndBytesFromStruct;
+ public static final MethodHandle MH_addByteAnd20BytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct_returnBytePointer;
+ public static final MethodHandle MH_addByteAndBytesFromStructPointer;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add1ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ByteStructs_returnStruct;
+
+ public static final MethodHandle MH_addCharAndCharsFromStruct;
+ public static final MethodHandle MH_addCharAnd10CharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct_returnCharPointer;
+ public static final MethodHandle MH_addCharAndCharsFromStructPointer;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2CharStructs_returnStruct;
+ public static final MethodHandle MH_add2CharStructs_returnStructPointer;
+ public static final MethodHandle MH_add3CharStructs_returnStruct;
+
+ public static final MethodHandle MH_addShortAndShortsFromStruct;
+ public static final MethodHandle MH_addShortAnd10ShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct_returnShortPointer;
+ public static final MethodHandle MH_addShortAndShortsFromStructPointer;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2ShortStructs_returnStruct;
+ public static final MethodHandle MH_add2ShortStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ShortStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntsFromStruct;
+ public static final MethodHandle MH_addIntAnd5IntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct_returnIntPointer;
+ public static final MethodHandle MH_addIntAndIntsFromStructPointer;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2IntStructs_returnStruct;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer;
+ public static final MethodHandle MH_add3IntStructs_returnStruct;
+
+ public static final MethodHandle MH_addLongAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct_returnLongPointer;
+ public static final MethodHandle MH_addLongAndLongsFromStructPointer;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2LongStructs_returnStruct;
+ public static final MethodHandle MH_add2LongStructs_returnStructPointer;
+ public static final MethodHandle MH_add3LongStructs_returnStruct;
+
+ public static final MethodHandle MH_addFloatAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd5FloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2FloatStructs_returnStruct;
+ public static final MethodHandle MH_add2FloatStructs_returnStructPointer;
+ public static final MethodHandle MH_add3FloatStructs_returnStruct;
+
+ public static final MethodHandle MH_addDoubleAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructPointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2DoubleStructs_returnStruct;
+ public static final MethodHandle MH_add2DoubleStructs_returnStructPointer;
+ public static final MethodHandle MH_add3DoubleStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntShortFromStruct;
+ public static final MethodHandle MH_addIntAndShortIntFromStruct;
+ public static final MethodHandle MH_addIntAndIntLongFromStruct;
+ public static final MethodHandle MH_addIntAndLongIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAnd2FloatsDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDouble2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndInt2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndLongDoubleFromStruct;
+ public static final MethodHandle MH_addFloatAndInt3FloatsFromStruct;
+ public static final MethodHandle MH_addLongAndLong2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd3FloatsIntFromStruct;
+ public static final MethodHandle MH_addLongAndFloatLongFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleLongFromStruct;
+ public static final MethodHandle MH_addLongAnd2FloatsLongFromStruct;
+ public static final MethodHandle MH_addShortAnd3ShortsCharFromStruct;
+ public static final MethodHandle MH_addFloatAndIntFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleLongFromStruct;
+ public static final MethodHandle MH_return254BytesFromStruct;
+ public static final MethodHandle MH_return4KBytesFromStruct;
+
+ static {
+ try {
+ MH_add2BoolsWithOr = lookup.findStatic(UpcallMethodHandles.class, "add2BoolsWithOr", methodType(boolean.class, boolean.class, boolean.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPointerWithOr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPointerWithOr", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetPtr", MT_MemAddr_Bool_MemAddr); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetArgPtr", MT_MemAddr_Bool_MemAddr); //$NON-NLS-1$
+
+ MH_createNewCharFrom2Chars = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFrom2Chars", methodType(char.class, char.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPointer = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPointer", methodType(char.class, MemoryAddress.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetPtr", MT_MemAddr_MemAddr_Char); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetArgPtr", MT_MemAddr_MemAddr_Char); //$NON-NLS-1$
+
+ MH_add2Bytes = lookup.findStatic(UpcallMethodHandles.class, "add2Bytes", methodType(byte.class, byte.class, byte.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetPtr", MT_MemAddr_Byte_MemAddr); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetArgPtr", MT_MemAddr_Byte_MemAddr); //$NON-NLS-1$
+
+ MH_add2Shorts = lookup.findStatic(UpcallMethodHandles.class, "add2Shorts", methodType(short.class, short.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPointer", methodType(short.class, MemoryAddress.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetPtr", MT_MemAddr_MemAddr_Short); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetArgPtr", MT_MemAddr_MemAddr_Short); //$NON-NLS-1$
+
+ MH_add2Ints = lookup.findStatic(UpcallMethodHandles.class, "add2Ints", methodType(int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetPtr", MT_MemAddr_Int_MemAddr); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetArgPtr", MT_MemAddr_Int_MemAddr); //$NON-NLS-1$
+ MH_add3Ints = lookup.findStatic(UpcallMethodHandles.class, "add3Ints", methodType(int.class, int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndChar = lookup.findStatic(UpcallMethodHandles.class, "addIntAndChar", methodType(int.class, int.class, char.class)); //$NON-NLS-1$
+ MH_add2IntsReturnVoid = lookup.findStatic(UpcallMethodHandles.class, "add2IntsReturnVoid", methodType(void.class, int.class, int.class)); //$NON-NLS-1$
+
+ MH_add2Longs = lookup.findStatic(UpcallMethodHandles.class, "add2Longs", methodType(long.class, long.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPointer", methodType(long.class, MemoryAddress.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetPtr", MT_MemAddr_MemAddr_Long); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetArgPtr", MT_MemAddr_MemAddr_Long); //$NON-NLS-1$
+
+ MH_add2Floats = lookup.findStatic(UpcallMethodHandles.class, "add2Floats", methodType(float.class, float.class, float.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetPtr", MT_MemAddr_Float_MemAddr); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetArgPtr", MT_MemAddr_Float_MemAddr); //$NON-NLS-1$
+
+ MH_add2Doubles = lookup.findStatic(UpcallMethodHandles.class, "add2Doubles", methodType(double.class, double.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPointer", methodType(double.class, MemoryAddress.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetPtr", MT_MemAddr_MemAddr_Double); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetArgPtr", MT_MemAddr_MemAddr_Double); //$NON-NLS-1$
+
+ MH_compare = lookup.findStatic(UpcallMethodHandles.class, "compare", methodType(int.class, MemoryAddress.class, MemoryAddress.class)); //$NON-NLS-1$
+
+ MH_addBoolAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAnd20BoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAnd20BoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor", methodType(boolean.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructPointerWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructPointerWithXor", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addByteAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAnd20BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAnd20BytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct", methodType(byte.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct_returnBytePointer = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct_returnBytePointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_add1ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add1ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addCharAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAnd10CharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAnd10CharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct", methodType(char.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct_returnCharPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct_returnCharPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructPointer", methodType(char.class, char.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addShortAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd10ShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd10ShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct", methodType(short.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct_returnShortPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct_returnShortPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructPointer", methodType(short.class, short.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAnd5IntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAnd5IntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct", methodType(int.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct_returnIntPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct_returnIntPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addLongAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct", methodType(long.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct_returnLongPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct_returnLongPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructPointer", methodType(long.class, long.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addFloatAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd5FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd5FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct", methodType(float.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct_returnFloatPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addDoubleAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct", methodType(double.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructPointer", methodType(double.class, double.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStructPointer", MT_MemAddr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntShortFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntShortFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndShortIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndShortIntFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntLongFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndLongIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndLongIntFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAnd2FloatsDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAnd2FloatsDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDouble2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDouble2FloatsFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt2FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndLongDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndLongDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt3FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt3FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLong2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLong2FloatsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd3FloatsIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd3FloatsIntFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndFloatLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndFloatLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addLongAnd2FloatsLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAnd2FloatsLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd3ShortsCharFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd3ShortsCharFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndIntFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndIntFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_return254BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return254BytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+ MH_return4KBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return4KBytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static boolean byteToBool(byte value) {
+ return (value != 0);
+ }
+
+ public static byte boolToByte(boolean value) {
+ int intValue = (value == true) ? 1 : 0;
+ return (byte)intValue;
+ }
+
+ public static boolean add2BoolsWithOr(boolean boolArg1, boolean boolArg2) {
+ boolean result = boolArg1 || boolArg2;
+ return result;
+ }
+
+ public static boolean addBoolAndBoolFromPointerWithOr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte boolArg2 = MemoryAccess.getByte(boolArg2Segmt);
+ boolean result = boolArg1 || byteToBool(boolArg2);
+ return result;
+ }
+
+ public static MemoryAddress addBoolAndBoolFromPtrWithOr_RetPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte boolArg2 = MemoryAccess.getByte(boolArg2Segmt);
+ boolean result = boolArg1 || byteToBool(boolArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_CHAR.byteSize(), scope);
+ MemoryAccess.setByte(resultSegmt, boolToByte(result));
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addBoolAndBoolFromPtrWithOr_RetArgPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte boolArg2 = MemoryAccess.getByte(boolArg2Segmt);
+ boolean result = boolArg1 || byteToBool(boolArg2);
+ MemoryAccess.setByte(boolArg2Segmt, boolToByte(result));
+ return boolArg2Addr;
+ }
+
+ public static char createNewCharFrom2Chars(char charArg1, char charArg2) {
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static char createNewCharFromCharAndCharFromPointer(MemoryAddress charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short charArg1 = MemoryAccess.getShort(charArg1Segmt);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static MemoryAddress createNewCharFromCharAndCharFromPtr_RetPtr(MemoryAddress charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short charArg1 = MemoryAccess.getShort(charArg1Segmt);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_SHORT.byteSize(), scope);
+ MemoryAccess.setChar(resultSegmt, result);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress createNewCharFromCharAndCharFromPtr_RetArgPtr(MemoryAddress charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short charArg1 = MemoryAccess.getShort(charArg1Segmt);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ MemoryAccess.setChar(charArg1Segmt, result);
+ return charArg1Addr;
+ }
+
+ public static byte add2Bytes(byte byteArg1, byte byteArg2) {
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static byte addByteAndByteFromPointer(byte byteArg1, MemoryAddress byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte byteArg2 = MemoryAccess.getByte(byteArg2Segmt);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static MemoryAddress addByteAndByteFromPtr_RetPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte byteArg2 = MemoryAccess.getByte(byteArg2Segmt);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_CHAR.byteSize(), scope);
+ MemoryAccess.setByte(resultSegmt, byteSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addByteAndByteFromPtr_RetArgPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.asSegment(C_CHAR.byteSize(), scope);
+ byte byteArg2 = MemoryAccess.getByte(byteArg2Segmt);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ MemoryAccess.setByte(byteArg2Segmt, byteSum);
+ return byteArg2Addr;
+ }
+
+ public static short add2Shorts(short shortArg1, short shortArg2) {
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortFromPointer(MemoryAddress shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short shortArg1 = MemoryAccess.getShort(shortArg1Segmt);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static MemoryAddress addShortAndShortFromPtr_RetPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short shortArg1 = MemoryAccess.getShort(shortArg1Segmt);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_SHORT.byteSize(), scope);
+ MemoryAccess.setShort(resultSegmt, shortSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addShortAndShortFromPtr_RetArgPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.asSegment(C_SHORT.byteSize(), scope);
+ short shortArg1 = MemoryAccess.getShort(shortArg1Segmt);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ MemoryAccess.setShort(shortArg1Segmt, shortSum);
+ return shortArg1Addr;
+ }
+
+ public static int add2Ints(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static int addIntAndIntFromPointer(int intArg1, MemoryAddress intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.asSegment(C_INT.byteSize(), scope);
+ int intArg2 = MemoryAccess.getInt(intArg2Segmt);
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static MemoryAddress addIntAndIntFromPtr_RetPtr(int intArg1, MemoryAddress intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.asSegment(C_INT.byteSize(), scope);
+ int intArg2 = MemoryAccess.getInt(intArg2Segmt);
+ int intSum = intArg1 + intArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_INT.byteSize(), scope);
+ MemoryAccess.setInt(resultSegmt, intSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addIntAndIntFromPtr_RetArgPtr(int intArg1, MemoryAddress intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.asSegment(C_INT.byteSize(), scope);
+ int intArg2 = MemoryAccess.getInt(intArg2Segmt);
+ int intSum = intArg1 + intArg2;
+ MemoryAccess.setInt(intArg2Segmt, intSum);
+ return intArg2Addr;
+ }
+
+ public static int add3Ints(int intArg1, int intArg2, int intArg3) {
+ int intSum = intArg1 + intArg2 + intArg3;
+ return intSum;
+ }
+
+ public static int addIntAndChar(int intArg, char charArg) {
+ int sum = intArg + charArg;
+ return sum;
+ }
+
+ public static void add2IntsReturnVoid(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ System.out.println("add2IntsReturnVoid: intSum = " + intSum + "\n");
+ }
+
+ public static long add2Longs(long longArg1, long longArg2) {
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static long addLongAndLongFromPointer(MemoryAddress longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.asSegment(longLayout.byteSize(), scope);
+ long longArg1 = MemoryAccess.getLong(longArg1Segmt);
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static MemoryAddress addLongAndLongFromPtr_RetPtr(MemoryAddress longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.asSegment(longLayout.byteSize(), scope);
+ long longArg1 = MemoryAccess.getLong(longArg1Segmt);
+ long longSum = longArg1 + longArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(longLayout.byteSize(), scope);
+ MemoryAccess.setLong(resultSegmt, longSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addLongAndLongFromPtr_RetArgPtr(MemoryAddress longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.asSegment(longLayout.byteSize(), scope);
+ long longArg1 = MemoryAccess.getLong(longArg1Segmt);
+ long longSum = longArg1 + longArg2;
+ MemoryAccess.setLong(longArg1Segmt, longSum);
+ return longArg1Addr;
+ }
+
+ public static float add2Floats(float floatArg1, float floatArg2) {
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatFromPointer(float floatArg1, MemoryAddress floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.asSegment(C_FLOAT.byteSize(), scope);
+ float floatArg2 = MemoryAccess.getFloat(floatArg2Segmt);
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static MemoryAddress addFloatAndFloatFromPtr_RetPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.asSegment(C_FLOAT.byteSize(), scope);
+ float floatArg2 = MemoryAccess.getFloat(floatArg2Segmt);
+ float floatSum = floatArg1 + floatArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_FLOAT.byteSize(), scope);
+ MemoryAccess.setFloat(resultSegmt, floatSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addFloatAndFloatFromPtr_RetArgPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.asSegment(C_FLOAT.byteSize(), scope);
+ float floatArg2 = MemoryAccess.getFloat(floatArg2Segmt);
+ float floatSum = floatArg1 + floatArg2;
+ MemoryAccess.setFloat(floatArg2Segmt, floatSum);
+ return floatArg2Addr;
+ }
+
+ public static double add2Doubles(double doubleArg1, double doubleArg2) {
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFromPointer(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.asSegment(C_DOUBLE.byteSize(), scope);
+ double doubleArg1 = MemoryAccess.getDouble(doubleArg1Segmt);
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static MemoryAddress addDoubleAndDoubleFromPtr_RetPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.asSegment(C_DOUBLE.byteSize(), scope);
+ double doubleArg1 = MemoryAccess.getDouble(doubleArg1Segmt);
+ double doubleSum = doubleArg1 + doubleArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(C_DOUBLE.byteSize(), scope);
+ MemoryAccess.setDouble(resultSegmt, doubleSum);
+ return resultSegmt.address();
+ }
+
+ public static MemoryAddress addDoubleAndDoubleFromPtr_RetArgPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.asSegment(C_DOUBLE.byteSize(), scope);
+ double doubleArg1 = MemoryAccess.getDouble(doubleArg1Segmt);
+ double doubleSum = doubleArg1 + doubleArg2;
+ MemoryAccess.setDouble(doubleArg1Segmt, doubleSum);
+ return doubleArg1Addr;
+ }
+
+ public static int compare(MemoryAddress argAddr1, MemoryAddress argAddr2) {
+ int intArg1 = MemoryAccess.getInt(argAddr1.asSegment(C_INT.byteSize(), scope));
+ int intArg2 = MemoryAccess.getInt(argAddr2.asSegment(C_INT.byteSize(), scope));
+ return (intArg1 - intArg2);
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ boolean boolSum = arg1 ^ byteToBool((byte)boolHandle1.get(arg2)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ return boolSum;
+ }
+
+ public static boolean addBoolAnd20BoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), C_CHAR.withName("elem4"), C_CHAR.withName("elem5"), C_CHAR.withName("elem6"),
+ C_CHAR.withName("elem7"), C_CHAR.withName("elem8"), C_CHAR.withName("elem9"), C_CHAR.withName("elem10"),
+ C_CHAR.withName("elem11"), C_CHAR.withName("elem12"), C_CHAR.withName("elem13"), C_CHAR.withName("elem14"),
+ C_CHAR.withName("elem15"), C_CHAR.withName("elem16"), C_CHAR.withName("elem17"), C_CHAR.withName("elem18"),
+ C_CHAR.withName("elem19"), C_CHAR.withName("elem20"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+ VarHandle boolHandle4 = structLayout.varHandle(byte.class, PathElement.groupElement("elem4"));
+ VarHandle boolHandle5 = structLayout.varHandle(byte.class, PathElement.groupElement("elem5"));
+ VarHandle boolHandle6 = structLayout.varHandle(byte.class, PathElement.groupElement("elem6"));
+ VarHandle boolHandle7 = structLayout.varHandle(byte.class, PathElement.groupElement("elem7"));
+ VarHandle boolHandle8 = structLayout.varHandle(byte.class, PathElement.groupElement("elem8"));
+ VarHandle boolHandle9 = structLayout.varHandle(byte.class, PathElement.groupElement("elem9"));
+ VarHandle boolHandle10 = structLayout.varHandle(byte.class, PathElement.groupElement("elem10"));
+ VarHandle boolHandle11 = structLayout.varHandle(byte.class, PathElement.groupElement("elem11"));
+ VarHandle boolHandle12 = structLayout.varHandle(byte.class, PathElement.groupElement("elem12"));
+ VarHandle boolHandle13 = structLayout.varHandle(byte.class, PathElement.groupElement("elem13"));
+ VarHandle boolHandle14 = structLayout.varHandle(byte.class, PathElement.groupElement("elem14"));
+ VarHandle boolHandle15 = structLayout.varHandle(byte.class, PathElement.groupElement("elem15"));
+ VarHandle boolHandle16 = structLayout.varHandle(byte.class, PathElement.groupElement("elem16"));
+ VarHandle boolHandle17 = structLayout.varHandle(byte.class, PathElement.groupElement("elem17"));
+ VarHandle boolHandle18 = structLayout.varHandle(byte.class, PathElement.groupElement("elem18"));
+ VarHandle boolHandle19 = structLayout.varHandle(byte.class, PathElement.groupElement("elem19"));
+ VarHandle boolHandle20 = structLayout.varHandle(byte.class, PathElement.groupElement("elem20"));
+
+ boolean boolSum = arg1 ^ byteToBool((byte)boolHandle1.get(arg2)) ^ byteToBool((byte)boolHandle2.get(arg2))
+ ^ byteToBool((byte)boolHandle3.get(arg2)) ^ byteToBool((byte)boolHandle4.get(arg2)) ^ byteToBool((byte)boolHandle5.get(arg2))
+ ^ byteToBool((byte)boolHandle6.get(arg2)) ^ byteToBool((byte)boolHandle7.get(arg2)) ^ byteToBool((byte)boolHandle8.get(arg2))
+ ^ byteToBool((byte)boolHandle9.get(arg2)) ^ byteToBool((byte)boolHandle10.get(arg2)) ^ byteToBool((byte)boolHandle11.get(arg2))
+ ^ byteToBool((byte)boolHandle12.get(arg2)) ^ byteToBool((byte)boolHandle13.get(arg2)) ^ byteToBool((byte)boolHandle14.get(arg2))
+ ^ byteToBool((byte)boolHandle15.get(arg2)) ^ byteToBool((byte)boolHandle16.get(arg2)) ^ byteToBool((byte)boolHandle17.get(arg2))
+ ^ byteToBool((byte)boolHandle18.get(arg2)) ^ byteToBool((byte)boolHandle19.get(arg2)) ^ byteToBool((byte)boolHandle20.get(arg2));
+ return boolSum;
+ }
+
+ public static boolean addBoolFromPointerAndBoolsFromStructWithXor(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_CHAR.byteSize(), arg1Addr.scope());
+ byte arg1 = MemoryAccess.getByte(arg1Segmt);
+ boolean boolSum = byteToBool(arg1) ^ byteToBool((byte)boolHandle1.get(arg2)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ return boolSum;
+ }
+
+ public static MemoryAddress addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_CHAR.byteSize(), arg1Addr.scope());
+ byte arg1 = MemoryAccess.getByte(arg1Segmt);
+ boolean boolSum = byteToBool(arg1) ^ byteToBool((byte)boolHandle1.get(arg2)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ MemoryAccess.setByte(arg1Segmt, boolToByte(boolSum));
+ return arg1Addr;
+ }
+
+ public static boolean addBoolAndBoolsFromStructPointerWithXor(boolean arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ boolean boolSum = arg1 ^ byteToBool((byte)boolHandle1.get(arg2)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor(boolean arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ boolean nestedStructElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedStructElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean structElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+ boolean boolSum = arg1 ^ nestedStructElem1 ^ nestedStructElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor_reverseOrder(boolean arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+
+ boolean structElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedStructElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean nestedStructElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+ boolean boolSum = arg1 ^ structElem1 ^ nestedStructElem1 ^ nestedStructElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray(boolean arg1, MemorySegment arg2) {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ boolean nestedBoolArrayElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedBoolArrayElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean structElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+
+ boolean boolSum = arg1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+
+ boolean structElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedBoolArrayElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean nestedBoolArrayElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+
+ boolean boolSum = arg1 ^ structElem1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray(boolean arg1, MemorySegment arg2) {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+
+ boolean nestedStructArrayElem1_Elem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedStructArrayElem1_Elem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean nestedStructArrayElem2_Elem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+ boolean nestedStructArrayElem2_Elem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 3));
+ boolean structElem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 4));
+
+ boolean boolSum = arg1 ^ structElem2
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+
+ boolean structElem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 0));
+ boolean nestedStructArrayElem1_Elem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 1));
+ boolean nestedStructArrayElem1_Elem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 2));
+ boolean nestedStructArrayElem2_Elem1 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 3));
+ boolean nestedStructArrayElem2_Elem2 = byteToBool(MemoryAccess.getByteAtOffset(arg2, 4));
+
+ boolean boolSum = arg1 ^ structElem1
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static MemorySegment add2BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ boolean boolStruct_Elem1 = byteToBool((byte)boolHandle1.get(arg1)) ^ byteToBool((byte)boolHandle1.get(arg2));
+ boolean boolStruct_Elem2 = byteToBool((byte)boolHandle2.get(arg1)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ boolHandle1.set(boolStructSegmt, boolToByte(boolStruct_Elem1));
+ boolHandle2.set(boolStructSegmt, boolToByte(boolStruct_Elem2));
+ return boolStructSegmt;
+ }
+
+ public static MemoryAddress add2BoolStructsWithXor_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ boolean boolStruct_Elem1 = byteToBool((byte)boolHandle1.get(arg1)) ^ byteToBool((byte)boolHandle1.get(arg2));
+ boolean boolStruct_Elem2 = byteToBool((byte)boolHandle2.get(arg1)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ boolHandle1.set(arg1, boolToByte(boolStruct_Elem1));
+ boolHandle2.set(arg1, boolToByte(boolStruct_Elem2));
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle boolHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ boolean boolStruct_Elem1 = byteToBool((byte)boolHandle1.get(arg1)) ^ byteToBool((byte)boolHandle1.get(arg2));
+ boolean boolStruct_Elem2 = byteToBool((byte)boolHandle2.get(arg1)) ^ byteToBool((byte)boolHandle2.get(arg2));
+ boolean boolStruct_Elem3 = byteToBool((byte)boolHandle3.get(arg1)) ^ byteToBool((byte)boolHandle3.get(arg2));
+ boolHandle1.set(boolStructSegmt, boolToByte(boolStruct_Elem1));
+ boolHandle2.set(boolStructSegmt, boolToByte(boolStruct_Elem2));
+ boolHandle3.set(boolStructSegmt, boolToByte(boolStruct_Elem3));
+ return boolStructSegmt;
+ }
+
+ public static byte addByteAndBytesFromStruct(byte arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ byte byteSum = (byte)(arg1 + (byte)byteHandle1.get(arg2) + (byte)byteHandle2.get(arg2));
+ return byteSum;
+ }
+
+ public static byte addByteAnd20BytesFromStruct(byte arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), C_CHAR.withName("elem4"), C_CHAR.withName("elem5"), C_CHAR.withName("elem6"),
+ C_CHAR.withName("elem7"), C_CHAR.withName("elem8"), C_CHAR.withName("elem9"), C_CHAR.withName("elem10"),
+ C_CHAR.withName("elem11"), C_CHAR.withName("elem12"), C_CHAR.withName("elem13"), C_CHAR.withName("elem14"),
+ C_CHAR.withName("elem15"), C_CHAR.withName("elem16"), C_CHAR.withName("elem17"), C_CHAR.withName("elem18"),
+ C_CHAR.withName("elem19"), C_CHAR.withName("elem20"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(byte.class, PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(byte.class, PathElement.groupElement("elem5"));
+ VarHandle byteHandle6 = structLayout.varHandle(byte.class, PathElement.groupElement("elem6"));
+ VarHandle byteHandle7 = structLayout.varHandle(byte.class, PathElement.groupElement("elem7"));
+ VarHandle byteHandle8 = structLayout.varHandle(byte.class, PathElement.groupElement("elem8"));
+ VarHandle byteHandle9 = structLayout.varHandle(byte.class, PathElement.groupElement("elem9"));
+ VarHandle byteHandle10 = structLayout.varHandle(byte.class, PathElement.groupElement("elem10"));
+ VarHandle byteHandle11 = structLayout.varHandle(byte.class, PathElement.groupElement("elem11"));
+ VarHandle byteHandle12 = structLayout.varHandle(byte.class, PathElement.groupElement("elem12"));
+ VarHandle byteHandle13 = structLayout.varHandle(byte.class, PathElement.groupElement("elem13"));
+ VarHandle byteHandle14 = structLayout.varHandle(byte.class, PathElement.groupElement("elem14"));
+ VarHandle byteHandle15 = structLayout.varHandle(byte.class, PathElement.groupElement("elem15"));
+ VarHandle byteHandle16 = structLayout.varHandle(byte.class, PathElement.groupElement("elem16"));
+ VarHandle byteHandle17 = structLayout.varHandle(byte.class, PathElement.groupElement("elem17"));
+ VarHandle byteHandle18 = structLayout.varHandle(byte.class, PathElement.groupElement("elem18"));
+ VarHandle byteHandle19 = structLayout.varHandle(byte.class, PathElement.groupElement("elem19"));
+ VarHandle byteHandle20 = structLayout.varHandle(byte.class, PathElement.groupElement("elem20"));
+
+ byte bytelSum = (byte)(arg1 + (byte)byteHandle1.get(arg2) + (byte)byteHandle2.get(arg2)
+ + (byte)byteHandle3.get(arg2) + (byte)byteHandle4.get(arg2) + (byte)byteHandle5.get(arg2)
+ + (byte)byteHandle6.get(arg2) + (byte)byteHandle7.get(arg2) + (byte)byteHandle8.get(arg2)
+ + (byte)byteHandle9.get(arg2) + (byte)byteHandle10.get(arg2) + (byte)byteHandle11.get(arg2)
+ + (byte)byteHandle12.get(arg2) + (byte)byteHandle13.get(arg2) + (byte)byteHandle14.get(arg2)
+ + (byte)byteHandle15.get(arg2) + (byte)byteHandle16.get(arg2) + (byte)byteHandle17.get(arg2)
+ + (byte)byteHandle18.get(arg2) + (byte)byteHandle19.get(arg2) + (byte)byteHandle20.get(arg2));
+ return bytelSum;
+ }
+
+ public static byte addByteFromPointerAndBytesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_CHAR.byteSize(), arg1Addr.scope());
+ byte arg1 = MemoryAccess.getByte(arg1Segmt);
+ byte byteSum = (byte)(arg1 + (byte)byteHandle1.get(arg2) + (byte)byteHandle2.get(arg2));
+ return byteSum;
+ }
+
+ public static MemoryAddress addByteFromPointerAndBytesFromStruct_returnBytePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_CHAR.byteSize(), arg1Addr.scope());
+ byte arg1 = MemoryAccess.getByte(arg1Segmt);
+ byte byteSum = (byte)(arg1 + (byte)byteHandle1.get(arg2) + (byte)byteHandle2.get(arg2));
+ MemoryAccess.setByte(arg1Segmt, byteSum);
+ return arg1Addr;
+ }
+
+ public static byte addByteAndBytesFromStructPointer(byte arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ byte byteSum = (byte)(arg1 + (byte)byteHandle1.get(arg2) + (byte)byteHandle2.get(arg2));
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct(byte arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ byte nestedStructElem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedStructElem2 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte structElem2 = MemoryAccess.getByteAtOffset(arg2, 2);
+
+ byte byteSum = (byte)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct_reverseOrder(byte arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+
+ byte structElem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedStructElem1 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte nestedStructElem2 = MemoryAccess.getByteAtOffset(arg2, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray(byte arg1, MemorySegment arg2) {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ byte nestedByteArrayElem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedByteArrayElem2 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte structElem2 = MemoryAccess.getByteAtOffset(arg2, 2);
+
+ byte byteSum = (byte)(arg1 + nestedByteArrayElem1 + nestedByteArrayElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+
+ byte structElem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedByteArrayElem1 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte nestedByteArrayElem2 = MemoryAccess.getByteAtOffset(arg2, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedByteArrayElem1 + nestedByteArrayElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray(byte arg1, MemorySegment arg2) {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ C_CHAR.withName("elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+
+ byte nestedStructArrayElem1_Elem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedStructArrayElem1_Elem2 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte nestedStructArrayElem2_Elem1 = MemoryAccess.getByteAtOffset(arg2, 2);
+ byte nestedStructArrayElem2_Elem2 = MemoryAccess.getByteAtOffset(arg2, 3);
+ byte structElem2 = MemoryAccess.getByteAtOffset(arg2, 4);
+
+ byte byteSum = (byte)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ GroupLayout byteStruct = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(C_CHAR.bitSize() * 3));
+
+ byte structElem1 = MemoryAccess.getByteAtOffset(arg2, 0);
+ byte nestedStructArrayElem1_Elem1 = MemoryAccess.getByteAtOffset(arg2, 1);
+ byte nestedStructArrayElem1_Elem2 = MemoryAccess.getByteAtOffset(arg2, 2);
+ byte nestedStructArrayElem2_Elem1 = MemoryAccess.getByteAtOffset(arg2, 3);
+ byte nestedStructArrayElem2_Elem2 = MemoryAccess.getByteAtOffset(arg2, 4);
+
+ byte byteSum = (byte)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static MemorySegment add1ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)((byte)byteHandle1.get(arg1) + (byte)byteHandle1.get(arg2));
+ byteHandle1.set(byteStructSegmt, byteStruct_Elem1);
+ return byteStructSegmt;
+ }
+
+ public static MemorySegment add2ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)((byte)byteHandle1.get(arg1) + (byte)byteHandle1.get(arg2));
+ byte byteStruct_Elem2 = (byte)((byte)byteHandle2.get(arg1) + (byte)byteHandle2.get(arg2));
+ byteHandle1.set(byteStructSegmt, byteStruct_Elem1);
+ byteHandle2.set(byteStructSegmt, byteStruct_Elem2);
+ return byteStructSegmt;
+ }
+
+ public static MemoryAddress add2ByteStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ byte byteStruct_Elem1 = (byte)((byte)byteHandle1.get(arg1) + (byte)byteHandle1.get(arg2));
+ byte byteStruct_Elem2 = (byte)((byte)byteHandle2.get(arg1) + (byte)byteHandle2.get(arg2));
+ byteHandle1.set(arg1, byteStruct_Elem1);
+ byteHandle2.set(arg1, byteStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_CHAR.withName("elem1"), C_CHAR.withName("elem2"),
+ C_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle byteHandle1 = structLayout.varHandle(byte.class, PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(byte.class, PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(byte.class, PathElement.groupElement("elem3"));
+
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)((byte)byteHandle1.get(arg1) + (byte)byteHandle1.get(arg2));
+ byte byteStruct_Elem2 = (byte)((byte)byteHandle2.get(arg1) + (byte)byteHandle2.get(arg2));
+ byte byteStruct_Elem3 = (byte)((byte)byteHandle3.get(arg1) + (byte)byteHandle3.get(arg2));
+ byteHandle1.set(byteStructSegmt, byteStruct_Elem1);
+ byteHandle2.set(byteStructSegmt, byteStruct_Elem2);
+ byteHandle3.set(byteStructSegmt, byteStruct_Elem3);
+ return byteStructSegmt;
+ }
+
+ public static char addCharAndCharsFromStruct(char arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ char result = (char)(arg1 + (char)charHandle1.get(arg2) + (char)charHandle2.get(arg2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAnd10CharsFromStruct(char arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), C_SHORT.withName("elem4"), C_SHORT.withName("elem5"),
+ C_SHORT.withName("elem6"), C_SHORT.withName("elem7"), C_SHORT.withName("elem8"),
+ C_SHORT.withName("elem9"), C_SHORT.withName("elem10"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(char.class, PathElement.groupElement("elem3"));
+ VarHandle charHandle4 = structLayout.varHandle(char.class, PathElement.groupElement("elem4"));
+ VarHandle charHandle5 = structLayout.varHandle(char.class, PathElement.groupElement("elem5"));
+ VarHandle charHandle6 = structLayout.varHandle(char.class, PathElement.groupElement("elem6"));
+ VarHandle charHandle7 = structLayout.varHandle(char.class, PathElement.groupElement("elem7"));
+ VarHandle charHandle8 = structLayout.varHandle(char.class, PathElement.groupElement("elem8"));
+ VarHandle charHandle9 = structLayout.varHandle(char.class, PathElement.groupElement("elem9"));
+ VarHandle charHandle10 = structLayout.varHandle(char.class, PathElement.groupElement("elem10"));
+
+ char result = (char)(arg1 + (char)charHandle1.get(arg2) + (char)charHandle2.get(arg2)
+ + (char)charHandle3.get(arg2) + (char)charHandle4.get(arg2) + (char)charHandle5.get(arg2)
+ + (char)charHandle6.get(arg2) + (char)charHandle7.get(arg2) + (char)charHandle8.get(arg2)
+ + (char)charHandle9.get(arg2) + (char)charHandle10.get(arg2) - 10 * 'A');
+ return result;
+ }
+
+ public static char addCharFromPointerAndCharsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_SHORT.byteSize(), arg1Addr.scope());
+ char arg1 = MemoryAccess.getChar(arg1Segmt);
+ char result = (char)(arg1 + (char)charHandle1.get(arg2) + (char)charHandle2.get(arg2) - 2 * 'A');
+ return result;
+ }
+
+ public static MemoryAddress addCharFromPointerAndCharsFromStruct_returnCharPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_SHORT.byteSize(), arg1Addr.scope());
+ char arg1 = MemoryAccess.getChar(arg1Segmt);
+ char result = (char)(arg1 + (char)charHandle1.get(arg2) + (char)charHandle2.get(arg2) - 2 * 'A');
+ MemoryAccess.setChar(arg1Segmt, result);
+ return arg1Addr;
+ }
+
+ public static char addCharAndCharsFromStructPointer(char arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ char result = (char)(arg1 + (char)charHandle1.get(arg2) + (char)charHandle2.get(arg2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct(char arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ char nestedStructElem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedStructElem2 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char structElem2 = MemoryAccess.getCharAtOffset(arg2, 4);
+
+ char result = (char)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct_reverseOrder(char arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+
+ char structElem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedStructElem1 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char nestedStructElem2 = MemoryAccess.getCharAtOffset(arg2, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray(char arg1, MemorySegment arg2) {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ char nestedCharArrayElem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedCharArrayElem2 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char structElem2 = MemoryAccess.getCharAtOffset(arg2, 4);
+
+ char result = (char)(arg1 + nestedCharArrayElem1 + nestedCharArrayElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray_reverseOrder(char arg1, MemorySegment arg2) {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+
+ char structElem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedCharArrayElem1 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char nestedCharArrayElem2 = MemoryAccess.getCharAtOffset(arg2, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedCharArrayElem1 + nestedCharArrayElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray(char arg1, MemorySegment arg2) {
+ GroupLayout charStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_SHORT.withName("elem2"));
+
+ char nestedStructArrayElem1_Elem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedStructArrayElem1_Elem2 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char nestedStructArrayElem2_Elem1 = MemoryAccess.getCharAtOffset(arg2, 4);
+ char nestedStructArrayElem2_Elem2 = MemoryAccess.getCharAtOffset(arg2, 6);
+ char structElem2 = MemoryAccess.getCharAtOffset(arg2, 8);
+
+ char result = (char)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray_reverseOrder(char arg1, MemorySegment arg2) {
+ GroupLayout charStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(16));
+
+ char structElem1 = MemoryAccess.getCharAtOffset(arg2, 0);
+ char nestedStructArrayElem1_Elem1 = MemoryAccess.getCharAtOffset(arg2, 2);
+ char nestedStructArrayElem1_Elem2 = MemoryAccess.getCharAtOffset(arg2, 4);
+ char nestedStructArrayElem2_Elem1 = MemoryAccess.getCharAtOffset(arg2, 6);
+ char nestedStructArrayElem2_Elem2 = MemoryAccess.getCharAtOffset(arg2, 8);
+
+ char result = (char)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static MemorySegment add2CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ char charStruct_Elem1 = (char)((char)charHandle1.get(arg1) + (char)charHandle1.get(arg2) - 'A');
+ char charStruct_Elem2 = (char)((char)charHandle2.get(arg1) + (char)charHandle2.get(arg2) - 'A');
+ charHandle1.set(charStructSegmt, charStruct_Elem1);
+ charHandle2.set(charStructSegmt, charStruct_Elem2);
+ return charStructSegmt;
+ }
+
+ public static MemoryAddress add2CharStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ char charStruct_Elem1 = (char)((char)charHandle1.get(arg1) + (char)charHandle1.get(arg2) - 'A');
+ char charStruct_Elem2 = (char)((char)charHandle2.get(arg1) + (char)charHandle2.get(arg2) - 'A');
+ charHandle1.set(arg1, charStruct_Elem1);
+ charHandle2.set(arg1, charStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle charHandle1 = structLayout.varHandle(char.class, PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(char.class, PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(char.class, PathElement.groupElement("elem3"));
+
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ char charStruct_Elem1 = (char)((char)charHandle1.get(arg1) + (char)charHandle1.get(arg2) - 'A');
+ char charStruct_Elem2 = (char)((char)charHandle2.get(arg1) + (char)charHandle2.get(arg2) - 'A');
+ char charStruct_Elem3 = (char)((char)charHandle3.get(arg1) + (char)charHandle3.get(arg2) - 'A');
+ charHandle1.set(charStructSegmt, charStruct_Elem1);
+ charHandle2.set(charStructSegmt, charStruct_Elem2);
+ charHandle3.set(charStructSegmt, charStruct_Elem3);
+ return charStructSegmt;
+ }
+
+ public static short addShortAndShortsFromStruct(short arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ short shortSum = (short)(arg1 + (short)shortHandle1.get(arg2) + (short)shortHandle2.get(arg2));
+ return shortSum;
+ }
+
+ public static short addShortAnd10ShortsFromStruct(short arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), C_SHORT.withName("elem4"), C_SHORT.withName("elem5"),
+ C_SHORT.withName("elem6"), C_SHORT.withName("elem7"), C_SHORT.withName("elem8"),
+ C_SHORT.withName("elem9"), C_SHORT.withName("elem10"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(short.class, PathElement.groupElement("elem3"));
+ VarHandle shortHandle4 = structLayout.varHandle(short.class, PathElement.groupElement("elem4"));
+ VarHandle shortHandle5 = structLayout.varHandle(short.class, PathElement.groupElement("elem5"));
+ VarHandle shortHandle6 = structLayout.varHandle(short.class, PathElement.groupElement("elem6"));
+ VarHandle shortHandle7 = structLayout.varHandle(short.class, PathElement.groupElement("elem7"));
+ VarHandle shortHandle8 = structLayout.varHandle(short.class, PathElement.groupElement("elem8"));
+ VarHandle shortHandle9 = structLayout.varHandle(short.class, PathElement.groupElement("elem9"));
+ VarHandle shortHandle10 = structLayout.varHandle(short.class, PathElement.groupElement("elem10"));
+
+ short shortSum = (short)(arg1 + (short)shortHandle1.get(arg2) + (short)shortHandle2.get(arg2)
+ + (short)shortHandle3.get(arg2) + (short)shortHandle4.get(arg2) + (short)shortHandle5.get(arg2)
+ + (short)shortHandle6.get(arg2) + (short)shortHandle7.get(arg2) + (short)shortHandle8.get(arg2)
+ + (short)shortHandle9.get(arg2) + (short)shortHandle10.get(arg2));
+ return shortSum;
+ }
+
+ public static short addShortFromPointerAndShortsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_SHORT.byteSize(), arg1Addr.scope());
+ short arg1 = MemoryAccess.getShort(arg1Segmt);
+ short shortSum = (short)(arg1 + (short)shortHandle1.get(arg2) + (short)shortHandle2.get(arg2));
+ return shortSum;
+ }
+
+ public static MemoryAddress addShortFromPointerAndShortsFromStruct_returnShortPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_SHORT.byteSize(), arg1Addr.scope());
+ short arg1 = MemoryAccess.getShort(arg1Segmt);
+ short shortSum = (short)(arg1 + (short)shortHandle1.get(arg2) + (short)shortHandle2.get(arg2));
+ MemoryAccess.setShort(arg1Segmt, shortSum);
+ return arg1Addr;
+ }
+
+ public static short addShortAndShortsFromStructPointer(short arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ short shortSum = (short)(arg1 + (short)shortHandle1.get(arg2) + (short)shortHandle2.get(arg2));
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct(short arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ short nestedStructElem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedStructElem2 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short structElem2 = MemoryAccess.getShortAtOffset(arg2, 4);
+
+ short shortSum = (short)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct_reverseOrder(short arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+
+ short structElem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedStructElem1 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short nestedStructElem2 = MemoryAccess.getShortAtOffset(arg2, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray(short arg1, MemorySegment arg2) {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+
+ short nestedShortArrayElem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedShortArrayElem2 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short structElem2 = MemoryAccess.getShortAtOffset(arg2, 4);
+
+ short shortSum = (short)(arg1 + nestedShortArrayElem1 + nestedShortArrayElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray_reverseOrder(short arg1, MemorySegment arg2) {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, C_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+
+ short structElem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedShortArrayElem1 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short nestedShortArrayElem2 = MemoryAccess.getShortAtOffset(arg2, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedShortArrayElem1 + nestedShortArrayElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray(short arg1, MemorySegment arg2) {
+ GroupLayout shortStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), C_SHORT.withName("elem2"));
+
+ short nestedStructArrayElem1_Elem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedStructArrayElem1_Elem2 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short nestedStructArrayElem2_Elem1 = MemoryAccess.getShortAtOffset(arg2, 4);
+ short nestedStructArrayElem2_Elem2 = MemoryAccess.getShortAtOffset(arg2, 6);
+ short structElem2 = MemoryAccess.getShortAtOffset(arg2, 8);
+
+ short shortSum = (short)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray_reverseOrder(short arg1, MemorySegment arg2) {
+ GroupLayout shortStruct = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+
+ short structElem1 = MemoryAccess.getShortAtOffset(arg2, 0);
+ short nestedStructArrayElem1_Elem1 = MemoryAccess.getShortAtOffset(arg2, 2);
+ short nestedStructArrayElem1_Elem2 = MemoryAccess.getShortAtOffset(arg2, 4);
+ short nestedStructArrayElem2_Elem1 = MemoryAccess.getShortAtOffset(arg2, 6);
+ short nestedStructArrayElem2_Elem2 = MemoryAccess.getShortAtOffset(arg2, 8);
+
+ short shortSum = (short)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static MemorySegment add2ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ short shortStruct_Elem1 = (short)((short)shortHandle1.get(arg1) + (short)shortHandle1.get(arg2));
+ short shortStruct_Elem2 = (short)((short)shortHandle2.get(arg1) + (short)shortHandle2.get(arg2));
+ shortHandle1.set(shortStructSegmt, shortStruct_Elem1);
+ shortHandle2.set(shortStructSegmt, shortStruct_Elem2);
+ return shortStructSegmt;
+ }
+
+ public static MemoryAddress add2ShortStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ short shortStruct_Elem1 = (short)((short)shortHandle1.get(arg1) + (short)shortHandle1.get(arg2));
+ short shortStruct_Elem2 = (short)((short)shortHandle2.get(arg1) + (short)shortHandle2.get(arg2));
+ shortHandle1.set(arg1, shortStruct_Elem1);
+ shortHandle2.set(arg1, shortStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"), C_SHORT.withName("elem2"),
+ C_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle shortHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(short.class, PathElement.groupElement("elem3"));
+
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ short shortStruct_Elem1 = (short)((short)shortHandle1.get(arg1) + (short)shortHandle1.get(arg2));
+ short shortStruct_Elem2 = (short)((short)shortHandle2.get(arg1) + (short)shortHandle2.get(arg2));
+ short shortStruct_Elem3 = (short)((short)shortHandle3.get(arg1) + (short)shortHandle3.get(arg2));
+ shortHandle1.set(shortStructSegmt, shortStruct_Elem1);
+ shortHandle2.set(shortStructSegmt, shortStruct_Elem2);
+ shortHandle3.set(shortStructSegmt, shortStruct_Elem3);
+ return shortStructSegmt;
+ }
+
+ public static int addIntAndIntsFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ int intSum = arg1 + (int)intHandle1.get(arg2) + (int)intHandle2.get(arg2);
+ return intSum;
+ }
+
+ public static int addIntAnd5IntsFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"),
+ C_INT.withName("elem3"), C_INT.withName("elem4"), C_INT.withName("elem5"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+ VarHandle intHandle4 = structLayout.varHandle(int.class, PathElement.groupElement("elem4"));
+ VarHandle intHandle5 = structLayout.varHandle(int.class, PathElement.groupElement("elem5"));
+
+ int intSum = arg1 + (int)intHandle1.get(arg2) + (int)intHandle2.get(arg2)
+ + (int)intHandle3.get(arg2) + (int)intHandle4.get(arg2) + (int)intHandle5.get(arg2);
+ return intSum;
+ }
+
+ public static int addIntFromPointerAndIntsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_INT.byteSize(), arg1Addr.scope());
+ int arg1 = MemoryAccess.getInt(arg1Segmt);
+ int intSum = arg1 + (int)intHandle1.get(arg2) + (int)intHandle2.get(arg2);
+ return intSum;
+ }
+
+ public static MemoryAddress addIntFromPointerAndIntsFromStruct_returnIntPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_INT.byteSize(), arg1Addr.scope());
+ int arg1 = MemoryAccess.getInt(arg1Segmt);
+ int intSum = arg1 + (int)intHandle1.get(arg2) + (int)intHandle2.get(arg2);
+ MemoryAccess.setInt(arg1Segmt, intSum);
+ return arg1Addr;
+ }
+
+ public static int addIntAndIntsFromStructPointer(int arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ int intSum = arg1 + (int)intHandle1.get(arg2) + (int)intHandle2.get(arg2);
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct(int arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_INT.withName("elem2"));
+
+ int nestedStructElem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedStructElem2 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int structElem2 = MemoryAccess.getIntAtOffset(arg2, 8);
+
+ int intSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct_reverseOrder(int arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ int structElem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedStructElem1 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int nestedStructElem2 = MemoryAccess.getIntAtOffset(arg2, 8);
+
+ int intSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray(int arg1, MemorySegment arg2) {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), C_INT.withName("elem2"));
+
+ int nestedIntArrayElem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedIntArrayElem2 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int structElem2 = MemoryAccess.getIntAtOffset(arg2, 8);
+
+ int intSum = arg1 + nestedIntArrayElem1 + nestedIntArrayElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray_reverseOrder(int arg1, MemorySegment arg2) {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, C_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), intArray.withName("array_elem2"));
+
+ int structElem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedIntArrayElem1 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int nestedIntArrayElem2 = MemoryAccess.getIntAtOffset(arg2, 8);
+
+ int intSum = arg1 + structElem1 + nestedIntArrayElem1 + nestedIntArrayElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray(int arg1, MemorySegment arg2) {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_INT.withName("elem2"));
+
+ int nestedStructArrayElem1_Elem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedStructArrayElem1_Elem2 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int nestedStructArrayElem2_Elem1 = MemoryAccess.getIntAtOffset(arg2, 8);
+ int nestedStructArrayElem2_Elem2 = MemoryAccess.getIntAtOffset(arg2, 12);
+ int structElem2 = MemoryAccess.getIntAtOffset(arg2, 16);
+
+ int intSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray_reverseOrder(int arg1, MemorySegment arg2) {
+ GroupLayout intStruct = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+
+ int structElem1 = MemoryAccess.getIntAtOffset(arg2, 0);
+ int nestedStructArrayElem1_Elem1 = MemoryAccess.getIntAtOffset(arg2, 4);
+ int nestedStructArrayElem1_Elem2 = MemoryAccess.getIntAtOffset(arg2, 8);
+ int nestedStructArrayElem2_Elem1 = MemoryAccess.getIntAtOffset(arg2, 12);
+ int nestedStructArrayElem2_Elem2 = MemoryAccess.getIntAtOffset(arg2, 16);
+
+ int intSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ int intStruct_Elem1 = (int)intHandle1.get(arg1) + (int)intHandle1.get(arg2);
+ int intStruct_Elem2 = (int)intHandle2.get(arg1) + (int)intHandle2.get(arg2);
+ intHandle1.set(intStructSegmt, intStruct_Elem1);
+ intHandle2.set(intStructSegmt, intStruct_Elem2);
+ return intStructSegmt;
+ }
+
+ public static MemoryAddress add2IntStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ int intSum_Elem1 = (int)intHandle1.get(arg1) + (int)intHandle1.get(arg2);
+ int intSum_Elem2 = (int)intHandle2.get(arg1) + (int)intHandle2.get(arg2);
+ intHandle1.set(arg1, intSum_Elem1);
+ intHandle2.set(arg1, intSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"), C_INT.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ int intStruct_Elem1 = (int)intHandle1.get(arg1) + (int)intHandle1.get(arg2);
+ int intStruct_Elem2 = (int)intHandle2.get(arg1) + (int)intHandle2.get(arg2);
+ int intStruct_Elem3 = (int)intHandle3.get(arg1) + (int)intHandle3.get(arg2);
+ intHandle1.set(intStructSegmt, intStruct_Elem1);
+ intHandle2.set(intStructSegmt, intStruct_Elem2);
+ intHandle3.set(intStructSegmt, intStruct_Elem3);
+ return intStructSegmt;
+ }
+
+ public static long addLongAndLongsFromStruct(long arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ long longSum = arg1 + (long)longHandle1.get(arg2) + (long)longHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static long addLongFromPointerAndLongsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(longLayout.byteSize(), arg1Addr.scope());
+ long arg1 = MemoryAccess.getLong(arg1Segmt);
+ long longSum = arg1 + (long)longHandle1.get(arg2) + (long)longHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static MemoryAddress addLongFromPointerAndLongsFromStruct_returnLongPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(longLayout.byteSize(), arg1Addr.scope());
+ long arg1 = MemoryAccess.getLong(arg1Segmt);
+ long longSum = arg1 + (long)longHandle1.get(arg2) + (long)longHandle2.get(arg2);
+ MemoryAccess.setLong(arg1Segmt, longSum);
+ return arg1Addr;
+ }
+
+ public static long addLongAndLongsFromStructPointer(long arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ long longSum = arg1 + (long)longHandle1.get(arg2) + (long)longHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct(long arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ long nestedStructElem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedStructElem2 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long structElem2 = MemoryAccess.getLongAtOffset(arg2, 16);
+
+ long longSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct_reverseOrder(long arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ long structElem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedStructElem1 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long nestedStructElem2 = MemoryAccess.getLongAtOffset(arg2, 16);
+
+ long longSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray(long arg1, MemorySegment arg2) {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, longLayout);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), longLayout.withName("elem2"));
+
+ long nestedLongrrayElem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedLongrrayElem2 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long structElem2 = MemoryAccess.getLongAtOffset(arg2, 16);
+
+ long longSum = arg1 + nestedLongrrayElem1 + nestedLongrrayElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray_reverseOrder(long arg1, MemorySegment arg2) {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, longLayout);
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longArray.withName("array_elem2"));
+
+ long structElem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedLongrrayElem1 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long nestedLongrrayElem2 = MemoryAccess.getLongAtOffset(arg2, 16);
+
+ long longSum = arg1 + structElem1 + nestedLongrrayElem1 + nestedLongrrayElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray(long arg1, MemorySegment arg2) {
+ GroupLayout longStruct = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), longLayout.withName("elem2"));
+
+ long nestedStructArrayElem1_Elem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedStructArrayElem1_Elem2 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long nestedStructArrayElem2_Elem1 = MemoryAccess.getLongAtOffset(arg2, 16);
+ long nestedStructArrayElem2_Elem2 = MemoryAccess.getLongAtOffset(arg2, 24);
+ long structElem2 = MemoryAccess.getLongAtOffset(arg2, 32);
+
+ long longSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray_reverseOrder(long arg1, MemorySegment arg2) {
+ GroupLayout longStruct = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), structArray.withName("struct_array_elem2"));
+
+ long structElem1 = MemoryAccess.getLongAtOffset(arg2, 0);
+ long nestedStructArrayElem1_Elem1 = MemoryAccess.getLongAtOffset(arg2, 8);
+ long nestedStructArrayElem1_Elem2 = MemoryAccess.getLongAtOffset(arg2, 16);
+ long nestedStructArrayElem2_Elem1 = MemoryAccess.getLongAtOffset(arg2, 24);
+ long nestedStructArrayElem2_Elem2 = MemoryAccess.getLongAtOffset(arg2, 32);
+
+ long longSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static MemorySegment add2LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ long longStruct_Elem1 = (long)longHandle1.get(arg1) + (long)longHandle1.get(arg2);
+ long longStruct_Elem2 = (long)longHandle2.get(arg1) + (long)longHandle2.get(arg2);
+ longHandle1.set(longStructSegmt, longStruct_Elem1);
+ longHandle2.set(longStructSegmt, longStruct_Elem2);
+ return longStructSegmt;
+ }
+
+ public static MemoryAddress add2LongStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ long longSum_Elem1 = (long)longHandle1.get(arg1) + (long)longHandle1.get(arg2);
+ long longSum_Elem2 = (long)longHandle2.get(arg1) + (long)longHandle2.get(arg2);
+ longHandle1.set(arg1, longSum_Elem1);
+ longHandle2.set(arg1, longSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), longLayout.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ long longStruct_Elem1 = (long)longHandle1.get(arg1) + (long)longHandle1.get(arg2);
+ long longStruct_Elem2 = (long)longHandle2.get(arg1) + (long)longHandle2.get(arg2);
+ long longStruct_Elem3 = (long)longHandle3.get(arg1) + (long)longHandle3.get(arg2);
+ longHandle1.set(longStructSegmt, longStruct_Elem1);
+ longHandle2.set(longStructSegmt, longStruct_Elem2);
+ longHandle3.set(longStructSegmt, longStruct_Elem3);
+ return longStructSegmt;
+ }
+
+ public static float addFloatAndFloatsFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ float floatSum = arg1 + (float)floatHandle1.get(arg2) + (float)floatHandle2.get(arg2);
+ return floatSum;
+ }
+
+ public static float addFloatAnd5FloatsFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"),
+ C_FLOAT.withName("elem3"), C_FLOAT.withName("elem4"), C_FLOAT.withName("elem5"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle floatHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+ VarHandle floatHandle5 = structLayout.varHandle(float.class, PathElement.groupElement("elem5"));
+
+ float floatSum = arg1 + (float)floatHandle1.get(arg2) + (float)floatHandle2.get(arg2)
+ + (float)floatHandle3.get(arg2) + (float)floatHandle4.get(arg2) + (float)floatHandle5.get(arg2);
+ return floatSum;
+ }
+
+ public static float addFloatFromPointerAndFloatsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_FLOAT.byteSize(), arg1Addr.scope());
+ float arg1 = MemoryAccess.getFloat(arg1Segmt);
+ float floatSum = arg1 + (float)floatHandle1.get(arg2) + (float)floatHandle2.get(arg2);
+ return floatSum;
+ }
+
+ public static MemoryAddress addFloatFromPointerAndFloatsFromStruct_returnFloatPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_FLOAT.byteSize(), arg1Addr.scope());
+ float arg1 = MemoryAccess.getFloat(arg1Segmt);
+ float floatSum = arg1 + (float)floatHandle1.get(arg2) + (float)floatHandle2.get(arg2);
+ MemoryAccess.setFloat(arg1Segmt, floatSum);
+ return arg1Addr;
+ }
+
+ public static float addFloatAndFloatsFromStructPointer(float arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ float floatSum = arg1 + (float)floatHandle1.get(arg2) + (float)floatHandle2.get(arg2);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct(float arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_FLOAT.withName("elem2"));
+
+ float nestedStructElem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedStructElem2 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float structElem2 = MemoryAccess.getFloatAtOffset(arg2, 8);
+
+ float floatSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct_reverseOrder(float arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ float structElem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedStructElem1 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float nestedStructElem2 = MemoryAccess.getFloatAtOffset(arg2, 8);
+
+ float floatSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray(float arg1, MemorySegment arg2) {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, C_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), C_FLOAT.withName("elem2"));
+
+ float nestedFloatArrayElem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedFloatArrayElem2 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float structElem2 = MemoryAccess.getFloatAtOffset(arg2, 8);
+
+ float floatSum = arg1 + nestedFloatArrayElem1 + nestedFloatArrayElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder(float arg1, MemorySegment arg2) {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, C_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+
+ float structElem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedFloatArrayElem1 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float nestedFloatArrayElem2 = MemoryAccess.getFloatAtOffset(arg2, 8);
+
+ float floatSum = arg1 + structElem1 + nestedFloatArrayElem1 + nestedFloatArrayElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray(float arg1, MemorySegment arg2) {
+ GroupLayout floatStruct = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_FLOAT.withName("elem2"));
+
+ float nestedStructArrayElem1_Elem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedStructArrayElem1_Elem2 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float nestedStructArrayElem2_Elem1 = MemoryAccess.getFloatAtOffset(arg2, 8);
+ float nestedStructArrayElem2_Elem2 = MemoryAccess.getFloatAtOffset(arg2, 12);
+ float structElem2 = MemoryAccess.getFloatAtOffset(arg2, 16);
+
+ float floatSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder(float arg1, MemorySegment arg2) {
+ GroupLayout floatStruct = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+
+ float structElem1 = MemoryAccess.getFloatAtOffset(arg2, 0);
+ float nestedStructArrayElem1_Elem1 = MemoryAccess.getFloatAtOffset(arg2, 4);
+ float nestedStructArrayElem1_Elem2 = MemoryAccess.getFloatAtOffset(arg2, 8);
+ float nestedStructArrayElem2_Elem1 = MemoryAccess.getFloatAtOffset(arg2, 12);
+ float nestedStructArrayElem2_Elem2 = MemoryAccess.getFloatAtOffset(arg2, 16);
+
+ float floatSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static MemorySegment add2FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ float floatStruct_Elem1 = (float)floatHandle1.get(arg1) + (float)floatHandle1.get(arg2);
+ float floatStruct_Elem2 = (float)floatHandle2.get(arg1) + (float)floatHandle2.get(arg2);
+ floatHandle1.set(floatStructSegmt, floatStruct_Elem1);
+ floatHandle2.set(floatStructSegmt, floatStruct_Elem2);
+ return floatStructSegmt;
+ }
+
+ public static MemoryAddress add2FloatStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ float floatSum_Elem1 = (float)floatHandle1.get(arg1) + (float)floatHandle1.get(arg2);
+ float floatSum_Elem2 = (float)floatHandle2.get(arg1) + (float)floatHandle2.get(arg2);
+ floatHandle1.set(arg1, floatSum_Elem1);
+ floatHandle2.set(arg1, floatSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"), C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ float floatStruct_Elem1 = (float)floatHandle1.get(arg1) + (float)floatHandle1.get(arg2);
+ float floatStruct_Elem2 = (float)floatHandle2.get(arg1) + (float)floatHandle2.get(arg2);
+ float floatStruct_Elem3 = (float)floatHandle3.get(arg1) + (float)floatHandle3.get(arg2);
+ floatHandle1.set(floatStructSegmt, floatStruct_Elem1);
+ floatHandle2.set(floatStructSegmt, floatStruct_Elem2);
+ floatHandle3.set(floatStructSegmt, floatStruct_Elem3);
+ return floatStructSegmt;
+ }
+
+ public static double addDoubleAndDoublesFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (double)doubleHandle1.get(arg2) + (double)doubleHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleFromPointerAndDoublesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_DOUBLE.byteSize(), arg1Addr.scope());
+ double arg1 = MemoryAccess.getDouble(arg1Segmt);
+ double doubleSum = arg1 + (double)doubleHandle1.get(arg2) + (double)doubleHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static MemoryAddress addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1Segmt = arg1Addr.asSegment(C_DOUBLE.byteSize(), arg1Addr.scope());
+ double arg1 = MemoryAccess.getDouble(arg1Segmt);
+ double doubleSum = arg1 + (double)doubleHandle1.get(arg2) + (double)doubleHandle2.get(arg2);
+ MemoryAccess.setDouble(arg1Segmt, doubleSum);
+ return arg1Addr;
+ }
+
+ public static double addDoubleAndDoublesFromStructPointer(double arg1, MemoryAddress arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg2 = arg2Addr.asSegment(structLayout.byteSize(), arg2Addr.scope());
+ double doubleSum = arg1 + (double)doubleHandle1.get(arg2) + (double)doubleHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct(double arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), C_DOUBLE.withName("elem2"));
+
+ double nestedStructElem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedStructElem2 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double structElem2 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+
+ double doubleSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct_reverseOrder(double arg1, MemorySegment arg2) {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ double structElem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedStructElem1 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double nestedStructElem2 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray(double arg1, MemorySegment arg2) {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, C_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), C_DOUBLE.withName("elem2"));
+
+ double nestedDoubleArrayElem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedDoubleArrayElem2 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double structElem2 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+
+ double doubleSum = arg1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder(double arg1, MemorySegment arg2) {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, C_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+
+ double structElem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedDoubleArrayElem1 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double nestedDoubleArrayElem2 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray(double arg1, MemorySegment arg2) {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), C_DOUBLE.withName("elem2"));
+
+ double nestedStructArrayElem1_Elem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedStructArrayElem1_Elem2 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double nestedStructArrayElem2_Elem1 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+ double nestedStructArrayElem2_Elem2 = MemoryAccess.getDoubleAtOffset(arg2, 24);
+ double structElem2 = MemoryAccess.getDoubleAtOffset(arg2, 32);
+
+ double doubleSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder(double arg1, MemorySegment arg2) {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+
+ double structElem1 = MemoryAccess.getDoubleAtOffset(arg2, 0);
+ double nestedStructArrayElem1_Elem1 = MemoryAccess.getDoubleAtOffset(arg2, 8);
+ double nestedStructArrayElem1_Elem2 = MemoryAccess.getDoubleAtOffset(arg2, 16);
+ double nestedStructArrayElem2_Elem1 = MemoryAccess.getDoubleAtOffset(arg2, 24);
+ double nestedStructArrayElem2_Elem2 = MemoryAccess.getDoubleAtOffset(arg2, 32);
+
+ double doubleSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static MemorySegment add2DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ double doubleStruct_Elem1 = (double)doubleHandle1.get(arg1) + (double)doubleHandle1.get(arg2);
+ double doubleStruct_Elem2 = (double)doubleHandle2.get(arg1) + (double)doubleHandle2.get(arg2);
+ doubleHandle1.set(doubleStructSegmt, doubleStruct_Elem1);
+ doubleHandle2.set(doubleStructSegmt, doubleStruct_Elem2);
+ return doubleStructSegmt;
+ }
+
+ public static MemoryAddress add2DoubleStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ MemorySegment arg1 = arg1Addr.asSegment(structLayout.byteSize(), arg1Addr.scope());
+ double doubleSum_Elem1 = (double)doubleHandle1.get(arg1) + (double)doubleHandle1.get(arg2);
+ double doubleSum_Elem2 = (double)doubleHandle2.get(arg1) + (double)doubleHandle2.get(arg2);
+ doubleHandle1.set(arg1, doubleSum_Elem1);
+ doubleHandle2.set(arg1, doubleSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_DOUBLE.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ double doubleStruct_Elem1 = (double)doubleHandle1.get(arg1) + (double)doubleHandle1.get(arg2);
+ double doubleStruct_Elem2 = (double)doubleHandle2.get(arg1) + (double)doubleHandle2.get(arg2);
+ double doubleStruct_Elem3 = (double)doubleHandle3.get(arg1) + (double)doubleHandle3.get(arg2);
+ doubleHandle1.set(doubleStructSegmt, doubleStruct_Elem1);
+ doubleHandle2.set(doubleStructSegmt, doubleStruct_Elem2);
+ doubleHandle3.set(doubleStructSegmt, doubleStruct_Elem3);
+ return doubleStructSegmt;
+ }
+
+ public static int addIntAndIntShortFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+
+ int intSum = arg1 + (int)elemHandle1.get(arg2) + (short)elemHandle2.get(arg2);
+ return intSum;
+ }
+
+ public static int addIntAndShortIntFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), C_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ int intSum = arg1 + (short)elemHandle1.get(arg2) + (int)elemHandle2.get(arg2);
+ return intSum;
+ }
+
+ public static long addIntAndIntLongFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ long longSum = arg1 + (int)elemHandle1.get(arg2) + (long)elemHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static long addIntAndLongIntFromStruct(int arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"),
+ C_INT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ long longSum = arg1 + (long)elemHandle1.get(arg2) + (int)elemHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static double addDoubleAndIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (int)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (double)elemHandle1.get(arg2) + (int)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (float)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), C_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (double)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAnd2FloatsDoubleFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (float)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2) + (double)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDouble2FloatsFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (double)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2) + (float)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt2FloatsFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ float floatSum = arg1 + (int)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2) + (float)elemHandle3.get(arg2);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_INT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ float structElem2 = Integer.valueOf((int)elemHandle2.get(arg2)).floatValue();
+ float floatSum = arg1 + (float)elemHandle1.get(arg2) + structElem2 + (float)elemHandle3.get(arg2);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (int)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2) + (double)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_INT.withName("elem2"), C_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(int.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(double.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (float)elemHandle1.get(arg2) + (int)elemHandle2.get(arg2) + (double)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndLongDoubleFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"), C_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (long)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt3FloatsFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"), C_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+
+ float floatSum = arg1 + (int)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2)
+ + (float)elemHandle3.get(arg2) + (float)elemHandle4.get(arg2);
+ return floatSum;
+ }
+
+ public static long addLongAndLong2FloatsFromStruct(long arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(longLayout.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(long.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ long structElem1 = (long)elemHandle1.get(arg2);
+ long structElem2 = Float.valueOf((float)elemHandle2.get(arg2)).longValue();
+ long structElem3 = Float.valueOf((float)elemHandle3.get(arg2)).longValue();
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static float addFloatAnd3FloatsIntFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_FLOAT.withName("elem3"), C_INT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(int.class, PathElement.groupElement("elem4"));
+
+ float floatSum = arg1 + (float)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2)
+ + (float)elemHandle3.get(arg2) + (int)elemHandle4.get(arg2);
+ return floatSum;
+ }
+
+ public static long addLongAndFloatLongFromStruct(long arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ long structElem1 = Float.valueOf((float)elemHandle1.get(arg2)).longValue();
+ long longSum = arg1 + structElem1 + (long)elemHandle2.get(arg2);
+ return longSum;
+ }
+
+ public static double addDoubleAndDoubleFloatIntFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (double)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2) + (int)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_DOUBLE.withName("elem1"), longLayout.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(double.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(long.class, PathElement.groupElement("elem2"));
+
+ double doubleSum = arg1 + (double)elemHandle1.get(arg2) + (long)elemHandle2.get(arg2);
+ return doubleSum;
+ }
+
+ public static long addLongAnd2FloatsLongFromStruct(long arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_FLOAT.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ long structElem1 = Float.valueOf((float)elemHandle1.get(arg2)).longValue();
+ long structElem2 = Float.valueOf((float)elemHandle2.get(arg2)).longValue();
+ long structElem3 = (long)elemHandle3.get(arg2);
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static short addShortAnd3ShortsCharFromStruct(short arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_SHORT.withName("elem1"),
+ C_SHORT.withName("elem2"), C_SHORT.withName("elem3"), C_SHORT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(short.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(short.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(short.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(char.class, PathElement.groupElement("elem4"));
+
+ short shortSum = (short)(arg1 + (short)elemHandle1.get(arg2) + (short)elemHandle2.get(arg2)
+ + (short)elemHandle3.get(arg2) + (char)elemHandle4.get(arg2));
+ return shortSum;
+ }
+
+ public static float addFloatAndIntFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_FLOAT.withName("elem2"), C_INT.withName("elem3"), C_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(float.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(float.class, PathElement.groupElement("elem4"));
+
+ float floatSum = arg1 + (int)elemHandle1.get(arg2) + (float)elemHandle2.get(arg2)
+ + (int)elemHandle3.get(arg2) + (float)elemHandle4.get(arg2);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [int, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(C_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (int)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2) + (float)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"))
+ : MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), C_DOUBLE.withName("elem2"),
+ C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (float)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2) + (int)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"))
+ : MemoryLayout.structLayout(C_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(int.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (int)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2) + (int)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_FLOAT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(C_FLOAT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), C_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(float.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(float.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (float)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2) + (float)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(C_INT.withName("elem1"),
+ C_DOUBLE.withName("elem2"), longLayout.withName("elem3"))
+ : MemoryLayout.structLayout(C_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ C_DOUBLE.withName("elem2"), longLayout.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(int.class, PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(double.class, PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(long.class, PathElement.groupElement("elem3"));
+
+ double doubleSum = arg1 + (int)elemHandle1.get(arg2) + (double)elemHandle2.get(arg2) + (long)elemHandle3.get(arg2);
+ return doubleSum;
+ }
+
+ public static MemorySegment return254BytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, scope);
+
+ for (int i = 0; i < 254; i++) {
+ MemoryAccess.setByteAtOffset(byteArrStruSegment, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+
+ public static MemorySegment return4KBytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, C_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, scope);
+
+ for (int i = 0; i < 4096; i++) {
+ MemoryAccess.setByteAtOffset(byteArrStruSegment, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/ApiTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/ApiTests.java
new file mode 100644
index 00000000000..8da17fa7253
--- /dev/null
+++ b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/ApiTests.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep389.valist;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.CLinker;
+import static jdk.incubator.foreign.CLinker.*;
+import static jdk.incubator.foreign.CLinker.VaList.Builder;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+
+/**
+ * Test cases for JEP 389: Foreign Linker API (Incubator) for the vararg list in VaList API specific cases.
+ */
+@Test(groups = { "level.sanity" })
+public class ApiTests {
+}
diff --git a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/VaListTests.java b/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/VaListTests.java
deleted file mode 100644
index de6d2d3ec53..00000000000
--- a/test/functional/Java17andUp/src_170/org/openj9/test/jep389/valist/VaListTests.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2021, 2022 IBM Corp. and others
- *
- * This program and the accompanying materials are made available under
- * the terms of the Eclipse Public License 2.0 which accompanies this
- * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
- * or the Apache License, Version 2.0 which accompanies this distribution and
- * is available at https://www.apache.org/licenses/LICENSE-2.0.
- *
- * This Source Code may also be made available under the following
- * Secondary Licenses when the conditions for such availability set
- * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
- * General Public License, version 2 with the GNU Classpath
- * Exception [1] and GNU General Public License, version 2 with the
- * OpenJDK Assembly Exception [2].
- *
- * [1] https://www.gnu.org/software/classpath/license.html
- * [2] http://openjdk.java.net/legal/assembly-exception.html
- *
- * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
- *******************************************************************************/
-package org.openj9.test.jep389.valist;
-
-import org.testng.annotations.Test;
-import org.testng.Assert;
-import org.testng.AssertJUnit;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-
-import jdk.incubator.foreign.Addressable;
-import jdk.incubator.foreign.CLinker;
-import static jdk.incubator.foreign.CLinker.*;
-import static jdk.incubator.foreign.CLinker.VaList.Builder;
-import jdk.incubator.foreign.FunctionDescriptor;
-import jdk.incubator.foreign.MemoryAccess;
-import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.MemoryLayout;
-import jdk.incubator.foreign.MemorySegment;
-import jdk.incubator.foreign.ResourceScope;
-import jdk.incubator.foreign.SegmentAllocator;
-import jdk.incubator.foreign.SymbolLookup;
-import jdk.incubator.foreign.ValueLayout;
-
-/**
- * Test cases for JEP 389: Foreign Linker API (Incubator) DownCall for the vararg list.
- */
-@Test(groups = { "level.sanity" })
-public class VaListTests {
- private static String osName = System.getProperty("os.name").toLowerCase();
- private static boolean isAixOS = osName.contains("aix");
- private static boolean isWinOS = osName.contains("win");
- /* long long is 64 bits on AIX/ppc64, which is the same as Windows */
- private static ValueLayout longLayout = (isWinOS || isAixOS) ? C_LONG_LONG : C_LONG;
- private static CLinker clinker = CLinker.getInstance();
-
- static {
- System.loadLibrary("clinkerffitests");
- }
- private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
- private static final SymbolLookup defaultLibLookup = (!isAixOS) ? CLinker.systemLookup() : null;
-
- @Test
- public void test_addIntsWithVaList() throws Throwable {
- Addressable functionSymbol = nativeLibLookup.lookup("addIntsFromVaList").get();
- MethodType mt = MethodType.methodType(int.class, int.class, VaList.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT, C_VA_LIST);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = CLinker.VaList.make(vaListBuilder -> vaListBuilder.vargFromInt(C_INT, 700)
- .vargFromInt(C_INT, 800)
- .vargFromInt(C_INT, 900)
- .vargFromInt(C_INT, 1000), scope);
- int result = (int)mh.invoke(4, vaList);
- Assert.assertEquals(result, 3400);
- }
- }
-
- @Test
- public void test_addLongsWithVaList() throws Throwable {
- Addressable functionSymbol = nativeLibLookup.lookup("addLongsFromVaList").get();
- MethodType mt = MethodType.methodType(long.class, int.class, VaList.class);
- FunctionDescriptor fd = FunctionDescriptor.of(longLayout, C_INT, C_VA_LIST);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = CLinker.VaList.make(vaListBuilder -> vaListBuilder.vargFromLong(longLayout, 700000L)
- .vargFromLong(longLayout, 800000L)
- .vargFromLong(longLayout, 900000L)
- .vargFromLong(longLayout, 1000000L), scope);
- long result = (long)mh.invoke(4, vaList);
- Assert.assertEquals(result, 3400000L);
- }
- }
-
- @Test
- public void test_addDoublesWithVaList() throws Throwable {
- Addressable functionSymbol = nativeLibLookup.lookup("addDoublesFromVaList").get();
- MethodType mt = MethodType.methodType(double.class, int.class, VaList.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_DOUBLE, C_INT, C_VA_LIST);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = CLinker.VaList.make(vaListBuilder -> vaListBuilder.vargFromDouble(C_DOUBLE, 150.1001D)
- .vargFromDouble(C_DOUBLE, 160.2002D)
- .vargFromDouble(C_DOUBLE, 170.1001D)
- .vargFromDouble(C_DOUBLE, 180.2002D), scope);
- double result = (double)mh.invoke(4, vaList);
- Assert.assertEquals(result, 660.6006D);
- }
- }
-
- @Test
- public void test_vprintfFromDefaultLibWithVaList() throws Throwable {
- /* Disable the test on Windows given a misaligned access exception coming from
- * java.base/java.lang.invoke.MemoryAccessVarHandleBase triggered by CLinker.toCString()
- * is also captured on OpenJDK/Hotspot.
- */
- if (!isWinOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("vprintf").get();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, VaList.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_VA_LIST);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, mt, fd);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- MemorySegment formatMemSegment = CLinker.toCString("%d * %d = %d\n", scope);
- VaList vaList = CLinker.VaList.make(vaListBuilder -> vaListBuilder.vargFromInt(C_INT, 7)
- .vargFromInt(C_INT, 8)
- .vargFromInt(C_INT, 56), scope);
- mh.invoke(formatMemSegment.address(), vaList);
- }
- }
- }
-
- @Test
- public void test_vprintfFromDefaultLibWithVaList_fromMemAddr() throws Throwable {
- /* Disable the test on Windows given a misaligned access exception coming from
- * java.base/java.lang.invoke.MemoryAccessVarHandleBase triggered by CLinker.toCString()
- * is also captured on OpenJDK/Hotspot.
- */
- if (!isWinOS) {
- Addressable functionSymbol = defaultLibLookup.lookup("vprintf").get();
- MemoryAddress memAddr = functionSymbol.address();
- MethodType mt = MethodType.methodType(int.class, MemoryAddress.class, VaList.class);
- FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_POINTER, C_VA_LIST);
- MethodHandle mh = clinker.downcallHandle(memAddr, mt, fd);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- MemorySegment formatMemSegment = CLinker.toCString("%d * %d = %d\n", scope);
- VaList vaList = CLinker.VaList.make(vaListBuilder -> vaListBuilder.vargFromInt(C_INT, 7)
- .vargFromInt(C_INT, 8)
- .vargFromInt(C_INT, 56), scope);
- mh.invoke(formatMemSegment.address(), vaList);
- }
- }
- }
-}
diff --git a/test/functional/Java17andUp/testng_170.xml b/test/functional/Java17andUp/testng_170.xml
index a6bc668c82a..c163d8114b7 100644
--- a/test/functional/Java17andUp/testng_170.xml
+++ b/test/functional/Java17andUp/testng_170.xml
@@ -32,6 +32,7 @@
+
@@ -39,9 +40,19 @@
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/test/functional/Java18andUp/playlist.xml b/test/functional/Java18andUp/playlist.xml
index d7317f33df3..ff01df786a9 100644
--- a/test/functional/Java18andUp/playlist.xml
+++ b/test/functional/Java18andUp/playlist.xml
@@ -36,7 +36,7 @@
-excludegroups $(DEFAULT_EXCLUDE); \
$(TEST_STATUS)
- bits.64,^arch.x86,^arch.aarch64,^arch.ppc,^arch.390,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
sanity
@@ -50,6 +50,37 @@
18
+
+
+ Jep419Tests_testClinkerFfi_UpCall
+
+ --enable-preview
+
+ $(ADD_JVM_LIB_DIR_TO_LIBPATH) $(JAVA_COMMAND) $(JVM_OPTIONS) \
+ --add-modules jdk.incubator.foreign \
+ --enable-native-access=ALL-UNNAMED \
+ -Dforeign.restricted=permit \
+ -cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)GeneralTest.jar$(Q) \
+ org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng_180.xml$(Q) -testnames Jep419Tests_testClinkerFfi_UpCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 18
+
+
+
Jep419Tests_testClinkerFfi_VaList
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/InvalidDownCallTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/InvalidDownCallTests.java
index 960ffb85837..ebe5da0ce5c 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/InvalidDownCallTests.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/InvalidDownCallTests.java
@@ -34,16 +34,14 @@
import jdk.incubator.foreign.SymbolLookup;
import static jdk.incubator.foreign.ValueLayout.*;
-
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
* which verifies the illegal cases including unsupported layouts, etc.
* Note: the majority of illegal cases are removed given the corresponding method type
* is deduced from the function descriptor which is verified in OpenJDK.
*/
@Test(groups = { "level.sanity" })
public class InvalidDownCallTests {
- private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
private static CLinker clinker = CLinker.systemCLinker();
static {
@@ -61,33 +59,17 @@ public void test_invalidMemoryLayoutForIntType() throws Throwable {
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unsupported layout.*")
public void test_invalidMemoryLayoutForMemoryAddress() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (isAixOS) {
- throw new IllegalArgumentException("Unsupported layout");
- } else {
- NativeSymbol functionSymbol = clinker.lookup("strlen").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, MemoryLayout.paddingLayout(64));
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
- }
+ NativeSymbol functionSymbol = clinker.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, MemoryLayout.paddingLayout(64));
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unsupported layout.*")
public void test_invalidMemoryLayoutForReturnType() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (isAixOS) {
- throw new IllegalArgumentException("Unsupported layout");
- } else {
- NativeSymbol functionSymbol = clinker.lookup("strlen").get();
- FunctionDescriptor fd = FunctionDescriptor.of(MemoryLayout.paddingLayout(64), JAVA_LONG);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
- }
+ NativeSymbol functionSymbol = clinker.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(MemoryLayout.paddingLayout(64), JAVA_LONG);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
}
}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiCallTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiCallTests.java
index dc26a91a554..04afaad75b2 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiCallTests.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiCallTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021, 2021 IBM Corp. and others
+ * Copyright (c) 2021, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -33,7 +33,7 @@
import static jdk.incubator.foreign.ValueLayout.*;
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
* which verifies multiple downcalls with the same or different layouts or argument/return types.
*/
@Test(groups = { "level.sanity" })
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests1.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests1.java
index da6c491abaf..25d0d2513ff 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests1.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests1.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021, 2021 IBM Corp. and others
+ * Copyright (c) 2021, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -28,13 +28,17 @@
import java.lang.invoke.MethodHandle;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
import jdk.incubator.foreign.SymbolLookup;
import static jdk.incubator.foreign.ValueLayout.*;
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
- * which verifies the downcalls with the same layout & argument and return types in multithreading.
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
+ * which verifies the downcalls with the same downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests1 implements Thread.UncaughtExceptionHandler {
@@ -53,37 +57,49 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithSameFuncDescriptor() throws Throwable {
+ public void test_twoThreadsWithSameFuncDesc_SameDowncallHandler() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(112, 123);
- Assert.assertEquals(result, 235);
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(321, intSegmt);
+ Assert.assertEquals(result, 536);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
};
- thr1.setUncaughtExceptionHandler(this);
- thr1.start();
Thread thr2 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(235, 439);
- Assert.assertEquals(result, 674);
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(322, intSegmt);
+ Assert.assertEquals(result, 537);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
};
+
+ thr1.setUncaughtExceptionHandler(this);
thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
thr2.start();
thr1.join();
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests2.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests2.java
index dd2cdc35fa9..bdc0d4f312e 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests2.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021, 2021 IBM Corp. and others
+ * Copyright (c) 2021, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -26,15 +26,25 @@
import org.testng.AssertJUnit;
import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
import jdk.incubator.foreign.SymbolLookup;
import static jdk.incubator.foreign.ValueLayout.*;
+
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
- * which verifies the downcalls with the diffrent layouts and arguments/return types in multithreading.
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
+ * which verifies the downcalls with the shared downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests2 implements Thread.UncaughtExceptionHandler {
@@ -44,7 +54,10 @@ public class MultiThreadingTests2 implements Thread.UncaughtExceptionHandler {
static {
System.loadLibrary("clinkerffitests");
}
- private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ private static final FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ private static final NativeSymbol functionSymbol = SymbolLookup.loaderLookup().lookup("add2IntStructs_returnStruct").get();
+ private static final MethodHandle mh = CLinker.systemCLinker().downcallHandle(functionSymbol, fd);
@Test(enabled=false)
@Override
@@ -53,15 +66,26 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithDiffFuncDescriptor() throws Throwable {
+ public void test_twoThreadsWithSameFuncDesc_SharedDowncallHandler() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(112, 123);
- Assert.assertEquals(result, 235);
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -71,11 +95,22 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(112, 123, 235);
- Assert.assertEquals(result, 470);
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001123);
+ intHandle2.set(structSegmt2, 33445567);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224467);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113355);
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests3.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests3.java
index bf2c22f47d8..88ec4f06c58 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests3.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests3.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021, 2021 IBM Corp. and others
+ * Copyright (c) 2021, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -33,8 +33,8 @@
import static jdk.incubator.foreign.ValueLayout.*;
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
- * which verifies the downcalls with the diffrent return types in multithreading.
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
+ * which verifies the downcalls with the diffrent layouts and arguments/return types in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests3 implements Thread.UncaughtExceptionHandler {
@@ -53,7 +53,7 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_twoThreadsWithDiffReturnType() throws Throwable {
+ public void test_twoThreadsWithDiffFuncDescriptor() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
@@ -71,10 +71,11 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- mh.invokeExact(454, 398);
+ int result = (int)mh.invokeExact(112, 123, 235);
+ Assert.assertEquals(result, 470);
} catch (Throwable t) {
throw new RuntimeException(t);
}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests4.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests4.java
index 142f843354f..e9739e56bb6 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests4.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests4.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021, 2021 IBM Corp. and others
+ * Copyright (c) 2021, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
@@ -33,8 +33,8 @@
import static jdk.incubator.foreign.ValueLayout.*;
/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) DownCall for primitive types,
- * which verifies multiple downcalls combined with the diffrent layouts/arguments/return types in multithreading.
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
+ * which verifies the downcalls with the diffrent return types in multithreading.
*/
@Test(groups = { "level.sanity" })
public class MultiThreadingTests4 implements Thread.UncaughtExceptionHandler {
@@ -53,15 +53,15 @@ public void uncaughtException(Thread thr, Throwable t) {
}
@Test
- public void test_multiThreadsWithMixedFuncDescriptors() throws Throwable {
+ public void test_twoThreadsWithDiffReturnType() throws Throwable {
Thread thr1 = new Thread(){
public void run() {
try {
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(128, 246);
- Assert.assertEquals(result, 374);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -71,67 +71,10 @@ public void run() {
Thread thr2 = new Thread(){
public void run() {
try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(112, 642, 971);
- Assert.assertEquals(result, 1725);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr3 = new Thread(){
- public void run() {
- try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- boolean result = (boolean)mh.invokeExact(true, false);
- Assert.assertEquals(result, true);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr4 = new Thread(){
- public void run() {
- try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(416, 728);
- Assert.assertEquals(result, 1144);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr5 = new Thread(){
- public void run() {
- try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invokeExact(1012, 1023, 2035);
- Assert.assertEquals(result, 4070);
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
- };
-
- Thread thr6 = new Thread(){
- public void run() {
- try {
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- boolean result = (boolean)mh.invokeExact(false, false);
- Assert.assertEquals(result, false);
+ mh.invokeExact(454, 398);
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -140,24 +83,12 @@ public void run() {
thr1.setUncaughtExceptionHandler(this);
thr2.setUncaughtExceptionHandler(this);
- thr3.setUncaughtExceptionHandler(this);
- thr4.setUncaughtExceptionHandler(this);
- thr5.setUncaughtExceptionHandler(this);
- thr6.setUncaughtExceptionHandler(this);
thr1.start();
thr2.start();
- thr3.start();
- thr4.start();
- thr5.start();
- thr6.start();
- thr6.join();
- thr5.join();
- thr4.join();
- thr3.join();
- thr2.join();
thr1.join();
+ thr2.join();
if (initException != null){
throw new RuntimeException(initException);
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests5.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests5.java
new file mode 100644
index 00000000000..3fc7fed4825
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/MultiThreadingTests5.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.SymbolLookup;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in downcall,
+ * which verifies multiple downcalls combined with the diffrent layouts/arguments/return types in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests5 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiThreadsWithMixedFuncDescriptors() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(128, 246);
+ Assert.assertEquals(result, 374);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 642, 971);
+ Assert.assertEquals(result, 1725);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ boolean result = (boolean)mh.invokeExact(true, false);
+ Assert.assertEquals(result, true);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr4 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(416, 728);
+ Assert.assertEquals(result, 1144);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr5 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(1012, 1023, 2035);
+ Assert.assertEquals(result, 4070);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr6 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ boolean result = (boolean)mh.invokeExact(false, false);
+ Assert.assertEquals(result, false);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+ thr3.setUncaughtExceptionHandler(this);
+ thr4.setUncaughtExceptionHandler(this);
+ thr5.setUncaughtExceptionHandler(this);
+ thr6.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+ thr3.start();
+ thr4.start();
+ thr5.start();
+ thr6.start();
+
+ thr6.join();
+ thr5.join();
+ thr4.join();
+ thr3.join();
+ thr2.join();
+ thr1.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests1.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests1.java
index 191bb151691..97a11dd8407 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests1.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests1.java
@@ -45,7 +45,6 @@
*/
@Test(groups = { "level.sanity" })
public class PrimitiveTypeTests1 {
- private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
private static CLinker clinker = CLinker.systemCLinker();
private static ResourceScope resourceScope = ResourceScope.newImplicitScope();
private static SegmentAllocator nativeAllocator = SegmentAllocator.nativeAllocator(resourceScope);
@@ -262,53 +261,35 @@ public void test_addDoubleAndDoubleFromPointer_1() throws Throwable {
@Test
public void test_strlenFromDefaultLibWithMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol strlenSymbol = clinker.lookup("strlen").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
- MethodHandle mh = clinker.downcallHandle(strlenSymbol, fd);
- MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP419 DOWNCALL TEST SUITES");
- long strLength = (long)mh.invoke(funcSegmt);
- Assert.assertEquals(strLength, 27);
- }
+ NativeSymbol strlenSymbol = clinker.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = clinker.downcallHandle(strlenSymbol, fd);
+ MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP419 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(funcSegmt);
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol allocSymbol = clinker.lookup("malloc").get();
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
- MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
- allocMemAddr.set(JAVA_INT, 0, 15);
- Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
-
- NativeSymbol freeSymbol = clinker.lookup("free").get();
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
- MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, freeFuncDesc);
- freeHandle.invoke(allocMemAddr);
- }
+ NativeSymbol allocSymbol = clinker.lookup("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = clinker.downcallHandle(allocSymbol, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ allocMemAddr.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
+
+ NativeSymbol freeSymbol = clinker.lookup("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = clinker.downcallHandle(freeSymbol, freeFuncDesc);
+ freeHandle.invoke(allocMemAddr);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_1() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol functionSymbol = clinker.lookup("printf").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
- mh.invoke(formatSegmt, 15, 27, 42);
- }
+ NativeSymbol functionSymbol = clinker.lookup("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
+ mh.invoke(formatSegmt, 15, 27, 42);
}
}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests2.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests2.java
index 7d9ffcb9869..2b708c3228f 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests2.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/PrimitiveTypeTests2.java
@@ -47,7 +47,6 @@
*/
@Test(groups = { "level.sanity" })
public class PrimitiveTypeTests2 {
- private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
private static CLinker clinker = CLinker.systemCLinker();
private static ResourceScope resourceScope = ResourceScope.newImplicitScope();
private static SegmentAllocator nativeAllocator = SegmentAllocator.nativeAllocator(resourceScope);
@@ -264,53 +263,35 @@ public void test_addDoubleAndDoubleFromPointer_2() throws Throwable {
@Test
public void test_strlenFromDefaultLibWithMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol strlenSymbol = clinker.lookup("strlen").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
- MethodHandle mh = clinker.downcallHandle(fd);
- MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP419 DOWNCALL TEST SUITES");
- long strLength = (long)mh.invoke(strlenSymbol, funcSegmt);
- Assert.assertEquals(strLength, 27);
- }
+ NativeSymbol strlenSymbol = clinker.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = clinker.downcallHandle(fd);
+ MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP419 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(strlenSymbol, funcSegmt);
+ Assert.assertEquals(strLength, 27);
}
@Test
public void test_memoryAllocFreeFromDefaultLib_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol allocSymbol = clinker.lookup("malloc").get();
- FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
- MethodHandle allocHandle = clinker.downcallHandle(allocFuncDesc);
- MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
- allocMemAddr.set(JAVA_INT, 0, 15);
- Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
-
- NativeSymbol freeSymbol = clinker.lookup("free").get();
- FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
- MethodHandle freeHandle = clinker.downcallHandle(freeFuncDesc);
- freeHandle.invoke(freeSymbol, allocMemAddr);
- }
+ NativeSymbol allocSymbol = clinker.lookup("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = clinker.downcallHandle(allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
+ allocMemAddr.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
+
+ NativeSymbol freeSymbol = clinker.lookup("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = clinker.downcallHandle(freeFuncDesc);
+ freeHandle.invoke(freeSymbol, allocMemAddr);
}
@Test
public void test_printfFromDefaultLibWithMemAddr_2() throws Throwable {
- /* Temporarily disable the default library loading on AIX till we figure out a way
- * around to handle the case as the official implementation in OpenJDK17 doesn't
- * help to load the static libray (libc.a).
- */
- if (!isAixOS) {
- NativeSymbol functionSymbol = clinker.lookup("printf").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
- MethodHandle mh = clinker.downcallHandle(fd);
- MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
- mh.invoke(functionSymbol, formatSegmt, 15, 27, 42);
- }
+ NativeSymbol functionSymbol = clinker.lookup("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = clinker.downcallHandle(fd);
+ MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
+ mh.invoke(functionSymbol, formatSegmt, 15, 27, 42);
}
}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests1.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests1.java
index 469305b1e4a..5520f165495 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests1.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests1.java
@@ -31,9 +31,7 @@
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.GroupLayout;
-import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemoryLayout.PathElement;
import jdk.incubator.foreign.MemorySegment;
@@ -154,7 +152,8 @@ public void test_addBoolAndBoolsFromStructPointerWithXor_1() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -174,8 +173,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_1() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), nestedStructLayout.withName("struct_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -195,7 +194,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_1() throws
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -215,8 +215,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_1() th
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_1() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"), JAVA_BOOLEAN.withName("elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -236,8 +236,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_1() throws Throwab
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_1() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), boolArray.withName("array_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -257,7 +257,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_1() t
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_1() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -278,8 +279,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_
public void test_addBoolAndBoolsFromStructWithNestedStructArray_1() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_BOOLEAN.withName("elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -302,8 +303,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_1() throws Throw
public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), structArray.withName("struct_array_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -326,7 +327,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_1()
public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -515,7 +517,8 @@ public void test_addByteAndBytesFromStructPointer_1() throws Throwable {
@Test
public void test_addByteAndBytesFromNestedStruct_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -556,7 +559,8 @@ public void test_addByteAndBytesFromNestedStruct_reverseOrder_1() throws Throwab
@Test
public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -618,7 +622,8 @@ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_1() t
@Test
public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_1() throws Throwable {
SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
- GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -687,7 +692,8 @@ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_1()
public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -714,11 +720,10 @@ public void test_add2ByteStructs_returnStruct_1() throws Throwable {
FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStruct").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
-
MemorySegment structSegmt1 = allocator.allocate(structLayout);
byteHandle1.set(structSegmt1, (byte)25);
byteHandle2.set(structSegmt1, (byte)11);
@@ -877,7 +882,8 @@ public void test_addCharAndCharsFromStructPointer_1() throws Throwable {
@Test
public void test_addCharAndCharsFromNestedStruct_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -1099,7 +1105,8 @@ public void test_add2CharStructs_returnStructPointer_1() throws Throwable {
@Test
public void test_add3CharStructs_returnStruct_1() throws Throwable {
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"), JAVA_CHAR.withName("elem3"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
@@ -1141,6 +1148,7 @@ public void test_addShortAndShortsFromStruct_1() throws Throwable {
MemorySegment structSegmt = allocator.allocate(structLayout);
shortHandle1.set(structSegmt, (short)8);
shortHandle2.set(structSegmt, (short)9);
+
short result = (short)mh.invokeExact((short)6, structSegmt);
Assert.assertEquals(result, 23);
}
@@ -1257,7 +1265,8 @@ public void test_addShortAndShortsFromNestedStruct_reverseOrder_1() throws Throw
@Test
public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_1() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT,
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
@@ -1901,6 +1910,7 @@ public void test_addLongAndLongsFromStruct_1() throws Throwable {
MemorySegment structSegmt = allocator.allocate(structLayout);
longHandle1.set(structSegmt, 1234567890L);
longHandle2.set(structSegmt, 9876543210L);
+
long result = (long)mh.invokeExact(2468024680L, structSegmt);
Assert.assertEquals(result, 13579135780L);
}
@@ -2299,6 +2309,7 @@ public void test_addFloatAndFloatsFromStruct_1() throws Throwable {
MemorySegment structSegmt = allocator.allocate(structLayout);
floatHandle1.set(structSegmt, 8.12F);
floatHandle2.set(structSegmt, 9.24F);
+
float result = (float)mh.invokeExact(6.56F, structSegmt);
Assert.assertEquals(result, 23.92F, 0.01F);
}
@@ -2653,6 +2664,7 @@ public void test_addDoubleAndDoublesFromStruct_1() throws Throwable {
MemorySegment structSegmt = allocator.allocate(structLayout);
doubleHandle1.set(structSegmt, 2228.111D);
doubleHandle2.set(structSegmt, 2229.221D);
+
double result = (double)mh.invokeExact(3336.333D, structSegmt);
Assert.assertEquals(result, 7793.665D, 0.001D);
}
@@ -2660,33 +2672,24 @@ public void test_addDoubleAndDoublesFromStruct_1() throws Throwable {
@Test
public void test_addDoubleAndFloatDoubleFromStruct_1() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
-
- /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- structSegmt.set(JAVA_FLOAT, 0, 18.444F);
- structSegmt.set(JAVA_DOUBLE, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
- MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18.444F);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(113.567D, structSegmt);
Assert.assertEquals(result, 751.788D, 0.001D);
@@ -2695,33 +2698,24 @@ public void test_addDoubleAndFloatDoubleFromStruct_1() throws Throwable {
@Test
public void test_addDoubleAndIntDoubleFromStruct_1() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
-
- /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- structSegmt.set(JAVA_INT, 0, 18);
- structSegmt.set(JAVA_DOUBLE, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
- MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(113.567D, structSegmt);
Assert.assertEquals(result, 751.344D, 0.001D);
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests2.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests2.java
index 7aed1f3c7bb..279ba188d9d 100644
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests2.java
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/downcall/StructTests2.java
@@ -31,9 +31,7 @@
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.GroupLayout;
-import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemoryLayout.PathElement;
import jdk.incubator.foreign.MemorySegment;
@@ -154,7 +152,8 @@ public void test_addBoolAndBoolsFromStructPointerWithXor_2() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -174,8 +173,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_2() throws Throwable {
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), nestedStructLayout.withName("struct_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -195,7 +194,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_2() throws
@Test
public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -215,8 +215,8 @@ public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_2() th
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_2() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"), JAVA_BOOLEAN.withName("elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -236,8 +236,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_2() throws Throwab
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_2() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), boolArray.withName("array_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -257,7 +257,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_2() t
@Test
public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_2() throws Throwable {
SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
- GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -278,8 +279,8 @@ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_
public void test_addBoolAndBoolsFromStructWithNestedStructArray_2() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_BOOLEAN.withName("elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -302,8 +303,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_2() throws Throw
public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), structArray.withName("struct_array_elem2"),
- MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -326,7 +327,8 @@ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_2()
public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -515,7 +517,8 @@ public void test_addByteAndBytesFromStructPointer_2() throws Throwable {
@Test
public void test_addByteAndBytesFromNestedStruct_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -556,7 +559,8 @@ public void test_addByteAndBytesFromNestedStruct_reverseOrder_2() throws Throwab
@Test
public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -618,7 +622,8 @@ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_2() t
@Test
public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_2() throws Throwable {
SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
- GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -687,7 +692,8 @@ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_2()
public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
- GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -877,7 +883,8 @@ public void test_addCharAndCharsFromStructPointer_2() throws Throwable {
@Test
public void test_addCharAndCharsFromNestedStruct_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -1099,7 +1106,8 @@ public void test_add2CharStructs_returnStructPointer_2() throws Throwable {
@Test
public void test_add3CharStructs_returnStruct_2() throws Throwable {
- GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"), JAVA_CHAR.withName("elem3"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
@@ -1257,7 +1265,8 @@ public void test_addShortAndShortsFromNestedStruct_reverseOrder_2() throws Throw
@Test
public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_2() throws Throwable {
GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
- GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT,
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
MethodHandle mh = clinker.downcallHandle(fd);
@@ -2660,33 +2669,24 @@ public void test_addDoubleAndDoublesFromStruct_2() throws Throwable {
@Test
public void test_addDoubleAndFloatDoubleFromStruct_2() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
-
- /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- structSegmt.set(JAVA_FLOAT, 0, 18.444F);
- structSegmt.set(JAVA_DOUBLE, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
- MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18.444F);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
Assert.assertEquals(result, 751.788D, 0.001D);
@@ -2695,33 +2695,24 @@ public void test_addDoubleAndFloatDoubleFromStruct_2() throws Throwable {
@Test
public void test_addDoubleAndIntDoubleFromStruct_2() throws Throwable {
- GroupLayout structLayout = null;
- MemorySegment structSegmt = null;
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = clinker.downcallHandle(fd);
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
-
- /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
- * while the same struct is 16 bytes with padding on other platforms.
- */
- if (isAixOS) {
- structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
- structSegmt = allocator.allocate(structLayout);
- structSegmt.set(JAVA_INT, 0, 18);
- structSegmt.set(JAVA_DOUBLE, 4, 619.777D);
- } else {
- structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
- MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
- VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
- VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
- structSegmt = allocator.allocate(structLayout);
- elemHandle1.set(structSegmt, 18);
- elemHandle2.set(structSegmt, 619.777D);
- }
-
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
- MethodHandle mh = clinker.downcallHandle(fd);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
Assert.assertEquals(result, 751.344D, 0.001D);
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallMHTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallMHTests.java
new file mode 100644
index 00000000000..f91083f49a7
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallMHTests.java
@@ -0,0 +1,560 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) intended for
+ * the situations when the multiple primitive specific upcalls happen within
+ * the same resource scope or from different resource scopes.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallMHTests {
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr1);
+ Assert.assertEquals(result, true);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ result = (boolean)mh.invoke(true, false, upcallFuncAddr2);
+ Assert.assertEquals(result, true);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ result = (boolean)mh.invoke(true, false, upcallFuncAddr3);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ MemorySegment charSegmt1 = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt1, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ MemorySegment charSegmt2 = allocator.allocate(JAVA_CHAR, 'B');
+ result = (char)mh.invoke(charSegmt2, 'D', upcallFuncAddr2);
+ Assert.assertEquals(result, 'C');
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ MemorySegment charSegmt3 = allocator.allocate(JAVA_CHAR, 'B');
+ result = (char)mh.invoke(charSegmt3, 'D', upcallFuncAddr3);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr1);
+ Assert.assertEquals(result, (byte)88);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ result = (byte)mh.invoke((byte)33, upcallFuncAddr2);
+ Assert.assertEquals(result, (byte)88);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ result = (byte)mh.invoke((byte)33, upcallFuncAddr3);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ MemorySegment shortSegmt1 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invoke(shortSegmt1, (short)555, upcallFuncAddr1);
+ Assert.assertEquals(resultAddr1.get(JAVA_SHORT, 0), (short)999);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ MemorySegment shortSegmt2 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invoke(shortSegmt2, (short)555, upcallFuncAddr2);
+ Assert.assertEquals(resultAddr2.get(JAVA_SHORT, 0), (short)999);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ MemorySegment shortSegmt3 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invoke(shortSegmt3, (short)555, upcallFuncAddr3);
+ Assert.assertEquals(resultAddr3.get(JAVA_SHORT, 0), (short)999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr1);
+ Assert.assertEquals(result, 222235);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ result = (int)mh.invoke(111112, 111123, upcallFuncAddr2);
+ Assert.assertEquals(result, 222235);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ result = (int)mh.invoke(111112, 111123, upcallFuncAddr3);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr1);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr2);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr3);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt1, 6666698235L, upcallFuncAddr1);
+ Assert.assertEquals(result, 12409155659L);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 5742457424L);
+ result = (long)mh.invoke(longSegmt2, 6666698235L, upcallFuncAddr2);
+ Assert.assertEquals(result, 12409155659L);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 5742457424L);
+ result = (long)mh.invoke(longSegmt3, 6666698235L, upcallFuncAddr3);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr1);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ result = (float)mh.invoke(5.74F, upcallFuncAddr2);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ result = (float)mh.invoke(5.74F, upcallFuncAddr3);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+
+ NativeSymbol upcallFuncAddr1 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invoke(doubleSegmt1, 1262.795D, upcallFuncAddr1);
+ Assert.assertEquals(resultAddr1.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ NativeSymbol upcallFuncAddr2 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invoke(doubleSegmt2, 1262.795D, upcallFuncAddr2);
+ Assert.assertEquals(resultAddr2.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ NativeSymbol upcallFuncAddr3 = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invoke(doubleSegmt3, 1262.795D, upcallFuncAddr3);
+ Assert.assertEquals(resultAddr3.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests1.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests1.java
new file mode 100644
index 00000000000..a3d7bc99558
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests1.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within different resource scopes, in which case the upcall
+ * metadata and the generated thunk are allocated separately.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests1 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithDiffScopes() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests2.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests2.java
new file mode 100644
index 00000000000..91de80f0b8b
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/MultiUpcallThrdsMHTests2.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within the same resource scope, in which case the upcall
+ * metadata and the generated thunk are only allocated once and shared among
+ * these threads.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests2 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static CLinker clinker = CLinker.systemCLinker();
+ private static ResourceScope resourceScope = ResourceScope.newImplicitScope();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithSameScope() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), resourceScope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), resourceScope);
+ int result = (int)mh.invoke(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), resourceScope);
+ int result = (int)mh.invoke(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithMixedSigStruTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithMixedSigStruTests.java
new file mode 100644
index 00000000000..059362d8f06
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithMixedSigStruTests.java
@@ -0,0 +1,892 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for the mixed native signatures
+ * in argument/return struct in upcall, which are not covered in UpcallMHWithStructTests and
+ * specially designed to validate the native signature types required in the genenerated thunk.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithMixedSigStruTests {
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addIntAndIntShortFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntShortFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntShortFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, (short)32766);
+
+ int result = (int)mh.invoke(22334455, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33590565);
+ }
+ }
+
+ @Test
+ public void test_addIntAndShortIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndShortIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndShortIntFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, (short)32766);
+ elemHandle2.set(structSegmt, 22446688);
+
+ int result = (int)mh.invoke(11335577, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33815031);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, 667788990011L);
+
+ long result = (long)mh.invoke(22446688, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667822660043L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndLongIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndLongIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndLongIntFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 667788990011L);
+ elemHandle2.set(structSegmt, 11223344);
+
+ long result = (long)mh.invoke(1234567, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667801447922L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111844.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 111111111);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111546.221D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 751.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ public static void test_addDoubleAndDoubleFloatPlusPaddingFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAnd2FloatsDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAnd2FloatsDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAnd2FloatsDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDouble2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDouble2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDouble2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ double result = (double)mh.invoke(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndInt2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invoke(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 111111);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invoke(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntFloatDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatIntDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_INT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22.33F);
+ elemHandle2.set(structSegmt, 111111111);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndLongDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndLongDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndLongDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22222222222222L);
+ elemHandle2.set(structSegmt, 33333.444D);
+
+ double result = (double)mh.invoke(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 22222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt3FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), JAVA_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndInt3FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt3FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 77777777);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+ elemHandle4.set(structSegmt, 44.55F);
+
+ float result = (float)mh.invoke(66.678F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.778F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLong2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLong2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLong2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 777777777777L);
+ elemHandle2.set(structSegmt, 11.25F);
+ elemHandle3.set(structSegmt, 22.75F);
+
+ long result = (long)mh.invoke(555555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1333333333365L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd3FloatsIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), JAVA_INT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAnd3FloatsIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAnd3FloatsIntFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 44.55F);
+ elemHandle4.set(structSegmt, 77777777);
+
+ float result = (float)mh.invoke(66.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.556F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndFloatLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndFloatLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndFloatLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 55.11F);
+ elemHandle2.set(structSegmt, 150000000000L);
+
+ long result = (long)mh.invoke(5555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 155555555610L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 111111111);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.341D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33333.444D);
+ elemHandle2.set(structSegmt, 222222222222L);
+
+ double result = (double)mh.invoke(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addLongAnd2FloatsLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAnd2FloatsLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAnd2FloatsLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.11F);
+ elemHandle2.set(structSegmt, 22.11F);
+ elemHandle3.set(structSegmt, 4444444444L);
+
+ long result = (long)mh.invoke(11111111111L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15555555588L);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd3ShortsCharFromStructByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(3, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray, JAVA_CHAR);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAnd3ShortsCharFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAnd3ShortsCharFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1000);
+ structSegmt.set(JAVA_SHORT, 2, (short)2000);
+ structSegmt.set(JAVA_SHORT, 4, (short)3000);
+ structSegmt.set(JAVA_CHAR, 6, 'A');
+
+ short result = (short)mh.invoke((short)4000, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 10065);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndIntFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_INT.withName("elem3"), JAVA_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndIntFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndIntFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 555555555);
+ elemHandle2.set(structSegmt, 11.222F);
+ elemHandle3.set(structSegmt, 666666666);
+ elemHandle4.set(structSegmt, 33.444F);
+
+ float result = (float)mh.invoke(77.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1222222343.122F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFloatFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), JAVA_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"),
+ JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 7777);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33.444F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 6666);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15217.122D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFloatFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), JAVA_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ JAVA_DOUBLE.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.222F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 818.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleLongFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), JAVA_LONG.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ JAVA_DOUBLE.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+ elemHandle3.set(structSegmt, 888888888888L);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 889000000732.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_return254BytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("return254BytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_return254BytesFromStruct,
+ FunctionDescriptor.of(structLayout), scope);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(allocator, upcallFuncAddr);
+ for (int i = 0; i < 254; i++) {
+ Assert.assertEquals(byteArrStruSegment.get(JAVA_BYTE, i), (byte)i);
+ }
+ }
+ }
+
+ @Test
+ public void test_return4KBytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("return4KBytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_return4KBytesFromStruct,
+ FunctionDescriptor.of(structLayout), scope);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(allocator, upcallFuncAddr);
+ for (int i = 0; i < 4096; i++) {
+ Assert.assertEquals(byteArrStruSegment.get(JAVA_BYTE, i), (byte)i);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithPrimTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithPrimTests.java
new file mode 100644
index 00000000000..a9c686f5962
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithPrimTests.java
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for primitive types in upcall.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithPrimTests {
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), scope);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPointerWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPointerWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), scope);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ boolean result = (boolean)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromNativePtrWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromNativePtrWithOrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), scope);
+ boolean result = (boolean)mh.invoke(false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), scope);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), scope);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBytesByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BytesByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Bytes,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE), scope);
+ byte result = (byte)mh.invoke((byte)6, (byte)3, upcallFuncAddr);
+ Assert.assertEquals(result, 9);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)7);
+ byte result = (byte)mh.invoke((byte)8, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, 88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFrom2CharsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFrom2CharsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFrom2Chars,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR), scope);
+ char result = (char)mh.invoke('B', 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), scope);
+ char result = (char)mh.invoke('D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_addTwoShortsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ShortsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Shorts,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT), scope);
+ short result = (short)mh.invoke((short)1111, (short)2222, upcallFuncAddr);
+ Assert.assertEquals(result, 3333);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)2222);
+ short result = (short)mh.invoke(shortSegmt, (short)3333, upcallFuncAddr);
+ Assert.assertEquals(result, 5555);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), scope);
+ short result = (short)mh.invoke((short)789, upcallFuncAddr);
+ Assert.assertEquals(result, 1245);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ int result = (int)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), scope);
+ int result = (int)mh.invoke(222222, upcallFuncAddr);
+ Assert.assertEquals(result, 666666);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 555536);
+ }
+ }
+
+ @Test
+ public void test_add3IntsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3IntsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT), scope);
+ int result = (int)mh.invoke(111112, 111123, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 333359);
+ }
+ }
+
+ @Test
+ public void test_addIntAndCharByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndCharByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndChar,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR), scope);
+ int result = (int)mh.invoke(555558, 'A', upcallFuncAddr);
+ Assert.assertEquals(result, 555623);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), scope);
+ mh.invoke(44454, 333398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addTwoLongsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2LongsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Longs,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG), scope);
+ long result = (long)mh.invoke(333333222222L, 111111555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 444444777777L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), scope);
+ long result = (long)mh.invoke(5555555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 8888888888L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addTwoFloatsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2FloatsByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Floats,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT), scope);
+ float result = (float)mh.invoke(15.74F, 16.79F, upcallFuncAddr);
+ Assert.assertEquals(result, 32.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ float result = (float)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2DoublesByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2DoublesByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2Doubles,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE), scope);
+ double result = (double)mh.invoke(159.748D, 262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ double result = (double)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromNativePtrByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), scope);
+ double result = (double)mh.invoke(1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_qsortByUpcallMH() throws Throwable {
+ int expectedArray[] = {11, 12, 13, 14, 15, 16, 17};
+ int expectedArrayLength = expectedArray.length;
+
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(ADDRESS, JAVA_INT, JAVA_INT, ADDRESS);
+ NativeSymbol functionSymbol = clinker.lookup("qsort").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_compare,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment arraySegmt = allocator.allocateArray(JAVA_INT, new int[]{17, 14, 13, 16, 15, 12, 11});
+ mh.invoke(arraySegmt, 7, 4, upcallFuncAddr);
+ int[] sortedArray = arraySegmt.toArray(JAVA_INT);
+ for (int index = 0; index < expectedArrayLength; index++) {
+ Assert.assertEquals(sortedArray[index], expectedArray[index]);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithStructTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithStructTests.java
new file mode 100644
index 00000000000..aab3d19e94e
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMHWithStructTests.java
@@ -0,0 +1,2886 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.CLinker;
+import jdk.incubator.foreign.FunctionDescriptor;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.NativeSymbol;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.SymbolLookup;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for argument/return struct in upcall.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithStructTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ /* The padding of struct is not required on Linux/s390x and Windows/x64 */
+ private static boolean isStructPaddingNotRequired = osName.contains("win") && (arch.equals("amd64") || arch.equals("x86_64"))
+ || osName.contains("linux") && arch.equals("s390x");
+ private static CLinker clinker = CLinker.systemCLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAnd20BoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN
+ );
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAnd20BoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAnd20BoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+ structSegmt.set(JAVA_BOOLEAN, 5, true);
+ structSegmt.set(JAVA_BOOLEAN, 6, false);
+ structSegmt.set(JAVA_BOOLEAN, 7, true);
+ structSegmt.set(JAVA_BOOLEAN, 8, false);
+ structSegmt.set(JAVA_BOOLEAN, 9, true);
+ structSegmt.set(JAVA_BOOLEAN, 10, false);
+ structSegmt.set(JAVA_BOOLEAN, 11, true);
+ structSegmt.set(JAVA_BOOLEAN, 12, false);
+ structSegmt.set(JAVA_BOOLEAN, 13, true);
+ structSegmt.set(JAVA_BOOLEAN, 14, false);
+ structSegmt.set(JAVA_BOOLEAN, 15, true);
+ structSegmt.set(JAVA_BOOLEAN, 16, false);
+ structSegmt.set(JAVA_BOOLEAN, 17, true);
+ structSegmt.set(JAVA_BOOLEAN, 18, false);
+ structSegmt.set(JAVA_BOOLEAN, 19, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout), scope);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(boolSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(boolSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultAddr.toRawLongValue(), boolSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructPointerWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructPointerWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructPointerWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, true);
+ boolHandle2.set(structSegmt, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXorByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 1), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ boolHandle3.set(structSegmt1, true);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+ boolHandle3.set(structSegmt2, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)8);
+ byteHandle2.set(structSegmt, (byte)9);
+
+ byte result = (byte)mh.invoke((byte)6, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addByteAnd20BytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE
+ );
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAnd20BytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAnd20BytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)1);
+ structSegmt.set(JAVA_BYTE, 1, (byte)2);
+ structSegmt.set(JAVA_BYTE, 2, (byte)3);
+ structSegmt.set(JAVA_BYTE, 3, (byte)4);
+ structSegmt.set(JAVA_BYTE, 4, (byte)5);
+ structSegmt.set(JAVA_BYTE, 5, (byte)6);
+ structSegmt.set(JAVA_BYTE, 6, (byte)7);
+ structSegmt.set(JAVA_BYTE, 7, (byte)8);
+ structSegmt.set(JAVA_BYTE, 8, (byte)9);
+ structSegmt.set(JAVA_BYTE, 9, (byte)10);
+ structSegmt.set(JAVA_BYTE, 10, (byte)1);
+ structSegmt.set(JAVA_BYTE, 11, (byte)2);
+ structSegmt.set(JAVA_BYTE, 12, (byte)3);
+ structSegmt.set(JAVA_BYTE, 13, (byte)4);
+ structSegmt.set(JAVA_BYTE, 14, (byte)5);
+ structSegmt.set(JAVA_BYTE, 15, (byte)6);
+ structSegmt.set(JAVA_BYTE, 16, (byte)7);
+ structSegmt.set(JAVA_BYTE, 17, (byte)8);
+ structSegmt.set(JAVA_BYTE, 18, (byte)9);
+ structSegmt.set(JAVA_BYTE, 19, (byte)10);
+
+ byte result = (byte)mh.invoke((byte)11, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 121);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)18);
+ byteHandle2.set(structSegmt, (byte)19);
+
+ byte result = (byte)mh.invoke(byteSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct_returnBytePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)14);
+ byteHandle2.set(structSegmt, (byte)16);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(byteSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 42);
+ Assert.assertEquals(resultAddr.toRawLongValue(), byteSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)11);
+ byteHandle2.set(structSegmt, (byte)12);
+ byte result = (byte)mh.invoke((byte)13, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 36);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invoke((byte)46, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)24);
+ structSegmt.set(JAVA_BYTE, 2, (byte)36);
+
+ byte result = (byte)mh.invoke((byte)48, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 120);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArrayByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invoke((byte)14, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 80);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+
+ byte result = (byte)mh.invoke((byte)18, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 60);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invoke((byte)16, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+ structSegmt.set(JAVA_BYTE, 3, (byte)18);
+ structSegmt.set(JAVA_BYTE, 4, (byte)20);
+
+ byte result = (byte)mh.invoke((byte)22, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 102);
+ }
+ }
+
+ @Test
+ public void test_add1ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add1ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add1ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 1), 24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ byteHandle3.set(structSegmt1, (byte)12);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+ byteHandle3.set(structSegmt2, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt), (byte)28);
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'A');
+ charHandle2.set(structSegmt, 'B');
+
+ char result = (char)mh.invoke('C', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'D');
+ }
+ }
+
+ @Test
+ public void test_addCharAnd10CharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR,
+ JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAnd10CharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAnd10CharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'A');
+ structSegmt.set(JAVA_CHAR, 4, 'B');
+ structSegmt.set(JAVA_CHAR, 6, 'B');
+ structSegmt.set(JAVA_CHAR, 8, 'C');
+ structSegmt.set(JAVA_CHAR, 10, 'C');
+ structSegmt.set(JAVA_CHAR, 12, 'D');
+ structSegmt.set(JAVA_CHAR, 14, 'D');
+ structSegmt.set(JAVA_CHAR, 16, 'E');
+ structSegmt.set(JAVA_CHAR, 18, 'E');
+
+ char result = (char)mh.invoke('A', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'U');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ char result = (char)mh.invoke(charSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'M');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct_returnCharPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultAddr.toRawLongValue(), charSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructPointer,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'H');
+ charHandle2.set(structSegmt, 'I');
+
+ char result = (char)mh.invoke('G', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'V');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invoke('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invoke('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArrayByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2")) : MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invoke('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invoke('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invoke('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invoke('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 2), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ charHandle3.set(structSegmt1, 'C');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'B');
+ charHandle2.set(structSegmt2, 'C');
+ charHandle3.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt), 'F');
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)888);
+ shortHandle2.set(structSegmt, (short)999);
+
+ short result = (short)mh.invoke((short)777, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2664);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd10ShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT,
+ JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAnd10ShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAnd10ShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)10);
+ structSegmt.set(JAVA_SHORT, 2, (short)20);
+ structSegmt.set(JAVA_SHORT, 4, (short)30);
+ structSegmt.set(JAVA_SHORT, 6, (short)40);
+ structSegmt.set(JAVA_SHORT, 8, (short)50);
+ structSegmt.set(JAVA_SHORT, 10, (short)60);
+ structSegmt.set(JAVA_SHORT, 12, (short)70);
+ structSegmt.set(JAVA_SHORT, 14, (short)80);
+ structSegmt.set(JAVA_SHORT, 16, (short)90);
+ structSegmt.set(JAVA_SHORT, 18, (short)100);
+
+ short result = (short)mh.invoke((short)110, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 660);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ short result = (short)mh.invoke(shortSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 3349);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct_returnShortPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 3349);
+ Assert.assertEquals(resultAddr.toRawLongValue(), shortSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructPointer,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)2222);
+ shortHandle2.set(structSegmt, (short)4444);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 13332);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)331);
+ structSegmt.set(JAVA_SHORT, 2, (short)333);
+ structSegmt.set(JAVA_SHORT, 4, (short)335);
+
+ short result = (short)mh.invoke((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)331);
+ structSegmt.set(JAVA_SHORT, 2, (short)333);
+ structSegmt.set(JAVA_SHORT, 4, (short)335);
+
+ short result = (short)mh.invoke((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArrayByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2")) : MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+
+ short result = (short)mh.invoke((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+
+ short result = (short)mh.invoke((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+ structSegmt.set(JAVA_SHORT, 6, (short)4444);
+ structSegmt.set(JAVA_SHORT, 8, (short)5555);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+ structSegmt.set(JAVA_SHORT, 6, (short)4444);
+ structSegmt.set(JAVA_SHORT, 8, (short)5555);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)734);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)712);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 734);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 2), 712);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)325);
+ shortHandle2.set(structSegmt1, (short)326);
+ shortHandle3.set(structSegmt1, (short)327);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)334);
+ shortHandle2.set(structSegmt2, (short)335);
+ shortHandle3.set(structSegmt2, (short)336);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)659);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)661);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt), (short)663);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1122334);
+ intHandle2.set(structSegmt, 1234567);
+
+ int result = (int)mh.invoke(2244668, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 4601569);
+ }
+ }
+
+ @Test
+ public void test_addIntAnd5IntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"),
+ JAVA_INT.withName("elem3"), JAVA_INT.withName("elem4"), JAVA_INT.withName("elem5"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle intHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle intHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAnd5IntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAnd5IntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1111111);
+ intHandle2.set(structSegmt, 2222222);
+ intHandle3.set(structSegmt, 3333333);
+ intHandle4.set(structSegmt, 2222222);
+ intHandle5.set(structSegmt, 1111111);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 14444443);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 7654321);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1234567);
+ intHandle2.set(structSegmt, 2468024);
+
+ int result = (int)mh.invoke(intSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11356912);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct_returnIntPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 1122333);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 4455666);
+ intHandle2.set(structSegmt, 7788999);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(intSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultAddr.toRawLongValue(), intSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 11121314);
+ intHandle2.set(structSegmt, 15161718);
+
+ int result = (int)mh.invoke(19202122, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 45485154);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_INT.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invoke(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invoke(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArrayByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), intArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invoke(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invoke(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 4), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add3IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ intHandle3.set(structSegmt1, 99001122);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 33445566);
+ intHandle2.set(structSegmt2, 77889900);
+ intHandle3.set(structSegmt2, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt), 143333333);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 1234567890L);
+ longHandle2.set(structSegmt, 9876543210L);
+
+ long result = (long)mh.invoke(2468024680L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 13579135780L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 3333333333L);
+ longHandle2.set(structSegmt, 5555555555L);
+
+ long result = (long)mh.invoke(longSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 9999999999L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct_returnLongPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 6677889900L);
+ longHandle2.set(structSegmt, 1234567890L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultAddr.toRawLongValue(), longSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructPointer,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 224466880022L);
+ longHandle2.set(structSegmt, 446688002244L);
+
+ long result = (long)mh.invoke(668800224466L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1339955106732L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invoke(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invoke(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArrayByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+
+ long result = (long)mh.invoke(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), longArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+
+ long result = (long)mh.invoke(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+ structSegmt.set(JAVA_LONG, 24, 44444444444L);
+ structSegmt.set(JAVA_LONG, 32, 55555555555L);
+
+ long result = (long)mh.invoke(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+ structSegmt.set(JAVA_LONG, 24, 44444444444L);
+ structSegmt.set(JAVA_LONG, 32, 55555555555L);
+
+ long result = (long)mh.invoke(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 5566778899L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 9900112233L);
+ longHandle2.set(structSegmt2, 3344556677L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 8), 8911335576L);
+ }
+ }
+
+ @Test
+ public void test_add3LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ longHandle3.set(structSegmt1, 112233445566L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+ longHandle3.set(structSegmt2, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt), 891132446688L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 8.12F);
+ floatHandle2.set(structSegmt, 9.24F);
+
+ float result = (float)mh.invoke(6.56F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23.92F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd5FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"),
+ JAVA_FLOAT.withName("elem3"), JAVA_FLOAT.withName("elem4"), JAVA_FLOAT.withName("elem5"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle floatHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle floatHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAnd5FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAnd5FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 1.01F);
+ floatHandle2.set(structSegmt, 1.02F);
+ floatHandle3.set(structSegmt, 1.03F);
+ floatHandle4.set(structSegmt, 1.04F);
+ floatHandle5.set(structSegmt, 1.05F);
+
+ float result = (float)mh.invoke(1.06F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 6.21F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ float result = (float)mh.invoke(floatSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(floatSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultAddr.toRawLongValue(), floatSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 35.11F);
+ floatHandle2.set(structSegmt, 46.22F);
+
+ float result = (float)mh.invoke(79.33F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 160.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invoke(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invoke(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invoke(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invoke(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invoke(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invoke(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ floatHandle3.set(structSegmt1, 45.67F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+ floatHandle3.set(structSegmt2, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt), 115.39, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 4), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 2228.111D);
+ doubleHandle2.set(structSegmt, 2229.221D);
+
+ double result = (double)mh.invoke(3336.333D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 7793.665D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 118.456D);
+ doubleHandle2.set(structSegmt, 119.789D);
+
+ double result = (double)mh.invoke(doubleSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 350.368D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 218.456D);
+ doubleHandle2.set(structSegmt, 219.789D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultAddr.toRawLongValue(), doubleSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 22.111D);
+ doubleHandle2.set(structSegmt, 44.222D);
+
+ double result = (double)mh.invoke(66.333D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 132.666D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_DOUBLE.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invoke(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invoke(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invoke(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invoke(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invoke(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invoke(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 8), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add3DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ NativeSymbol functionSymbol = nativeLibLookup.lookup("add3DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
+
+ try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+ NativeSymbol upcallFuncAddr = clinker.upcallStub(UpcallMethodHandles.MH_add3DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), scope);
+ SegmentAllocator allocator = SegmentAllocator.nativeAllocator(scope);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ doubleHandle3.set(structSegmt1, 33.123D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+ doubleHandle3.set(structSegmt2, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMethodHandles.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMethodHandles.java
new file mode 100644
index 00000000000..f3cb05cf430
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/upcall/UpcallMethodHandles.java
@@ -0,0 +1,1887 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.upcall;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import static java.lang.invoke.MethodType.methodType;
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.Addressable;
+import static jdk.incubator.foreign.CLinker.*;
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.SequenceLayout;
+import jdk.incubator.foreign.ValueLayout;
+import static jdk.incubator.foreign.ValueLayout.*;
+import jdk.incubator.foreign.VaList;
+
+/**
+ * The helper class that contains all upcall method handles with primitive types or struct
+ * as arguments.
+ */
+public class UpcallMethodHandles {
+ private static final Lookup lookup = MethodHandles.lookup();
+ private static ResourceScope scope = ResourceScope.newImplicitScope();
+ private static SegmentAllocator allocator = SegmentAllocator.newNativeArena(scope);
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+
+ static final MethodType MT_Bool_Bool_MemSegmt = methodType(boolean.class, boolean.class, MemorySegment.class);
+ static final MethodType MT_Addr_Bool_MemAddr = methodType(Addressable.class, boolean.class, MemoryAddress.class);
+ static final MethodType MT_Char_Char_MemSegmt = methodType(char.class, char.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Char = methodType(Addressable.class, MemoryAddress.class, char.class);
+ static final MethodType MT_Byte_Byte_MemSegmt = methodType(byte.class, byte.class, MemorySegment.class);
+ static final MethodType MT_Addr_Byte_MemAddr = methodType(Addressable.class, byte.class, MemoryAddress.class);
+ static final MethodType MT_Short_Short_MemSegmt = methodType(short.class, short.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Short = methodType(Addressable.class, MemoryAddress.class, short.class);
+ static final MethodType MT_Int_Int_MemSegmt = methodType(int.class, int.class, MemorySegment.class);
+ static final MethodType MT_Addr_Int_MemAddr = methodType(Addressable.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Long_Long_MemSegmt = methodType(long.class, long.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Long = methodType(Addressable.class, MemoryAddress.class, long.class);
+ static final MethodType MT_Long_Int_MemSegmt = methodType(long.class, int.class, MemorySegment.class);
+ static final MethodType MT_Float_Float_MemSegmt = methodType(float.class, float.class, MemorySegment.class);
+ static final MethodType MT_Addr_Float_MemAddr = methodType(Addressable.class, float.class, MemoryAddress.class);
+ static final MethodType MT_Double_Double_MemSegmt = methodType(double.class, double.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Double = methodType(Addressable.class, MemoryAddress.class, double.class);
+ static final MethodType MT_Addr_MemAddr_MemSegmt = methodType(Addressable.class, MemoryAddress.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt_MemSegmt_MemSegmt = methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt = methodType(MemorySegment.class);
+
+ public static final MethodHandle MH_add2BoolsWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPointerWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetPtr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetArgPtr;
+ public static final MethodHandle MH_createNewCharFrom2Chars;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPointer;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetPtr;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Bytes;
+ public static final MethodHandle MH_addByteAndByteFromPointer;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetPtr;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Shorts;
+ public static final MethodHandle MH_addShortAndShortFromPointer;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetPtr;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Ints;
+ public static final MethodHandle MH_addIntAndIntFromPointer;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetPtr;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add3Ints;
+ public static final MethodHandle MH_addIntAndChar;
+ public static final MethodHandle MH_add2IntsReturnVoid;
+ public static final MethodHandle MH_add2Longs;
+ public static final MethodHandle MH_addLongAndLongFromPointer;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetPtr;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Floats;
+ public static final MethodHandle MH_addFloatAndFloatFromPointer;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetPtr;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Doubles;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPointer;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetPtr;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetArgPtr;
+ public static final MethodHandle MH_compare;
+
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolAnd20BoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructPointerWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStruct;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStructPointer;
+ public static final MethodHandle MH_add3BoolStructsWithXor_returnStruct;
+
+ public static final MethodHandle MH_addByteAndBytesFromStruct;
+ public static final MethodHandle MH_addByteAnd20BytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct_returnBytePointer;
+ public static final MethodHandle MH_addByteAndBytesFromStructPointer;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add1ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ByteStructs_returnStruct;
+
+ public static final MethodHandle MH_addCharAndCharsFromStruct;
+ public static final MethodHandle MH_addCharAnd10CharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct_returnCharPointer;
+ public static final MethodHandle MH_addCharAndCharsFromStructPointer;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2CharStructs_returnStruct;
+ public static final MethodHandle MH_add2CharStructs_returnStructPointer;
+ public static final MethodHandle MH_add3CharStructs_returnStruct;
+
+ public static final MethodHandle MH_addShortAndShortsFromStruct;
+ public static final MethodHandle MH_addShortAnd10ShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct_returnShortPointer;
+ public static final MethodHandle MH_addShortAndShortsFromStructPointer;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2ShortStructs_returnStruct;
+ public static final MethodHandle MH_add2ShortStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ShortStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntsFromStruct;
+ public static final MethodHandle MH_addIntAnd5IntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct_returnIntPointer;
+ public static final MethodHandle MH_addIntAndIntsFromStructPointer;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2IntStructs_returnStruct;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer;
+ public static final MethodHandle MH_add3IntStructs_returnStruct;
+
+ public static final MethodHandle MH_addLongAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct_returnLongPointer;
+ public static final MethodHandle MH_addLongAndLongsFromStructPointer;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2LongStructs_returnStruct;
+ public static final MethodHandle MH_add2LongStructs_returnStructPointer;
+ public static final MethodHandle MH_add3LongStructs_returnStruct;
+
+ public static final MethodHandle MH_addFloatAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd5FloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2FloatStructs_returnStruct;
+ public static final MethodHandle MH_add2FloatStructs_returnStructPointer;
+ public static final MethodHandle MH_add3FloatStructs_returnStruct;
+
+ public static final MethodHandle MH_addDoubleAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructPointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2DoubleStructs_returnStruct;
+ public static final MethodHandle MH_add2DoubleStructs_returnStructPointer;
+ public static final MethodHandle MH_add3DoubleStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntShortFromStruct;
+ public static final MethodHandle MH_addIntAndShortIntFromStruct;
+ public static final MethodHandle MH_addIntAndIntLongFromStruct;
+ public static final MethodHandle MH_addIntAndLongIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAnd2FloatsDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDouble2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndInt2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndLongDoubleFromStruct;
+ public static final MethodHandle MH_addFloatAndInt3FloatsFromStruct;
+ public static final MethodHandle MH_addLongAndLong2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd3FloatsIntFromStruct;
+ public static final MethodHandle MH_addLongAndFloatLongFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleLongFromStruct;
+ public static final MethodHandle MH_addLongAnd2FloatsLongFromStruct;
+ public static final MethodHandle MH_addShortAnd3ShortsCharFromStruct;
+ public static final MethodHandle MH_addFloatAndIntFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleLongFromStruct;
+ public static final MethodHandle MH_return254BytesFromStruct;
+ public static final MethodHandle MH_return4KBytesFromStruct;
+
+ static {
+ try {
+ MH_add2BoolsWithOr = lookup.findStatic(UpcallMethodHandles.class, "add2BoolsWithOr", methodType(boolean.class, boolean.class, boolean.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPointerWithOr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPointerWithOr", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetPtr", MT_Addr_Bool_MemAddr); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetArgPtr", MT_Addr_Bool_MemAddr); //$NON-NLS-1$
+
+ MH_createNewCharFrom2Chars = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFrom2Chars", methodType(char.class, char.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPointer = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPointer", methodType(char.class, MemoryAddress.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetPtr", MT_Addr_MemAddr_Char); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetArgPtr", MT_Addr_MemAddr_Char); //$NON-NLS-1$
+
+ MH_add2Bytes = lookup.findStatic(UpcallMethodHandles.class, "add2Bytes", methodType(byte.class, byte.class, byte.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetPtr", MT_Addr_Byte_MemAddr); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetArgPtr", MT_Addr_Byte_MemAddr); //$NON-NLS-1$
+
+ MH_add2Shorts = lookup.findStatic(UpcallMethodHandles.class, "add2Shorts", methodType(short.class, short.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPointer", methodType(short.class, MemoryAddress.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetPtr", MT_Addr_MemAddr_Short); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetArgPtr", MT_Addr_MemAddr_Short); //$NON-NLS-1$
+
+ MH_add2Ints = lookup.findStatic(UpcallMethodHandles.class, "add2Ints", methodType(int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetPtr", MT_Addr_Int_MemAddr); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetArgPtr", MT_Addr_Int_MemAddr); //$NON-NLS-1$
+ MH_add3Ints = lookup.findStatic(UpcallMethodHandles.class, "add3Ints", methodType(int.class, int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndChar = lookup.findStatic(UpcallMethodHandles.class, "addIntAndChar", methodType(int.class, int.class, char.class)); //$NON-NLS-1$
+ MH_add2IntsReturnVoid = lookup.findStatic(UpcallMethodHandles.class, "add2IntsReturnVoid", methodType(void.class, int.class, int.class)); //$NON-NLS-1$
+
+ MH_add2Longs = lookup.findStatic(UpcallMethodHandles.class, "add2Longs", methodType(long.class, long.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPointer", methodType(long.class, MemoryAddress.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetPtr", MT_Addr_MemAddr_Long); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetArgPtr", MT_Addr_MemAddr_Long); //$NON-NLS-1$
+
+ MH_add2Floats = lookup.findStatic(UpcallMethodHandles.class, "add2Floats", methodType(float.class, float.class, float.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetPtr", MT_Addr_Float_MemAddr); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetArgPtr", MT_Addr_Float_MemAddr); //$NON-NLS-1$
+
+ MH_add2Doubles = lookup.findStatic(UpcallMethodHandles.class, "add2Doubles", methodType(double.class, double.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPointer", methodType(double.class, MemoryAddress.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetPtr", MT_Addr_MemAddr_Double); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetArgPtr", MT_Addr_MemAddr_Double); //$NON-NLS-1$
+
+ MH_compare = lookup.findStatic(UpcallMethodHandles.class, "compare", methodType(int.class, MemoryAddress.class, MemoryAddress.class)); //$NON-NLS-1$
+
+ MH_addBoolAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAnd20BoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAnd20BoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor", methodType(boolean.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructPointerWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructPointerWithXor", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addByteAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAnd20BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAnd20BytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct", methodType(byte.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct_returnBytePointer = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct_returnBytePointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_add1ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add1ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addCharAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAnd10CharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAnd10CharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct", methodType(char.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct_returnCharPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct_returnCharPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructPointer", methodType(char.class, char.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addShortAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd10ShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd10ShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct", methodType(short.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct_returnShortPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct_returnShortPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructPointer", methodType(short.class, short.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAnd5IntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAnd5IntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct", methodType(int.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct_returnIntPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct_returnIntPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addLongAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct", methodType(long.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct_returnLongPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct_returnLongPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructPointer", methodType(long.class, long.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addFloatAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd5FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd5FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct", methodType(float.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct_returnFloatPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addDoubleAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct", methodType(double.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructPointer", methodType(double.class, double.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntShortFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntShortFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndShortIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndShortIntFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntLongFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndLongIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndLongIntFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAnd2FloatsDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAnd2FloatsDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDouble2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDouble2FloatsFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt2FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndLongDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndLongDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt3FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt3FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLong2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLong2FloatsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd3FloatsIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd3FloatsIntFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndFloatLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndFloatLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addLongAnd2FloatsLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAnd2FloatsLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd3ShortsCharFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd3ShortsCharFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndIntFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndIntFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_return254BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return254BytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+ MH_return4KBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return4KBytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static boolean add2BoolsWithOr(boolean boolArg1, boolean boolArg2) {
+ boolean result = boolArg1 || boolArg2;
+ return result;
+ }
+
+ public static boolean addBoolAndBoolFromPointerWithOr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ return result;
+ }
+
+ public static Addressable addBoolAndBoolFromPtrWithOr_RetPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, scope);
+ resultSegmt.set(JAVA_BOOLEAN, 0, result);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addBoolAndBoolFromPtrWithOr_RetArgPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ boolArg2Addr.set(JAVA_BOOLEAN, 0, result);
+ return boolArg2Addr;
+ }
+
+ public static char createNewCharFrom2Chars(char charArg1, char charArg2) {
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static char createNewCharFromCharAndCharFromPointer(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static Addressable createNewCharFromCharAndCharFromPtr_RetPtr(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_CHAR.byteSize(), scope);
+ resultSegmt.set(JAVA_CHAR, 0, result);
+ return resultSegmt.address();
+ }
+
+ public static Addressable createNewCharFromCharAndCharFromPtr_RetArgPtr(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ charArg1Addr.set(JAVA_CHAR, 0, result);
+ return charArg1Addr;
+ }
+
+ public static byte add2Bytes(byte byteArg1, byte byteArg2) {
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static byte addByteAndByteFromPointer(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static Addressable addByteAndByteFromPtr_RetPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_BYTE.byteSize(), scope);
+ resultSegmt.set(JAVA_BYTE, 0, byteSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addByteAndByteFromPtr_RetArgPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ byteArg2Addr.set(JAVA_BYTE, 0, byteSum);
+ return byteArg2Addr;
+ }
+
+ public static short add2Shorts(short shortArg1, short shortArg2) {
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortFromPointer(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static Addressable addShortAndShortFromPtr_RetPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_SHORT.byteSize(), scope);
+ resultSegmt.set(JAVA_SHORT, 0, shortSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addShortAndShortFromPtr_RetArgPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ shortArg1Addr.set(JAVA_SHORT, 0, shortSum);
+ return shortArg1Addr;
+ }
+
+ public static int add2Ints(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static int addIntAndIntFromPointer(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static Addressable addIntAndIntFromPtr_RetPtr(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_INT.byteSize(), scope);
+ resultSegmt.set(JAVA_INT, 0, intSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addIntAndIntFromPtr_RetArgPtr(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ intArg2Addr.set(JAVA_INT, 0, intSum);
+ return intArg2Addr;
+ }
+
+ public static int add3Ints(int intArg1, int intArg2, int intArg3) {
+ int intSum = intArg1 + intArg2 + intArg3;
+ return intSum;
+ }
+
+ public static int addIntAndChar(int intArg, char charArg) {
+ int sum = intArg + charArg;
+ return sum;
+ }
+
+ public static void add2IntsReturnVoid(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ System.out.println("add2IntsReturnVoid: intSum = " + intSum + "\n");
+ }
+
+ public static long add2Longs(long longArg1, long longArg2) {
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static long addLongAndLongFromPointer(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static Addressable addLongAndLongFromPtr_RetPtr(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_LONG.byteSize(), scope);
+ resultSegmt.set(JAVA_LONG, 0, longSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addLongAndLongFromPtr_RetArgPtr(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ longArg1Addr.set(JAVA_LONG, 0, longSum);
+ return longArg1Addr;
+ }
+
+ public static float add2Floats(float floatArg1, float floatArg2) {
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatFromPointer(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static Addressable addFloatAndFloatFromPtr_RetPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_FLOAT.byteSize(), scope);
+ resultSegmt.set(JAVA_FLOAT, 0, floatSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addFloatAndFloatFromPtr_RetArgPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ floatArg2Addr.set(JAVA_FLOAT, 0, floatSum);
+ return floatArg2Addr;
+ }
+
+ public static double add2Doubles(double doubleArg1, double doubleArg2) {
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFromPointer(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static Addressable addDoubleAndDoubleFromPtr_RetPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_DOUBLE.byteSize(), scope);
+ resultSegmt.set(JAVA_DOUBLE, 0, doubleSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addDoubleAndDoubleFromPtr_RetArgPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ doubleArg1Addr.set(JAVA_DOUBLE, 0, doubleSum);
+ return doubleArg1Addr;
+ }
+
+ public static int compare(MemoryAddress argAddr1, MemoryAddress argAddr2) {
+ int intArg1 = argAddr1.get(JAVA_INT, 0);
+ int intArg2 = argAddr2.get(JAVA_INT, 0);
+ return (intArg1 - intArg2);
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean boolSum = arg1 ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static boolean addBoolAnd20BoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean boolSum = arg1 ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1)
+ ^ arg2.get(JAVA_BOOLEAN, 2) ^ arg2.get(JAVA_BOOLEAN, 3) ^ arg2.get(JAVA_BOOLEAN, 4)
+ ^ arg2.get(JAVA_BOOLEAN, 5) ^ arg2.get(JAVA_BOOLEAN, 6) ^ arg2.get(JAVA_BOOLEAN, 7)
+ ^ arg2.get(JAVA_BOOLEAN, 8) ^ arg2.get(JAVA_BOOLEAN, 9) ^ arg2.get(JAVA_BOOLEAN, 10)
+ ^ arg2.get(JAVA_BOOLEAN, 11) ^ arg2.get(JAVA_BOOLEAN, 12) ^ arg2.get(JAVA_BOOLEAN, 13)
+ ^ arg2.get(JAVA_BOOLEAN, 14) ^ arg2.get(JAVA_BOOLEAN, 15) ^ arg2.get(JAVA_BOOLEAN, 16)
+ ^ arg2.get(JAVA_BOOLEAN, 17) ^ arg2.get(JAVA_BOOLEAN, 18) ^ arg2.get(JAVA_BOOLEAN, 19);
+ return boolSum;
+ }
+
+ public static boolean addBoolFromPointerAndBoolsFromStructWithXor(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolSum = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static Addressable addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolSum = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Addr.set(JAVA_BOOLEAN, 0, boolSum);
+ return arg1Addr;
+ }
+
+ public static boolean addBoolAndBoolsFromStructPointerWithXor(boolean arg1, MemoryAddress arg2Addr) {
+ boolean boolSum = arg1 ^ arg2Addr.get(JAVA_BOOLEAN, 0) ^ arg2Addr.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean nestedStructElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructElem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean boolSum = arg1 ^ nestedStructElem1 ^ nestedStructElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructElem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructElem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean boolSum = arg1 ^ structElem1 ^ nestedStructElem1 ^ nestedStructElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray(boolean arg1, MemorySegment arg2) {
+ boolean nestedBoolArrayElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedBoolArrayElem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 2);
+
+ boolean boolSum = arg1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedBoolArrayElem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedBoolArrayElem2 = arg2.get(JAVA_BOOLEAN, 2);
+
+ boolean boolSum = arg1 ^ structElem1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray(boolean arg1, MemorySegment arg2) {
+ boolean nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BOOLEAN, 3);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 4);
+
+ boolean boolSum = arg1 ^ structElem2
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BOOLEAN, 3);
+ boolean nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BOOLEAN, 4);
+
+ boolean boolSum = arg1 ^ structElem1
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static MemorySegment add2BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ boolean boolStruct_Elem1 = arg1.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ return boolStructSegmt;
+ }
+
+ public static Addressable add2BoolStructsWithXor_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolStruct_Elem1 = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1Addr.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Addr.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ arg1Addr.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ JAVA_BOOLEAN.withName("elem2"), JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(8));
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ boolean boolStruct_Elem1 = arg1.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ boolean boolStruct_Elem3 = arg1.get(JAVA_BOOLEAN, 2) ^ arg2.get(JAVA_BOOLEAN, 2);
+ boolStructSegmt.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ boolStructSegmt.set(JAVA_BOOLEAN, 2, boolStruct_Elem3);
+ return boolStructSegmt;
+ }
+
+ public static byte addByteAndBytesFromStruct(byte arg1, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1 + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static byte addByteAnd20BytesFromStruct(byte arg1, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1 + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1)
+ + arg2.get(JAVA_BYTE, 2) + arg2.get(JAVA_BYTE, 3) + arg2.get(JAVA_BYTE, 4)
+ + arg2.get(JAVA_BYTE, 5) + arg2.get(JAVA_BYTE, 6) + arg2.get(JAVA_BYTE, 7)
+ + arg2.get(JAVA_BYTE, 8) + arg2.get(JAVA_BYTE, 9) + arg2.get(JAVA_BYTE, 10)
+ + arg2.get(JAVA_BYTE, 11) + arg2.get(JAVA_BYTE, 12) + arg2.get(JAVA_BYTE, 13)
+ + arg2.get(JAVA_BYTE, 14) + arg2.get(JAVA_BYTE, 15) + arg2.get(JAVA_BYTE, 16)
+ + arg2.get(JAVA_BYTE, 17) + arg2.get(JAVA_BYTE, 18) + arg2.get(JAVA_BYTE, 19));
+ return byteSum;
+ }
+
+ public static byte addByteFromPointerAndBytesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static Addressable addByteFromPointerAndBytesFromStruct_returnBytePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ arg1Addr.set(JAVA_BYTE, 0, byteSum);
+ return arg1Addr;
+ }
+
+ public static byte addByteAndBytesFromStructPointer(byte arg1, MemoryAddress arg2Addr) {
+ byte byteSum = (byte)(arg1 + arg2Addr.get(JAVA_BYTE, 0) + arg2Addr.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct(byte arg1, MemorySegment arg2) {
+ byte nestedStructElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructElem2 = arg2.get(JAVA_BYTE, 1);
+ byte structElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructElem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray(byte arg1, MemorySegment arg2) {
+ byte nestedByteArrayElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedByteArrayElem2 = arg2.get(JAVA_BYTE, 1);
+ byte structElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + nestedByteArrayElem1 + nestedByteArrayElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedByteArrayElem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedByteArrayElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedByteArrayElem1 + nestedByteArrayElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray(byte arg1, MemorySegment arg2) {
+ byte nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BYTE, 2);
+ byte nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BYTE, 3);
+ byte structElem2 = arg2.get(JAVA_BYTE, 4);
+
+ byte byteSum = (byte)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BYTE, 2);
+ byte nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BYTE, 3);
+ byte nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BYTE, 4);
+
+ byte byteSum = (byte)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static MemorySegment add1ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ return byteStructSegmt;
+ }
+
+ public static MemorySegment add2ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ byteStructSegmt.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ return byteStructSegmt;
+ }
+
+ public static Addressable add2ByteStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteStruct_Elem1 = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1Addr.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ arg1Addr.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ arg1Addr.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(8));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ byte byteStruct_Elem3 = (byte)(arg1.get(JAVA_BYTE, 2) + arg2.get(JAVA_BYTE, 2));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ byteStructSegmt.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ byteStructSegmt.set(JAVA_BYTE, 2, byteStruct_Elem3);
+ return byteStructSegmt;
+ }
+
+ public static char addCharAndCharsFromStruct(char arg1, MemorySegment arg2) {
+ char result = (char)(arg1 + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAnd10CharsFromStruct(char arg1, MemorySegment arg2) {
+ char result = (char)(arg1 + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2)
+ + arg2.get(JAVA_CHAR, 4) + arg2.get(JAVA_CHAR, 6) + arg2.get(JAVA_CHAR, 8)
+ + arg2.get(JAVA_CHAR, 10) + arg2.get(JAVA_CHAR, 12) + arg2.get(JAVA_CHAR, 14)
+ + arg2.get(JAVA_CHAR, 16) + arg2.get(JAVA_CHAR, 18) - 10 * 'A');
+ return result;
+ }
+
+ public static char addCharFromPointerAndCharsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char result = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static Addressable addCharFromPointerAndCharsFromStruct_returnCharPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char result = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ arg1Addr.set(JAVA_CHAR, 0, result);
+ return arg1Addr;
+ }
+
+ public static char addCharAndCharsFromStructPointer(char arg1, MemoryAddress arg2Addr) {
+ char result = (char)(arg1 + arg2Addr.get(JAVA_CHAR, 0) + arg2Addr.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct(char arg1, MemorySegment arg2) {
+ char nestedStructElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructElem2 = arg2.get(JAVA_CHAR, 2);
+ char structElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructElem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray(char arg1, MemorySegment arg2) {
+ char nestedCharArrayElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedCharArrayElem2 = arg2.get(JAVA_CHAR, 2);
+ char structElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + nestedCharArrayElem1 + nestedCharArrayElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedCharArrayElem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedCharArrayElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedCharArrayElem1 + nestedCharArrayElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray(char arg1, MemorySegment arg2) {
+ char nestedStructArrayElem1_Elem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructArrayElem1_Elem2 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructArrayElem2_Elem1 = arg2.get(JAVA_CHAR, 4);
+ char nestedStructArrayElem2_Elem2 = arg2.get(JAVA_CHAR, 6);
+ char structElem2 = arg2.get(JAVA_CHAR, 8);
+
+ char result = (char)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructArrayElem1_Elem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructArrayElem1_Elem2 = arg2.get(JAVA_CHAR, 4);
+ char nestedStructArrayElem2_Elem1 = arg2.get(JAVA_CHAR, 6);
+ char nestedStructArrayElem2_Elem2 = arg2.get(JAVA_CHAR, 8);
+
+ char result = (char)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static MemorySegment add2CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ char charStruct_Elem1 = (char)(arg1.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ charStructSegmt.set(JAVA_CHAR, 0, charStruct_Elem1);
+ charStructSegmt.set(JAVA_CHAR, 2, charStruct_Elem2);
+ return charStructSegmt;
+ }
+
+ public static Addressable add2CharStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char charStruct_Elem1 = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1Addr.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ arg1Addr.set(JAVA_CHAR, 0, charStruct_Elem1);
+ arg1Addr.set(JAVA_CHAR, 2, charStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ char charStruct_Elem1 = (char)(arg1.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ char charStruct_Elem3 = (char)(arg1.get(JAVA_CHAR, 4) + arg2.get(JAVA_CHAR, 4) - 'A');
+ charStructSegmt.set(JAVA_CHAR, 0, charStruct_Elem1);
+ charStructSegmt.set(JAVA_CHAR, 2, charStruct_Elem2);
+ charStructSegmt.set(JAVA_CHAR, 4, charStruct_Elem3);
+ return charStructSegmt;
+ }
+
+ public static short addShortAndShortsFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static short addShortAnd10ShortsFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2)
+ + arg2.get(JAVA_SHORT, 4) + arg2.get(JAVA_SHORT, 6) + arg2.get(JAVA_SHORT, 8)
+ + arg2.get(JAVA_SHORT, 10) + arg2.get(JAVA_SHORT, 12) + arg2.get(JAVA_SHORT, 14)
+ + arg2.get(JAVA_SHORT, 16) + arg2.get(JAVA_SHORT, 18));
+ return shortSum;
+ }
+
+ public static short addShortFromPointerAndShortsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortSum = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static Addressable addShortFromPointerAndShortsFromStruct_returnShortPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortSum = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ arg1Addr.set(JAVA_SHORT, 0, shortSum);
+ return arg1Addr;
+ }
+
+ public static short addShortAndShortsFromStructPointer(short arg1, MemoryAddress arg2Addr) {
+ short shortSum = (short)(arg1 + arg2Addr.get(JAVA_SHORT, 0) + arg2Addr.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct(short arg1, MemorySegment arg2) {
+ short nestedStructElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructElem2 = arg2.get(JAVA_SHORT, 2);
+ short structElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructElem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray(short arg1, MemorySegment arg2) {
+ short nestedShortArrayElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedShortArrayElem2 = arg2.get(JAVA_SHORT, 2);
+ short structElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + nestedShortArrayElem1 + nestedShortArrayElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedShortArrayElem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedShortArrayElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedShortArrayElem1 + nestedShortArrayElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray(short arg1, MemorySegment arg2) {
+ short nestedStructArrayElem1_Elem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructArrayElem1_Elem2 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructArrayElem2_Elem1 = arg2.get(JAVA_SHORT, 4);
+ short nestedStructArrayElem2_Elem2 = arg2.get(JAVA_SHORT, 6);
+ short structElem2 = arg2.get(JAVA_SHORT, 8);
+
+ short shortSum = (short)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructArrayElem1_Elem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructArrayElem1_Elem2 = arg2.get(JAVA_SHORT, 4);
+ short nestedStructArrayElem2_Elem1 = arg2.get(JAVA_SHORT, 6);
+ short nestedStructArrayElem2_Elem2 = arg2.get(JAVA_SHORT, 8);
+
+ short shortSum = (short)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static MemorySegment add2ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ short shortStruct_Elem1 = (short)(arg1.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ shortStructSegmt.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ shortStructSegmt.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ return shortStructSegmt;
+ }
+
+ public static Addressable add2ShortStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortStruct_Elem1 = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1Addr.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ arg1Addr.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ arg1Addr.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ short shortStruct_Elem1 = (short)(arg1.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ short shortStruct_Elem3 = (short)(arg1.get(JAVA_SHORT, 4) + arg2.get(JAVA_SHORT, 4));
+ shortStructSegmt.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ shortStructSegmt.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ shortStructSegmt.set(JAVA_SHORT, 4, shortStruct_Elem3);
+ return shortStructSegmt;
+ }
+
+ public static int addIntAndIntsFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static int addIntAnd5IntsFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4)
+ + arg2.get(JAVA_INT, 8) + arg2.get(JAVA_INT, 12) + arg2.get(JAVA_INT, 16);
+ return intSum;
+ }
+
+ public static int addIntFromPointerAndIntsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static Addressable addIntFromPointerAndIntsFromStruct_returnIntPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ arg1Addr.set(JAVA_INT, 0, intSum);
+ return arg1Addr;
+ }
+
+ public static int addIntAndIntsFromStructPointer(int arg1, MemoryAddress arg2Addr) {
+ int intSum = arg1 + arg2Addr.get(JAVA_INT, 0) + arg2Addr.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct(int arg1, MemorySegment arg2) {
+ int nestedStructElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructElem2 = arg2.get(JAVA_INT, 4);
+ int structElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructElem1 = arg2.get(JAVA_INT, 4);
+ int nestedStructElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray(int arg1, MemorySegment arg2) {
+ int nestedIntArrayElem1 = arg2.get(JAVA_INT, 0);
+ int nestedIntArrayElem2 = arg2.get(JAVA_INT, 4);
+ int structElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + nestedIntArrayElem1 + nestedIntArrayElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedIntArrayElem1 = arg2.get(JAVA_INT, 4);
+ int nestedIntArrayElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + structElem1 + nestedIntArrayElem1 + nestedIntArrayElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray(int arg1, MemorySegment arg2) {
+ int nestedStructArrayElem1_Elem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructArrayElem1_Elem2 = arg2.get(JAVA_INT, 4);
+ int nestedStructArrayElem2_Elem1 = arg2.get(JAVA_INT, 8);
+ int nestedStructArrayElem2_Elem2 = arg2.get(JAVA_INT, 12);
+ int structElem2 = arg2.get(JAVA_INT, 16);
+
+ int intSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructArrayElem1_Elem1 = arg2.get(JAVA_INT, 4);
+ int nestedStructArrayElem1_Elem2 = arg2.get(JAVA_INT, 8);
+ int nestedStructArrayElem2_Elem1 = arg2.get(JAVA_INT, 12);
+ int nestedStructArrayElem2_Elem2 = arg2.get(JAVA_INT, 16);
+
+ int intSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ int intStruct_Elem1 = arg1.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intStruct_Elem2 = arg1.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ intStructSegmt.set(JAVA_INT, 0, intStruct_Elem1);
+ intStructSegmt.set(JAVA_INT, 4, intStruct_Elem2);
+ return intStructSegmt;
+ }
+
+ public static Addressable add2IntStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum_Elem1 = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intSum_Elem2 = arg1Addr.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ arg1Addr.set(JAVA_INT, 0, intSum_Elem1);
+ arg1Addr.set(JAVA_INT, 4, intSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ int intStruct_Elem1 = arg1.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intStruct_Elem2 = arg1.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ int intStruct_Elem3 = arg1.get(JAVA_INT, 8) + arg2.get(JAVA_INT, 8);
+ intStructSegmt.set(JAVA_INT, 0, intStruct_Elem1);
+ intStructSegmt.set(JAVA_INT, 4, intStruct_Elem2);
+ intStructSegmt.set(JAVA_INT, 8, intStruct_Elem3);
+ return intStructSegmt;
+ }
+
+ public static long addLongAndLongsFromStruct(long arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addLongFromPointerAndLongsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static Addressable addLongFromPointerAndLongsFromStruct_returnLongPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ arg1Addr.set(JAVA_LONG, 0, longSum);
+ return arg1Addr;
+ }
+
+ public static long addLongAndLongsFromStructPointer(long arg1, MemoryAddress arg2Addr) {
+ long longSum = arg1 + arg2Addr.get(JAVA_LONG, 0) + arg2Addr.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct(long arg1, MemorySegment arg2) {
+ long nestedStructElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructElem2 = arg2.get(JAVA_LONG, 8);
+ long structElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructElem1 = arg2.get(JAVA_LONG, 8);
+ long nestedStructElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray(long arg1, MemorySegment arg2) {
+ long nestedLongrrayElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedLongrrayElem2 = arg2.get(JAVA_LONG, 8);
+ long structElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + nestedLongrrayElem1 + nestedLongrrayElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedLongrrayElem1 = arg2.get(JAVA_LONG, 8);
+ long nestedLongrrayElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + structElem1 + nestedLongrrayElem1 + nestedLongrrayElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray(long arg1, MemorySegment arg2) {
+ long nestedStructArrayElem1_Elem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructArrayElem1_Elem2 = arg2.get(JAVA_LONG, 8);
+ long nestedStructArrayElem2_Elem1 = arg2.get(JAVA_LONG, 16);
+ long nestedStructArrayElem2_Elem2 = arg2.get(JAVA_LONG, 24);
+ long structElem2 = arg2.get(JAVA_LONG, 32);
+
+ long longSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructArrayElem1_Elem1 = arg2.get(JAVA_LONG, 8);
+ long nestedStructArrayElem1_Elem2 = arg2.get(JAVA_LONG, 16);
+ long nestedStructArrayElem2_Elem1 = arg2.get(JAVA_LONG, 24);
+ long nestedStructArrayElem2_Elem2 = arg2.get(JAVA_LONG, 32);
+
+ long longSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static MemorySegment add2LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ long longStruct_Elem1 = arg1.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longStruct_Elem2 = arg1.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ longStructSegmt.set(JAVA_LONG, 0, longStruct_Elem1);
+ longStructSegmt.set(JAVA_LONG, 8, longStruct_Elem2);
+ return longStructSegmt;
+ }
+
+ public static Addressable add2LongStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum_Elem1 = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longSum_Elem2 = arg1Addr.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ arg1Addr.set(JAVA_LONG, 0, longSum_Elem1);
+ arg1Addr.set(JAVA_LONG, 8, longSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ long longStruct_Elem1 = arg1.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longStruct_Elem2 = arg1.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ long longStruct_Elem3 = arg1.get(JAVA_LONG, 16) + arg2.get(JAVA_LONG, 16);
+ longStructSegmt.set(JAVA_LONG, 0, longStruct_Elem1);
+ longStructSegmt.set(JAVA_LONG, 8, longStruct_Elem2);
+ longStructSegmt.set(JAVA_LONG, 16, longStruct_Elem3);
+ return longStructSegmt;
+ }
+
+ public static float addFloatAndFloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static float addFloatAnd5FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12) + arg2.get(JAVA_FLOAT, 16);
+ return floatSum;
+ }
+
+ public static float addFloatFromPointerAndFloatsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static Addressable addFloatFromPointerAndFloatsFromStruct_returnFloatPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ arg1Addr.set(JAVA_FLOAT, 0, floatSum);
+ return arg1Addr;
+ }
+
+ public static float addFloatAndFloatsFromStructPointer(float arg1, MemoryAddress arg2Addr) {
+ float floatSum = arg1 + arg2Addr.get(JAVA_FLOAT, 0) + arg2Addr.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct(float arg1, MemorySegment arg2) {
+ float nestedStructElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructElem2 = arg2.get(JAVA_FLOAT, 4);
+ float structElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructElem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray(float arg1, MemorySegment arg2) {
+ float nestedFloatArrayElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedFloatArrayElem2 = arg2.get(JAVA_FLOAT, 4);
+ float structElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + nestedFloatArrayElem1 + nestedFloatArrayElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedFloatArrayElem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedFloatArrayElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + structElem1 + nestedFloatArrayElem1 + nestedFloatArrayElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray(float arg1, MemorySegment arg2) {
+ float nestedStructArrayElem1_Elem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructArrayElem1_Elem2 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructArrayElem2_Elem1 = arg2.get(JAVA_FLOAT, 8);
+ float nestedStructArrayElem2_Elem2 = arg2.get(JAVA_FLOAT, 12);
+ float structElem2 = arg2.get(JAVA_FLOAT, 16);
+
+ float floatSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructArrayElem1_Elem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructArrayElem1_Elem2 = arg2.get(JAVA_FLOAT, 8);
+ float nestedStructArrayElem2_Elem1 = arg2.get(JAVA_FLOAT, 12);
+ float nestedStructArrayElem2_Elem2 = arg2.get(JAVA_FLOAT, 16);
+
+ float floatSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static MemorySegment add2FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ float floatStruct_Elem1 = arg1.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatStruct_Elem2 = arg1.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ floatStructSegmt.set(JAVA_FLOAT, 0, floatStruct_Elem1);
+ floatStructSegmt.set(JAVA_FLOAT, 4, floatStruct_Elem2);
+ return floatStructSegmt;
+ }
+
+ public static Addressable add2FloatStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum_Elem1 = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatSum_Elem2 = arg1Addr.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ arg1Addr.set(JAVA_FLOAT, 0, floatSum_Elem1);
+ arg1Addr.set(JAVA_FLOAT, 4, floatSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ float floatStruct_Elem1 = arg1.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatStruct_Elem2 = arg1.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ float floatStruct_Elem3 = arg1.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 8);
+ floatStructSegmt.set(JAVA_FLOAT, 0, floatStruct_Elem1);
+ floatStructSegmt.set(JAVA_FLOAT, 4, floatStruct_Elem2);
+ floatStructSegmt.set(JAVA_FLOAT, 8, floatStruct_Elem3);
+ return floatStructSegmt;
+ }
+
+ public static double addDoubleAndDoublesFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleFromPointerAndDoublesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static Addressable addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Addr.set(JAVA_DOUBLE, 0, doubleSum);
+ return arg1Addr;
+ }
+
+ public static double addDoubleAndDoublesFromStructPointer(double arg1, MemoryAddress arg2Addr) {
+ double doubleSum = arg1 + arg2Addr.get(JAVA_DOUBLE, 0) + arg2Addr.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct(double arg1, MemorySegment arg2) {
+ double nestedStructElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructElem2 = arg2.get(JAVA_DOUBLE, 8);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructElem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray(double arg1, MemorySegment arg2) {
+ double nestedDoubleArrayElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedDoubleArrayElem2 = arg2.get(JAVA_DOUBLE, 8);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedDoubleArrayElem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedDoubleArrayElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray(double arg1, MemorySegment arg2) {
+ double nestedStructArrayElem1_Elem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructArrayElem1_Elem2 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructArrayElem2_Elem1 = arg2.get(JAVA_DOUBLE, 16);
+ double nestedStructArrayElem2_Elem2 = arg2.get(JAVA_DOUBLE, 24);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 32);
+
+ double doubleSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructArrayElem1_Elem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructArrayElem1_Elem2 = arg2.get(JAVA_DOUBLE, 16);
+ double nestedStructArrayElem2_Elem1 = arg2.get(JAVA_DOUBLE, 24);
+ double nestedStructArrayElem2_Elem2 = arg2.get(JAVA_DOUBLE, 32);
+
+ double doubleSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static MemorySegment add2DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ double doubleStruct_Elem1 = arg1.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleStruct_Elem2 = arg1.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ doubleStructSegmt.set(JAVA_DOUBLE, 0, doubleStruct_Elem1);
+ doubleStructSegmt.set(JAVA_DOUBLE, 8, doubleStruct_Elem2);
+ return doubleStructSegmt;
+ }
+
+ public static Addressable add2DoubleStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum_Elem1 = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleSum_Elem2 = arg1Addr.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Addr.set(JAVA_DOUBLE, 0, doubleSum_Elem1);
+ arg1Addr.set(JAVA_DOUBLE, 8, doubleSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, scope);
+ double doubleStruct_Elem1 = arg1.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleStruct_Elem2 = arg1.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ double doubleStruct_Elem3 = arg1.get(JAVA_DOUBLE, 16) + arg2.get(JAVA_DOUBLE, 16);
+ doubleStructSegmt.set(JAVA_DOUBLE, 0, doubleStruct_Elem1);
+ doubleStructSegmt.set(JAVA_DOUBLE, 8, doubleStruct_Elem2);
+ doubleStructSegmt.set(JAVA_DOUBLE, 16, doubleStruct_Elem3);
+ return doubleStructSegmt;
+ }
+
+ public static int addIntAndIntShortFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_SHORT, 4);
+ return intSum;
+ }
+
+ public static int addIntAndShortIntFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static long addIntAndIntLongFromStruct(int arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addIntAndLongIntFromStruct(int arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_INT, 8);
+ return longSum;
+ }
+
+ public static double addDoubleAndIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ double doubleSum = arg1 + structElem1 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_INT, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ double doubleSum = arg1 + structElem1 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAnd2FloatsDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDouble2FloatsFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt2FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 8);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ float structElem2 = Integer.valueOf(arg2.get(JAVA_INT, 4)).floatValue();
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + structElem2 + arg2.get(JAVA_FLOAT, 8);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_INT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndLongDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt3FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return floatSum;
+ }
+
+ public static long addLongAndLong2FloatsFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long structElem2 = Float.valueOf(arg2.get(JAVA_FLOAT, 8)).longValue();
+ long structElem3 = Float.valueOf(arg2.get(JAVA_FLOAT, 12)).longValue();
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static float addFloatAnd3FloatsIntFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_INT, 12);
+ return floatSum;
+ }
+
+ public static long addLongAndFloatLongFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = Float.valueOf(arg2.get(JAVA_FLOAT, 0)).longValue();
+ long structElem2 = arg2.get(JAVA_LONG, 8);
+ long longSum = arg1 + structElem1 + structElem2;
+ return longSum;
+ }
+
+ public static double addDoubleAndDoubleFloatIntFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_INT, 12);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_LONG, 8);
+ return doubleSum;
+ }
+
+ public static long addLongAnd2FloatsLongFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = Float.valueOf(arg2.get(JAVA_FLOAT, 0)).longValue();
+ long structElem2 = Float.valueOf(arg2.get(JAVA_FLOAT, 4)).longValue();
+ long structElem3 = arg2.get(JAVA_LONG, 8);
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static short addShortAnd3ShortsCharFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2)
+ + arg2.get(JAVA_SHORT, 4) + arg2.get(JAVA_CHAR, 6));
+ return shortSum;
+ }
+
+ public static float addFloatAndIntFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4)+ arg2.get(JAVA_INT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ float structElem3 = arg2.get(JAVA_FLOAT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ int structElem3 = arg2.get(JAVA_INT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ int structElem3 = arg2.get(JAVA_INT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ float structElem3 = arg2.get(JAVA_FLOAT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ double structElem3 = arg2.get(JAVA_LONG, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static MemorySegment return254BytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, scope);
+
+ for (int i = 0; i < 254; i++) {
+ byteArrStruSegment.set(JAVA_BYTE, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+
+ public static MemorySegment return4KBytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, scope);
+
+ for (int i = 0; i < 4096; i++) {
+ byteArrStruSegment.set(JAVA_BYTE, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/ApiTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/ApiTests.java
new file mode 100644
index 00000000000..c8c07f74e33
--- /dev/null
+++ b/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/ApiTests.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep419.valist;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.VarHandle;
+
+import jdk.incubator.foreign.GroupLayout;
+import jdk.incubator.foreign.MemoryAddress;
+import jdk.incubator.foreign.MemoryLayout;
+import jdk.incubator.foreign.MemoryLayout.PathElement;
+import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.ResourceScope;
+import jdk.incubator.foreign.SegmentAllocator;
+import jdk.incubator.foreign.VaList;
+import static jdk.incubator.foreign.ValueLayout.*;
+import static jdk.incubator.foreign.VaList.Builder;
+
+/**
+ * Test cases for JEP 419: Foreign Linker API (Second Incubator) for the vararg list in VaList API specific cases.
+ */
+@Test(groups = { "level.sanity" })
+public class ApiTests {
+}
diff --git a/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/VaListTests.java b/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/VaListTests.java
deleted file mode 100644
index e7fc6989f9a..00000000000
--- a/test/functional/Java18andUp/src/org/openj9/test/jep419/valist/VaListTests.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2021, 2022 IBM Corp. and others
- *
- * This program and the accompanying materials are made available under
- * the terms of the Eclipse Public License 2.0 which accompanies this
- * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
- * or the Apache License, Version 2.0 which accompanies this distribution and
- * is available at https://www.apache.org/licenses/LICENSE-2.0.
- *
- * This Source Code may also be made available under the following
- * Secondary Licenses when the conditions for such availability set
- * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
- * General Public License, version 2 with the GNU Classpath
- * Exception [1] and GNU General Public License, version 2 with the
- * OpenJDK Assembly Exception [2].
- *
- * [1] https://www.gnu.org/software/classpath/license.html
- * [2] http://openjdk.java.net/legal/assembly-exception.html
- *
- * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
- *******************************************************************************/
-package org.openj9.test.jep419.valist;
-
-import org.testng.annotations.Test;
-import org.testng.Assert;
-import org.testng.AssertJUnit;
-
-import org.testng.annotations.Test;
-import org.testng.Assert;
-import org.testng.AssertJUnit;
-
-import java.lang.invoke.MethodHandle;
-import jdk.incubator.foreign.CLinker;
-import jdk.incubator.foreign.FunctionDescriptor;
-import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.MemoryLayout;
-import jdk.incubator.foreign.MemorySegment;
-import jdk.incubator.foreign.NativeSymbol;
-import jdk.incubator.foreign.ResourceScope;
-import jdk.incubator.foreign.SegmentAllocator;
-import jdk.incubator.foreign.SymbolLookup;
-import jdk.incubator.foreign.VaList;
-import static jdk.incubator.foreign.ValueLayout.*;
-import static jdk.incubator.foreign.VaList.Builder;
-
-/**
- * Test cases for JEP 419: Foreign Linker API (Second Incubator) for the vararg list in downcall.
- */
-@Test(groups = { "level.sanity" })
-public class VaListTests {
- private static boolean isWinOS = System.getProperty("os.name").toLowerCase().contains("win");
- private static CLinker clinker = CLinker.systemCLinker();
-
- static {
- System.loadLibrary("clinkerffitests");
- }
- private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
-
- @Test
- public void test_addIntsWithVaList() throws Throwable {
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addIntsFromVaList").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
- .addVarg(JAVA_INT, 800)
- .addVarg(JAVA_INT, 900)
- .addVarg(JAVA_INT, 1000), scope);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- int result = (int)mh.invoke(4, vaList);
- Assert.assertEquals(result, 3400);
- }
- }
-
- @Test
- public void test_addLongsWithVaList() throws Throwable {
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addLongsFromVaList").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
- .addVarg(JAVA_LONG, 800000L)
- .addVarg(JAVA_LONG, 900000L)
- .addVarg(JAVA_LONG, 1000000L), scope);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- long result = (long)mh.invoke(4, vaList);
- Assert.assertEquals(result, 3400000L);
- }
- }
-
- @Test
- public void test_addDoublesWithVaList() throws Throwable {
- NativeSymbol functionSymbol = nativeLibLookup.lookup("addDoublesFromVaList").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 150.1001D)
- .addVarg(JAVA_DOUBLE, 160.2002D)
- .addVarg(JAVA_DOUBLE, 170.1001D)
- .addVarg(JAVA_DOUBLE, 180.2002D), scope);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- double result = (double)mh.invoke(4, vaList);
- Assert.assertEquals(result, 660.6006D);
- }
- }
-
- @Test
- public void test_vprintfFromDefaultLibWithVaList() throws Throwable {
- /* Disable the test on Windows given a misaligned access exception coming from
- * java.base/java.lang.invoke.MemoryAccessVarHandleBase triggered by CLinker.toCString()
- * is also captured on OpenJDK/Hotspot.
- */
- if (!isWinOS) {
- NativeSymbol functionSymbol = clinker.lookup("vprintf").get();
- FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS);
-
- try (ResourceScope scope = ResourceScope.newConfinedScope()) {
- SegmentAllocator nativeAllocator = SegmentAllocator.nativeAllocator(scope);
- MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("%d * %d = %d\n");
- VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 7)
- .addVarg(JAVA_INT, 8)
- .addVarg(JAVA_INT, 56), scope);
- MethodHandle mh = clinker.downcallHandle(functionSymbol, fd);
- mh.invoke(formatSegmt, vaList);
- }
- }
- }
-}
diff --git a/test/functional/Java18andUp/testng_180.xml b/test/functional/Java18andUp/testng_180.xml
index b051d9a0662..4f790572845 100644
--- a/test/functional/Java18andUp/testng_180.xml
+++ b/test/functional/Java18andUp/testng_180.xml
@@ -32,15 +32,26 @@
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/test/functional/Java19andUp/playlist.xml b/test/functional/Java19andUp/playlist.xml
index 456f485ea6e..ca82d3366c1 100644
--- a/test/functional/Java19andUp/playlist.xml
+++ b/test/functional/Java19andUp/playlist.xml
@@ -52,4 +52,91 @@
19+
+
+
+ Jep424Tests_testLinkerFfi_DownCall
+
+ --enable-preview
+
+ $(ADD_JVM_LIB_DIR_TO_LIBPATH) $(JAVA_COMMAND) $(JVM_OPTIONS) \
+ --enable-native-access=ALL-UNNAMED \
+ -Dforeign.restricted=permit \
+ -cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)GeneralTest.jar$(Q) \
+ org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng_190.xml$(Q) -testnames Jep424Tests_testLinkerFfi_DownCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 19+
+
+
+
+
+ Jep424Tests_testLinkerFfi_UpCall
+
+ --enable-preview
+
+ $(ADD_JVM_LIB_DIR_TO_LIBPATH) $(JAVA_COMMAND) $(JVM_OPTIONS) \
+ --enable-native-access=ALL-UNNAMED \
+ -Dforeign.restricted=permit \
+ -cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)GeneralTest.jar$(Q) \
+ org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng_190.xml$(Q) -testnames Jep424Tests_testLinkerFfi_UpCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.x86,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 19+
+
+
+
+
+ Jep424Tests_testLinkerFfi_VaList
+
+ --enable-preview
+
+ $(ADD_JVM_LIB_DIR_TO_LIBPATH) $(JAVA_COMMAND) $(JVM_OPTIONS) \
+ --enable-native-access=ALL-UNNAMED \
+ -Dforeign.restricted=permit \
+ -cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)GeneralTest.jar$(Q) \
+ org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng_190.xml$(Q) -testnames Jep424Tests_testLinkerFfi_VaList \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.x86,^arch.aarch64,^arch.390,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 19+
+
+
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/InvalidDownCallTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/InvalidDownCallTests.java
new file mode 100644
index 00000000000..e5557dc4db7
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/InvalidDownCallTests.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import static org.testng.Assert.fail;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall,
+ * which verifies the illegal cases including unsupported layouts, etc.
+ * Note: the majority of illegal cases are removed given the corresponding method type
+ * is deduced from the function descriptor which is verified in OpenJDK.
+ */
+@Test(groups = { "level.sanity" })
+public class InvalidDownCallTests {
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = linker.defaultLookup();
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unsupported layout.*")
+ public void test_invalidMemoryLayoutForIntType() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, MemoryLayout.paddingLayout(32));
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unsupported layout.*")
+ public void test_invalidMemoryLayoutForMemoryAddress() throws Throwable {
+ Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, MemoryLayout.paddingLayout(64));
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unsupported layout.*")
+ public void test_invalidMemoryLayoutForReturnType() throws Throwable {
+ Addressable functionSymbol = defaultLibLookup.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(MemoryLayout.paddingLayout(64), JAVA_LONG);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiCallTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiCallTests.java
new file mode 100644
index 00000000000..7ed0559e2b7
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiCallTests.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall,
+ * which verifies multiple downcalls with the same or different layouts or argument/return types.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiCallTests {
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_twoCallsWithSameFuncDescriptor() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+
+ mh = linker.downcallHandle(functionSymbol, fd);
+ result = (int)mh.invokeExact(235, 439);
+ Assert.assertEquals(result, 674);
+ }
+
+ @Test
+ public void test_twoCallsWithDiffFuncDescriptor() throws Throwable {
+ FunctionDescriptor fd1 = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol1 = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol1, fd1);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+
+ FunctionDescriptor fd2 = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol2 = nativeLibLookup.lookup("add3Ints").get();
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ result = (int)mh.invokeExact(112, 123, 235);
+ Assert.assertEquals(result, 470);
+ }
+
+ @Test
+ public void test_multiCallsWithMixedFuncDescriptors() throws Throwable {
+ FunctionDescriptor fd1 = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol1 = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol1, fd1);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+
+ FunctionDescriptor fd2 = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol2 = nativeLibLookup.lookup("add3Ints").get();
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ result = (int)mh.invokeExact(112, 123, 235);
+ Assert.assertEquals(result, 470);
+
+ FunctionDescriptor fd3 = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol3 = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ mh = linker.downcallHandle(functionSymbol3, fd3);
+ mh.invokeExact(454, 398);
+
+ mh = linker.downcallHandle(functionSymbol1, fd1);
+ result = (int)mh.invokeExact(234, 567);
+ Assert.assertEquals(result, 801);
+
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ result = (int)mh.invokeExact(312, 323, 334);
+ Assert.assertEquals(result, 969);
+
+ mh = linker.downcallHandle(functionSymbol3, fd3);
+ mh.invokeExact(539, 672);
+ }
+
+ @Test
+ public void test_twoCallsWithDiffReturnType() throws Throwable {
+ FunctionDescriptor fd1 = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol1 = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol1, fd1);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+
+ FunctionDescriptor fd2 = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol2 = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ mh.invokeExact(454, 398);
+ }
+
+ @Test
+ public void test_multiCallsWithSameArgLayouts() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol1 = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol1, fd);
+ int intResult = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(intResult, 235);
+
+ mh = linker.downcallHandle(functionSymbol1, fd);
+ intResult = (int)mh.invokeExact(234, 567);
+ Assert.assertEquals(intResult, 801);
+
+ FunctionDescriptor fd2 = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol2 = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ mh.invokeExact(454, 398);
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests1.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests1.java
new file mode 100644
index 00000000000..667ee373595
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests1.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.SegmentAllocator;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall, which
+ * verifies the downcalls with the same downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests1 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_twoThreadsWithSameFuncDesc_SameDowncallHandler() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(321, intSegmt);
+ Assert.assertEquals(result, 536);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(322, intSegmt);
+ Assert.assertEquals(result, 537);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+
+ thr1.join();
+ thr2.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests2.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests2.java
new file mode 100644
index 00000000000..5f5ceac981f
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests2.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall, which
+ * verifies the downcalls with the shared downcall handlder (cached as soft reference in OpenJDK)
+ * in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests2 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ private static final FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ private static final Addressable functionSymbol = SymbolLookup.loaderLookup().lookup("add2IntStructs_returnStruct").get();
+ private static final MethodHandle mh = Linker.nativeLinker().downcallHandle(functionSymbol, fd);
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_twoThreadsWithSameFuncDesc_SharedDowncallHandler() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001123);
+ intHandle2.set(structSegmt2, 33445567);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224467);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113355);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+
+ thr1.join();
+ thr2.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests3.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests3.java
new file mode 100644
index 00000000000..51efde78825
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests3.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall,
+ * which verifies the downcalls with the diffrent layouts and arguments/return types in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests3 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_twoThreadsWithDiffFuncDescriptor() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 123, 235);
+ Assert.assertEquals(result, 470);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+
+ thr1.join();
+ thr2.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests4.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests4.java
new file mode 100644
index 00000000000..9d3ff9869df
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests4.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall,
+ * which verifies the downcalls with the diffrent return types in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests4 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_twoThreadsWithDiffReturnType() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ mh.invokeExact(454, 398);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+
+ thr1.join();
+ thr2.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests5.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests5.java
new file mode 100644
index 00000000000..e243511ce68
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/MultiThreadingTests5.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall,
+ * which verifies multiple downcalls combined with the diffrent layouts/arguments/return types in multithreading.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiThreadingTests5 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiThreadsWithMixedFuncDescriptors() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(128, 246);
+ Assert.assertEquals(result, 374);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 642, 971);
+ Assert.assertEquals(result, 1725);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ boolean result = (boolean)mh.invokeExact(true, false);
+ Assert.assertEquals(result, true);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr4 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(416, 728);
+ Assert.assertEquals(result, 1144);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr5 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(1012, 1023, 2035);
+ Assert.assertEquals(result, 4070);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr6 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ boolean result = (boolean)mh.invokeExact(false, false);
+ Assert.assertEquals(result, false);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ thr1.setUncaughtExceptionHandler(this);
+ thr2.setUncaughtExceptionHandler(this);
+ thr3.setUncaughtExceptionHandler(this);
+ thr4.setUncaughtExceptionHandler(this);
+ thr5.setUncaughtExceptionHandler(this);
+ thr6.setUncaughtExceptionHandler(this);
+
+ thr1.start();
+ thr2.start();
+ thr3.start();
+ thr4.start();
+ thr5.start();
+ thr6.start();
+
+ thr6.join();
+ thr5.join();
+ thr4.join();
+ thr3.join();
+ thr2.join();
+ thr1.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests1.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests1.java
new file mode 100644
index 00000000000..8c3b0d0fca9
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests1.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall.
+ *
+ * Note: the test suite is intended for the following Clinker API:
+ * MethodHandle downcallHandle(Addressable symbol, FunctionDescriptor function)
+ */
+@Test(groups = { "level.sanity" })
+public class PrimitiveTypeTests1 {
+ private static Linker linker = Linker.nativeLinker();
+ private static MemorySession session = MemorySession.openImplicit();
+ private static SegmentAllocator nativeAllocator = SegmentAllocator.newNativeArena(session);
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = linker.defaultLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOr_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ boolean result = (boolean)mh.invokeExact(true, false);
+ Assert.assertEquals(result, true);
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPointerWithOr_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPointerWithOr").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ boolean result = (boolean)mh.invoke(false, boolSegmt);
+ Assert.assertEquals(result, true);
+ }
+
+ @Test
+ public void test_generateNewChar_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFrom2Chars").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ char result = (char)mh.invokeExact('B', 'D');
+ Assert.assertEquals(result, 'C');
+ }
+
+ @Test
+ public void test_generateNewCharFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment charSegmt = nativeAllocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D');
+ Assert.assertEquals(result, 'C');
+ }
+
+ @Test
+ public void test_addTwoBytes_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Bytes").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ byte result = (byte)mh.invokeExact((byte)6, (byte)3);
+ Assert.assertEquals(result, (byte)9);
+ }
+
+ @Test
+ public void test_addTwoNegtiveBytes_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Bytes").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ byte result = (byte)mh.invokeExact((byte)-6, (byte)-3);
+ Assert.assertEquals(result, (byte)-9);
+ }
+
+ @Test
+ public void test_addByteAndByteFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment byteSegmt = nativeAllocator.allocate(JAVA_BYTE, (byte)3);
+ byte result = (byte)mh.invoke((byte)6, byteSegmt);
+ Assert.assertEquals(result, (byte)9);
+ }
+
+ @Test
+ public void test_addTwoShorts_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Shorts").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ short result = (short)mh.invokeExact((short)24, (short)32);
+ Assert.assertEquals(result, (short)56);
+ }
+
+ @Test
+ public void test_addTwoNegtiveShorts_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Shorts").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ short result = (short)mh.invokeExact((short)-24, (short)-32);
+ Assert.assertEquals(result, (short)-56);
+ }
+
+ @Test
+ public void test_addShortAndShortFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment shortSegmt = nativeAllocator.allocate(JAVA_SHORT, (short)24);
+ short result = (short)mh.invoke(shortSegmt, (short)32);
+ Assert.assertEquals(result, (short)56);
+ }
+
+ @Test
+ public void test_addTwoInts_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(112, 123);
+ Assert.assertEquals(result, 235);
+ }
+
+ @Test
+ public void test_addTwoNegtiveInts_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(-112, -123);
+ Assert.assertEquals(result, -235);
+ }
+
+ @Test
+ public void test_addIntAndIntFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment intSegmt = nativeAllocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(321, intSegmt);
+ Assert.assertEquals(result, 536);
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoid_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ mh.invokeExact(454, 398);
+ }
+
+ @Test
+ public void test_addIntAndChar_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndChar").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ int result = (int)mh.invokeExact(58, 'A');
+ Assert.assertEquals(result, 123);
+ }
+
+ @Test
+ public void test_addTwoLongs_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Longs").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ long result = (long)mh.invokeExact(57424L, 698235L);
+ Assert.assertEquals(result, 755659L);
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment longSegmt = nativeAllocator.allocate(JAVA_LONG, 57424L);
+ long result = (long)mh.invoke(longSegmt, 698235L);
+ Assert.assertEquals(result, 755659L);
+ }
+
+ @Test
+ public void test_addTwoFloats_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Floats").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ float result = (float)mh.invokeExact(5.74f, 6.79f);
+ Assert.assertEquals(result, 12.53f, 0.01f);
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment floatSegmt = nativeAllocator.allocate(JAVA_FLOAT, 6.79f);
+ float result = (float)mh.invoke(5.74f, floatSegmt);
+ Assert.assertEquals(result, 12.53f, 0.01f);
+ }
+
+ @Test
+ public void test_addTwoDoubles_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Doubles").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ double result = (double)mh.invokeExact(159.748d, 262.795d);
+ Assert.assertEquals(result, 422.543d, 0.001d);
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPointer_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment doubleSegmt = nativeAllocator.allocate(JAVA_DOUBLE, 159.748d);
+ double result = (double)mh.invoke(doubleSegmt, 262.795d);
+ Assert.assertEquals(result, 422.543d, 0.001d);
+ }
+
+ @Test
+ public void test_strlenFromDefaultLibWithMemAddr_1() throws Throwable {
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(strlenSymbol, fd);
+ MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP424 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(funcSegmt);
+ Assert.assertEquals(strLength, 27);
+ }
+
+ @Test
+ public void test_memoryAllocFreeFromDefaultLib_1() throws Throwable {
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = linker.downcallHandle(allocSymbol, allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(10L);
+ allocMemAddr.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = linker.downcallHandle(freeSymbol, freeFuncDesc);
+ freeHandle.invoke(allocMemAddr);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_1() throws Throwable {
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
+ mh.invoke(formatSegmt, 15, 27, 42);
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests2.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests2.java
new file mode 100644
index 00000000000..2dcf772cb7f
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/PrimitiveTypeTests2.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.VaList;
+import static java.lang.foreign.ValueLayout.*;
+import static java.lang.foreign.VaList.Builder;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in downcall.
+ *
+ * Note: the test suite is intended for the following Clinker API:
+ * MethodHandle downcallHandle(FunctionDescriptor function)
+ */
+@Test(groups = { "level.sanity" })
+public class PrimitiveTypeTests2 {
+ private static Linker linker = Linker.nativeLinker();
+ private static MemorySession session = MemorySession.openImplicit();
+ private static SegmentAllocator nativeAllocator = SegmentAllocator.newNativeArena(session);
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = linker.defaultLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOr_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOr").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, false);
+ Assert.assertEquals(result, true);
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPointerWithOr_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPointerWithOr").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ boolean result = (boolean)mh.invoke(functionSymbol, false, boolSegmt);
+ Assert.assertEquals(result, true);
+ }
+
+ @Test
+ public void test_generateNewChar_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFrom2Chars").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ char result = (char)mh.invokeExact(functionSymbol, 'B', 'D');
+ Assert.assertEquals(result, 'C');
+ }
+
+ @Test
+ public void test_generateNewCharFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment charSegmt = nativeAllocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(functionSymbol, charSegmt, 'D');
+ Assert.assertEquals(result, 'C');
+ }
+
+ @Test
+ public void test_addTwoBytes_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Bytes").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)6, (byte)3);
+ Assert.assertEquals(result, (byte)9);
+ }
+
+ @Test
+ public void test_addTwoNegtiveBytes_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Bytes").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)-6, (byte)-3);
+ Assert.assertEquals(result, (byte)-9);
+ }
+
+ @Test
+ public void test_addByteAndByteFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment byteSegmt = nativeAllocator.allocate(JAVA_BYTE, (byte)3);
+ byte result = (byte)mh.invoke(functionSymbol, (byte)6, byteSegmt);
+ Assert.assertEquals(result, (byte)9);
+ }
+
+ @Test
+ public void test_addTwoShorts_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Shorts").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ short result = (short)mh.invokeExact(functionSymbol, (short)24, (short)32);
+ Assert.assertEquals(result, (short)56);
+ }
+
+ @Test
+ public void test_addTwoNegtiveShorts_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Shorts").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ short result = (short)mh.invokeExact(functionSymbol, (short)-24, (short)-32);
+ Assert.assertEquals(result, (short)-56);
+ }
+
+ @Test
+ public void test_addShortAndShortFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment shortSegmt = nativeAllocator.allocate(JAVA_SHORT, (short)24);
+ short result = (short)mh.invoke(functionSymbol, shortSegmt, (short)32);
+ Assert.assertEquals(result, (short)56);
+ }
+
+ @Test
+ public void test_addTwoInts_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ int result = (int)mh.invokeExact(functionSymbol, 112, 123);
+ Assert.assertEquals(result, 235);
+ }
+
+ @Test
+ public void test_addTwoNegtiveInts_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Ints").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ int result = (int)mh.invokeExact(functionSymbol, -112, -123);
+ Assert.assertEquals(result, -235);
+ }
+
+ @Test
+ public void test_addIntAndIntFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment intSegmt = nativeAllocator.allocate(JAVA_INT, 215);
+ int result = (int)mh.invoke(functionSymbol, 321, intSegmt);
+ Assert.assertEquals(result, 536);
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoid_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoid").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ mh.invokeExact(functionSymbol, 454, 398);
+ }
+
+ @Test
+ public void test_addIntAndChar_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndChar").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ int result = (int)mh.invokeExact(functionSymbol, 58, 'A');
+ Assert.assertEquals(result, 123);
+ }
+
+ @Test
+ public void test_addTwoLongs_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Longs").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ long result = (long)mh.invokeExact(functionSymbol, 57424L, 698235L);
+ Assert.assertEquals(result, 755659L);
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment longSegmt = nativeAllocator.allocate(JAVA_LONG, 57424L);
+ long result = (long)mh.invoke(functionSymbol, longSegmt, 698235L);
+ Assert.assertEquals(result, 755659L);
+ }
+
+ @Test
+ public void test_addTwoFloats_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Floats").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ float result = (float)mh.invokeExact(functionSymbol, 5.74f, 6.79f);
+ Assert.assertEquals(result, 12.53f, 0.01f);
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment floatSegmt = nativeAllocator.allocate(JAVA_FLOAT, 6.79f);
+ float result = (float)mh.invoke(functionSymbol, 5.74f, floatSegmt);
+ Assert.assertEquals(result, 12.53f, 0.01f);
+ }
+
+ @Test
+ public void test_addTwoDoubles_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2Doubles").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+ double result = (double)mh.invokeExact(functionSymbol, 159.748d, 262.795d);
+ Assert.assertEquals(result, 422.543d, 0.001d);
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPointer_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment doubleSegmt = nativeAllocator.allocate(JAVA_DOUBLE, 159.748d);
+ double result = (double)mh.invoke(functionSymbol, doubleSegmt, 262.795d);
+ Assert.assertEquals(result, 422.543d, 0.001d);
+ }
+
+ @Test
+ public void test_strlenFromDefaultLibWithMemAddr_2() throws Throwable {
+ Addressable strlenSymbol = defaultLibLookup.lookup("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(fd);
+ MemorySegment funcSegmt = nativeAllocator.allocateUtf8String("JEP424 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(strlenSymbol, funcSegmt);
+ Assert.assertEquals(strLength, 27);
+ }
+
+ @Test
+ public void test_memoryAllocFreeFromDefaultLib_2() throws Throwable {
+ Addressable allocSymbol = defaultLibLookup.lookup("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = linker.downcallHandle(allocFuncDesc);
+ MemoryAddress allocMemAddr = (MemoryAddress)allocHandle.invokeExact(allocSymbol, 10L);
+ allocMemAddr.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemAddr.get(JAVA_INT, 0), 15);
+
+ Addressable freeSymbol = defaultLibLookup.lookup("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = linker.downcallHandle(freeFuncDesc);
+ freeHandle.invoke(freeSymbol, allocMemAddr);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_2() throws Throwable {
+ Addressable functionSymbol = defaultLibLookup.lookup("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(fd);
+ MemorySegment formatSegmt = nativeAllocator.allocateUtf8String("\n%d + %d = %d\n");
+ mh.invoke(functionSymbol, formatSegmt, 15, 27, 42);
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests1.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests1.java
new file mode 100644
index 00000000000..ad27fcecf2d
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests1.java
@@ -0,0 +1,3103 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for argument/return struct in downcall.
+ *
+ * Note:
+ * [1] the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ *
+ * [2] the test suite is mainly intended for the following Clinker API:
+ * MethodHandle downcallHandle(MemorySegment symbol, FunctionDescriptor function)
+ */
+@Test(groups = { "level.sanity" })
+public class StructTests1 {
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithXor_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(boolSegmt, structSegmt);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(boolSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultAddr.toRawLongValue(), boolSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructPointerWithXor_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructPointerWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, true);
+ boolHandle2.set(structSegmt, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_1() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_1() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invokeExact(true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+ structSegmt.set(JAVA_BOOLEAN, 3, false);
+ structSegmt.set(JAVA_BOOLEAN, 4, true);
+
+ boolean result = (boolean)mh.invokeExact(false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 1), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ boolHandle3.set(structSegmt1, true);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+ boolHandle3.set(structSegmt2, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)8);
+ byteHandle2.set(structSegmt, (byte)9);
+
+ byte result = (byte)mh.invokeExact((byte)6, structSegmt);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)14);
+ byteHandle2.set(structSegmt, (byte)16);
+
+ byte result = (byte)mh.invoke(byteSegmt, structSegmt);
+ Assert.assertEquals(result, 42);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_returnBytePointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct_returnBytePointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)18);
+ byteHandle2.set(structSegmt, (byte)19);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(byteSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.toRawLongValue(), byteSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)11);
+ byteHandle2.set(structSegmt, (byte)12);
+
+ byte result = (byte)mh.invoke((byte)13, structSegmt);
+ Assert.assertEquals(result, 36);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invokeExact((byte)46, structSegmt);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)24);
+ structSegmt.set(JAVA_BYTE, 2, (byte)36);
+
+ byte result = (byte)mh.invokeExact((byte)48, structSegmt);
+ Assert.assertEquals(result, 120);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invokeExact((byte)46, structSegmt);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_1() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+
+ byte result = (byte)mh.invokeExact((byte)14, structSegmt);
+ Assert.assertEquals(result, 50);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_1() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+
+ byte result = (byte)mh.invokeExact((byte)18, structSegmt);
+ Assert.assertEquals(result, 60);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+
+ byte result = (byte)mh.invokeExact((byte)14, structSegmt);
+ Assert.assertEquals(result, 50);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invokeExact((byte)16, structSegmt);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+ structSegmt.set(JAVA_BYTE, 3, (byte)18);
+ structSegmt.set(JAVA_BYTE, 4, (byte)20);
+
+ byte result = (byte)mh.invokeExact((byte)22, structSegmt);
+ Assert.assertEquals(result, 102);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invokeExact((byte)16, structSegmt);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 1), 24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ byteHandle3.set(structSegmt1, (byte)12);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+ byteHandle3.set(structSegmt2, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt), (byte)28);
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'A');
+ charHandle2.set(structSegmt, 'B');
+
+ char result = (char)mh.invokeExact('C', structSegmt);
+ Assert.assertEquals(result, 'D');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ char result = (char)mh.invoke(charSegmt, structSegmt);
+ Assert.assertEquals(result, 'M');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_returnCharPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct_returnCharPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultAddr.toRawLongValue(), charSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'H');
+ charHandle2.set(structSegmt, 'I');
+
+ char result = (char)mh.invoke('G', structSegmt);
+ Assert.assertEquals(result, 'V');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invokeExact('H', structSegmt);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invokeExact('H', structSegmt);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_1() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact('D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_reverseOrder_1() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact('D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(charArray, JAVA_CHAR, MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact('D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact('J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact('J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR, JAVA_CHAR);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_CHAR);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact('J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 2), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ charHandle3.set(structSegmt1, 'C');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'B');
+ charHandle2.set(structSegmt2, 'C');
+ charHandle3.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt), 'F');
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)8);
+ shortHandle2.set(structSegmt, (short)9);
+
+ short result = (short)mh.invokeExact((short)6, structSegmt);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)18);
+ shortHandle2.set(structSegmt, (short)19);
+
+ short result = (short)mh.invoke(shortSegmt, structSegmt);
+ Assert.assertEquals(result, 49);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_returnShortPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct_returnShortPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)18);
+ shortHandle2.set(structSegmt, (short)19);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 49);
+ Assert.assertEquals(resultAddr.toRawLongValue(), shortSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)22);
+ shortHandle2.set(structSegmt, (short)44);
+
+ short result = (short)mh.invoke((short)66, structSegmt);
+ Assert.assertEquals(result, 132);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact((short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact((short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT,
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact((short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_1() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact((short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_reverseOrder_1() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact((short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray, JAVA_SHORT, MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact((short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact((short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact((short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_SHORT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact((short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)56);
+ shortHandle2.set(structSegmt1, (short)45);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)78);
+ shortHandle2.set(structSegmt2, (short)67);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)134);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)112);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)56);
+ shortHandle2.set(structSegmt1, (short)45);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)78);
+ shortHandle2.set(structSegmt2, (short)67);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 134);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 2), 112);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortStructs_returnStruct").get();
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)25);
+ shortHandle2.set(structSegmt1, (short)26);
+ shortHandle3.set(structSegmt1, (short)27);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)34);
+ shortHandle2.set(structSegmt2, (short)35);
+ shortHandle3.set(structSegmt2, (short)36);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)59);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)61);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt), (short)63);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1122334);
+ intHandle2.set(structSegmt, 1234567);
+
+ int result = (int)mh.invokeExact(2244668, structSegmt);
+ Assert.assertEquals(result, 4601569);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntShortFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntShortFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, (short)32766);
+
+ int result = (int)mh.invokeExact(22334455, structSegmt);
+ Assert.assertEquals(result, 33590565);
+ }
+ }
+
+ @Test
+ public void test_addIntAndShortIntFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndShortIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, (short)32766);
+ elemHandle2.set(structSegmt, 22446688);
+
+ int result = (int)mh.invokeExact(11335577, structSegmt);
+ Assert.assertEquals(result, 33815031);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 7654321);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1234567);
+ intHandle2.set(structSegmt, 2468024);
+
+ int result = (int)mh.invoke(intSegmt, structSegmt);
+ Assert.assertEquals(result, 11356912);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_returnIntPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct_returnIntPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 1122333);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 4455666);
+ intHandle2.set(structSegmt, 7788999);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(intSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultAddr.toRawLongValue(), intSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 11121314);
+ intHandle2.set(structSegmt, 15161718);
+
+ int result = (int)mh.invoke(19202122, structSegmt);
+ Assert.assertEquals(result, 45485154);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_INT.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_1() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_reverseOrder_1() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), intArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT, JAVA_INT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 4), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add3IntStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ intHandle3.set(structSegmt1, 99001122);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 33445566);
+ intHandle2.set(structSegmt2, 77889900);
+ intHandle3.set(structSegmt2, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt), 143333333);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 1234567890L);
+ longHandle2.set(structSegmt, 9876543210L);
+
+ long result = (long)mh.invokeExact(2468024680L, structSegmt);
+ Assert.assertEquals(result, 13579135780L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntLongFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntLongFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, 667788990011L);
+
+ long result = (long)mh.invokeExact(22446688, structSegmt);
+ Assert.assertEquals(result, 667822660043L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndLongIntFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.bitSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndLongIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 667788990011L);
+ elemHandle2.set(structSegmt, 11223344);
+
+ long result = (long)mh.invokeExact(1234567, structSegmt);
+ Assert.assertEquals(result, 667801447922L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 3333333333L);
+ longHandle2.set(structSegmt, 5555555555L);
+
+ long result = (long)mh.invoke(longSegmt, structSegmt);
+ Assert.assertEquals(result, 9999999999L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_returnLongPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct_returnLongPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 6677889900L);
+ longHandle2.set(structSegmt, 1234567890L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultAddr.toRawLongValue(), longSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 224466880022L);
+ longHandle2.set(structSegmt, 446688002244L);
+
+ long result = (long)mh.invoke(668800224466L, structSegmt);
+ Assert.assertEquals(result, 1339955106732L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG, nestedStructLayout);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_1() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_reverseOrder_1() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), longArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray, JAVA_LONG);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG, JAVA_LONG);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_LONG);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 5566778899L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 9900112233L);
+ longHandle2.set(structSegmt2, 3344556677L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 8), 8911335576L);
+ }
+ }
+
+ @Test
+ public void test_add3LongStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ longHandle3.set(structSegmt1, 112233445566L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+ longHandle3.set(structSegmt2, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt), 891132446688L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 8.12F);
+ floatHandle2.set(structSegmt, 9.24F);
+
+ float result = (float)mh.invokeExact(6.56F, structSegmt);
+ Assert.assertEquals(result, 23.92F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ float result = (float)mh.invoke(floatSegmt, structSegmt);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct_returnFloatPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(floatSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultAddr.toRawLongValue(), floatSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 35.11F);
+ floatHandle2.set(structSegmt, 46.22F);
+
+ float result = (float)mh.invoke(79.33F, structSegmt);
+ Assert.assertEquals(result, 160.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_1() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder_1() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT, JAVA_FLOAT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 4), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ floatHandle3.set(structSegmt1, 45.67F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+ floatHandle3.set(structSegmt2, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt), 115.39, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 2228.111D);
+ doubleHandle2.set(structSegmt, 2229.221D);
+
+ double result = (double)mh.invokeExact(3336.333D, structSegmt);
+ Assert.assertEquals(result, 7793.665D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFromStruct_1() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ double result = (double)mh.invokeExact(113.567D, structSegmt);
+ Assert.assertEquals(result, 751.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFromStruct_1() throws Throwable {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ double result = (double)mh.invokeExact(113.567D, structSegmt);
+ Assert.assertEquals(result, 751.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invokeExact(216.666D, structSegmt);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleIntFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19);
+
+ double result = (double)mh.invokeExact(216.666D, structSegmt);
+ Assert.assertEquals(result, 454.221D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 118.456D);
+ doubleHandle2.set(structSegmt, 119.789D);
+
+ double result = (double)mh.invoke(doubleSegmt, structSegmt);
+ Assert.assertEquals(result, 350.368D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 218.456D);
+ doubleHandle2.set(structSegmt, 219.789D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultAddr.toRawLongValue(), doubleSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 22.111D);
+ doubleHandle2.set(structSegmt, 44.222D);
+
+ double result = (double)mh.invoke(66.333D, structSegmt);
+ Assert.assertEquals(result, 132.666D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_DOUBLE.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_reverseOrder_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_withoutLayoutName_1() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_DOUBLE);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_1() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder_1() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_withoutLayoutName_1() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray, JAVA_DOUBLE);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_1() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder_1() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_withoutLayoutName_1() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE, JAVA_DOUBLE);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_DOUBLE);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructPointer_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 8), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add3DoubleStructs_returnStruct_1() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ doubleHandle3.set(structSegmt1, 33.123D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+ doubleHandle3.set(structSegmt2, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests2.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests2.java
new file mode 100644
index 00000000000..32ff55c5b0d
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/downcall/StructTests2.java
@@ -0,0 +1,3100 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for argument/return struct in downcall.
+ *
+ * Note:
+ * [1] the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ *
+ * [2] the test suite is mainly intended for the following Clinker API:
+ * MethodHandle downcallHandle(FunctionDescriptor function)
+ */
+@Test(groups = { "level.sanity" })
+public class StructTests2 {
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithXor_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(functionSymbol, boolSegmt, structSegmt);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, boolSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultAddr.toRawLongValue(), boolSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructPointerWithXor_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructPointerWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, true);
+ boolHandle2.set(structSegmt, false);
+
+ boolean result = (boolean)mh.invoke(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_2() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder_2() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, true, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BOOLEAN,
+ MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+ structSegmt.set(JAVA_BOOLEAN, 3, false);
+ structSegmt.set(JAVA_BOOLEAN, 4, true);
+
+ boolean result = (boolean)mh.invokeExact(functionSymbol, false, structSegmt);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 1), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize()));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ boolHandle3.set(structSegmt1, true);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+ boolHandle3.set(structSegmt2, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)8);
+ byteHandle2.set(structSegmt, (byte)9);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)6, structSegmt);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)14);
+ byteHandle2.set(structSegmt, (byte)16);
+
+ byte result = (byte)mh.invoke(functionSymbol, byteSegmt, structSegmt);
+ Assert.assertEquals(result, 42);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_returnBytePointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct_returnBytePointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)18);
+ byteHandle2.set(structSegmt, (byte)19);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, byteSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.toRawLongValue(), byteSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)11);
+ byteHandle2.set(structSegmt, (byte)12);
+
+ byte result = (byte)mh.invoke(functionSymbol, (byte)13, structSegmt);
+ Assert.assertEquals(result, 36);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)46, structSegmt);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)24);
+ structSegmt.set(JAVA_BYTE, 2, (byte)36);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)48, structSegmt);
+ Assert.assertEquals(result, 120);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)46, structSegmt);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_2() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)14, structSegmt);
+ Assert.assertEquals(result, 50);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrder_2() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)18, structSegmt);
+ Assert.assertEquals(result, 60);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)14, structSegmt);
+ Assert.assertEquals(result, 50);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)16, structSegmt);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+ structSegmt.set(JAVA_BYTE, 3, (byte)18);
+ structSegmt.set(JAVA_BYTE, 4, (byte)20);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)22, structSegmt);
+ Assert.assertEquals(result, 102);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_BYTE,
+ MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invokeExact(functionSymbol, (byte)16, structSegmt);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStruct").get();
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 1), 24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize()));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ byteHandle3.set(structSegmt1, (byte)12);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+ byteHandle3.set(structSegmt2, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt), (byte)28);
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'A');
+ charHandle2.set(structSegmt, 'B');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'C', structSegmt);
+ Assert.assertEquals(result, 'D');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ char result = (char)mh.invoke(functionSymbol, charSegmt, structSegmt);
+ Assert.assertEquals(result, 'M');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_returnCharPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct_returnCharPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, charSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultAddr.toRawLongValue(), charSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'H');
+ charHandle2.set(structSegmt, 'I');
+
+ char result = (char)mh.invoke(functionSymbol, 'G', structSegmt);
+ Assert.assertEquals(result, 'V');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'H', structSegmt);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'H', structSegmt);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_2() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_reverseOrder_2() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = MemoryLayout.structLayout(charArray, JAVA_CHAR, MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'D', structSegmt);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR, JAVA_CHAR);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_CHAR);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invokeExact(functionSymbol, 'J', structSegmt);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 2), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(JAVA_CHAR.bitSize()));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ charHandle3.set(structSegmt1, 'C');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'B');
+ charHandle2.set(structSegmt2, 'C');
+ charHandle3.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt), 'F');
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)8);
+ shortHandle2.set(structSegmt, (short)9);
+ short result = (short)mh.invokeExact(functionSymbol, (short)6, structSegmt);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)18);
+ shortHandle2.set(structSegmt, (short)19);
+
+ short result = (short)mh.invoke(functionSymbol, shortSegmt, structSegmt);
+ Assert.assertEquals(result, 49);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_returnShortPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct_returnShortPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)18);
+ shortHandle2.set(structSegmt, (short)19);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, shortSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 49);
+ Assert.assertEquals(resultAddr.toRawLongValue(), shortSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)22);
+ shortHandle2.set(structSegmt, (short)44);
+
+ short result = (short)mh.invoke(functionSymbol, (short)66, structSegmt);
+ Assert.assertEquals(result, 132);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_SHORT,
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)31);
+ structSegmt.set(JAVA_SHORT, 2, (short)33);
+ structSegmt.set(JAVA_SHORT, 4, (short)35);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)37, structSegmt);
+ Assert.assertEquals(result, 136);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_2() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_reverseOrder_2() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray, JAVA_SHORT, MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)444, structSegmt);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_SHORT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)111);
+ structSegmt.set(JAVA_SHORT, 2, (short)222);
+ structSegmt.set(JAVA_SHORT, 4, (short)333);
+ structSegmt.set(JAVA_SHORT, 6, (short)444);
+ structSegmt.set(JAVA_SHORT, 8, (short)555);
+
+ short result = (short)mh.invokeExact(functionSymbol, (short)666, structSegmt);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)56);
+ shortHandle2.set(structSegmt1, (short)45);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)78);
+ shortHandle2.set(structSegmt2, (short)67);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)134);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)112);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)56);
+ shortHandle2.set(structSegmt1, (short)45);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)78);
+ shortHandle2.set(structSegmt2, (short)67);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 134);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 2), 112);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortStructs_returnStruct").get();
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)25);
+ shortHandle2.set(structSegmt1, (short)26);
+ shortHandle3.set(structSegmt1, (short)27);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)34);
+ shortHandle2.set(structSegmt2, (short)35);
+ shortHandle3.set(structSegmt2, (short)36);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)59);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)61);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt), (short)63);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1122334);
+ intHandle2.set(structSegmt, 1234567);
+
+ int result = (int)mh.invokeExact(functionSymbol, 2244668, structSegmt);
+ Assert.assertEquals(result, 4601569);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntShortFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntShortFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, (short)32766);
+
+ int result = (int)mh.invokeExact(functionSymbol, 22334455, structSegmt);
+ Assert.assertEquals(result, 33590565);
+ }
+ }
+
+ @Test
+ public void test_addIntAndShortIntFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_SHORT.bitSize()), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndShortIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, (short)32766);
+ elemHandle2.set(structSegmt, 22446688);
+
+ int result = (int)mh.invokeExact(functionSymbol, 11335577, structSegmt);
+ Assert.assertEquals(result, 33815031);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 7654321);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1234567);
+ intHandle2.set(structSegmt, 2468024);
+
+ int result = (int)mh.invoke(functionSymbol, intSegmt, structSegmt);
+ Assert.assertEquals(result, 11356912);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_returnIntPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct_returnIntPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 1122333);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 4455666);
+ intHandle2.set(structSegmt, 7788999);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, intSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultAddr.toRawLongValue(), intSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 11121314);
+ intHandle2.set(structSegmt, 15161718);
+
+ int result = (int)mh.invoke(functionSymbol, 19202122, structSegmt);
+ Assert.assertEquals(result, 45485154);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_INT.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(functionSymbol, 33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(functionSymbol, 33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invokeExact(functionSymbol, 33343536, structSegmt);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_2() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(functionSymbol, 4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_reverseOrder_2() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), intArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(functionSymbol, 4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invokeExact(functionSymbol, 4444444, structSegmt);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(functionSymbol, 6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(functionSymbol, 6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT, JAVA_INT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_INT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invokeExact(functionSymbol, 6666666, structSegmt);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 4), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add3IntStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ intHandle3.set(structSegmt1, 99001122);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 33445566);
+ intHandle2.set(structSegmt2, 77889900);
+ intHandle3.set(structSegmt2, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt), 143333333);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 1234567890L);
+ longHandle2.set(structSegmt, 9876543210L);
+ long result = (long)mh.invokeExact(functionSymbol, 2468024680L, structSegmt);
+ Assert.assertEquals(result, 13579135780L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntLongFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntLongFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, 667788990011L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 22446688, structSegmt);
+ Assert.assertEquals(result, 667822660043L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndLongIntFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.bitSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndLongIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 667788990011L);
+ elemHandle2.set(structSegmt, 11223344);
+
+ long result = (long)mh.invokeExact(functionSymbol, 1234567, structSegmt);
+ Assert.assertEquals(result, 667801447922L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 3333333333L);
+ longHandle2.set(structSegmt, 5555555555L);
+
+ long result = (long)mh.invoke(functionSymbol, longSegmt, structSegmt);
+ Assert.assertEquals(result, 9999999999L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_returnLongPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct_returnLongPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 6677889900L);
+ longHandle2.set(structSegmt, 1234567890L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, longSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultAddr.toRawLongValue(), longSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 224466880022L);
+ longHandle2.set(structSegmt, 446688002244L);
+
+ long result = (long)mh.invoke(functionSymbol, 668800224466L, structSegmt);
+ Assert.assertEquals(result, 1339955106732L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG, nestedStructLayout);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 778899001122L, structSegmt);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_2() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_reverseOrder_2() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), longArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray, JAVA_LONG);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 444444444L, structSegmt);
+ Assert.assertEquals(result, 1111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG, JAVA_LONG);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_LONG);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 111111111L);
+ structSegmt.set(JAVA_LONG, 8, 222222222L);
+ structSegmt.set(JAVA_LONG, 16, 333333333L);
+ structSegmt.set(JAVA_LONG, 24, 444444444L);
+ structSegmt.set(JAVA_LONG, 32, 555555555L);
+
+ long result = (long)mh.invokeExact(functionSymbol, 666666666L, structSegmt);
+ Assert.assertEquals(result, 2333333331L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 5566778899L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 9900112233L);
+ longHandle2.set(structSegmt2, 3344556677L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 8), 8911335576L);
+ }
+ }
+
+ @Test
+ public void test_add3LongStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ longHandle3.set(structSegmt1, 112233445566L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+ longHandle3.set(structSegmt2, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt), 891132446688L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 8.12F);
+ floatHandle2.set(structSegmt, 9.24F);
+ float result = (float)mh.invokeExact(functionSymbol, 6.56F, structSegmt);
+ Assert.assertEquals(result, 23.92F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ float result = (float)mh.invoke(functionSymbol, floatSegmt, structSegmt);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct_returnFloatPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, floatSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultAddr.toRawLongValue(), floatSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 35.11F);
+ floatHandle2.set(structSegmt, 46.22F);
+
+ float result = (float)mh.invoke(functionSymbol, 79.33F, structSegmt);
+ Assert.assertEquals(result, 160.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 37.88F, structSegmt);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_2() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder_2() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 444.44F, structSegmt);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT, JAVA_FLOAT);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_FLOAT);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invokeExact(functionSymbol, 666.66F, structSegmt);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 4), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ floatHandle3.set(structSegmt1, 45.67F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+ floatHandle3.set(structSegmt2, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt), 115.39, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 2228.111D);
+ doubleHandle2.set(structSegmt, 2229.221D);
+ double result = (double)mh.invokeExact(functionSymbol, 3336.333D, structSegmt);
+ Assert.assertEquals(result, 7793.665D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFromStruct_2() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
+ Assert.assertEquals(result, 751.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFromStruct_2() throws Throwable {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.bitSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ double result = (double)mh.invokeExact(functionSymbol, 113.567D, structSegmt);
+ Assert.assertEquals(result, 751.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invokeExact(functionSymbol, 216.666D, structSegmt);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleIntFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19);
+
+ double result = (double)mh.invokeExact(functionSymbol, 216.666D, structSegmt);
+ Assert.assertEquals(result, 454.221D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 118.456D);
+ doubleHandle2.set(structSegmt, 119.789D);
+
+ double result = (double)mh.invoke(functionSymbol, doubleSegmt, structSegmt);
+ Assert.assertEquals(result, 350.368D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 218.456D);
+ doubleHandle2.set(structSegmt, 219.789D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, doubleSegmt, structSegmt);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultAddr.toRawLongValue(), doubleSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 22.111D);
+ doubleHandle2.set(structSegmt, 44.222D);
+
+ double result = (double)mh.invoke(functionSymbol, 66.333D, structSegmt);
+ Assert.assertEquals(result, 132.666D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_DOUBLE.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_reverseOrder_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_withoutLayoutName_2() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout, JAVA_DOUBLE);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 37.864D, structSegmt);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_2() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder_2() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_withoutLayoutName_2() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray, JAVA_DOUBLE);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 444.444D, structSegmt);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_2() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder_2() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_withoutLayoutName_2() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE, JAVA_DOUBLE);
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray, JAVA_DOUBLE);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invokeExact(functionSymbol, 666.666D, structSegmt);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructPointer_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 8), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add3DoubleStructs_returnStruct_2() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ doubleHandle3.set(structSegmt1, 33.123D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+ doubleHandle3.set(structSegmt2, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, allocator, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallMHTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallMHTests.java
new file mode 100644
index 00000000000..1cf7193145b
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallMHTests.java
@@ -0,0 +1,560 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) intended for
+ * the situations when the multiple primitive specific upcalls happen within
+ * the same memory session or from different memory sessions.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallMHTests {
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr1);
+ Assert.assertEquals(result, true);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ result = (boolean)mh.invoke(true, false, upcallFuncAddr2);
+ Assert.assertEquals(result, true);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ result = (boolean)mh.invoke(true, false, upcallFuncAddr3);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ MemorySegment charSegmt1 = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt1, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ MemorySegment charSegmt2 = allocator.allocate(JAVA_CHAR, 'B');
+ result = (char)mh.invoke(charSegmt2, 'D', upcallFuncAddr2);
+ Assert.assertEquals(result, 'C');
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ MemorySegment charSegmt3 = allocator.allocate(JAVA_CHAR, 'B');
+ result = (char)mh.invoke(charSegmt3, 'D', upcallFuncAddr3);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr1);
+ Assert.assertEquals(result, (byte)88);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ result = (byte)mh.invoke((byte)33, upcallFuncAddr2);
+ Assert.assertEquals(result, (byte)88);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ result = (byte)mh.invoke((byte)33, upcallFuncAddr3);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ MemorySegment shortSegmt1 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invoke(shortSegmt1, (short)555, upcallFuncAddr1);
+ Assert.assertEquals(resultAddr1.get(JAVA_SHORT, 0), (short)999);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ MemorySegment shortSegmt2 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invoke(shortSegmt2, (short)555, upcallFuncAddr2);
+ Assert.assertEquals(resultAddr2.get(JAVA_SHORT, 0), (short)999);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ MemorySegment shortSegmt3 = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invoke(shortSegmt3, (short)555, upcallFuncAddr3);
+ Assert.assertEquals(resultAddr3.get(JAVA_SHORT, 0), (short)999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), (short)999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr1);
+ Assert.assertEquals(result, 222235);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ result = (int)mh.invoke(111112, 111123, upcallFuncAddr2);
+ Assert.assertEquals(result, 222235);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ result = (int)mh.invoke(111112, 111123, upcallFuncAddr3);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr1);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr2);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr3);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt1, 6666698235L, upcallFuncAddr1);
+ Assert.assertEquals(result, 12409155659L);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 5742457424L);
+ result = (long)mh.invoke(longSegmt2, 6666698235L, upcallFuncAddr2);
+ Assert.assertEquals(result, 12409155659L);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 5742457424L);
+ result = (long)mh.invoke(longSegmt3, 6666698235L, upcallFuncAddr3);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr1);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ result = (float)mh.invoke(5.74F, upcallFuncAddr2);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ result = (float)mh.invoke(5.74F, upcallFuncAddr3);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_SameSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr1 = (MemoryAddress)mh.invoke(doubleSegmt1, 1262.795D, upcallFuncAddr1);
+ Assert.assertEquals(resultAddr1.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr2 = (MemoryAddress)mh.invoke(doubleSegmt2, 1262.795D, upcallFuncAddr2);
+ Assert.assertEquals(resultAddr2.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr3 = (MemoryAddress)mh.invoke(doubleSegmt3, 1262.795D, upcallFuncAddr3);
+ Assert.assertEquals(resultAddr3.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH_DiffSession() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests1.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests1.java
new file mode 100644
index 00000000000..2cd1f6050d2
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests1.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within different memory sessions, in which case the upcall
+ * metadata and the generated thunk are allocated separately.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests1 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithDiffSessions() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests2.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests2.java
new file mode 100644
index 00000000000..530346a3a3f
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/MultiUpcallThrdsMHTests2.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within the same memory session, in which case the upcall
+ * metadata and the generated thunk are only allocated once and shared among
+ * these threads.
+ */
+@Test(groups = { "level.sanity" })
+public class MultiUpcallThrdsMHTests2 implements Thread.UncaughtExceptionHandler {
+ private volatile Throwable initException;
+ private static Linker linker = Linker.nativeLinker();
+ private static MemorySession session = MemorySession.openImplicit();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(enabled=false)
+ @Override
+ public void uncaughtException(Thread thr, Throwable t) {
+ initException = t;
+ }
+
+ @Test
+ public void test_multiUpcallThrdsWithSameSession() throws Throwable {
+ Thread thr1 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr1.setUncaughtExceptionHandler(this);
+ thr1.start();
+
+ Thread thr2 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111113, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 222237);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr2.setUncaughtExceptionHandler(this);
+ thr2.start();
+
+ Thread thr3 = new Thread(){
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111114, 111125, upcallFuncAddr);
+ Assert.assertEquals(result, 222239);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+ thr3.setUncaughtExceptionHandler(this);
+ thr3.start();
+
+ thr1.join();
+ thr2.join();
+ thr3.join();
+
+ if (initException != null){
+ throw new RuntimeException(initException);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithMixedSigStruTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithMixedSigStruTests.java
new file mode 100644
index 00000000000..d23af321b2b
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithMixedSigStruTests.java
@@ -0,0 +1,892 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for the mixed native signatures
+ * in argument/return struct in upcall, which are not covered in UpcallMHWithStructTests and
+ * specially designed to validate the native signature types required in the genenerated thunk.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithMixedSigStruTests {
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addIntAndIntShortFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntShortFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntShortFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, (short)32766);
+
+ int result = (int)mh.invoke(22334455, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33590565);
+ }
+ }
+
+ @Test
+ public void test_addIntAndShortIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndShortIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndShortIntFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, (short)32766);
+ elemHandle2.set(structSegmt, 22446688);
+
+ int result = (int)mh.invoke(11335577, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 33815031);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11223344);
+ elemHandle2.set(structSegmt, 667788990011L);
+
+ long result = (long)mh.invoke(22446688, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667822660043L);
+ }
+ }
+
+ @Test
+ public void test_addIntAndLongIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndLongIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndLongIntFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 667788990011L);
+ elemHandle2.set(structSegmt, 11223344);
+
+ long result = (long)mh.invoke(1234567, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 667801447922L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111844.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 111111111);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111546.221D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 18.444F);
+ elemHandle2.set(structSegmt, 619.777D);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 751.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ public static void test_addDoubleAndDoubleFloatPlusPaddingFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(32));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 218.555D);
+ elemHandle2.set(structSegmt, 19.22F);
+
+ double result = (double)mh.invoke(216.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 454.441D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAnd2FloatsDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAnd2FloatsDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAnd2FloatsDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDouble2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDouble2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDouble2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ double result = (double)mh.invoke(111.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 478.105D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndInt2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invoke(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 111111);
+ elemHandle3.set(structSegmt, 22.33F);
+
+ float result = (float)mh.invoke(55.567F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111200.12F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntFloatDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatIntDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_INT.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22.33F);
+ elemHandle2.set(structSegmt, 111111111);
+ elemHandle3.set(structSegmt, 333.444D);
+
+ double result = (double)mh.invoke(555.55D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.324D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndLongDoubleFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndLongDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndLongDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 22222222222222L);
+ elemHandle2.set(structSegmt, 33333.444D);
+
+ double result = (double)mh.invoke(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 22222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndInt3FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), JAVA_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndInt3FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt3FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 77777777);
+ elemHandle2.set(structSegmt, 11.22F);
+ elemHandle3.set(structSegmt, 22.33F);
+ elemHandle4.set(structSegmt, 44.55F);
+
+ float result = (float)mh.invoke(66.678F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.778F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLong2FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLong2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLong2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 777777777777L);
+ elemHandle2.set(structSegmt, 11.25F);
+ elemHandle3.set(structSegmt, 22.75F);
+
+ long result = (long)mh.invoke(555555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1333333333365L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd3FloatsIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), JAVA_INT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAnd3FloatsIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAnd3FloatsIntFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.22F);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 44.55F);
+ elemHandle4.set(structSegmt, 77777777);
+
+ float result = (float)mh.invoke(66.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 77777921.556F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addLongAndFloatLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndFloatLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndFloatLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 55.11F);
+ elemHandle2.set(structSegmt, 150000000000L);
+
+ long result = (long)mh.invoke(5555555555L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 155555555610L);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFloatIntFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFloatIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 333.444D);
+ elemHandle2.set(structSegmt, 22.33F);
+ elemHandle3.set(structSegmt, 111111111);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111112022.341D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33333.444D);
+ elemHandle2.set(structSegmt, 222222222222L);
+
+ double result = (double)mh.invoke(55555.111D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 222222311110.555D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addLongAnd2FloatsLongFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAnd2FloatsLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAnd2FloatsLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.11F);
+ elemHandle2.set(structSegmt, 22.11F);
+ elemHandle3.set(structSegmt, 4444444444L);
+
+ long result = (long)mh.invoke(11111111111L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15555555588L);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd3ShortsCharFromStructByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(3, JAVA_SHORT);
+ GroupLayout structLayout = MemoryLayout.structLayout(shortArray, JAVA_CHAR);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAnd3ShortsCharFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAnd3ShortsCharFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1000);
+ structSegmt.set(JAVA_SHORT, 2, (short)2000);
+ structSegmt.set(JAVA_SHORT, 4, (short)3000);
+ structSegmt.set(JAVA_CHAR, 6, 'A');
+
+ short result = (short)mh.invoke((short)4000, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 10065);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndIntFloatIntFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_INT.withName("elem3"), JAVA_FLOAT.withName("elem4"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndIntFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndIntFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 555555555);
+ elemHandle2.set(structSegmt, 11.222F);
+ elemHandle3.set(structSegmt, 666666666);
+ elemHandle4.set(structSegmt, 33.444F);
+
+ float result = (float)mh.invoke(77.456F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1222222343.122F, 0.001F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleFloatFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32), JAVA_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"),
+ JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 7777);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32), JAVA_INT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"),
+ JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 33.444F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 8584.566D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleIntFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32), JAVA_INT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"),
+ JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 6666);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 7777);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15217.122D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndFloatDoubleFloatFromStructByUpcallMH() throws Throwable {
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32), JAVA_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"),
+ JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndFloatDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 11.222F);
+ elemHandle2.set(structSegmt, 218.555D);
+ elemHandle3.set(structSegmt, 33.444F);
+
+ double result = (double)mh.invoke(555.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 818.788D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndIntDoubleLongFromStructByUpcallMH() throws Throwable {
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32), JAVA_LONG.withName("elem3").withBitAlignment(32))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"), MemoryLayout.paddingLayout(32),
+ JAVA_DOUBLE.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndIntDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt, 111111111);
+ elemHandle2.set(structSegmt, 619.777D);
+ elemHandle3.set(structSegmt, 888888888888L);
+
+ double result = (double)mh.invoke(113.567D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 889000000732.344D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_return254BytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("return254BytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_return254BytesFromStruct,
+ FunctionDescriptor.of(structLayout), session);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(allocator, upcallFuncAddr);
+ for (int i = 0; i < 254; i++) {
+ Assert.assertEquals(byteArrStruSegment.get(JAVA_BYTE, i), (byte)i);
+ }
+ }
+ }
+
+ @Test
+ public void test_return4KBytesFromStructByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("return4KBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_return4KBytesFromStruct,
+ FunctionDescriptor.of(structLayout), session);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke(allocator, upcallFuncAddr);
+ for (int i = 0; i < 4096; i++) {
+ Assert.assertEquals(byteArrStruSegment.get(JAVA_BYTE, i), (byte)i);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithPrimTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithPrimTests.java
new file mode 100644
index 00000000000..bf41a92f4bd
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithPrimTests.java
@@ -0,0 +1,724 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for primitive types in upcall.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithPrimTests {
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = linker.defaultLookup();
+
+ @Test
+ public void test_addTwoBoolsWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), session);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPointerWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPointerWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), session);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ boolean result = (boolean)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromNativePtrWithOrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromNativePtrWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), session);
+ boolean result = (boolean)mh.invoke(false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), session);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), session);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBytesByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BytesByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Bytes,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE), session);
+ byte result = (byte)mh.invoke((byte)6, (byte)3, upcallFuncAddr);
+ Assert.assertEquals(result, 9);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)7);
+ byte result = (byte)mh.invoke((byte)8, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 15);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, 88);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)35);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFrom2CharsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFrom2CharsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFrom2Chars,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR), session);
+ char result = (char)mh.invoke('B', 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), session);
+ char result = (char)mh.invoke('D', upcallFuncAddr);
+ Assert.assertEquals(result, 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'B');
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_addTwoShortsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Shorts,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT), session);
+ short result = (short)mh.invoke((short)1111, (short)2222, upcallFuncAddr);
+ Assert.assertEquals(result, 3333);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)2222);
+ short result = (short)mh.invoke(shortSegmt, (short)3333, upcallFuncAddr);
+ Assert.assertEquals(result, 5555);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), session);
+ short result = (short)mh.invoke((short)789, upcallFuncAddr);
+ Assert.assertEquals(result, 1245);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)444);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ int result = (int)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+ int result = (int)mh.invoke(222222, upcallFuncAddr);
+ Assert.assertEquals(result, 666666);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 222215);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 555536);
+ }
+ }
+
+ @Test
+ public void test_add3IntsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT), session);
+ int result = (int)mh.invoke(111112, 111123, 111124, upcallFuncAddr);
+ Assert.assertEquals(result, 333359);
+ }
+ }
+
+ @Test
+ public void test_addIntAndCharByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndCharByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndChar,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR), session);
+ int result = (int)mh.invoke(555558, 'A', upcallFuncAddr);
+ Assert.assertEquals(result, 555623);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), session);
+ mh.invoke(44454, 333398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addTwoLongsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Longs,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG), session);
+ long result = (long)mh.invoke(333333222222L, 111111555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 444444777777L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), session);
+ long result = (long)mh.invoke(5555555555L, upcallFuncAddr);
+ Assert.assertEquals(result, 8888888888L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 5742457424L);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addTwoFloatsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Floats,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT), session);
+ float result = (float)mh.invoke(15.74F, 16.79F, upcallFuncAddr);
+ Assert.assertEquals(result, 32.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ float result = (float)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 6.79F);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 12.53F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2DoublesByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoublesByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Doubles,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE), session);
+ double result = (double)mh.invoke(159.748D, 262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPointerByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ double result = (double)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromNativePtrByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), session);
+ double result = (double)mh.invoke(1262.795D, upcallFuncAddr);
+ Assert.assertEquals(result, 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoubleFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 1159.748D);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_qsortByUpcallMH() throws Throwable {
+ int expectedArray[] = {11, 12, 13, 14, 15, 16, 17};
+ int expectedArrayLength = expectedArray.length;
+
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(ADDRESS, JAVA_INT, JAVA_INT, ADDRESS);
+ Addressable functionSymbol = defaultLibLookup.lookup("qsort").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_compare,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment arraySegmt = allocator.allocateArray(JAVA_INT, new int[]{17, 14, 13, 16, 15, 12, 11});
+ mh.invoke(arraySegmt, 7, 4, upcallFuncAddr);
+ int[] sortedArray = arraySegmt.toArray(JAVA_INT);
+ for (int index = 0; index < expectedArrayLength; index++) {
+ Assert.assertEquals(sortedArray[index], expectedArray[index]);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithStructTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithStructTests.java
new file mode 100644
index 00000000000..00d94aec007
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMHWithStructTests.java
@@ -0,0 +1,2886 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for argument/return struct in upcall.
+ *
+ * Note: the padding elements in the struct are only required by RI or VarHandle (accessing the
+ * data address) while they are totally ignored in OpenJ9 given the padding/alignment are
+ * computed by libffi automatically in native.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallMHWithStructTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ /* The padding of struct is not required on Linux/s390x and Windows/x64 */
+ private static boolean isStructPaddingNotRequired = osName.contains("win") && (arch.equals("amd64") || arch.equals("x86_64"))
+ || osName.contains("linux") && arch.equals("s390x");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAnd20BoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN,
+ JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN
+ );
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAnd20BoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAnd20BoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+ structSegmt.set(JAVA_BOOLEAN, 5, true);
+ structSegmt.set(JAVA_BOOLEAN, 6, false);
+ structSegmt.set(JAVA_BOOLEAN, 7, true);
+ structSegmt.set(JAVA_BOOLEAN, 8, false);
+ structSegmt.set(JAVA_BOOLEAN, 9, true);
+ structSegmt.set(JAVA_BOOLEAN, 10, false);
+ structSegmt.set(JAVA_BOOLEAN, 11, true);
+ structSegmt.set(JAVA_BOOLEAN, 12, false);
+ structSegmt.set(JAVA_BOOLEAN, 13, true);
+ structSegmt.set(JAVA_BOOLEAN, 14, false);
+ structSegmt.set(JAVA_BOOLEAN, 15, true);
+ structSegmt.set(JAVA_BOOLEAN, 16, false);
+ structSegmt.set(JAVA_BOOLEAN, 17, true);
+ structSegmt.set(JAVA_BOOLEAN, 18, false);
+ structSegmt.set(JAVA_BOOLEAN, 19, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout), session);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, false);
+ boolHandle2.set(structSegmt, true);
+
+ boolean result = (boolean)mh.invoke(boolSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, false);
+ }
+ }
+
+ @Test
+ public void test_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN, JAVA_BOOLEAN);
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ MemorySegment boolSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(boolSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultAddr.toRawLongValue(), boolSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructPointerWithXorByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructPointerWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructPointerWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt, true);
+ boolHandle2.set(structSegmt, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXorByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, true);
+ structSegmt.set(JAVA_BOOLEAN, 1, false);
+ structSegmt.set(JAVA_BOOLEAN, 2, true);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(boolArray.withName("array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout boolArray = MemoryLayout.sequenceLayout(2, JAVA_BOOLEAN);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ boolArray.withName("array_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+
+ boolean result = (boolean)mh.invoke(false, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BOOLEAN.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout boolStruct = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, boolStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BOOLEAN.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+ structSegmt.set(JAVA_BOOLEAN, 2, false);
+ structSegmt.set(JAVA_BOOLEAN, 3, true);
+ structSegmt.set(JAVA_BOOLEAN, 4, false);
+
+ boolean result = (boolean)mh.invoke(true, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_add2BoolStructsWithXor_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BoolStructsWithXor_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultAddr.get(JAVA_BOOLEAN, 1), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3")) : MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"),
+ JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle boolHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle boolHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle boolHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt1, true);
+ boolHandle2.set(structSegmt1, false);
+ boolHandle3.set(structSegmt1, true);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ boolHandle1.set(structSegmt2, true);
+ boolHandle2.set(structSegmt2, true);
+ boolHandle3.set(structSegmt2, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt), true);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)8);
+ byteHandle2.set(structSegmt, (byte)9);
+
+ byte result = (byte)mh.invoke((byte)6, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23);
+ }
+ }
+
+ @Test
+ public void test_addByteAnd20BytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE,
+ JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, JAVA_BYTE
+ );
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAnd20BytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAnd20BytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)1);
+ structSegmt.set(JAVA_BYTE, 1, (byte)2);
+ structSegmt.set(JAVA_BYTE, 2, (byte)3);
+ structSegmt.set(JAVA_BYTE, 3, (byte)4);
+ structSegmt.set(JAVA_BYTE, 4, (byte)5);
+ structSegmt.set(JAVA_BYTE, 5, (byte)6);
+ structSegmt.set(JAVA_BYTE, 6, (byte)7);
+ structSegmt.set(JAVA_BYTE, 7, (byte)8);
+ structSegmt.set(JAVA_BYTE, 8, (byte)9);
+ structSegmt.set(JAVA_BYTE, 9, (byte)10);
+ structSegmt.set(JAVA_BYTE, 10, (byte)1);
+ structSegmt.set(JAVA_BYTE, 11, (byte)2);
+ structSegmt.set(JAVA_BYTE, 12, (byte)3);
+ structSegmt.set(JAVA_BYTE, 13, (byte)4);
+ structSegmt.set(JAVA_BYTE, 14, (byte)5);
+ structSegmt.set(JAVA_BYTE, 15, (byte)6);
+ structSegmt.set(JAVA_BYTE, 16, (byte)7);
+ structSegmt.set(JAVA_BYTE, 17, (byte)8);
+ structSegmt.set(JAVA_BYTE, 18, (byte)9);
+ structSegmt.set(JAVA_BYTE, 19, (byte)10);
+
+ byte result = (byte)mh.invoke((byte)11, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 121);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)18);
+ byteHandle2.set(structSegmt, (byte)19);
+
+ byte result = (byte)mh.invoke(byteSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49);
+ }
+ }
+
+ @Test
+ public void test_addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct_returnBytePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment byteSegmt = allocator.allocate(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)14);
+ byteHandle2.set(structSegmt, (byte)16);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(byteSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 42);
+ Assert.assertEquals(resultAddr.toRawLongValue(), byteSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt, (byte)11);
+ byteHandle2.set(structSegmt, (byte)12);
+ byte result = (byte)mh.invoke((byte)13, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 36);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invoke((byte)46, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 112);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)24);
+ structSegmt.set(JAVA_BYTE, 2, (byte)36);
+
+ byte result = (byte)mh.invoke((byte)48, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 120);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArrayByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(byteArray.withName("array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)22);
+ structSegmt.set(JAVA_BYTE, 2, (byte)33);
+
+ byte result = (byte)mh.invoke((byte)14, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 80);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(2, JAVA_BYTE);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ byteArray.withName("array_elem2"), MemoryLayout.paddingLayout(8));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+
+ byte result = (byte)mh.invoke((byte)18, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 60);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2")) : MemoryLayout.structLayout(structArray.withName("struct_array_elem1"),
+ JAVA_BYTE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)11);
+ structSegmt.set(JAVA_BYTE, 1, (byte)12);
+ structSegmt.set(JAVA_BYTE, 2, (byte)13);
+ structSegmt.set(JAVA_BYTE, 3, (byte)14);
+ structSegmt.set(JAVA_BYTE, 4, (byte)15);
+
+ byte result = (byte)mh.invoke((byte)16, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 81);
+ }
+ }
+
+ @Test
+ public void test_addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout byteStruct = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, byteStruct);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(JAVA_BYTE.bitSize() * 3));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_BYTE, 0, (byte)12);
+ structSegmt.set(JAVA_BYTE, 1, (byte)14);
+ structSegmt.set(JAVA_BYTE, 2, (byte)16);
+ structSegmt.set(JAVA_BYTE, 3, (byte)18);
+ structSegmt.set(JAVA_BYTE, 4, (byte)20);
+
+ byte result = (byte)mh.invoke((byte)22, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 102);
+ }
+ }
+
+ @Test
+ public void test_add1ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add1ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ }
+ }
+
+ @Test
+ public void test_add2ByteStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ByteStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultAddr.get(JAVA_BYTE, 1), 24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3")) : MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(8));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)25);
+ byteHandle2.set(structSegmt1, (byte)11);
+ byteHandle3.set(structSegmt1, (byte)12);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)24);
+ byteHandle2.set(structSegmt2, (byte)13);
+ byteHandle3.set(structSegmt2, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt), (byte)28);
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'A');
+ charHandle2.set(structSegmt, 'B');
+
+ char result = (char)mh.invoke('C', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'D');
+ }
+ }
+
+ @Test
+ public void test_addCharAnd10CharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR,
+ JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, JAVA_CHAR);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAnd10CharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAnd10CharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'A');
+ structSegmt.set(JAVA_CHAR, 4, 'B');
+ structSegmt.set(JAVA_CHAR, 6, 'B');
+ structSegmt.set(JAVA_CHAR, 8, 'C');
+ structSegmt.set(JAVA_CHAR, 10, 'C');
+ structSegmt.set(JAVA_CHAR, 12, 'D');
+ structSegmt.set(JAVA_CHAR, 14, 'D');
+ structSegmt.set(JAVA_CHAR, 16, 'E');
+ structSegmt.set(JAVA_CHAR, 18, 'E');
+
+ char result = (char)mh.invoke('A', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'U');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ char result = (char)mh.invoke(charSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'M');
+ }
+ }
+
+ @Test
+ public void test_addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct_returnCharPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment charSegmt = allocator.allocate(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'E');
+ charHandle2.set(structSegmt, 'F');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(charSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultAddr.toRawLongValue(), charSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructPointer,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt, 'H');
+ charHandle2.set(structSegmt, 'I');
+
+ char result = (char)mh.invoke('G', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'V');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invoke('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+
+ char result = (char)mh.invoke('H', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'W');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArrayByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2")) : MemoryLayout.structLayout(charArray.withName("array_elem1"),
+ JAVA_CHAR.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invoke('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout charArray = MemoryLayout.sequenceLayout(2, JAVA_CHAR);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ charArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'A');
+ structSegmt.set(JAVA_CHAR, 2, 'B');
+ structSegmt.set(JAVA_CHAR, 4, 'C');
+
+ char result = (char)mh.invoke('D', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'G');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invoke('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout charStruct = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, charStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ structArray.withName("struct_array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_CHAR, 0, 'E');
+ structSegmt.set(JAVA_CHAR, 2, 'F');
+ structSegmt.set(JAVA_CHAR, 4, 'G');
+ structSegmt.set(JAVA_CHAR, 6, 'H');
+ structSegmt.set(JAVA_CHAR, 8, 'I');
+
+ char result = (char)mh.invoke('J', structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 'h');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'E');
+ }
+ }
+
+ @Test
+ public void test_add2CharStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2CharStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'C');
+ charHandle2.set(structSegmt2, 'D');
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultAddr.get(JAVA_CHAR, 2), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3")) : MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle charHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle charHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle charHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt1, 'A');
+ charHandle2.set(structSegmt1, 'B');
+ charHandle3.set(structSegmt1, 'C');
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ charHandle1.set(structSegmt2, 'B');
+ charHandle2.set(structSegmt2, 'C');
+ charHandle3.set(structSegmt2, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt), 'F');
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)888);
+ shortHandle2.set(structSegmt, (short)999);
+
+ short result = (short)mh.invoke((short)777, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2664);
+ }
+ }
+
+ @Test
+ public void test_addShortAnd10ShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT,
+ JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, JAVA_SHORT);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAnd10ShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAnd10ShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)10);
+ structSegmt.set(JAVA_SHORT, 2, (short)20);
+ structSegmt.set(JAVA_SHORT, 4, (short)30);
+ structSegmt.set(JAVA_SHORT, 6, (short)40);
+ structSegmt.set(JAVA_SHORT, 8, (short)50);
+ structSegmt.set(JAVA_SHORT, 10, (short)60);
+ structSegmt.set(JAVA_SHORT, 12, (short)70);
+ structSegmt.set(JAVA_SHORT, 14, (short)80);
+ structSegmt.set(JAVA_SHORT, 16, (short)90);
+ structSegmt.set(JAVA_SHORT, 18, (short)100);
+
+ short result = (short)mh.invoke((short)110, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 660);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ short result = (short)mh.invoke(shortSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 3349);
+ }
+ }
+
+ @Test
+ public void test_addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct_returnShortPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment shortSegmt = allocator.allocate(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)1118);
+ shortHandle2.set(structSegmt, (short)1119);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(shortSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 3349);
+ Assert.assertEquals(resultAddr.toRawLongValue(), shortSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructPointer,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt, (short)2222);
+ shortHandle2.set(structSegmt, (short)4444);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 13332);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2")) : MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)331);
+ structSegmt.set(JAVA_SHORT, 2, (short)333);
+ structSegmt.set(JAVA_SHORT, 4, (short)335);
+
+ short result = (short)mh.invoke((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ nestedStructLayout.withName("struct_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)331);
+ structSegmt.set(JAVA_SHORT, 2, (short)333);
+ structSegmt.set(JAVA_SHORT, 4, (short)335);
+
+ short result = (short)mh.invoke((short)337, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1336);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArrayByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2")) : MemoryLayout.structLayout(shortArray.withName("array_elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+
+ short result = (short)mh.invoke((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout shortArray = MemoryLayout.sequenceLayout(2, JAVA_SHORT);
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ shortArray.withName("array_elem2"), MemoryLayout.paddingLayout(16));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+
+ short result = (short)mh.invoke((short)4444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11110);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struc_array_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+ structSegmt.set(JAVA_SHORT, 6, (short)4444);
+ structSegmt.set(JAVA_SHORT, 8, (short)5555);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout shortStruct = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, shortStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), structArray.withName("struc_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_SHORT, 0, (short)1111);
+ structSegmt.set(JAVA_SHORT, 2, (short)2222);
+ structSegmt.set(JAVA_SHORT, 4, (short)3333);
+ structSegmt.set(JAVA_SHORT, 6, (short)4444);
+ structSegmt.set(JAVA_SHORT, 8, (short)5555);
+
+ short result = (short)mh.invoke((short)6666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23331);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)734);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)712);
+ }
+ }
+
+ @Test
+ public void test_add2ShortStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)356);
+ shortHandle2.set(structSegmt1, (short)345);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)378);
+ shortHandle2.set(structSegmt2, (short)367);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 0), 734);
+ Assert.assertEquals(resultAddr.get(JAVA_SHORT, 2), 712);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3")) : MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)325);
+ shortHandle2.set(structSegmt1, (short)326);
+ shortHandle3.set(structSegmt1, (short)327);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)334);
+ shortHandle2.set(structSegmt2, (short)335);
+ shortHandle3.set(structSegmt2, (short)336);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt), (short)659);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt), (short)661);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt), (short)663);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1122334);
+ intHandle2.set(structSegmt, 1234567);
+
+ int result = (int)mh.invoke(2244668, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 4601569);
+ }
+ }
+
+ @Test
+ public void test_addIntAnd5IntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"),
+ JAVA_INT.withName("elem3"), JAVA_INT.withName("elem4"), JAVA_INT.withName("elem5"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle intHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle intHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAnd5IntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAnd5IntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1111111);
+ intHandle2.set(structSegmt, 2222222);
+ intHandle3.set(structSegmt, 3333333);
+ intHandle4.set(structSegmt, 2222222);
+ intHandle5.set(structSegmt, 1111111);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 14444443);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 7654321);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 1234567);
+ intHandle2.set(structSegmt, 2468024);
+
+ int result = (int)mh.invoke(intSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11356912);
+ }
+ }
+
+ @Test
+ public void test_addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct_returnIntPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt = allocator.allocate(JAVA_INT, 1122333);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 4455666);
+ intHandle2.set(structSegmt, 7788999);
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(intSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultAddr.toRawLongValue(), intSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt, 11121314);
+ intHandle2.set(structSegmt, 15161718);
+
+ int result = (int)mh.invoke(19202122, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 45485154);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_INT.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invoke(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 21222324);
+ structSegmt.set(JAVA_INT, 4, 25262728);
+ structSegmt.set(JAVA_INT, 8, 29303132);
+
+ int result = (int)mh.invoke(33343536, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 109131720);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArrayByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(intArray.withName("array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout intArray = MemoryLayout.sequenceLayout(2, JAVA_INT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), intArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+
+ int result = (int)mh.invoke(4444444, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 11111110);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invoke(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout intStruct = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, intStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_INT, 0, 1111111);
+ structSegmt.set(JAVA_INT, 4, 2222222);
+ structSegmt.set(JAVA_INT, 8, 3333333);
+ structSegmt.set(JAVA_INT, 12, 4444444);
+ structSegmt.set(JAVA_INT, 16, 5555555);
+
+ int result = (int)mh.invoke(6666666, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23333331);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add2IntStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 99001122);
+ intHandle2.set(structSegmt2, 33445566);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 4), 89113354);
+ }
+ }
+
+ @Test
+ public void test_add3IntStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 11223344);
+ intHandle2.set(structSegmt1, 55667788);
+ intHandle3.set(structSegmt1, 99001122);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 33445566);
+ intHandle2.set(structSegmt2, 77889900);
+ intHandle3.set(structSegmt2, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt), 143333333);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 1234567890L);
+ longHandle2.set(structSegmt, 9876543210L);
+
+ long result = (long)mh.invoke(2468024680L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 13579135780L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 3333333333L);
+ longHandle2.set(structSegmt, 5555555555L);
+
+ long result = (long)mh.invoke(longSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 9999999999L);
+ }
+ }
+
+ @Test
+ public void test_addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct_returnLongPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt = allocator.allocate(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 6677889900L);
+ longHandle2.set(structSegmt, 1234567890L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(longSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultAddr.toRawLongValue(), longSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructPointer,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt, 224466880022L);
+ longHandle2.set(structSegmt, 446688002244L);
+
+ long result = (long)mh.invoke(668800224466L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1339955106732L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invoke(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 135791357913L);
+ structSegmt.set(JAVA_LONG, 8, 246802468024L);
+ structSegmt.set(JAVA_LONG, 16,112233445566L);
+
+ long result = (long)mh.invoke(778899001122L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1273726272625L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArrayByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(longArray.withName("array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+
+ long result = (long)mh.invoke(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout longArray = MemoryLayout.sequenceLayout(2, JAVA_LONG);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), longArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+
+ long result = (long)mh.invoke(44444444444L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 111111111110L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_LONG.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+ structSegmt.set(JAVA_LONG, 24, 44444444444L);
+ structSegmt.set(JAVA_LONG, 32, 55555555555L);
+
+ long result = (long)mh.invoke(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout longStruct = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, longStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_LONG, 0, 11111111111L);
+ structSegmt.set(JAVA_LONG, 8, 22222222222L);
+ structSegmt.set(JAVA_LONG, 16, 33333333333L);
+ structSegmt.set(JAVA_LONG, 24, 44444444444L);
+ structSegmt.set(JAVA_LONG, 32, 55555555555L);
+
+ long result = (long)mh.invoke(66666666666L, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 233333333331L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ }
+ }
+
+ @Test
+ public void test_add2LongStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 5566778899L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 9900112233L);
+ longHandle2.set(structSegmt2, 3344556677L);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 8), 8911335576L);
+ }
+ }
+
+ @Test
+ public void test_add3LongStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle longHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 987654321987L);
+ longHandle2.set(structSegmt1, 123456789123L);
+ longHandle3.set(structSegmt1, 112233445566L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 224466880022L);
+ longHandle2.set(structSegmt2, 113355779911L);
+ longHandle3.set(structSegmt2, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt), 891132446688L);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 8.12F);
+ floatHandle2.set(structSegmt, 9.24F);
+
+ float result = (float)mh.invoke(6.56F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 23.92F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAnd5FloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"),
+ JAVA_FLOAT.withName("elem3"), JAVA_FLOAT.withName("elem4"), JAVA_FLOAT.withName("elem5"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle floatHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle floatHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAnd5FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAnd5FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 1.01F);
+ floatHandle2.set(structSegmt, 1.02F);
+ floatHandle3.set(structSegmt, 1.03F);
+ floatHandle4.set(structSegmt, 1.04F);
+ floatHandle5.set(structSegmt, 1.05F);
+
+ float result = (float)mh.invoke(1.06F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 6.21F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ float result = (float)mh.invoke(floatSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 49.69F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment floatSegmt = allocator.allocate(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 18.23F);
+ floatHandle2.set(structSegmt, 19.34F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(floatSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultAddr.toRawLongValue(), floatSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt, 35.11F);
+ floatHandle2.set(structSegmt, 46.22F);
+
+ float result = (float)mh.invoke(79.33F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 160.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invoke(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 31.22F);
+ structSegmt.set(JAVA_FLOAT, 4, 33.44F);
+ structSegmt.set(JAVA_FLOAT, 8, 35.66F);
+
+ float result = (float)mh.invoke(37.88F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.2F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(floatArray.withName("array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invoke(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout floatArray = MemoryLayout.sequenceLayout(2, JAVA_FLOAT);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), floatArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+
+ float result = (float)mh.invoke(444.44F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.1F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_FLOAT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invoke(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout floatStruct = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, floatStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_FLOAT, 0, 111.11F);
+ structSegmt.set(JAVA_FLOAT, 4, 222.22F);
+ structSegmt.set(JAVA_FLOAT, 8, 333.33F);
+ structSegmt.set(JAVA_FLOAT, 12, 444.44F);
+ structSegmt.set(JAVA_FLOAT, 16, 555.55F);
+
+ float result = (float)mh.invoke(666.66F, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.31F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ floatHandle3.set(structSegmt1, 45.67F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+ floatHandle3.set(structSegmt2, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt), 115.39, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 25.12F);
+ floatHandle2.set(structSegmt1, 11.23F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 24.34F);
+ floatHandle2.set(structSegmt2, 13.45F);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultAddr.get(JAVA_FLOAT, 4), 24.68F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 2228.111D);
+ doubleHandle2.set(structSegmt, 2229.221D);
+
+ double result = (double)mh.invoke(3336.333D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 7793.665D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 118.456D);
+ doubleHandle2.set(structSegmt, 119.789D);
+
+ double result = (double)mh.invoke(doubleSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 350.368D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt = allocator.allocate(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 218.456D);
+ doubleHandle2.set(structSegmt, 219.789D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(doubleSegmt, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultAddr.toRawLongValue(), doubleSegmt.address().toRawLongValue());
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 22.111D);
+ doubleHandle2.set(structSegmt, 44.222D);
+
+ double result = (double)mh.invoke(66.333D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 132.666D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStructByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_DOUBLE.withName("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invoke(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout nestedStructLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 31.789D);
+ structSegmt.set(JAVA_DOUBLE, 8, 33.456D);
+ structSegmt.set(JAVA_DOUBLE, 16, 35.123D);
+
+ double result = (double)mh.invoke(37.864D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 138.232D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(doubleArray.withName("array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invoke(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH() throws Throwable {
+ SequenceLayout doubleArray = MemoryLayout.sequenceLayout(2, JAVA_DOUBLE);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), doubleArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+
+ double result = (double)mh.invoke(444.444D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 1111.11D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_DOUBLE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invoke(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH() throws Throwable {
+ GroupLayout doubleStruct = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ SequenceLayout structArray = MemoryLayout.sequenceLayout(2, doubleStruct);
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt = allocator.allocate(structLayout);
+ structSegmt.set(JAVA_DOUBLE, 0, 111.111D);
+ structSegmt.set(JAVA_DOUBLE, 8, 222.222D);
+ structSegmt.set(JAVA_DOUBLE, 16, 333.333D);
+ structSegmt.set(JAVA_DOUBLE, 24, 444.444D);
+ structSegmt.set(JAVA_DOUBLE, 32, 555.555D);
+
+ double result = (double)mh.invoke(666.666D, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, 2333.331D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoubleStructs_returnStructPointerByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoubleStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+
+ MemoryAddress resultAddr = (MemoryAddress)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 8), 66.888D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_add3DoubleStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle doubleHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ Addressable functionSymbol = nativeLibLookup.lookup("add3DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), session);
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11.222D);
+ doubleHandle2.set(structSegmt1, 22.333D);
+ doubleHandle3.set(structSegmt1, 33.123D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 33.444D);
+ doubleHandle2.set(structSegmt2, 44.555D);
+ doubleHandle3.set(structSegmt2, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke(allocator, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMethodHandles.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMethodHandles.java
new file mode 100644
index 00000000000..ce67852927b
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/upcall/UpcallMethodHandles.java
@@ -0,0 +1,1886 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.upcall;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import static java.lang.invoke.MethodType.methodType;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import static java.lang.foreign.Linker.*;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * The helper class that contains all upcall method handles with primitive types or struct
+ * as arguments.
+ */
+public class UpcallMethodHandles {
+ private static final Lookup lookup = MethodHandles.lookup();
+ private static MemorySession session = MemorySession.openImplicit();
+ private static SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+
+ static final MethodType MT_Bool_Bool_MemSegmt = methodType(boolean.class, boolean.class, MemorySegment.class);
+ static final MethodType MT_Addr_Bool_MemAddr = methodType(Addressable.class, boolean.class, MemoryAddress.class);
+ static final MethodType MT_Char_Char_MemSegmt = methodType(char.class, char.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Char = methodType(Addressable.class, MemoryAddress.class, char.class);
+ static final MethodType MT_Byte_Byte_MemSegmt = methodType(byte.class, byte.class, MemorySegment.class);
+ static final MethodType MT_Addr_Byte_MemAddr = methodType(Addressable.class, byte.class, MemoryAddress.class);
+ static final MethodType MT_Short_Short_MemSegmt = methodType(short.class, short.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Short = methodType(Addressable.class, MemoryAddress.class, short.class);
+ static final MethodType MT_Int_Int_MemSegmt = methodType(int.class, int.class, MemorySegment.class);
+ static final MethodType MT_Addr_Int_MemAddr = methodType(Addressable.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Long_Long_MemSegmt = methodType(long.class, long.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Long = methodType(Addressable.class, MemoryAddress.class, long.class);
+ static final MethodType MT_Long_Int_MemSegmt = methodType(long.class, int.class, MemorySegment.class);
+ static final MethodType MT_Float_Float_MemSegmt = methodType(float.class, float.class, MemorySegment.class);
+ static final MethodType MT_Addr_Float_MemAddr = methodType(Addressable.class, float.class, MemoryAddress.class);
+ static final MethodType MT_Double_Double_MemSegmt = methodType(double.class, double.class, MemorySegment.class);
+ static final MethodType MT_Addr_MemAddr_Double = methodType(Addressable.class, MemoryAddress.class, double.class);
+ static final MethodType MT_Addr_MemAddr_MemSegmt = methodType(Addressable.class, MemoryAddress.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt_MemSegmt_MemSegmt = methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class);
+ static final MethodType MT_MemSegmt = methodType(MemorySegment.class);
+
+ public static final MethodHandle MH_add2BoolsWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPointerWithOr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetPtr;
+ public static final MethodHandle MH_addBoolAndBoolFromPtrWithOr_RetArgPtr;
+ public static final MethodHandle MH_createNewCharFrom2Chars;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPointer;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetPtr;
+ public static final MethodHandle MH_createNewCharFromCharAndCharFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Bytes;
+ public static final MethodHandle MH_addByteAndByteFromPointer;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetPtr;
+ public static final MethodHandle MH_addByteAndByteFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Shorts;
+ public static final MethodHandle MH_addShortAndShortFromPointer;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetPtr;
+ public static final MethodHandle MH_addShortAndShortFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Ints;
+ public static final MethodHandle MH_addIntAndIntFromPointer;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetPtr;
+ public static final MethodHandle MH_addIntAndIntFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add3Ints;
+ public static final MethodHandle MH_addIntAndChar;
+ public static final MethodHandle MH_add2IntsReturnVoid;
+ public static final MethodHandle MH_add2Longs;
+ public static final MethodHandle MH_addLongAndLongFromPointer;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetPtr;
+ public static final MethodHandle MH_addLongAndLongFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Floats;
+ public static final MethodHandle MH_addFloatAndFloatFromPointer;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetPtr;
+ public static final MethodHandle MH_addFloatAndFloatFromPtr_RetArgPtr;
+ public static final MethodHandle MH_add2Doubles;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPointer;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetPtr;
+ public static final MethodHandle MH_addDoubleAndDoubleFromPtr_RetArgPtr;
+ public static final MethodHandle MH_compare;
+
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolAnd20BoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor;
+ public static final MethodHandle MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructPointerWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor;
+ public static final MethodHandle MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStruct;
+ public static final MethodHandle MH_add2BoolStructsWithXor_returnStructPointer;
+ public static final MethodHandle MH_add3BoolStructsWithXor_returnStruct;
+
+ public static final MethodHandle MH_addByteAndBytesFromStruct;
+ public static final MethodHandle MH_addByteAnd20BytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct;
+ public static final MethodHandle MH_addByteFromPointerAndBytesFromStruct_returnBytePointer;
+ public static final MethodHandle MH_addByteAndBytesFromStructPointer;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct;
+ public static final MethodHandle MH_addByteAndBytesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add1ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStruct;
+ public static final MethodHandle MH_add2ByteStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ByteStructs_returnStruct;
+
+ public static final MethodHandle MH_addCharAndCharsFromStruct;
+ public static final MethodHandle MH_addCharAnd10CharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct;
+ public static final MethodHandle MH_addCharFromPointerAndCharsFromStruct_returnCharPointer;
+ public static final MethodHandle MH_addCharAndCharsFromStructPointer;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct;
+ public static final MethodHandle MH_addCharAndCharsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2CharStructs_returnStruct;
+ public static final MethodHandle MH_add2CharStructs_returnStructPointer;
+ public static final MethodHandle MH_add3CharStructs_returnStruct;
+
+ public static final MethodHandle MH_addShortAndShortsFromStruct;
+ public static final MethodHandle MH_addShortAnd10ShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct;
+ public static final MethodHandle MH_addShortFromPointerAndShortsFromStruct_returnShortPointer;
+ public static final MethodHandle MH_addShortAndShortsFromStructPointer;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct;
+ public static final MethodHandle MH_addShortAndShortsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2ShortStructs_returnStruct;
+ public static final MethodHandle MH_add2ShortStructs_returnStructPointer;
+ public static final MethodHandle MH_add3ShortStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntsFromStruct;
+ public static final MethodHandle MH_addIntAnd5IntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct;
+ public static final MethodHandle MH_addIntFromPointerAndIntsFromStruct_returnIntPointer;
+ public static final MethodHandle MH_addIntAndIntsFromStructPointer;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct;
+ public static final MethodHandle MH_addIntAndIntsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2IntStructs_returnStruct;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer;
+ public static final MethodHandle MH_add3IntStructs_returnStruct;
+
+ public static final MethodHandle MH_addLongAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct;
+ public static final MethodHandle MH_addLongFromPointerAndLongsFromStruct_returnLongPointer;
+ public static final MethodHandle MH_addLongAndLongsFromStructPointer;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct;
+ public static final MethodHandle MH_addLongAndLongsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2LongStructs_returnStruct;
+ public static final MethodHandle MH_add2LongStructs_returnStructPointer;
+ public static final MethodHandle MH_add3LongStructs_returnStruct;
+
+ public static final MethodHandle MH_addFloatAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd5FloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct;
+ public static final MethodHandle MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructPointer;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct;
+ public static final MethodHandle MH_addFloatAndFloatsFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2FloatStructs_returnStruct;
+ public static final MethodHandle MH_add2FloatStructs_returnStructPointer;
+ public static final MethodHandle MH_add3FloatStructs_returnStruct;
+
+ public static final MethodHandle MH_addDoubleAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct;
+ public static final MethodHandle MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructPointer;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct;
+ public static final MethodHandle MH_addDoubleAndDoublesFromNestedStruct_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray;
+ public static final MethodHandle MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder;
+ public static final MethodHandle MH_add2DoubleStructs_returnStruct;
+ public static final MethodHandle MH_add2DoubleStructs_returnStructPointer;
+ public static final MethodHandle MH_add3DoubleStructs_returnStruct;
+
+ public static final MethodHandle MH_addIntAndIntShortFromStruct;
+ public static final MethodHandle MH_addIntAndShortIntFromStruct;
+ public static final MethodHandle MH_addIntAndIntLongFromStruct;
+ public static final MethodHandle MH_addIntAndLongIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAnd2FloatsDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndDouble2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndInt2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAndFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntFloatDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatIntDoubleFromStruct;
+ public static final MethodHandle MH_addDoubleAndLongDoubleFromStruct;
+ public static final MethodHandle MH_addFloatAndInt3FloatsFromStruct;
+ public static final MethodHandle MH_addLongAndLong2FloatsFromStruct;
+ public static final MethodHandle MH_addFloatAnd3FloatsIntFromStruct;
+ public static final MethodHandle MH_addLongAndFloatLongFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleFloatIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndDoubleLongFromStruct;
+ public static final MethodHandle MH_addLongAnd2FloatsLongFromStruct;
+ public static final MethodHandle MH_addShortAnd3ShortsCharFromStruct;
+ public static final MethodHandle MH_addFloatAndIntFloatIntFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleIntFromStruct;
+ public static final MethodHandle MH_addDoubleAndFloatDoubleFloatFromStruct;
+ public static final MethodHandle MH_addDoubleAndIntDoubleLongFromStruct;
+ public static final MethodHandle MH_return254BytesFromStruct;
+ public static final MethodHandle MH_return4KBytesFromStruct;
+
+ static {
+ try {
+ MH_add2BoolsWithOr = lookup.findStatic(UpcallMethodHandles.class, "add2BoolsWithOr", methodType(boolean.class, boolean.class, boolean.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPointerWithOr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPointerWithOr", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetPtr", MT_Addr_Bool_MemAddr); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetArgPtr", MT_Addr_Bool_MemAddr); //$NON-NLS-1$
+
+ MH_createNewCharFrom2Chars = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFrom2Chars", methodType(char.class, char.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPointer = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPointer", methodType(char.class, MemoryAddress.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetPtr", MT_Addr_MemAddr_Char); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetArgPtr", MT_Addr_MemAddr_Char); //$NON-NLS-1$
+
+ MH_add2Bytes = lookup.findStatic(UpcallMethodHandles.class, "add2Bytes", methodType(byte.class, byte.class, byte.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetPtr", MT_Addr_Byte_MemAddr); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetArgPtr", MT_Addr_Byte_MemAddr); //$NON-NLS-1$
+
+ MH_add2Shorts = lookup.findStatic(UpcallMethodHandles.class, "add2Shorts", methodType(short.class, short.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPointer", methodType(short.class, MemoryAddress.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetPtr", MT_Addr_MemAddr_Short); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetArgPtr", MT_Addr_MemAddr_Short); //$NON-NLS-1$
+
+ MH_add2Ints = lookup.findStatic(UpcallMethodHandles.class, "add2Ints", methodType(int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetPtr", MT_Addr_Int_MemAddr); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetArgPtr", MT_Addr_Int_MemAddr); //$NON-NLS-1$
+ MH_add3Ints = lookup.findStatic(UpcallMethodHandles.class, "add3Ints", methodType(int.class, int.class, int.class, int.class)); //$NON-NLS-1$
+ MH_addIntAndChar = lookup.findStatic(UpcallMethodHandles.class, "addIntAndChar", methodType(int.class, int.class, char.class)); //$NON-NLS-1$
+ MH_add2IntsReturnVoid = lookup.findStatic(UpcallMethodHandles.class, "add2IntsReturnVoid", methodType(void.class, int.class, int.class)); //$NON-NLS-1$
+
+ MH_add2Longs = lookup.findStatic(UpcallMethodHandles.class, "add2Longs", methodType(long.class, long.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPointer", methodType(long.class, MemoryAddress.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetPtr", MT_Addr_MemAddr_Long); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetArgPtr", MT_Addr_MemAddr_Long); //$NON-NLS-1$
+
+ MH_add2Floats = lookup.findStatic(UpcallMethodHandles.class, "add2Floats", methodType(float.class, float.class, float.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetPtr", MT_Addr_Float_MemAddr); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetArgPtr", MT_Addr_Float_MemAddr); //$NON-NLS-1$
+
+ MH_add2Doubles = lookup.findStatic(UpcallMethodHandles.class, "add2Doubles", methodType(double.class, double.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPointer", methodType(double.class, MemoryAddress.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetPtr", MT_Addr_MemAddr_Double); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetArgPtr", MT_Addr_MemAddr_Double); //$NON-NLS-1$
+
+ MH_compare = lookup.findStatic(UpcallMethodHandles.class, "compare", methodType(int.class, MemoryAddress.class, MemoryAddress.class)); //$NON-NLS-1$
+
+ MH_addBoolAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAnd20BoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAnd20BoolsFromStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor", methodType(boolean.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructPointerWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructPointerWithXor", methodType(boolean.class, boolean.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromNestedStructWithXor_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder", MT_Bool_Bool_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2BoolStructsWithXor_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2BoolStructsWithXor_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3BoolStructsWithXor_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3BoolStructsWithXor_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addByteAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAnd20BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAnd20BytesFromStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct", methodType(byte.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct_returnBytePointer = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct_returnBytePointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructPointer", methodType(byte.class, byte.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromNestedStruct_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedByteArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructWithNestedStructArray_reverseOrder", MT_Byte_Byte_MemSegmt); //$NON-NLS-1$
+ MH_add1ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add1ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ByteStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ByteStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ByteStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ByteStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addCharAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAnd10CharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAnd10CharsFromStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct", methodType(char.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct_returnCharPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct_returnCharPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructPointer", methodType(char.class, char.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromNestedStruct_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedCharArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructWithNestedStructArray_reverseOrder", MT_Char_Char_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2CharStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2CharStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3CharStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3CharStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addShortAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd10ShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd10ShortsFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct", methodType(short.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct_returnShortPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct_returnShortPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructPointer", methodType(short.class, short.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromNestedStruct_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedShortArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructWithNestedStructArray_reverseOrder", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2ShortStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2ShortStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3ShortStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3ShortStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAnd5IntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAnd5IntsFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct", methodType(int.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct_returnIntPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct_returnIntPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructPointer", methodType(int.class, int.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromNestedStruct_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedIntArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructWithNestedStructArray_reverseOrder", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3IntStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3IntStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addLongAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct", methodType(long.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct_returnLongPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct_returnLongPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructPointer", methodType(long.class, long.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromNestedStruct_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedLongArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructWithNestedStructArray_reverseOrder", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2LongStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2LongStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3LongStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3LongStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addFloatAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd5FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd5FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct", methodType(float.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct_returnFloatPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructPointer", methodType(float.class, float.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromNestedStruct_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2FloatStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2FloatStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3FloatStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3FloatStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addDoubleAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct", methodType(double.class, MemoryAddress.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructPointer", methodType(double.class, double.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromNestedStruct_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromNestedStruct_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2DoubleStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2DoubleStructs_returnStructPointer", MT_Addr_MemAddr_MemSegmt); //$NON-NLS-1$
+ MH_add3DoubleStructs_returnStruct = lookup.findStatic(UpcallMethodHandles.class, "add3DoubleStructs_returnStruct", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+
+ MH_addIntAndIntShortFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntShortFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndShortIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndShortIntFromStruct", MT_Int_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntLongFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndLongIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addIntAndLongIntFromStruct", MT_Long_Int_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAnd2FloatsDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAnd2FloatsDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDouble2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDouble2FloatsFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt2FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntFloatDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntFloatDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatIntDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatIntDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndLongDoubleFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndLongDoubleFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndInt3FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndInt3FloatsFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLong2FloatsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLong2FloatsFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAnd3FloatsIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAnd3FloatsIntFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndFloatLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAndFloatLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFloatIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFloatIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addLongAnd2FloatsLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addLongAnd2FloatsLongFromStruct", MT_Long_Long_MemSegmt); //$NON-NLS-1$
+ MH_addShortAnd3ShortsCharFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addShortAnd3ShortsCharFromStruct", MT_Short_Short_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndIntFloatIntFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndIntFloatIntFloatFromStruct", MT_Float_Float_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleIntFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleIntFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndFloatDoubleFloatFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndFloatDoubleFloatFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndIntDoubleLongFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndIntDoubleLongFromStruct", MT_Double_Double_MemSegmt); //$NON-NLS-1$
+ MH_return254BytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return254BytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+ MH_return4KBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "return4KBytesFromStruct", MT_MemSegmt); //$NON-NLS-1$
+
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static boolean add2BoolsWithOr(boolean boolArg1, boolean boolArg2) {
+ boolean result = boolArg1 || boolArg2;
+ return result;
+ }
+
+ public static boolean addBoolAndBoolFromPointerWithOr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ return result;
+ }
+
+ public static Addressable addBoolAndBoolFromPtrWithOr_RetPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_BOOLEAN, session);
+ resultSegmt.set(JAVA_BOOLEAN, 0, result);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addBoolAndBoolFromPtrWithOr_RetArgPtr(boolean boolArg1, MemoryAddress boolArg2Addr) {
+ boolean result = boolArg1 || boolArg2Addr.get(JAVA_BOOLEAN, 0);
+ boolArg2Addr.set(JAVA_BOOLEAN, 0, result);
+ return boolArg2Addr;
+ }
+
+ public static char createNewCharFrom2Chars(char charArg1, char charArg2) {
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static char createNewCharFromCharAndCharFromPointer(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ return result;
+ }
+
+ public static Addressable createNewCharFromCharAndCharFromPtr_RetPtr(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_CHAR.byteSize(), session);
+ resultSegmt.set(JAVA_CHAR, 0, result);
+ return resultSegmt.address();
+ }
+
+ public static Addressable createNewCharFromCharAndCharFromPtr_RetArgPtr(MemoryAddress charArg1Addr, char charArg2) {
+ char charArg1 = charArg1Addr.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ charArg1Addr.set(JAVA_CHAR, 0, result);
+ return charArg1Addr;
+ }
+
+ public static byte add2Bytes(byte byteArg1, byte byteArg2) {
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static byte addByteAndByteFromPointer(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static Addressable addByteAndByteFromPtr_RetPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_BYTE.byteSize(), session);
+ resultSegmt.set(JAVA_BYTE, 0, byteSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addByteAndByteFromPtr_RetArgPtr(byte byteArg1, MemoryAddress byteArg2Addr) {
+ byte byteArg2 = byteArg2Addr.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ byteArg2Addr.set(JAVA_BYTE, 0, byteSum);
+ return byteArg2Addr;
+ }
+
+ public static short add2Shorts(short shortArg1, short shortArg2) {
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortFromPointer(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static Addressable addShortAndShortFromPtr_RetPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_SHORT.byteSize(), session);
+ resultSegmt.set(JAVA_SHORT, 0, shortSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addShortAndShortFromPtr_RetArgPtr(MemoryAddress shortArg1Addr, short shortArg2) {
+ short shortArg1 = shortArg1Addr.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ shortArg1Addr.set(JAVA_SHORT, 0, shortSum);
+ return shortArg1Addr;
+ }
+
+ public static int add2Ints(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static int addIntAndIntFromPointer(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static Addressable addIntAndIntFromPtr_RetPtr(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_INT.byteSize(), session);
+ resultSegmt.set(JAVA_INT, 0, intSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addIntAndIntFromPtr_RetArgPtr(int intArg1, MemoryAddress intArg2Addr) {
+ int intArg2 = intArg2Addr.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ intArg2Addr.set(JAVA_INT, 0, intSum);
+ return intArg2Addr;
+ }
+
+ public static int add3Ints(int intArg1, int intArg2, int intArg3) {
+ int intSum = intArg1 + intArg2 + intArg3;
+ return intSum;
+ }
+
+ public static int addIntAndChar(int intArg, char charArg) {
+ int sum = intArg + charArg;
+ return sum;
+ }
+
+ public static void add2IntsReturnVoid(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ System.out.println("add2IntsReturnVoid: intSum = " + intSum + "\n");
+ }
+
+ public static long add2Longs(long longArg1, long longArg2) {
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static long addLongAndLongFromPointer(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static Addressable addLongAndLongFromPtr_RetPtr(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_LONG.byteSize(), session);
+ resultSegmt.set(JAVA_LONG, 0, longSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addLongAndLongFromPtr_RetArgPtr(MemoryAddress longArg1Addr, long longArg2) {
+ long longArg1 = longArg1Addr.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ longArg1Addr.set(JAVA_LONG, 0, longSum);
+ return longArg1Addr;
+ }
+
+ public static float add2Floats(float floatArg1, float floatArg2) {
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatFromPointer(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static Addressable addFloatAndFloatFromPtr_RetPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_FLOAT.byteSize(), session);
+ resultSegmt.set(JAVA_FLOAT, 0, floatSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addFloatAndFloatFromPtr_RetArgPtr(float floatArg1, MemoryAddress floatArg2Addr) {
+ float floatArg2 = floatArg2Addr.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ floatArg2Addr.set(JAVA_FLOAT, 0, floatSum);
+ return floatArg2Addr;
+ }
+
+ public static double add2Doubles(double doubleArg1, double doubleArg2) {
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFromPointer(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static Addressable addDoubleAndDoubleFromPtr_RetPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ MemorySegment resultSegmt = MemorySegment.allocateNative(JAVA_DOUBLE.byteSize(), session);
+ resultSegmt.set(JAVA_DOUBLE, 0, doubleSum);
+ return resultSegmt.address();
+ }
+
+ public static Addressable addDoubleAndDoubleFromPtr_RetArgPtr(MemoryAddress doubleArg1Addr, double doubleArg2) {
+ double doubleArg1 = doubleArg1Addr.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ doubleArg1Addr.set(JAVA_DOUBLE, 0, doubleSum);
+ return doubleArg1Addr;
+ }
+
+ public static int compare(MemoryAddress argAddr1, MemoryAddress argAddr2) {
+ int intArg1 = argAddr1.get(JAVA_INT, 0);
+ int intArg2 = argAddr2.get(JAVA_INT, 0);
+ return (intArg1 - intArg2);
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean boolSum = arg1 ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static boolean addBoolAnd20BoolsFromStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean boolSum = arg1 ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1)
+ ^ arg2.get(JAVA_BOOLEAN, 2) ^ arg2.get(JAVA_BOOLEAN, 3) ^ arg2.get(JAVA_BOOLEAN, 4)
+ ^ arg2.get(JAVA_BOOLEAN, 5) ^ arg2.get(JAVA_BOOLEAN, 6) ^ arg2.get(JAVA_BOOLEAN, 7)
+ ^ arg2.get(JAVA_BOOLEAN, 8) ^ arg2.get(JAVA_BOOLEAN, 9) ^ arg2.get(JAVA_BOOLEAN, 10)
+ ^ arg2.get(JAVA_BOOLEAN, 11) ^ arg2.get(JAVA_BOOLEAN, 12) ^ arg2.get(JAVA_BOOLEAN, 13)
+ ^ arg2.get(JAVA_BOOLEAN, 14) ^ arg2.get(JAVA_BOOLEAN, 15) ^ arg2.get(JAVA_BOOLEAN, 16)
+ ^ arg2.get(JAVA_BOOLEAN, 17) ^ arg2.get(JAVA_BOOLEAN, 18) ^ arg2.get(JAVA_BOOLEAN, 19);
+ return boolSum;
+ }
+
+ public static boolean addBoolFromPointerAndBoolsFromStructWithXor(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolSum = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static Addressable addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolSum = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Addr.set(JAVA_BOOLEAN, 0, boolSum);
+ return arg1Addr;
+ }
+
+ public static boolean addBoolAndBoolsFromStructPointerWithXor(boolean arg1, MemoryAddress arg2Addr) {
+ boolean boolSum = arg1 ^ arg2Addr.get(JAVA_BOOLEAN, 0) ^ arg2Addr.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor(boolean arg1, MemorySegment arg2) {
+ boolean nestedStructElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructElem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean boolSum = arg1 ^ nestedStructElem1 ^ nestedStructElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromNestedStructWithXor_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructElem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructElem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean boolSum = arg1 ^ structElem1 ^ nestedStructElem1 ^ nestedStructElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray(boolean arg1, MemorySegment arg2) {
+ boolean nestedBoolArrayElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedBoolArrayElem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 2);
+
+ boolean boolSum = arg1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2 ^ structElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedBoolArrayElem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedBoolArrayElem2 = arg2.get(JAVA_BOOLEAN, 2);
+
+ boolean boolSum = arg1 ^ structElem1 ^ nestedBoolArrayElem1 ^ nestedBoolArrayElem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray(boolean arg1, MemorySegment arg2) {
+ boolean nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BOOLEAN, 3);
+ boolean structElem2 = arg2.get(JAVA_BOOLEAN, 4);
+
+ boolean boolSum = arg1 ^ structElem2
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static boolean addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder(boolean arg1, MemorySegment arg2) {
+ boolean structElem1 = arg2.get(JAVA_BOOLEAN, 0);
+ boolean nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BOOLEAN, 1);
+ boolean nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BOOLEAN, 2);
+ boolean nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BOOLEAN, 3);
+ boolean nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BOOLEAN, 4);
+
+ boolean boolSum = arg1 ^ structElem1
+ ^ nestedStructArrayElem1_Elem1 ^ nestedStructArrayElem1_Elem2
+ ^ nestedStructArrayElem2_Elem1 ^ nestedStructArrayElem2_Elem2;
+ return boolSum;
+ }
+
+ public static MemorySegment add2BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ boolean boolStruct_Elem1 = arg1.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ return boolStructSegmt;
+ }
+
+ public static Addressable add2BoolStructsWithXor_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ boolean boolStruct_Elem1 = arg1Addr.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1Addr.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Addr.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ arg1Addr.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3BoolStructsWithXor_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ JAVA_BOOLEAN.withName("elem2"), JAVA_BOOLEAN.withName("elem3"), MemoryLayout.paddingLayout(8));
+ MemorySegment boolStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ boolean boolStruct_Elem1 = arg1.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ boolean boolStruct_Elem3 = arg1.get(JAVA_BOOLEAN, 2) ^ arg2.get(JAVA_BOOLEAN, 2);
+ boolStructSegmt.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ boolStructSegmt.set(JAVA_BOOLEAN, 1, boolStruct_Elem2);
+ boolStructSegmt.set(JAVA_BOOLEAN, 2, boolStruct_Elem3);
+ return boolStructSegmt;
+ }
+
+ public static byte addByteAndBytesFromStruct(byte arg1, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1 + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static byte addByteAnd20BytesFromStruct(byte arg1, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1 + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1)
+ + arg2.get(JAVA_BYTE, 2) + arg2.get(JAVA_BYTE, 3) + arg2.get(JAVA_BYTE, 4)
+ + arg2.get(JAVA_BYTE, 5) + arg2.get(JAVA_BYTE, 6) + arg2.get(JAVA_BYTE, 7)
+ + arg2.get(JAVA_BYTE, 8) + arg2.get(JAVA_BYTE, 9) + arg2.get(JAVA_BYTE, 10)
+ + arg2.get(JAVA_BYTE, 11) + arg2.get(JAVA_BYTE, 12) + arg2.get(JAVA_BYTE, 13)
+ + arg2.get(JAVA_BYTE, 14) + arg2.get(JAVA_BYTE, 15) + arg2.get(JAVA_BYTE, 16)
+ + arg2.get(JAVA_BYTE, 17) + arg2.get(JAVA_BYTE, 18) + arg2.get(JAVA_BYTE, 19));
+ return byteSum;
+ }
+
+ public static byte addByteFromPointerAndBytesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static Addressable addByteFromPointerAndBytesFromStruct_returnBytePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteSum = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ arg1Addr.set(JAVA_BYTE, 0, byteSum);
+ return arg1Addr;
+ }
+
+ public static byte addByteAndBytesFromStructPointer(byte arg1, MemoryAddress arg2Addr) {
+ byte byteSum = (byte)(arg1 + arg2Addr.get(JAVA_BYTE, 0) + arg2Addr.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct(byte arg1, MemorySegment arg2) {
+ byte nestedStructElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructElem2 = arg2.get(JAVA_BYTE, 1);
+ byte structElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromNestedStruct_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructElem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray(byte arg1, MemorySegment arg2) {
+ byte nestedByteArrayElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedByteArrayElem2 = arg2.get(JAVA_BYTE, 1);
+ byte structElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + nestedByteArrayElem1 + nestedByteArrayElem2 + structElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedByteArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedByteArrayElem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedByteArrayElem2 = arg2.get(JAVA_BYTE, 2);
+
+ byte byteSum = (byte)(arg1 + structElem1 + nestedByteArrayElem1 + nestedByteArrayElem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray(byte arg1, MemorySegment arg2) {
+ byte nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BYTE, 2);
+ byte nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BYTE, 3);
+ byte structElem2 = arg2.get(JAVA_BYTE, 4);
+
+ byte byteSum = (byte)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static byte addByteAndBytesFromStructWithNestedStructArray_reverseOrder(byte arg1, MemorySegment arg2) {
+ byte structElem1 = arg2.get(JAVA_BYTE, 0);
+ byte nestedStructArrayElem1_Elem1 = arg2.get(JAVA_BYTE, 1);
+ byte nestedStructArrayElem1_Elem2 = arg2.get(JAVA_BYTE, 2);
+ byte nestedStructArrayElem2_Elem1 = arg2.get(JAVA_BYTE, 3);
+ byte nestedStructArrayElem2_Elem2 = arg2.get(JAVA_BYTE, 4);
+
+ byte byteSum = (byte)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return byteSum;
+ }
+
+ public static MemorySegment add1ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ return byteStructSegmt;
+ }
+
+ public static MemorySegment add2ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ byteStructSegmt.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ return byteStructSegmt;
+ }
+
+ public static Addressable add2ByteStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ byte byteStruct_Elem1 = (byte)(arg1Addr.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1Addr.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ arg1Addr.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ arg1Addr.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ByteStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"),
+ JAVA_BYTE.withName("elem3"), MemoryLayout.paddingLayout(8));
+ MemorySegment byteStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ byte byteStruct_Elem1 = (byte)(arg1.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ byte byteStruct_Elem3 = (byte)(arg1.get(JAVA_BYTE, 2) + arg2.get(JAVA_BYTE, 2));
+ byteStructSegmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ byteStructSegmt.set(JAVA_BYTE, 1, byteStruct_Elem2);
+ byteStructSegmt.set(JAVA_BYTE, 2, byteStruct_Elem3);
+ return byteStructSegmt;
+ }
+
+ public static char addCharAndCharsFromStruct(char arg1, MemorySegment arg2) {
+ char result = (char)(arg1 + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAnd10CharsFromStruct(char arg1, MemorySegment arg2) {
+ char result = (char)(arg1 + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2)
+ + arg2.get(JAVA_CHAR, 4) + arg2.get(JAVA_CHAR, 6) + arg2.get(JAVA_CHAR, 8)
+ + arg2.get(JAVA_CHAR, 10) + arg2.get(JAVA_CHAR, 12) + arg2.get(JAVA_CHAR, 14)
+ + arg2.get(JAVA_CHAR, 16) + arg2.get(JAVA_CHAR, 18) - 10 * 'A');
+ return result;
+ }
+
+ public static char addCharFromPointerAndCharsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char result = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static Addressable addCharFromPointerAndCharsFromStruct_returnCharPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char result = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ arg1Addr.set(JAVA_CHAR, 0, result);
+ return arg1Addr;
+ }
+
+ public static char addCharAndCharsFromStructPointer(char arg1, MemoryAddress arg2Addr) {
+ char result = (char)(arg1 + arg2Addr.get(JAVA_CHAR, 0) + arg2Addr.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct(char arg1, MemorySegment arg2) {
+ char nestedStructElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructElem2 = arg2.get(JAVA_CHAR, 2);
+ char structElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromNestedStruct_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructElem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray(char arg1, MemorySegment arg2) {
+ char nestedCharArrayElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedCharArrayElem2 = arg2.get(JAVA_CHAR, 2);
+ char structElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + nestedCharArrayElem1 + nestedCharArrayElem2 + structElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedCharArray_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedCharArrayElem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedCharArrayElem2 = arg2.get(JAVA_CHAR, 4);
+
+ char result = (char)(arg1 + structElem1 + nestedCharArrayElem1 + nestedCharArrayElem2 - 3 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray(char arg1, MemorySegment arg2) {
+ char nestedStructArrayElem1_Elem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructArrayElem1_Elem2 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructArrayElem2_Elem1 = arg2.get(JAVA_CHAR, 4);
+ char nestedStructArrayElem2_Elem2 = arg2.get(JAVA_CHAR, 6);
+ char structElem2 = arg2.get(JAVA_CHAR, 8);
+
+ char result = (char)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static char addCharAndCharsFromStructWithNestedStructArray_reverseOrder(char arg1, MemorySegment arg2) {
+ char structElem1 = arg2.get(JAVA_CHAR, 0);
+ char nestedStructArrayElem1_Elem1 = arg2.get(JAVA_CHAR, 2);
+ char nestedStructArrayElem1_Elem2 = arg2.get(JAVA_CHAR, 4);
+ char nestedStructArrayElem2_Elem1 = arg2.get(JAVA_CHAR, 6);
+ char nestedStructArrayElem2_Elem2 = arg2.get(JAVA_CHAR, 8);
+
+ char result = (char)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2 - 5 * 'A');
+ return result;
+ }
+
+ public static MemorySegment add2CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ char charStruct_Elem1 = (char)(arg1.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ charStructSegmt.set(JAVA_CHAR, 0, charStruct_Elem1);
+ charStructSegmt.set(JAVA_CHAR, 2, charStruct_Elem2);
+ return charStructSegmt;
+ }
+
+ public static Addressable add2CharStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ char charStruct_Elem1 = (char)(arg1Addr.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1Addr.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ arg1Addr.set(JAVA_CHAR, 0, charStruct_Elem1);
+ arg1Addr.set(JAVA_CHAR, 2, charStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3CharStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"),
+ JAVA_CHAR.withName("elem3"), MemoryLayout.paddingLayout(16));
+ MemorySegment charStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ char charStruct_Elem1 = (char)(arg1.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ char charStruct_Elem3 = (char)(arg1.get(JAVA_CHAR, 4) + arg2.get(JAVA_CHAR, 4) - 'A');
+ charStructSegmt.set(JAVA_CHAR, 0, charStruct_Elem1);
+ charStructSegmt.set(JAVA_CHAR, 2, charStruct_Elem2);
+ charStructSegmt.set(JAVA_CHAR, 4, charStruct_Elem3);
+ return charStructSegmt;
+ }
+
+ public static short addShortAndShortsFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static short addShortAnd10ShortsFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2)
+ + arg2.get(JAVA_SHORT, 4) + arg2.get(JAVA_SHORT, 6) + arg2.get(JAVA_SHORT, 8)
+ + arg2.get(JAVA_SHORT, 10) + arg2.get(JAVA_SHORT, 12) + arg2.get(JAVA_SHORT, 14)
+ + arg2.get(JAVA_SHORT, 16) + arg2.get(JAVA_SHORT, 18));
+ return shortSum;
+ }
+
+ public static short addShortFromPointerAndShortsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortSum = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static Addressable addShortFromPointerAndShortsFromStruct_returnShortPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortSum = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ arg1Addr.set(JAVA_SHORT, 0, shortSum);
+ return arg1Addr;
+ }
+
+ public static short addShortAndShortsFromStructPointer(short arg1, MemoryAddress arg2Addr) {
+ short shortSum = (short)(arg1 + arg2Addr.get(JAVA_SHORT, 0) + arg2Addr.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct(short arg1, MemorySegment arg2) {
+ short nestedStructElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructElem2 = arg2.get(JAVA_SHORT, 2);
+ short structElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + nestedStructElem1 + nestedStructElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromNestedStruct_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructElem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedStructElem1 + nestedStructElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray(short arg1, MemorySegment arg2) {
+ short nestedShortArrayElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedShortArrayElem2 = arg2.get(JAVA_SHORT, 2);
+ short structElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + nestedShortArrayElem1 + nestedShortArrayElem2 + structElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedShortArray_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedShortArrayElem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedShortArrayElem2 = arg2.get(JAVA_SHORT, 4);
+
+ short shortSum = (short)(arg1 + structElem1 + nestedShortArrayElem1 + nestedShortArrayElem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray(short arg1, MemorySegment arg2) {
+ short nestedStructArrayElem1_Elem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructArrayElem1_Elem2 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructArrayElem2_Elem1 = arg2.get(JAVA_SHORT, 4);
+ short nestedStructArrayElem2_Elem2 = arg2.get(JAVA_SHORT, 6);
+ short structElem2 = arg2.get(JAVA_SHORT, 8);
+
+ short shortSum = (short)(arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortsFromStructWithNestedStructArray_reverseOrder(short arg1, MemorySegment arg2) {
+ short structElem1 = arg2.get(JAVA_SHORT, 0);
+ short nestedStructArrayElem1_Elem1 = arg2.get(JAVA_SHORT, 2);
+ short nestedStructArrayElem1_Elem2 = arg2.get(JAVA_SHORT, 4);
+ short nestedStructArrayElem2_Elem1 = arg2.get(JAVA_SHORT, 6);
+ short nestedStructArrayElem2_Elem2 = arg2.get(JAVA_SHORT, 8);
+
+ short shortSum = (short)(arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2);
+ return shortSum;
+ }
+
+ public static MemorySegment add2ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ short shortStruct_Elem1 = (short)(arg1.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ shortStructSegmt.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ shortStructSegmt.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ return shortStructSegmt;
+ }
+
+ public static Addressable add2ShortStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ short shortStruct_Elem1 = (short)(arg1Addr.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1Addr.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ arg1Addr.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ arg1Addr.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3ShortStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"),
+ JAVA_SHORT.withName("elem3"), MemoryLayout.paddingLayout(16));
+ MemorySegment shortStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ short shortStruct_Elem1 = (short)(arg1.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ short shortStruct_Elem3 = (short)(arg1.get(JAVA_SHORT, 4) + arg2.get(JAVA_SHORT, 4));
+ shortStructSegmt.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ shortStructSegmt.set(JAVA_SHORT, 2, shortStruct_Elem2);
+ shortStructSegmt.set(JAVA_SHORT, 4, shortStruct_Elem3);
+ return shortStructSegmt;
+ }
+
+ public static int addIntAndIntsFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static int addIntAnd5IntsFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4)
+ + arg2.get(JAVA_INT, 8) + arg2.get(JAVA_INT, 12) + arg2.get(JAVA_INT, 16);
+ return intSum;
+ }
+
+ public static int addIntFromPointerAndIntsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static Addressable addIntFromPointerAndIntsFromStruct_returnIntPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ arg1Addr.set(JAVA_INT, 0, intSum);
+ return arg1Addr;
+ }
+
+ public static int addIntAndIntsFromStructPointer(int arg1, MemoryAddress arg2Addr) {
+ int intSum = arg1 + arg2Addr.get(JAVA_INT, 0) + arg2Addr.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct(int arg1, MemorySegment arg2) {
+ int nestedStructElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructElem2 = arg2.get(JAVA_INT, 4);
+ int structElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromNestedStruct_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructElem1 = arg2.get(JAVA_INT, 4);
+ int nestedStructElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray(int arg1, MemorySegment arg2) {
+ int nestedIntArrayElem1 = arg2.get(JAVA_INT, 0);
+ int nestedIntArrayElem2 = arg2.get(JAVA_INT, 4);
+ int structElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + nestedIntArrayElem1 + nestedIntArrayElem2 + structElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedIntArray_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedIntArrayElem1 = arg2.get(JAVA_INT, 4);
+ int nestedIntArrayElem2 = arg2.get(JAVA_INT, 8);
+
+ int intSum = arg1 + structElem1 + nestedIntArrayElem1 + nestedIntArrayElem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray(int arg1, MemorySegment arg2) {
+ int nestedStructArrayElem1_Elem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructArrayElem1_Elem2 = arg2.get(JAVA_INT, 4);
+ int nestedStructArrayElem2_Elem1 = arg2.get(JAVA_INT, 8);
+ int nestedStructArrayElem2_Elem2 = arg2.get(JAVA_INT, 12);
+ int structElem2 = arg2.get(JAVA_INT, 16);
+
+ int intSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static int addIntAndIntsFromStructWithNestedStructArray_reverseOrder(int arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ int nestedStructArrayElem1_Elem1 = arg2.get(JAVA_INT, 4);
+ int nestedStructArrayElem1_Elem2 = arg2.get(JAVA_INT, 8);
+ int nestedStructArrayElem2_Elem1 = arg2.get(JAVA_INT, 12);
+ int nestedStructArrayElem2_Elem2 = arg2.get(JAVA_INT, 16);
+
+ int intSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return intSum;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ int intStruct_Elem1 = arg1.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intStruct_Elem2 = arg1.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ intStructSegmt.set(JAVA_INT, 0, intStruct_Elem1);
+ intStructSegmt.set(JAVA_INT, 4, intStruct_Elem2);
+ return intStructSegmt;
+ }
+
+ public static Addressable add2IntStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ int intSum_Elem1 = arg1Addr.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intSum_Elem2 = arg1Addr.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ arg1Addr.set(JAVA_INT, 0, intSum_Elem1);
+ arg1Addr.set(JAVA_INT, 4, intSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3IntStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ MemorySegment intStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ int intStruct_Elem1 = arg1.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intStruct_Elem2 = arg1.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ int intStruct_Elem3 = arg1.get(JAVA_INT, 8) + arg2.get(JAVA_INT, 8);
+ intStructSegmt.set(JAVA_INT, 0, intStruct_Elem1);
+ intStructSegmt.set(JAVA_INT, 4, intStruct_Elem2);
+ intStructSegmt.set(JAVA_INT, 8, intStruct_Elem3);
+ return intStructSegmt;
+ }
+
+ public static long addLongAndLongsFromStruct(long arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addLongFromPointerAndLongsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static Addressable addLongFromPointerAndLongsFromStruct_returnLongPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ arg1Addr.set(JAVA_LONG, 0, longSum);
+ return arg1Addr;
+ }
+
+ public static long addLongAndLongsFromStructPointer(long arg1, MemoryAddress arg2Addr) {
+ long longSum = arg1 + arg2Addr.get(JAVA_LONG, 0) + arg2Addr.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct(long arg1, MemorySegment arg2) {
+ long nestedStructElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructElem2 = arg2.get(JAVA_LONG, 8);
+ long structElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromNestedStruct_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructElem1 = arg2.get(JAVA_LONG, 8);
+ long nestedStructElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray(long arg1, MemorySegment arg2) {
+ long nestedLongrrayElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedLongrrayElem2 = arg2.get(JAVA_LONG, 8);
+ long structElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + nestedLongrrayElem1 + nestedLongrrayElem2 + structElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedLongArray_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedLongrrayElem1 = arg2.get(JAVA_LONG, 8);
+ long nestedLongrrayElem2 = arg2.get(JAVA_LONG, 16);
+
+ long longSum = arg1 + structElem1 + nestedLongrrayElem1 + nestedLongrrayElem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray(long arg1, MemorySegment arg2) {
+ long nestedStructArrayElem1_Elem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructArrayElem1_Elem2 = arg2.get(JAVA_LONG, 8);
+ long nestedStructArrayElem2_Elem1 = arg2.get(JAVA_LONG, 16);
+ long nestedStructArrayElem2_Elem2 = arg2.get(JAVA_LONG, 24);
+ long structElem2 = arg2.get(JAVA_LONG, 32);
+
+ long longSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static long addLongAndLongsFromStructWithNestedStructArray_reverseOrder(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long nestedStructArrayElem1_Elem1 = arg2.get(JAVA_LONG, 8);
+ long nestedStructArrayElem1_Elem2 = arg2.get(JAVA_LONG, 16);
+ long nestedStructArrayElem2_Elem1 = arg2.get(JAVA_LONG, 24);
+ long nestedStructArrayElem2_Elem2 = arg2.get(JAVA_LONG, 32);
+
+ long longSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return longSum;
+ }
+
+ public static MemorySegment add2LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ long longStruct_Elem1 = arg1.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longStruct_Elem2 = arg1.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ longStructSegmt.set(JAVA_LONG, 0, longStruct_Elem1);
+ longStructSegmt.set(JAVA_LONG, 8, longStruct_Elem2);
+ return longStructSegmt;
+ }
+
+ public static Addressable add2LongStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ long longSum_Elem1 = arg1Addr.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longSum_Elem2 = arg1Addr.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ arg1Addr.set(JAVA_LONG, 0, longSum_Elem1);
+ arg1Addr.set(JAVA_LONG, 8, longSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3LongStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"), JAVA_LONG.withName("elem3"));
+ MemorySegment longStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ long longStruct_Elem1 = arg1.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longStruct_Elem2 = arg1.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ long longStruct_Elem3 = arg1.get(JAVA_LONG, 16) + arg2.get(JAVA_LONG, 16);
+ longStructSegmt.set(JAVA_LONG, 0, longStruct_Elem1);
+ longStructSegmt.set(JAVA_LONG, 8, longStruct_Elem2);
+ longStructSegmt.set(JAVA_LONG, 16, longStruct_Elem3);
+ return longStructSegmt;
+ }
+
+ public static float addFloatAndFloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static float addFloatAnd5FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12) + arg2.get(JAVA_FLOAT, 16);
+ return floatSum;
+ }
+
+ public static float addFloatFromPointerAndFloatsFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static Addressable addFloatFromPointerAndFloatsFromStruct_returnFloatPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ arg1Addr.set(JAVA_FLOAT, 0, floatSum);
+ return arg1Addr;
+ }
+
+ public static float addFloatAndFloatsFromStructPointer(float arg1, MemoryAddress arg2Addr) {
+ float floatSum = arg1 + arg2Addr.get(JAVA_FLOAT, 0) + arg2Addr.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct(float arg1, MemorySegment arg2) {
+ float nestedStructElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructElem2 = arg2.get(JAVA_FLOAT, 4);
+ float structElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromNestedStruct_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructElem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray(float arg1, MemorySegment arg2) {
+ float nestedFloatArrayElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedFloatArrayElem2 = arg2.get(JAVA_FLOAT, 4);
+ float structElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + nestedFloatArrayElem1 + nestedFloatArrayElem2 + structElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedFloatArrayElem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedFloatArrayElem2 = arg2.get(JAVA_FLOAT, 8);
+
+ float floatSum = arg1 + structElem1 + nestedFloatArrayElem1 + nestedFloatArrayElem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray(float arg1, MemorySegment arg2) {
+ float nestedStructArrayElem1_Elem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructArrayElem1_Elem2 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructArrayElem2_Elem1 = arg2.get(JAVA_FLOAT, 8);
+ float nestedStructArrayElem2_Elem2 = arg2.get(JAVA_FLOAT, 12);
+ float structElem2 = arg2.get(JAVA_FLOAT, 16);
+
+ float floatSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder(float arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ float nestedStructArrayElem1_Elem1 = arg2.get(JAVA_FLOAT, 4);
+ float nestedStructArrayElem1_Elem2 = arg2.get(JAVA_FLOAT, 8);
+ float nestedStructArrayElem2_Elem1 = arg2.get(JAVA_FLOAT, 12);
+ float nestedStructArrayElem2_Elem2 = arg2.get(JAVA_FLOAT, 16);
+
+ float floatSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return floatSum;
+ }
+
+ public static MemorySegment add2FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ float floatStruct_Elem1 = arg1.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatStruct_Elem2 = arg1.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ floatStructSegmt.set(JAVA_FLOAT, 0, floatStruct_Elem1);
+ floatStructSegmt.set(JAVA_FLOAT, 4, floatStruct_Elem2);
+ return floatStructSegmt;
+ }
+
+ public static Addressable add2FloatStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ float floatSum_Elem1 = arg1Addr.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatSum_Elem2 = arg1Addr.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ arg1Addr.set(JAVA_FLOAT, 0, floatSum_Elem1);
+ arg1Addr.set(JAVA_FLOAT, 4, floatSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3FloatStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ MemorySegment floatStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ float floatStruct_Elem1 = arg1.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatStruct_Elem2 = arg1.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ float floatStruct_Elem3 = arg1.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 8);
+ floatStructSegmt.set(JAVA_FLOAT, 0, floatStruct_Elem1);
+ floatStructSegmt.set(JAVA_FLOAT, 4, floatStruct_Elem2);
+ floatStructSegmt.set(JAVA_FLOAT, 8, floatStruct_Elem3);
+ return floatStructSegmt;
+ }
+
+ public static double addDoubleAndDoublesFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleFromPointerAndDoublesFromStruct(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static Addressable addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Addr.set(JAVA_DOUBLE, 0, doubleSum);
+ return arg1Addr;
+ }
+
+ public static double addDoubleAndDoublesFromStructPointer(double arg1, MemoryAddress arg2Addr) {
+ double doubleSum = arg1 + arg2Addr.get(JAVA_DOUBLE, 0) + arg2Addr.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct(double arg1, MemorySegment arg2) {
+ double nestedStructElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructElem2 = arg2.get(JAVA_DOUBLE, 8);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + nestedStructElem1 + nestedStructElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromNestedStruct_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructElem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedStructElem1 + nestedStructElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray(double arg1, MemorySegment arg2) {
+ double nestedDoubleArrayElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedDoubleArrayElem2 = arg2.get(JAVA_DOUBLE, 8);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedDoubleArrayElem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedDoubleArrayElem2 = arg2.get(JAVA_DOUBLE, 16);
+
+ double doubleSum = arg1 + structElem1 + nestedDoubleArrayElem1 + nestedDoubleArrayElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray(double arg1, MemorySegment arg2) {
+ double nestedStructArrayElem1_Elem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructArrayElem1_Elem2 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructArrayElem2_Elem1 = arg2.get(JAVA_DOUBLE, 16);
+ double nestedStructArrayElem2_Elem2 = arg2.get(JAVA_DOUBLE, 24);
+ double structElem2 = arg2.get(JAVA_DOUBLE, 32);
+
+ double doubleSum = arg1 + structElem2
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder(double arg1, MemorySegment arg2) {
+ double structElem1 = arg2.get(JAVA_DOUBLE, 0);
+ double nestedStructArrayElem1_Elem1 = arg2.get(JAVA_DOUBLE, 8);
+ double nestedStructArrayElem1_Elem2 = arg2.get(JAVA_DOUBLE, 16);
+ double nestedStructArrayElem2_Elem1 = arg2.get(JAVA_DOUBLE, 24);
+ double nestedStructArrayElem2_Elem2 = arg2.get(JAVA_DOUBLE, 32);
+
+ double doubleSum = arg1 + structElem1
+ + nestedStructArrayElem1_Elem1 + nestedStructArrayElem1_Elem2
+ + nestedStructArrayElem2_Elem1 + nestedStructArrayElem2_Elem2;
+ return doubleSum;
+ }
+
+ public static MemorySegment add2DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ double doubleStruct_Elem1 = arg1.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleStruct_Elem2 = arg1.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ doubleStructSegmt.set(JAVA_DOUBLE, 0, doubleStruct_Elem1);
+ doubleStructSegmt.set(JAVA_DOUBLE, 8, doubleStruct_Elem2);
+ return doubleStructSegmt;
+ }
+
+ public static Addressable add2DoubleStructs_returnStructPointer(MemoryAddress arg1Addr, MemorySegment arg2) {
+ double doubleSum_Elem1 = arg1Addr.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleSum_Elem2 = arg1Addr.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Addr.set(JAVA_DOUBLE, 0, doubleSum_Elem1);
+ arg1Addr.set(JAVA_DOUBLE, 8, doubleSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add3DoubleStructs_returnStruct(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"), JAVA_DOUBLE.withName("elem3"));
+ MemorySegment doubleStructSegmt = MemorySegment.allocateNative(structLayout, session);
+ double doubleStruct_Elem1 = arg1.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleStruct_Elem2 = arg1.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ double doubleStruct_Elem3 = arg1.get(JAVA_DOUBLE, 16) + arg2.get(JAVA_DOUBLE, 16);
+ doubleStructSegmt.set(JAVA_DOUBLE, 0, doubleStruct_Elem1);
+ doubleStructSegmt.set(JAVA_DOUBLE, 8, doubleStruct_Elem2);
+ doubleStructSegmt.set(JAVA_DOUBLE, 16, doubleStruct_Elem3);
+ return doubleStructSegmt;
+ }
+
+ public static int addIntAndIntShortFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_SHORT, 4);
+ return intSum;
+ }
+
+ public static int addIntAndShortIntFromStruct(int arg1, MemorySegment arg2) {
+ int intSum = arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static long addIntAndIntLongFromStruct(int arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static long addIntAndLongIntFromStruct(int arg1, MemorySegment arg2) {
+ long longSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_INT, 8);
+ return longSum;
+ }
+
+ public static double addDoubleAndIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ double doubleSum = arg1 + structElem1 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_INT, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ double doubleSum = arg1 + structElem1 + structElem2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAnd2FloatsDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDouble2FloatsFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt2FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 8);
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ float structElem2 = Integer.valueOf(arg2.get(JAVA_INT, 4)).floatValue();
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + structElem2 + arg2.get(JAVA_FLOAT, 8);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntFloatDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatIntDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_INT, 4) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndLongDoubleFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static float addFloatAndInt3FloatsFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return floatSum;
+ }
+
+ public static long addLongAndLong2FloatsFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = arg2.get(JAVA_LONG, 0);
+ long structElem2 = Float.valueOf(arg2.get(JAVA_FLOAT, 8)).longValue();
+ long structElem3 = Float.valueOf(arg2.get(JAVA_FLOAT, 12)).longValue();
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static float addFloatAnd3FloatsIntFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4)
+ + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_INT, 12);
+ return floatSum;
+ }
+
+ public static long addLongAndFloatLongFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = Float.valueOf(arg2.get(JAVA_FLOAT, 0)).longValue();
+ long structElem2 = arg2.get(JAVA_LONG, 8);
+ long longSum = arg1 + structElem1 + structElem2;
+ return longSum;
+ }
+
+ public static double addDoubleAndDoubleFloatIntFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_FLOAT, 8) + arg2.get(JAVA_INT, 12);
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ double doubleSum = arg1 + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_LONG, 8);
+ return doubleSum;
+ }
+
+ public static long addLongAnd2FloatsLongFromStruct(long arg1, MemorySegment arg2) {
+ long structElem1 = Float.valueOf(arg2.get(JAVA_FLOAT, 0)).longValue();
+ long structElem2 = Float.valueOf(arg2.get(JAVA_FLOAT, 4)).longValue();
+ long structElem3 = arg2.get(JAVA_LONG, 8);
+ long longSum = arg1 + structElem1 + structElem2 + structElem3;
+ return longSum;
+ }
+
+ public static short addShortAnd3ShortsCharFromStruct(short arg1, MemorySegment arg2) {
+ short shortSum = (short)(arg1 + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2)
+ + arg2.get(JAVA_SHORT, 4) + arg2.get(JAVA_CHAR, 6));
+ return shortSum;
+ }
+
+ public static float addFloatAndIntFloatIntFloatFromStruct(float arg1, MemorySegment arg2) {
+ float floatSum = arg1 + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_FLOAT, 4)+ arg2.get(JAVA_INT, 8) + arg2.get(JAVA_FLOAT, 12);
+ return floatSum;
+ }
+
+ public static double addDoubleAndIntDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ float structElem3 = arg2.get(JAVA_FLOAT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ int structElem3 = arg2.get(JAVA_INT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleIntFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, int] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ int structElem3 = arg2.get(JAVA_INT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndFloatDoubleFloatFromStruct(double arg1, MemorySegment arg2) {
+ float structElem1 = arg2.get(JAVA_FLOAT, 0);
+ /* The size of [float, double, float] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 20 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ float structElem3 = arg2.get(JAVA_FLOAT, isAixOS ? 12 : 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndIntDoubleLongFromStruct(double arg1, MemorySegment arg2) {
+ int structElem1 = arg2.get(JAVA_INT, 0);
+ /* The size of [int, double, long] on AIX/PPC 64-bit is 16 bytes without padding by default
+ * while the same struct is 24 bytes with padding on other platforms.
+ */
+ double structElem2 = (isAixOS) ? arg2.get(JAVA_DOUBLE.withBitAlignment(32), 4) : arg2.get(JAVA_DOUBLE, 8);
+ double structElem3 = (isAixOS) ? arg2.get(JAVA_LONG.withBitAlignment(32), 12) : arg2.get(JAVA_LONG, 16);
+ double doubleSum = arg1 + structElem1 + structElem2 + structElem3;
+ return doubleSum;
+ }
+
+ public static MemorySegment return254BytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(254, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, session);
+
+ for (int i = 0; i < 254; i++) {
+ byteArrStruSegment.set(JAVA_BYTE, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+
+ public static MemorySegment return4KBytesFromStruct() {
+ SequenceLayout byteArray = MemoryLayout.sequenceLayout(4096, JAVA_BYTE);
+ GroupLayout structLayout = MemoryLayout.structLayout(byteArray);
+ MemorySegment byteArrStruSegment = MemorySegment.allocateNative(structLayout, session);
+
+ for (int i = 0; i < 4096; i++) {
+ byteArrStruSegment.set(JAVA_BYTE, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/ApiTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/ApiTests.java
new file mode 100644
index 00000000000..028a2b6e3e0
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/ApiTests.java
@@ -0,0 +1,903 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.valist;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import static org.testng.Assert.fail;
+
+import java.lang.invoke.VarHandle;
+import java.util.NoSuchElementException;
+
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.VaList;
+import static java.lang.foreign.ValueLayout.*;
+import static java.lang.foreign.VaList.Builder;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for the vararg list in VaList API specific cases.
+ */
+@Test(groups = { "level.sanity" })
+public class ApiTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ private static boolean isMacOsAarch64 = osName.contains("mac") && arch.contains("aarch64");
+ private static boolean isSysVPPC64le = osName.contains("linux") && arch.contains("ppc64");
+
+ @Test
+ public void test_emptyVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList emptyVaList = VaList.empty();
+ /* As specified in the implemention of OpenJDK, a NULL address is set to
+ * the empty va_list on Windows/x86_64, MacOS/Aarch64, Linux/ppc64le and
+ * AIX/ppc64 while the va_list without any argument is created on a fixed
+ * address on other platforms.
+ */
+ if (isWinOS || isMacOsAarch64 || isSysVPPC64le || isAixOS) {
+ Assert.assertEquals(emptyVaList.address(), MemoryAddress.NULL);
+ } else {
+ Assert.assertNotEquals(emptyVaList.address(), MemoryAddress.NULL);
+ }
+ }
+ }
+
+ @Test
+ public void test_vaListSession() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 100), session);
+ MemorySession vaListSession = vaList.session();
+ Assert.assertEquals(vaListSession, session);
+ }
+ }
+
+ @Test
+ public void test_checkIntVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900), session);
+
+ Assert.assertEquals(vaList.nextVarg(JAVA_INT), 700); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_INT), 800); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_INT), 900); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkLongVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L), session);
+
+ Assert.assertEquals(vaList.nextVarg(JAVA_LONG), 700000L); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_LONG), 800000L); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_LONG), 900000L); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkDoubleVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 111150.1001D)
+ .addVarg(JAVA_DOUBLE, 111160.2002D)
+ .addVarg(JAVA_DOUBLE, 111170.1001D), session);
+
+ Assert.assertEquals(vaList.nextVarg(JAVA_DOUBLE), 111150.1001D, 0.0001D); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_DOUBLE), 111160.2002D, 0.0001D); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(JAVA_DOUBLE), 111170.1001D, 0.0001D); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkIntPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address()), session);
+
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), intSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), intSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), intSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkLongPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address()), session);
+
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), longSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), longSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), longSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkDoublePtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 111150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 111160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 111170.1001D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address()), session);
+
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), doubleSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), doubleSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), doubleSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_checkIntStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(argSegmt), 1122333); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(intHandle2.get(argSegmt), 4455666); /* the 2nd element of the 1st struct argument */
+ argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(argSegmt), 2244668); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(intHandle2.get(argSegmt), 1133557); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_checkLongStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(argSegmt), 1122334455L); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(longHandle2.get(argSegmt), 6677889911L); /* the 2nd element of the 1st struct argument */
+ argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(argSegmt), 2233445566L); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(longHandle2.get(argSegmt), 7788991122L); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_checkLongStructVaListFromPrefixAllocator() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1), session);
+
+ MemorySegment structSegmt2 = MemorySegment.allocateNative(structLayout, session);
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, SegmentAllocator.prefixAllocator(structSegmt2));
+ Assert.assertEquals(longHandle1.get(argSegmt), 1122334455L); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(longHandle2.get(argSegmt), 6677889911L); /* the 2nd element of the 1st struct argument */
+ Assert.assertEquals(longHandle1.get(structSegmt2), 1122334455L); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(longHandle2.get(structSegmt2), 6677889911L); /* the 2nd element of the 1st struct argument */
+ }
+ }
+
+ @Test
+ public void test_checkDoubleStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 111150.1001D);
+ doubleHandle2.set(structSegmt1, 111160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 111170.1001D);
+ doubleHandle2.set(structSegmt2, 111180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(argSegmt), 111150.1001D, 0.0001D); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(argSegmt), 111160.2002D, 0.0001D); /* the 2nd element of the 1st struct argument */
+ argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(argSegmt), 111170.1001D, 0.0001D); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(argSegmt), 111180.2002D, 0.0001D); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_copyIntVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_INT), 700); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_INT), 800); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_INT), 900); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyLongVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_LONG), 700000L); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_LONG), 800000L); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_LONG), 900000L); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyDoubleVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 111150.1001D)
+ .addVarg(JAVA_DOUBLE, 111160.2002D)
+ .addVarg(JAVA_DOUBLE, 111170.1001D), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_DOUBLE), 111150.1001D, 0001D); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_DOUBLE), 111160.2002D, 0001D); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(JAVA_DOUBLE), 111170.1001D, 0001D); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyIntPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address()), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), intSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), intSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), intSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyLongPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address()), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), longSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), longSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), longSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyDoublePtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 111150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 111160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 111170.1001D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address()), session);
+ VaList resultVaList = vaList.copy();
+
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), doubleSegmt1.address()); /* the 1st argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), doubleSegmt2.address()); /* the 2nd argument */
+ Assert.assertEquals(resultVaList.nextVarg(ADDRESS), doubleSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_copyIntStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList resultVaList = vaList.copy();
+
+ MemorySegment resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(resultArgSegmt), 1122333); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(intHandle2.get(resultArgSegmt), 4455666); /* the 2nd element of the 1st struct argument */
+ resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(resultArgSegmt), 2244668); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(intHandle2.get(resultArgSegmt), 1133557); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_copyLongStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList resultVaList = vaList.copy();
+
+ MemorySegment resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(resultArgSegmt), 1122334455L); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(longHandle2.get(resultArgSegmt), 6677889911L); /* the 2nd element of the 1st struct argument */
+ resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(resultArgSegmt), 2233445566L); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(longHandle2.get(resultArgSegmt), 7788991122L); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_copyDoubleStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 111150.1001D);
+ doubleHandle2.set(structSegmt1, 111160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 111170.1001D);
+ doubleHandle2.set(structSegmt2, 111180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList resultVaList = vaList.copy();
+
+ MemorySegment resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(resultArgSegmt), 111150.1001D, 0.0001D); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(resultArgSegmt), 111160.2002D, 0.0001D); /* the 2nd element of the 1st struct argument */
+ resultArgSegmt = resultVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(resultArgSegmt), 111170.1001D, 0.0001D); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(resultArgSegmt), 111180.2002D, 0.0001D); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test(expectedExceptions = NoSuchElementException.class, expectedExceptionsMessageRegExp = "No such element.*")
+ public void test_NoMoreNextArg_IntVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900), session);
+
+ vaList.nextVarg(JAVA_INT); /* the 1st argument */
+ vaList.nextVarg(JAVA_INT); /* the 2nd argument */
+ vaList.nextVarg(JAVA_INT); /* the 3rd argument */
+
+ /* An exception is thrown as there is no more argument in VaList */
+ vaList.nextVarg(JAVA_INT);
+ fail("Failed to throw out NoSuchElementException when nextVarg() exceeds the memory region of VaList");
+ }
+ }
+
+ @Test
+ public void test_createIntVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ Assert.assertEquals(newVaList.nextVarg(JAVA_INT), 700); /* the 1st argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_INT), 800); /* the 2nd argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_INT), 900); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_createLongVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ Assert.assertEquals(newVaList.nextVarg(JAVA_LONG), 700000L); /* the 1st argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_LONG), 800000L); /* the 2nd argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_LONG), 900000L); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_createDoubleVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 111150.1001D)
+ .addVarg(JAVA_DOUBLE, 111160.2002D)
+ .addVarg(JAVA_DOUBLE, 111170.1001D), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ Assert.assertEquals(newVaList.nextVarg(JAVA_DOUBLE), 111150.1001D, 0.0001D); /* the 1st argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_DOUBLE), 111160.2002D, 0.0001D); /* the 2nd argument */
+ Assert.assertEquals(newVaList.nextVarg(JAVA_DOUBLE), 111170.1001D, 0.0001D); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_createIntPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address()), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemoryAddress resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 700); /* the 1st argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 800); /* the 2nd argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_INT, 0), 900); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_createLongPtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address()), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemoryAddress resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 700000L); /* the 1st argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 800000L); /* the 2nd argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_LONG, 0), 900000L); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_createDoublePtrVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 111150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 111160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 111170.1001D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address()), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemoryAddress resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 111150.1001D, 0.0001D); /* the 1st argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 111160.2002D, 0.0001D); /* the 2nd argument */
+ resultAddr = newVaList.nextVarg(ADDRESS);
+ Assert.assertEquals(resultAddr.get(JAVA_DOUBLE, 0), 111170.1001D, 0.0001D); /* the 3rd argument */
+ }
+ }
+
+ @Test(expectedExceptions = NoSuchElementException.class, expectedExceptionsMessageRegExp = "No such element.*")
+ public void test_NoMoreNextArg_IntStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+
+ vaList.nextVarg(structLayout, allocator); /* the 1st struct argument */
+ vaList.nextVarg(structLayout, allocator); /* the 2nd struct argument */
+
+ /* An exception is thrown as there is no more argument in VaList */
+ vaList.nextVarg(structLayout, allocator);
+ fail("Failed to throw out NoSuchElementException when nextVarg() exceeds the memory region of VaList");
+ }
+ }
+
+ @Test
+ public void test_createIntStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemorySegment newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(newArgSegmt), 1122333); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(intHandle2.get(newArgSegmt), 4455666); /* the 2nd element of the 1st struct argument */
+ newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(newArgSegmt), 2244668); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(intHandle2.get(newArgSegmt), 1133557); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_createLongStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemorySegment newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(newArgSegmt), 1122334455L); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals(longHandle2.get(newArgSegmt), 6677889911L); /* the 2nd element of the 1st struct argument */
+ newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(newArgSegmt), 2233445566L); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(longHandle2.get(newArgSegmt), 7788991122L); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_createDoubleStructVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11150.1001D);
+ doubleHandle2.set(structSegmt1, 11160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 11170.1001D);
+ doubleHandle2.set(structSegmt2, 11180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ VaList newVaList = VaList.ofAddress(vaList.address(), session);
+
+ MemorySegment newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(newArgSegmt), 11150.1001D, 0.0001D); /* the 1st element of the 1st struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(newArgSegmt), 11160.2002D, 0.0001D); /* the 2nd element of the 1st struct argument */
+ newArgSegmt = newVaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(newArgSegmt), 11170.1001D, 0.0001D); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(newArgSegmt), 11180.2002D, 0.0001D); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test(expectedExceptions = NoSuchElementException.class, expectedExceptionsMessageRegExp = "No such element.*")
+ public void test_NoMoreSkippedArg_IntArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_INT, 1000), session);
+ vaList.skip(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT); /* Skip over all arguments in VaList */
+
+ /* An exception is thrown as there is no more argument in VaList */
+ vaList.skip(JAVA_INT);
+ fail("Failed to throw out NoSuchElementException when skip() exceeds the memory region of VaList");
+ }
+ }
+
+ @Test
+ public void test_skipIntArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_INT, 1000), session);
+ vaList.skip(JAVA_INT);
+ Assert.assertEquals(vaList.nextVarg(JAVA_INT), 800); /* the 2nd argument */
+ vaList.skip(JAVA_INT);
+ Assert.assertEquals(vaList.nextVarg(JAVA_INT), 1000); /* the 4th argument */
+ }
+ }
+
+ @Test
+ public void test_skipLongArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L)
+ .addVarg(JAVA_LONG, 1000000L), session);
+ vaList.skip(JAVA_LONG, JAVA_LONG);
+ Assert.assertEquals(vaList.nextVarg(JAVA_LONG), 900000L); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_skipDoubleArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 111150.1001D)
+ .addVarg(JAVA_DOUBLE, 111160.2002D)
+ .addVarg(JAVA_DOUBLE, 111170.1001D)
+ .addVarg(JAVA_DOUBLE, 111180.2002D), session);
+ vaList.skip(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE);
+ Assert.assertEquals(vaList.nextVarg(JAVA_DOUBLE), 111180.2002D, 0.0001D); /* the 4th argument */
+ }
+ }
+
+ @Test
+ public void test_skipIntPtrArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+ MemorySegment intSegmt4 = allocator.allocate(JAVA_INT, 1000);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address())
+ .addVarg(ADDRESS, intSegmt4.address()), session);
+ vaList.skip(ADDRESS);
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), intSegmt2.address()); /* the 2nd argument */
+ }
+ }
+
+ @Test
+ public void test_skipLongPtrArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+ MemorySegment longSegmt4 = allocator.allocate(JAVA_LONG, 1000000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address())
+ .addVarg(ADDRESS, longSegmt4.address()), session);
+ vaList.skip(ADDRESS, ADDRESS);
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), longSegmt3.address()); /* the 3rd argument */
+ }
+ }
+
+ @Test
+ public void test_skipDoublePtrArgOfVaList() throws Throwable {
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 111150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 111160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 111170.1001D);
+ MemorySegment doubleSegmt4 = allocator.allocate(JAVA_DOUBLE, 111180.1002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address())
+ .addVarg(ADDRESS, doubleSegmt4.address()), session);
+ vaList.skip(ADDRESS, ADDRESS, ADDRESS);
+ Assert.assertEquals(vaList.nextVarg(ADDRESS), doubleSegmt4.address()); /* the 4th argument */
+ }
+ }
+
+ @Test(expectedExceptions = NoSuchElementException.class, expectedExceptionsMessageRegExp = "No such element.*")
+ public void test_NoMoreSkippedArg_IntStructOfVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ vaList.skip(structLayout, structLayout); /* Skip over all arguments in VaList */
+
+ /* An exception is thrown as there is no more argument in VaList */
+ vaList.skip(structLayout);
+ fail("Failed to throw out NoSuchElementException when skip() exceeds the memory region of VaList");
+ }
+ }
+
+ @Test
+ public void test_skipIntStructOfVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ vaList.skip(structLayout);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(intHandle1.get(argSegmt), 2244668); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(intHandle2.get(argSegmt), 1133557); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_skipLongStructOfVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ vaList.skip(structLayout);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals(longHandle1.get(argSegmt), 2233445566L); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals(longHandle2.get(argSegmt), 7788991122L); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+
+ @Test
+ public void test_skipDoubleStructOfVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11150.1001D);
+ doubleHandle2.set(structSegmt1, 11160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 11170.1001D);
+ doubleHandle2.set(structSegmt2, 11180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ vaList.skip(structLayout);
+
+ MemorySegment argSegmt = vaList.nextVarg(structLayout, allocator);
+ Assert.assertEquals((double)doubleHandle1.get(argSegmt), 11170.1001D, 0.0001D); /* the 1st element of the 2nd struct argument */
+ Assert.assertEquals((double)doubleHandle2.get(argSegmt), 11180.2002D, 0.0001D); /* the 2nd element of the 2nd struct argument */
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/DowncallTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/DowncallTests.java
new file mode 100644
index 00000000000..ac406c28b60
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/DowncallTests.java
@@ -0,0 +1,1106 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.valist;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.VaList;
+import static java.lang.foreign.ValueLayout.*;
+import static java.lang.foreign.VaList.Builder;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for the vararg list in downcall.
+ */
+@Test(groups = { "level.sanity" })
+public class DowncallTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ private static boolean isLinuxX64 = osName.contains("linux") && (arch.equals("amd64") || arch.equals("x86_64"));
+ private static boolean isLinuxAarch64 = osName.contains("linux") && arch.equals("aarch64");
+ /* The padding of struct is not required on Power in terms of VaList */
+ private static boolean isStructPaddingNotRequired = arch.startsWith("ppc64");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+ private static final SymbolLookup defaultLibLookup = linker.defaultLookup();
+
+ @Test
+ public void test_addIntsFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_INT, 1000), session);
+ int result = (int)mh.invoke(4, vaList);
+ Assert.assertEquals(result, 3400);
+ }
+ }
+
+ @Test
+ public void test_addLongsFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L)
+ .addVarg(JAVA_LONG, 1000000L), session);
+ long result = (long)mh.invoke(4, vaList);
+ Assert.assertEquals(result, 3400000L);
+ }
+ }
+
+ @Test
+ public void test_addDoublesFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoublesFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 150.1001D)
+ .addVarg(JAVA_DOUBLE, 160.2002D)
+ .addVarg(JAVA_DOUBLE, 170.1001D)
+ .addVarg(JAVA_DOUBLE, 180.2002D), session);
+ double result = (double)mh.invoke(4, vaList);
+ Assert.assertEquals(result, 660.6006D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_addMixedArgsFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addMixedArgsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_DOUBLE, 160.2002D), session);
+ double result = (double)mh.invoke(vaList);
+ Assert.assertEquals(result, 800860.2002D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_addMoreMixedArgsFromVaList() throws Throwable {
+ /* VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot). So the test is disabled
+ * for now till the issue is fixed by OpenJDK on Linux/x86_64.
+ */
+ if (!isLinuxX64) {
+ Addressable functionSymbol = nativeLibLookup.lookup("addMoreMixedArgsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 100)
+ .addVarg(JAVA_LONG, 200000L)
+ .addVarg(JAVA_INT, 300)
+ .addVarg(JAVA_LONG, 400000L)
+ .addVarg(JAVA_INT, 500)
+ .addVarg(JAVA_LONG, 600000L)
+ .addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_DOUBLE, 161.2001D)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_DOUBLE, 162.2002D)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_DOUBLE, 163.2003D)
+ .addVarg(JAVA_INT, 1000)
+ .addVarg(JAVA_DOUBLE, 164.2004D)
+ .addVarg(JAVA_INT, 1100)
+ .addVarg(JAVA_DOUBLE, 165.2005D), session);
+ double result = (double)mh.invoke(vaList);
+ Assert.assertEquals(result, 1206216.0015D, 0.0001D);
+ }
+ }
+ }
+
+ @Test
+ public void test_addIntsByPtrFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntsByPtrFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address()), session);
+ int result = (int)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 2400);
+ }
+ }
+
+ @Test
+ public void test_addLongsByPtrFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongsByPtrFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address()), session);
+ long result = (long)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 2400000L);
+ }
+ }
+
+ @Test
+ public void test_addDoublesByPtrFromVaList() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoublesByPtrFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 111150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 111160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 111170.1001D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address()), session);
+ double result = (double)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 333480.4004D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_add1ByteOfStructsFromVaList() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ByteOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)2);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt3, (byte)3);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt4, (byte)4);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt5, (byte)5);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt6, (byte)6);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt7, (byte)7);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt8, (byte)8);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt9, (byte)9);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt10, (byte)10);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ byte result = (byte)mh.invoke(10, vaList);
+ Assert.assertEquals(result, 55);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2BytesOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BytesOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)3);
+ byteHandle2.set(structSegmt2, (byte)4);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ byte result = (byte)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 10);
+ }
+ }
+
+ @Test
+ public void test_add3BytesOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BytesOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)4);
+ byteHandle2.set(structSegmt2, (byte)5);
+ byteHandle3.set(structSegmt2, (byte)6);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ byte result = (byte)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 21);
+ }
+ }
+
+ @Test
+ public void test_add5BytesOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"), JAVA_BYTE.withName("elem4"), JAVA_BYTE.withName("elem5"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add5BytesOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ byteHandle4.set(structSegmt1, (byte)4);
+ byteHandle5.set(structSegmt1, (byte)5);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)6);
+ byteHandle2.set(structSegmt2, (byte)7);
+ byteHandle3.set(structSegmt2, (byte)8);
+ byteHandle4.set(structSegmt2, (byte)9);
+ byteHandle5.set(structSegmt2, (byte)10);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ byte result = (byte)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 55);
+ }
+ }
+
+ @Test
+ public void test_add7BytesOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"), JAVA_BYTE.withName("elem4"),
+ JAVA_BYTE.withName("elem5"), JAVA_BYTE.withName("elem6"), JAVA_BYTE.withName("elem7"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+ VarHandle byteHandle6 = structLayout.varHandle(PathElement.groupElement("elem6"));
+ VarHandle byteHandle7 = structLayout.varHandle(PathElement.groupElement("elem7"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add7BytesOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ byteHandle4.set(structSegmt1, (byte)4);
+ byteHandle5.set(structSegmt1, (byte)5);
+ byteHandle6.set(structSegmt1, (byte)6);
+ byteHandle7.set(structSegmt1, (byte)7);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)8);
+ byteHandle2.set(structSegmt2, (byte)9);
+ byteHandle3.set(structSegmt2, (byte)10);
+ byteHandle4.set(structSegmt2, (byte)11);
+ byteHandle5.set(structSegmt2, (byte)12);
+ byteHandle6.set(structSegmt2, (byte)13);
+ byteHandle7.set(structSegmt2, (byte)14);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ byte result = (byte)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 105);
+ }
+ }
+
+ @Test
+ public void test_add7BytesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"), JAVA_BYTE.withName("elem4"),
+ JAVA_BYTE.withName("elem5"), JAVA_BYTE.withName("elem6"), JAVA_BYTE.withName("elem7"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+ VarHandle byteHandle6 = structLayout.varHandle(PathElement.groupElement("elem6"));
+ VarHandle byteHandle7 = structLayout.varHandle(PathElement.groupElement("elem7"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add7BytesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ byteHandle4.set(structSegmt1, (byte)4);
+ byteHandle5.set(structSegmt1, (byte)5);
+ byteHandle6.set(structSegmt1, (byte)6);
+ byteHandle7.set(structSegmt1, (byte)7);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)8);
+ byteHandle2.set(structSegmt2, (byte)9);
+ byteHandle3.set(structSegmt2, (byte)10);
+ byteHandle4.set(structSegmt2, (byte)11);
+ byteHandle5.set(structSegmt2, (byte)12);
+ byteHandle6.set(structSegmt2, (byte)13);
+ byteHandle7.set(structSegmt2, (byte)14);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add7BytesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 105);
+ }
+ }
+
+ @Test
+ public void test_add1ShortOfStructsFromVaList() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ShortOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt3, (short)333);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt4, (short)444);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt5, (short)555);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt6, (short)666);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt7, (short)777);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt8, (short)888);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt9, (short)999);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt10, (short)123);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ short result = (short)mh.invoke(10, vaList);
+ Assert.assertEquals(result, 5118);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2ShortsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ shortHandle2.set(structSegmt1, (short)222);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)333);
+ shortHandle2.set(structSegmt2, (short)444);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ short result = (short)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_add3ShortsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), JAVA_SHORT.withName("elem3"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ shortHandle2.set(structSegmt1, (short)222);
+ shortHandle3.set(structSegmt1, (short)333);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)444);
+ shortHandle2.set(structSegmt2, (short)555);
+ shortHandle3.set(structSegmt2, (short)666);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ short result = (short)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_add1IntOfStructsFromVaList() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1IntOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt3, 3333333);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt4, 4444444);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt5, 5555555);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt6, 6666666);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt7, 7777777);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt8, 8888888);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt9, 9999999);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt10, 1234567);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ int result = (int)mh.invoke(10, vaList);
+ Assert.assertEquals(result, 51234562);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2IntsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ int result = (int)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 8956224);
+ }
+ }
+
+ @Test
+ public void test_add3IntsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ intHandle3.set(structSegmt1, 7788999);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 1133555);
+ intHandle2.set(structSegmt2, 2244666);
+ intHandle3.set(structSegmt2, 3322111);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ int result = (int)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 20067330);
+ }
+ }
+
+ @Test
+ public void test_add2LongsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ long result = (long)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 17822661054L);
+ }
+ }
+
+ @Test
+ public void test_add1FloatOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1FloatOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 2.22F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 3.33F);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 4.44F);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 5.56F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5), session);
+ float result = (float)mh.invoke(5, vaList);
+ Assert.assertEquals(result, 16.66F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ floatHandle2.set(structSegmt1, 2.22F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 3.33F);
+ floatHandle2.set(structSegmt2, 4.44F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 5.55F);
+ floatHandle2.set(structSegmt3, 6.66F);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 7.77F);
+ floatHandle2.set(structSegmt4, 8.88F);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 9.99F);
+ floatHandle2.set(structSegmt5, 1.23F);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt6, 4.56F);
+ floatHandle2.set(structSegmt6, 7.89F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6), session);
+ float result = (float)mh.invoke(6, vaList);
+ Assert.assertEquals(result, 63.63F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatsOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), MemoryLayout.paddingLayout(32));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatsOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ floatHandle2.set(structSegmt1, 2.22F);
+ floatHandle3.set(structSegmt1, 3.33F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 4.44F);
+ floatHandle2.set(structSegmt2, 5.55F);
+ floatHandle3.set(structSegmt2, 6.66F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 7.77F);
+ floatHandle2.set(structSegmt3, 8.88F);
+ floatHandle3.set(structSegmt3, 9.99F);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 1.23F);
+ floatHandle2.set(structSegmt4, 4.56F);
+ floatHandle3.set(structSegmt4, 7.89F);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 9.87F);
+ floatHandle2.set(structSegmt5, 6.54F);
+ floatHandle3.set(structSegmt5, 3.21F);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt6, 2.46F);
+ floatHandle2.set(structSegmt6, 8.13F);
+ floatHandle3.set(structSegmt6, 5.79F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6), session);
+ float result = (float)mh.invoke(6, vaList);
+ Assert.assertEquals(result, 99.63F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add1DoubleOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1DoubleOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 11111.1001D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 11111.1002D);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 11111.1003D);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 11111.1004D);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 11111.1005D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5), session);
+ double result = (double)mh.invoke(5, vaList);
+ Assert.assertEquals(result, 55555.5015D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoublesOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoublesOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11150.1001D);
+ doubleHandle2.set(structSegmt1, 11160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 11170.1001D);
+ doubleHandle2.set(structSegmt2, 11180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ double result = (double)mh.invoke(2, vaList);
+ Assert.assertEquals(result, 44660.6006D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_vprintfFromDefaultLibFromVaList() throws Throwable {
+ /* 1) Disable the test on Windows given a misaligned access exception coming from
+ * java.base/java.lang.invoke.MemoryAccessVarHandleBase triggered by CLinker.toCString()
+ * is also captured on OpenJDK/Hotspot.
+ * 2) Disable the test on AIX as Valist is not yet implemented in OpenJDK.
+ */
+ if (!isWinOS && !isAixOS) {
+ Addressable functionSymbol = defaultLibLookup.lookup("vprintf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment formatSegmt = allocator.allocateUtf8String("%d * %d = %d\n");
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 7)
+ .addVarg(JAVA_INT, 8)
+ .addVarg(JAVA_INT, 56), session);
+ mh.invoke(formatSegmt, vaList);
+ }
+ }
+ }
+
+ @Test
+ public void test_addIntShortOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntShortOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1111111);
+ elemHandle2.set(structSegmt1, (short)123);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2222222);
+ elemHandle2.set(structSegmt2, (short)456);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3333333);
+ elemHandle2.set(structSegmt3, (short)789);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ int result = (int)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 6668034);
+ }
+ }
+
+ @Test
+ public void test_addShortIntOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortIntOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, (short)123);
+ elemHandle2.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, (short)456);
+ elemHandle2.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, (short)789);
+ elemHandle2.set(structSegmt3, 3333333);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ int result = (int)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 6668034);
+ }
+ }
+
+ @Test
+ public void test_addIntLongOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntLongOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1111111);
+ elemHandle2.set(structSegmt1, 101010101010L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2222222);
+ elemHandle2.set(structSegmt2, 202020202020L);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3333333);
+ elemHandle2.set(structSegmt3, 303030303030L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ long result = (long)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 606067272726L);
+ }
+ }
+
+ @Test
+ public void test_addLongIntOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongIntOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 101010101010L);
+ elemHandle2.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 202020202020L);
+ elemHandle2.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 303030303030L);
+ elemHandle2.set(structSegmt3, 3333333);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ long result = (long)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 606067272726L);
+ }
+ }
+
+ @Test
+ public void test_addFloatDoubleOfStructsFromVaList() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatDoubleOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1.11F);
+ elemHandle2.set(structSegmt1, 222.222D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2.22F);
+ elemHandle2.set(structSegmt2, 333.333D);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3.33F);
+ elemHandle2.set(structSegmt3, 444.444D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ double result = (double)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 1006.659D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFloatOfStructsFromVaList() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFloatOfStructsFromVaList").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 222.222D);
+ elemHandle2.set(structSegmt1, 1.11F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 333.333D);
+ elemHandle2.set(structSegmt2, 2.22F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 444.444D);
+ elemHandle2.set(structSegmt3, 3.33F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ double result = (double)mh.invoke(3, vaList);
+ Assert.assertEquals(result, 1006.659D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/UpcallTests.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/UpcallTests.java
new file mode 100644
index 00000000000..5cd53b94045
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/UpcallTests.java
@@ -0,0 +1,1121 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.valist;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+
+import java.lang.foreign.Addressable;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.VaList;
+import static java.lang.foreign.ValueLayout.*;
+import static java.lang.foreign.VaList.Builder;
+
+/**
+ * Test cases for JEP 424: Foreign Linker API (Preview) for the vararg list in upcall.
+ */
+@Test(groups = { "level.sanity" })
+public class UpcallTests {
+ private static String osName = System.getProperty("os.name").toLowerCase();
+ private static String arch = System.getProperty("os.arch").toLowerCase();
+ private static boolean isAixOS = osName.contains("aix");
+ private static boolean isWinOS = osName.contains("win");
+ private static boolean isLinuxX64 = osName.contains("linux") && (arch.equals("amd64") || arch.equals("x86_64"));
+ private static boolean isLinuxAarch64 = osName.contains("linux") && arch.equals("aarch64");
+ /* The padding of struct is not required on Power in terms of VaList */
+ private static boolean isStructPaddingNotRequired = arch.startsWith("ppc64");
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test
+ public void test_addIntsFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_INT, 1000), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addIntsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(4, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 3400);
+ }
+ }
+
+ @Test
+ public void test_addLongsFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_LONG, 700000L)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_LONG, 900000L)
+ .addVarg(JAVA_LONG, 1000000L), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addLongsFromVaList,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS), session);
+
+ long result = (long)mh.invoke(4, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 3400000L);
+ }
+ }
+
+ @Test
+ public void test_addDoublesFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoublesFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_DOUBLE, 111150.1001D)
+ .addVarg(JAVA_DOUBLE, 111160.2002D)
+ .addVarg(JAVA_DOUBLE, 111170.1001D)
+ .addVarg(JAVA_DOUBLE, 111180.2002D), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addDoublesFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(4, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 444660.6006D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_addMixedArgsFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addMixedArgsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_LONG, 800000L)
+ .addVarg(JAVA_DOUBLE, 160.2002D), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addMixedArgsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS), session);
+
+ double result = (double)mh.invoke(vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 800860.2002D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_addMoreMixedArgsFromVaListByUpcallMH() throws Throwable {
+ /* VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot). So the test is disabled
+ * for now till the issue is fixed by OpenJDK on Linux/x86_64.
+ */
+ if (!isLinuxX64) {
+ Addressable functionSymbol = nativeLibLookup.lookup("addMoreMixedArgsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(JAVA_INT, 100)
+ .addVarg(JAVA_LONG, 200000L)
+ .addVarg(JAVA_INT, 300)
+ .addVarg(JAVA_LONG, 400000L)
+ .addVarg(JAVA_INT, 500)
+ .addVarg(JAVA_LONG, 600000L)
+ .addVarg(JAVA_INT, 700)
+ .addVarg(JAVA_DOUBLE, 161.2001D)
+ .addVarg(JAVA_INT, 800)
+ .addVarg(JAVA_DOUBLE, 162.2002D)
+ .addVarg(JAVA_INT, 900)
+ .addVarg(JAVA_DOUBLE, 163.2003D)
+ .addVarg(JAVA_INT, 1000)
+ .addVarg(JAVA_DOUBLE, 164.2004D)
+ .addVarg(JAVA_INT, 1100)
+ .addVarg(JAVA_DOUBLE, 165.2005D), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addMoreMixedArgsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS), session);
+
+ double result = (double)mh.invoke(vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 1206216.0015D, 0.0001D);
+ }
+ }
+ }
+
+ @Test
+ public void test_addIntsByPtrFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntsByPtrFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment intSegmt1 = allocator.allocate(JAVA_INT, 700);
+ MemorySegment intSegmt2 = allocator.allocate(JAVA_INT, 800);
+ MemorySegment intSegmt3 = allocator.allocate(JAVA_INT, 900);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, intSegmt1.address())
+ .addVarg(ADDRESS, intSegmt2.address())
+ .addVarg(ADDRESS, intSegmt3.address()), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addIntsByPtrFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 2400);
+ }
+ }
+
+ @Test
+ public void test_addLongsByPtrFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongsByPtrFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment longSegmt1 = allocator.allocate(JAVA_LONG, 700000L);
+ MemorySegment longSegmt2 = allocator.allocate(JAVA_LONG, 800000L);
+ MemorySegment longSegmt3 = allocator.allocate(JAVA_LONG, 900000L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, longSegmt1.address())
+ .addVarg(ADDRESS, longSegmt2.address())
+ .addVarg(ADDRESS, longSegmt3.address()), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addLongsByPtrFromVaList,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS), session);
+
+ long result = (long)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 2400000L);
+ }
+ }
+
+ @Test
+ public void test_addDoublesByPtrFromVaListByUpcallMH() throws Throwable {
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoublesByPtrFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment doubleSegmt1 = allocator.allocate(JAVA_DOUBLE, 150.1001D);
+ MemorySegment doubleSegmt2 = allocator.allocate(JAVA_DOUBLE, 160.2002D);
+ MemorySegment doubleSegmt3 = allocator.allocate(JAVA_DOUBLE, 170.1001D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(ADDRESS, doubleSegmt1.address())
+ .addVarg(ADDRESS, doubleSegmt2.address())
+ .addVarg(ADDRESS, doubleSegmt3.address()), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addDoublesByPtrFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 480.4004D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_add1ByteOfStructsFromVaListByUpcallMH() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ByteOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)2);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt3, (byte)3);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt4, (byte)4);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt5, (byte)5);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt6, (byte)6);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt7, (byte)7);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt8, (byte)8);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt9, (byte)9);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt10, (byte)10);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add1ByteOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(10, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 55);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2BytesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2BytesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)3);
+ byteHandle2.set(structSegmt2, (byte)4);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2BytesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 10);
+ }
+ }
+
+ @Test
+ public void test_add3BytesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3BytesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)4);
+ byteHandle2.set(structSegmt2, (byte)5);
+ byteHandle3.set(structSegmt2, (byte)6);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add3BytesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 21);
+ }
+ }
+
+ @Test
+ public void test_add5BytesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"), JAVA_BYTE.withName("elem4"), JAVA_BYTE.withName("elem5"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add5BytesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ byteHandle4.set(structSegmt1, (byte)4);
+ byteHandle5.set(structSegmt1, (byte)5);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)6);
+ byteHandle2.set(structSegmt2, (byte)7);
+ byteHandle3.set(structSegmt2, (byte)8);
+ byteHandle4.set(structSegmt2, (byte)9);
+ byteHandle5.set(structSegmt2, (byte)10);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add5BytesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 55);
+ }
+ }
+
+ @Test
+ public void test_add7BytesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"), JAVA_BYTE.withName("elem4"),
+ JAVA_BYTE.withName("elem5"), JAVA_BYTE.withName("elem6"), JAVA_BYTE.withName("elem7"));
+ VarHandle byteHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle byteHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle byteHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle byteHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle byteHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+ VarHandle byteHandle6 = structLayout.varHandle(PathElement.groupElement("elem6"));
+ VarHandle byteHandle7 = structLayout.varHandle(PathElement.groupElement("elem7"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add7BytesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt1, (byte)1);
+ byteHandle2.set(structSegmt1, (byte)2);
+ byteHandle3.set(structSegmt1, (byte)3);
+ byteHandle4.set(structSegmt1, (byte)4);
+ byteHandle5.set(structSegmt1, (byte)5);
+ byteHandle6.set(structSegmt1, (byte)6);
+ byteHandle7.set(structSegmt1, (byte)7);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ byteHandle1.set(structSegmt2, (byte)8);
+ byteHandle2.set(structSegmt2, (byte)9);
+ byteHandle3.set(structSegmt2, (byte)10);
+ byteHandle4.set(structSegmt2, (byte)11);
+ byteHandle5.set(structSegmt2, (byte)12);
+ byteHandle6.set(structSegmt2, (byte)13);
+ byteHandle7.set(structSegmt2, (byte)14);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add7BytesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_INT, ADDRESS), session);
+
+ byte result = (byte)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 105);
+ }
+ }
+
+ @Test
+ public void test_add1ShortOfStructsFromVaListByUpcallMH() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1ShortOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt3, (short)333);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt4, (short)444);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt5, (short)555);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt6, (short)666);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt7, (short)777);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt8, (short)888);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt9, (short)999);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt10, (short)123);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add1ShortOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS), session);
+
+ short result = (short)mh.invoke(10, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 5118);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2ShortsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2ShortsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ shortHandle2.set(structSegmt1, (short)222);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)333);
+ shortHandle2.set(structSegmt2, (short)444);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2ShortsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS), session);
+
+ short result = (short)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 1110);
+ }
+ }
+
+ @Test
+ public void test_add3ShortsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), JAVA_SHORT.withName("elem3"));
+ VarHandle shortHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle shortHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle shortHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3ShortsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt1, (short)111);
+ shortHandle2.set(structSegmt1, (short)222);
+ shortHandle3.set(structSegmt1, (short)333);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ shortHandle1.set(structSegmt2, (short)444);
+ shortHandle2.set(structSegmt2, (short)555);
+ shortHandle3.set(structSegmt2, (short)666);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add3ShortsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_INT, ADDRESS), session);
+
+ short result = (short)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 2331);
+ }
+ }
+
+ @Test
+ public void test_add1IntOfStructsFromVaListByUpcallMH() throws Throwable {
+ /* There are a few issues with the test on some platforms as follows:
+ * 1) VaList on Linux/x86_64 in OpenJDK is unable to handle the va_list with
+ * over 8 arguments (confirmed by OpenJDK/Hotspot).
+ * 2) VaList on Linux/Aarch64 in OpenJDK has problem in supporting the struct
+ * with only one integral element (confirmed by OpenJDK/Hotspot).
+ * Thus, the test is disabled on both these platforms for now till these issues
+ * are fixed in OpenJDK and verified on OpenJDK/Hotspot in the future.
+ */
+ if (!isLinuxX64 && !isLinuxAarch64) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1IntOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt3, 3333333);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt4, 4444444);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt5, 5555555);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt6, 6666666);
+ MemorySegment structSegmt7 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt7, 7777777);
+ MemorySegment structSegmt8 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt8, 8888888);
+ MemorySegment structSegmt9 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt9, 9999999);
+ MemorySegment structSegmt10 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt10, 1234567);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6)
+ .addVarg(structLayout, structSegmt7)
+ .addVarg(structLayout, structSegmt8)
+ .addVarg(structLayout, structSegmt9)
+ .addVarg(structLayout, structSegmt10), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add1IntOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(10, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 51234562);
+ }
+ }
+ }
+
+ @Test
+ public void test_add2IntsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2IntsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 2244668);
+ intHandle2.set(structSegmt2, 1133557);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2IntsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 8956224);
+ }
+ }
+
+ @Test
+ public void test_add3IntsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle intHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3IntsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt1, 1122333);
+ intHandle2.set(structSegmt1, 4455666);
+ intHandle3.set(structSegmt1, 7788999);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ intHandle1.set(structSegmt2, 1133555);
+ intHandle2.set(structSegmt2, 2244666);
+ intHandle3.set(structSegmt2, 3322111);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add3IntsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 20067330);
+ }
+ }
+
+ @Test
+ public void test_add2LongsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle longHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle longHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2LongsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt1, 1122334455L);
+ longHandle2.set(structSegmt1, 6677889911L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ longHandle1.set(structSegmt2, 2233445566L);
+ longHandle2.set(structSegmt2, 7788991122L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2LongsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS), session);
+
+ long result = (long)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 17822661054L);
+ }
+ }
+
+ @Test
+ public void test_add1FloatOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1FloatOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 2.22F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add1FloatOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS), session);
+
+ float result = (float)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 3.33F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add2FloatsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2FloatsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ floatHandle2.set(structSegmt1, 2.22F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 3.33F);
+ floatHandle2.set(structSegmt2, 4.44F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 5.55F);
+ floatHandle2.set(structSegmt3, 6.66F);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 7.77F);
+ floatHandle2.set(structSegmt4, 8.88F);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 9.99F);
+ floatHandle2.set(structSegmt5, 1.23F);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt6, 4.56F);
+ floatHandle2.set(structSegmt6, 7.89F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2FloatsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS), session);
+
+ float result = (float)mh.invoke(6, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 63.63F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add3FloatsOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = isStructPaddingNotRequired ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"), MemoryLayout.paddingLayout(32));
+ VarHandle floatHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle floatHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle floatHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add3FloatsOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 1.11F);
+ floatHandle2.set(structSegmt1, 2.22F);
+ floatHandle3.set(structSegmt1, 3.33F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 4.44F);
+ floatHandle2.set(structSegmt2, 5.55F);
+ floatHandle3.set(structSegmt2, 6.66F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt3, 7.77F);
+ floatHandle2.set(structSegmt3, 8.88F);
+ floatHandle3.set(structSegmt3, 9.99F);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt4, 1.23F);
+ floatHandle2.set(structSegmt4, 4.56F);
+ floatHandle3.set(structSegmt4, 7.89F);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt5, 9.87F);
+ floatHandle2.set(structSegmt5, 6.54F);
+ floatHandle3.set(structSegmt5, 3.21F);
+ MemorySegment structSegmt6 = allocator.allocate(structLayout);
+ floatHandle1.set(structSegmt6, 2.46F);
+ floatHandle2.set(structSegmt6, 8.13F);
+ floatHandle3.set(structSegmt6, 5.79F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5)
+ .addVarg(structLayout, structSegmt6), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add3FloatsOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_INT, ADDRESS), session);
+
+ float result = (float)mh.invoke(6, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 99.63F, 0.01F);
+ }
+ }
+
+ @Test
+ public void test_add1DoubleOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add1DoubleOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11111.1001D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 11111.1002D);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt3, 11111.1003D);
+ MemorySegment structSegmt4 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt4, 11111.1004D);
+ MemorySegment structSegmt5 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt5, 11111.1005D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3)
+ .addVarg(structLayout, structSegmt4)
+ .addVarg(structLayout, structSegmt5), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add1DoubleOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(5, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 55555.5015D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_add2DoublesOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle doubleHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle doubleHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("add2DoublesOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 11150.1001D);
+ doubleHandle2.set(structSegmt1, 11160.2002D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 11170.1001D);
+ doubleHandle2.set(structSegmt2, 11180.2002D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_add2DoublesOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(2, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 44660.6006D, 0.0001D);
+ }
+ }
+
+ @Test
+ public void test_addIntShortOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntShortOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1111111);
+ elemHandle2.set(structSegmt1, (short)123);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2222222);
+ elemHandle2.set(structSegmt2, (short)456);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3333333);
+ elemHandle2.set(structSegmt3, (short)789);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addIntShortOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 6668034);
+ }
+ }
+
+ @Test
+ public void test_addShortIntOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addShortIntOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, (short)123);
+ elemHandle2.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, (short)456);
+ elemHandle2.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, (short)789);
+ elemHandle2.set(structSegmt3, 3333333);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addShortIntOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), session);
+
+ int result = (int)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 6668034);
+ }
+ }
+
+ @Test
+ public void test_addIntLongOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addIntLongOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1111111);
+ elemHandle2.set(structSegmt1, 101010101010L);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2222222);
+ elemHandle2.set(structSegmt2, 202020202020L);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3333333);
+ elemHandle2.set(structSegmt3, 303030303030L);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addIntLongOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS), session);
+
+ long result = (long)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 606067272726L);
+ }
+ }
+
+ @Test
+ public void test_addLongIntOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"),
+ JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addLongIntOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 101010101010L);
+ elemHandle2.set(structSegmt1, 1111111);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 202020202020L);
+ elemHandle2.set(structSegmt2, 2222222);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 303030303030L);
+ elemHandle2.set(structSegmt3, 3333333);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addLongIntOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, ADDRESS), session);
+
+ long result = (long)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 606067272726L);
+ }
+ }
+
+ @Test
+ public void test_addFloatDoubleOfStructsFromVaListByUpcallMH() throws Throwable {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addFloatDoubleOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 1.11F);
+ elemHandle2.set(structSegmt1, 222.222D);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 2.22F);
+ elemHandle2.set(structSegmt2, 333.333D);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 3.33F);
+ elemHandle2.set(structSegmt3, 444.444D);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addFloatDoubleOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 1006.659D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addDoubleFloatOfStructsFromVaListByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ Addressable functionSymbol = nativeLibLookup.lookup("addDoubleFloatOfStructsFromVaListByUpcallMH").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (MemorySession session = MemorySession.openConfined()) {
+ SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ MemorySegment structSegmt1 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt1, 222.222D);
+ elemHandle2.set(structSegmt1, 1.11F);
+ MemorySegment structSegmt2 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt2, 333.333D);
+ elemHandle2.set(structSegmt2, 2.22F);
+ MemorySegment structSegmt3 = allocator.allocate(structLayout);
+ elemHandle1.set(structSegmt3, 444.444D);
+ elemHandle2.set(structSegmt3, 3.33F);
+
+ VaList vaList = VaList.make(vaListBuilder -> vaListBuilder.addVarg(structLayout, structSegmt1)
+ .addVarg(structLayout, structSegmt2)
+ .addVarg(structLayout, structSegmt3), session);
+ MemorySegment upcallFuncAddr = linker.upcallStub(VaListUpcallMethodHandles.MH_addDoubleFloatOfStructsFromVaList,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT, ADDRESS), session);
+
+ double result = (double)mh.invoke(3, vaList, upcallFuncAddr);
+ Assert.assertEquals(result, 1006.659D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/VaListUpcallMethodHandles.java b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/VaListUpcallMethodHandles.java
new file mode 100644
index 00000000000..f0ebe02e644
--- /dev/null
+++ b/test/functional/Java19andUp/src/org/openj9/test/jep424/valist/VaListUpcallMethodHandles.java
@@ -0,0 +1,587 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 IBM Corp. and others
+ *
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which accompanies this
+ * distribution and is available at https://www.eclipse.org/legal/epl-2.0/
+ * or the Apache License, Version 2.0 which accompanies this distribution and
+ * is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * This Source Code may also be made available under the following
+ * Secondary Licenses when the conditions for such availability set
+ * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
+ * General Public License, version 2 with the GNU Classpath
+ * Exception [1] and GNU General Public License, version 2 with the
+ * OpenJDK Assembly Exception [2].
+ *
+ * [1] https://www.gnu.org/software/classpath/license.html
+ * [2] http://openjdk.java.net/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
+ *******************************************************************************/
+package org.openj9.test.jep424.valist;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import static java.lang.invoke.MethodType.methodType;
+import java.lang.invoke.VarHandle;
+
+import static java.lang.foreign.Linker.*;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.MemoryAddress;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.MemorySession;
+import java.lang.foreign.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+import java.lang.foreign.VaList;
+
+/**
+ * The helper class that contains all upcall method handles with VaList as arguments
+ *
+ * Note: VaList is simply treated as a pointer (specified in OpenJDK) in java
+ * when va_list is passed as argument in native.
+ */
+public class VaListUpcallMethodHandles {
+ private static final Lookup lookup = MethodHandles.lookup();
+ private static MemorySession session = MemorySession.openImplicit();
+ private static SegmentAllocator allocator = SegmentAllocator.newNativeArena(session);
+ private static boolean isAixOS = System.getProperty("os.name").toLowerCase().contains("aix");
+
+ static final MethodType MT_Byte_Int_MemAddr = methodType(byte.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Short_Int_MemAddr = methodType(short.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Int_Int_MemAddr = methodType(int.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Long_Int_MemAddr = methodType(long.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Float_Int_MemAddr = methodType(float.class, int.class, MemoryAddress.class);
+ static final MethodType MT_Double_Int_MemAddr = methodType(double.class, int.class, MemoryAddress.class);
+
+ public static final MethodHandle MH_addIntsFromVaList;
+ public static final MethodHandle MH_addLongsFromVaList;
+ public static final MethodHandle MH_addDoublesFromVaList;
+ public static final MethodHandle MH_addMixedArgsFromVaList;
+ public static final MethodHandle MH_addMoreMixedArgsFromVaList;
+ public static final MethodHandle MH_addIntsByPtrFromVaList;
+ public static final MethodHandle MH_addLongsByPtrFromVaList;
+ public static final MethodHandle MH_addDoublesByPtrFromVaList;
+ public static final MethodHandle MH_add1ByteOfStructsFromVaList;
+ public static final MethodHandle MH_add2BytesOfStructsFromVaList;
+ public static final MethodHandle MH_add3BytesOfStructsFromVaList;
+ public static final MethodHandle MH_add5BytesOfStructsFromVaList;
+ public static final MethodHandle MH_add7BytesOfStructsFromVaList;
+ public static final MethodHandle MH_add1ShortOfStructsFromVaList;
+ public static final MethodHandle MH_add2ShortsOfStructsFromVaList;
+ public static final MethodHandle MH_add3ShortsOfStructsFromVaList;
+ public static final MethodHandle MH_add1IntOfStructsFromVaList;
+ public static final MethodHandle MH_add2IntsOfStructsFromVaList;
+ public static final MethodHandle MH_add3IntsOfStructsFromVaList;
+ public static final MethodHandle MH_add2LongsOfStructsFromVaList;
+ public static final MethodHandle MH_add1FloatOfStructsFromVaList;
+ public static final MethodHandle MH_add2FloatsOfStructsFromVaList;
+ public static final MethodHandle MH_add3FloatsOfStructsFromVaList;
+ public static final MethodHandle MH_add1DoubleOfStructsFromVaList;
+ public static final MethodHandle MH_add2DoublesOfStructsFromVaList;
+ public static final MethodHandle MH_addIntShortOfStructsFromVaList;
+ public static final MethodHandle MH_addShortIntOfStructsFromVaList;
+ public static final MethodHandle MH_addIntLongOfStructsFromVaList;
+ public static final MethodHandle MH_addLongIntOfStructsFromVaList;
+ public static final MethodHandle MH_addFloatDoubleOfStructsFromVaList;
+ public static final MethodHandle MH_addDoubleFloatOfStructsFromVaList;
+
+ static {
+ try {
+ MH_addIntsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addIntsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_addLongsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addLongsFromVaList", MT_Long_Int_MemAddr); //$NON-NLS-1$
+ MH_addDoublesFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addDoublesFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+ MH_addMixedArgsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addMixedArgsFromVaList", methodType(double.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addMoreMixedArgsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addMoreMixedArgsFromVaList", methodType(double.class, MemoryAddress.class)); //$NON-NLS-1$
+ MH_addIntsByPtrFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addIntsByPtrFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_addLongsByPtrFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addLongsByPtrFromVaList", MT_Long_Int_MemAddr); //$NON-NLS-1$
+ MH_addDoublesByPtrFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addDoublesByPtrFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+ MH_add1ByteOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add1ByteOfStructsFromVaList", MT_Byte_Int_MemAddr); //$NON-NLS-1$
+ MH_add2BytesOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2BytesOfStructsFromVaList", MT_Byte_Int_MemAddr); //$NON-NLS-1$
+ MH_add3BytesOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add3BytesOfStructsFromVaList", MT_Byte_Int_MemAddr); //$NON-NLS-1$
+ MH_add5BytesOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add5BytesOfStructsFromVaList", MT_Byte_Int_MemAddr); //$NON-NLS-1$
+ MH_add7BytesOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add7BytesOfStructsFromVaList", MT_Byte_Int_MemAddr); //$NON-NLS-1$
+ MH_add1ShortOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add1ShortOfStructsFromVaList", MT_Short_Int_MemAddr); //$NON-NLS-1$
+ MH_add2ShortsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2ShortsOfStructsFromVaList", MT_Short_Int_MemAddr); //$NON-NLS-1$
+ MH_add3ShortsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add3ShortsOfStructsFromVaList", MT_Short_Int_MemAddr); //$NON-NLS-1$
+ MH_add1IntOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add1IntOfStructsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_add2IntsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2IntsOfStructsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_add3IntsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add3IntsOfStructsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_add2LongsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2LongsOfStructsFromVaList", MT_Long_Int_MemAddr); //$NON-NLS-1$
+ MH_add1FloatOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add1FloatOfStructsFromVaList", MT_Float_Int_MemAddr); //$NON-NLS-1$
+ MH_add2FloatsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2FloatsOfStructsFromVaList", MT_Float_Int_MemAddr); //$NON-NLS-1$
+ MH_add3FloatsOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add3FloatsOfStructsFromVaList", MT_Float_Int_MemAddr); //$NON-NLS-1$
+ MH_add1DoubleOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add1DoubleOfStructsFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+ MH_add2DoublesOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "add2DoublesOfStructsFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+ MH_addIntShortOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addIntShortOfStructsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_addShortIntOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addShortIntOfStructsFromVaList", MT_Int_Int_MemAddr); //$NON-NLS-1$
+ MH_addIntLongOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addIntLongOfStructsFromVaList", MT_Long_Int_MemAddr); //$NON-NLS-1$
+ MH_addLongIntOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addLongIntOfStructsFromVaList", MT_Long_Int_MemAddr); //$NON-NLS-1$
+ MH_addFloatDoubleOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addFloatDoubleOfStructsFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+ MH_addDoubleFloatOfStructsFromVaList = lookup.findStatic(VaListUpcallMethodHandles.class, "addDoubleFloatOfStructsFromVaList", MT_Double_Int_MemAddr); //$NON-NLS-1$
+
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
+ }
+
+ public static int addIntsFromVaList(int argCount, MemoryAddress intVaListAddr) {
+ VaList intVaList = VaList.ofAddress(intVaListAddr, session);
+ int intSum = 0;
+ while (argCount > 0) {
+ intSum += intVaList.nextVarg(JAVA_INT);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static long addLongsFromVaList(int argCount, MemoryAddress longVaListAddr) {
+ VaList longVaList = VaList.ofAddress(longVaListAddr, session);
+ long longSum = 0;
+ while (argCount > 0) {
+ longSum += longVaList.nextVarg(JAVA_LONG);
+ argCount--;
+ }
+ return longSum;
+ }
+
+ public static double addDoublesFromVaList(int argCount, MemoryAddress doubleVaListAddr) {
+ VaList doubleVaList = VaList.ofAddress(doubleVaListAddr, session);
+ double doubleSum = 0;
+ while (argCount > 0) {
+ doubleSum += doubleVaList.nextVarg(JAVA_DOUBLE);
+ argCount--;
+ }
+ return doubleSum;
+ }
+
+ public static double addMixedArgsFromVaList(MemoryAddress argVaListAddr) {
+ VaList argVaList = VaList.ofAddress(argVaListAddr, session);
+ double doubleSum = argVaList.nextVarg(JAVA_INT)
+ + argVaList.nextVarg(JAVA_LONG) + argVaList.nextVarg(JAVA_DOUBLE);
+ return doubleSum;
+ }
+
+ public static double addMoreMixedArgsFromVaList(MemoryAddress argVaListAddr) {
+ VaList argVaList = VaList.ofAddress(argVaListAddr, session);
+ double doubleSum = argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_LONG)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_LONG)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_LONG)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_DOUBLE)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_DOUBLE)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_DOUBLE)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_DOUBLE)
+ + argVaList.nextVarg(JAVA_INT) + argVaList.nextVarg(JAVA_DOUBLE);
+ return doubleSum;
+ }
+
+ public static int addIntsByPtrFromVaList(int argCount, MemoryAddress ptrVaListAddr) {
+ VaList ptrVaList = VaList.ofAddress(ptrVaListAddr, session);
+ int intSum = 0;
+ while (argCount > 0) {
+ intSum += ptrVaList.nextVarg(ADDRESS).get(JAVA_INT, 0);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static long addLongsByPtrFromVaList(int argCount, MemoryAddress ptrVaListAddr) {
+ VaList ptrVaList = VaList.ofAddress(ptrVaListAddr, session);
+ long longSum = 0;
+ while (argCount > 0) {
+ longSum += ptrVaList.nextVarg(ADDRESS).get(JAVA_LONG, 0);
+ argCount--;
+ }
+ return longSum;
+ }
+
+ public static double addDoublesByPtrFromVaList(int argCount, MemoryAddress ptrVaListAddr) {
+ VaList ptrVaList = VaList.ofAddress(ptrVaListAddr, session);
+ double doubleSum = 0;
+ while (argCount > 0) {
+ doubleSum += ptrVaList.nextVarg(ADDRESS).get(JAVA_DOUBLE, 0);
+ argCount--;
+ }
+ return doubleSum;
+ }
+
+ public static byte add1ByteOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ byte byteSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ byteSum += (byte)elemHandle1.get(argSegmt);
+ argCount--;
+ }
+ return byteSum;
+ }
+
+ public static byte add2BytesOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ byte byteSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ byteSum += (byte)elemHandle1.get(argSegmt) + (byte)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return byteSum;
+ }
+
+ public static byte add3BytesOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ byte byteSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ byteSum += (byte)elemHandle1.get(argSegmt) + (byte)elemHandle2.get(argSegmt) + (byte)elemHandle3.get(argSegmt);
+ argCount--;
+ }
+ return byteSum;
+ }
+
+ public static byte add5BytesOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"),
+ JAVA_BYTE.withName("elem4"), JAVA_BYTE.withName("elem5"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle elemHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+
+ byte byteSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ byteSum += (byte)elemHandle1.get(argSegmt) + (byte)elemHandle2.get(argSegmt)
+ + (byte)elemHandle3.get(argSegmt) + (byte)elemHandle4.get(argSegmt)
+ + (byte)elemHandle5.get(argSegmt);
+ argCount--;
+ }
+ return byteSum;
+ }
+
+ public static byte add7BytesOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"),
+ JAVA_BYTE.withName("elem2"), JAVA_BYTE.withName("elem3"),
+ JAVA_BYTE.withName("elem4"), JAVA_BYTE.withName("elem5"),
+ JAVA_BYTE.withName("elem6"), JAVA_BYTE.withName("elem7"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+ VarHandle elemHandle4 = structLayout.varHandle(PathElement.groupElement("elem4"));
+ VarHandle elemHandle5 = structLayout.varHandle(PathElement.groupElement("elem5"));
+ VarHandle elemHandle6 = structLayout.varHandle(PathElement.groupElement("elem6"));
+ VarHandle elemHandle7 = structLayout.varHandle(PathElement.groupElement("elem7"));
+
+ byte byteSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ byteSum += (byte)elemHandle1.get(argSegmt) + (byte)elemHandle2.get(argSegmt)
+ + (byte)elemHandle3.get(argSegmt) + (byte)elemHandle4.get(argSegmt)
+ + (byte)elemHandle5.get(argSegmt) + (byte)elemHandle6.get(argSegmt)
+ + (byte)elemHandle7.get(argSegmt);
+ argCount--;
+ }
+ return byteSum;
+ }
+
+ public static short add1ShortOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ short shortSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ shortSum += (short)elemHandle1.get(argSegmt);
+ argCount--;
+ }
+ return shortSum;
+ }
+
+ public static short add2ShortsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ short shortSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ shortSum += (short)elemHandle1.get(argSegmt) + (short)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return shortSum;
+ }
+
+ public static short add3ShortsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), JAVA_SHORT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ short shortSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ shortSum += (short)elemHandle1.get(argSegmt) + (short)elemHandle2.get(argSegmt) + (short)elemHandle3.get(argSegmt);
+ argCount--;
+ }
+ return shortSum;
+ }
+
+ public static int add1IntOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ int intSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ intSum += (int)elemHandle1.get(argSegmt);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static int add2IntsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ int intSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ intSum += (int)elemHandle1.get(argSegmt) + (int)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static int add3IntsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_INT.withName("elem2"), JAVA_INT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ int intSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ intSum += (int)elemHandle1.get(argSegmt) + (int)elemHandle2.get(argSegmt) + (int)elemHandle3.get(argSegmt);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static long add2LongsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ long longSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ longSum += (long)elemHandle1.get(argSegmt) + (long)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return longSum;
+ }
+
+ public static float add1FloatOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ float floatSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ floatSum += (float)elemHandle1.get(argSegmt);
+ argCount--;
+ }
+ return floatSum;
+ }
+
+ public static float add2FloatsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ float floatSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ floatSum += (float)elemHandle1.get(argSegmt) + (float)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return floatSum;
+ }
+
+ public static float add3FloatsOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), JAVA_FLOAT.withName("elem3"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+ VarHandle elemHandle3 = structLayout.varHandle(PathElement.groupElement("elem3"));
+
+ float floatSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ floatSum += (float)elemHandle1.get(argSegmt) + (float)elemHandle2.get(argSegmt) + (float)elemHandle3.get(argSegmt);
+ argCount--;
+ }
+ return floatSum;
+ }
+
+ public static double add1DoubleOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+
+ double doubleSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ doubleSum += (double)elemHandle1.get(argSegmt);
+ argCount--;
+ }
+ return doubleSum;
+ }
+
+ public static double add2DoublesOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ double doubleSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ doubleSum += (double)elemHandle1.get(argSegmt) + (double)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return doubleSum;
+ }
+
+ public static int addIntShortOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_SHORT.withName("elem2"), MemoryLayout.paddingLayout(16));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ int intSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ intSum += (int)elemHandle1.get(argSegmt) + (short)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static int addShortIntOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"),
+ MemoryLayout.paddingLayout(16), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ int intSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ intSum += (short)elemHandle1.get(argSegmt) + (int)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return intSum;
+ }
+
+ public static long addLongIntOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_INT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ long longSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ longSum += (long)elemHandle1.get(argSegmt) + (int)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return longSum;
+ }
+
+ public static long addIntLongOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_LONG.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ long longSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ longSum += (int)elemHandle1.get(argSegmt) + (long)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return longSum;
+ }
+
+ public static double addFloatDoubleOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ /* The size of [float, double] on AIX/PPC 64-bit is 12 bytes without padding by default
+ * while the same struct is 16 bytes with padding on other platforms.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2").withBitAlignment(32)) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(32), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ double doubleSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ doubleSum += (float)elemHandle1.get(argSegmt) + (double)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return doubleSum;
+ }
+
+ public static double addDoubleFloatOfStructsFromVaList(int argCount, MemoryAddress struVaListAddr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ double doubleSum = 0;
+ VaList struVaList = VaList.ofAddress(struVaListAddr, session);
+ while (argCount > 0) {
+ MemorySegment argSegmt = struVaList.nextVarg(structLayout, allocator);
+ doubleSum += (double)elemHandle1.get(argSegmt) + (float)elemHandle2.get(argSegmt);
+ argCount--;
+ }
+ return doubleSum;
+ }
+}
diff --git a/test/functional/Java19andUp/testng_190.xml b/test/functional/Java19andUp/testng_190.xml
index a1b84141255..9797ae5d00b 100644
--- a/test/functional/Java19andUp/testng_190.xml
+++ b/test/functional/Java19andUp/testng_190.xml
@@ -29,4 +29,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+