diff --git a/jcl/src/java.base/share/classes/java/lang/Access.java b/jcl/src/java.base/share/classes/java/lang/Access.java
index 1989d3938c0..8bbe07b0d28 100644
--- a/jcl/src/java.base/share/classes/java/lang/Access.java
+++ b/jcl/src/java.base/share/classes/java/lang/Access.java
@@ -23,6 +23,9 @@
package java.lang;
import java.lang.annotation.Annotation;
+/*[IF JAVA_SPEC_VERSION >= 22]*/
+import java.lang.foreign.MemorySegment;
+/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
/*[IF JAVA_SPEC_VERSION >= 15]*/
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
@@ -497,9 +500,16 @@ public String join(String prefix, String suffix, String delimiter, String[] elem
}
/*[IF JAVA_SPEC_VERSION >= 20]*/
+ @Override
+/*[IF JAVA_SPEC_VERSION >= 22]*/
+ public void ensureNativeAccess(Module mod, Class> clsOwner, String methodName, Class> clsCaller) {
+ mod.ensureNativeAccess(clsOwner, methodName, clsCaller);
+ }
+/*[ELSE] JAVA_SPEC_VERSION >= 22 */
public void ensureNativeAccess(Module mod, Class> clsOwner, String methodName) {
mod.ensureNativeAccess(clsOwner, methodName);
}
+/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
public void addEnableNativeAccessToAllUnnamed() {
Module.implAddEnableNativeAccessToAllUnnamed();
@@ -727,6 +737,18 @@ public String getLoaderNameID(ClassLoader loader) {
}
/*[ENDIF] JAVA_SPEC_VERSION >= 11 */
+/*[IF JAVA_SPEC_VERSION >= 22]*/
+ @Override
+ public boolean bytesCompatible(String string, Charset charset) {
+ return string.bytesCompatible(charset);
+ }
+
+ @Override
+ public void copyToSegmentRaw(String string, MemorySegment segment, long offset) {
+ string.copyToSegmentRaw(segment, offset);
+ }
+/*[ENDIF] JAVA_SPEC_VERSION >= 22 */
+
/*[IF INLINE-TYPES]*/
@Override
public boolean isPrimitiveClass(Class> c) {
diff --git a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java
index 830558b9af8..c784ca7c1df 100644
--- a/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java
+++ b/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java
@@ -764,7 +764,17 @@ Object runNativeMethod(Addressable downcallAddr, SegmentAllocator segmtAllocator
/*[IF JAVA_SPEC_VERSION >= 21]*/
try (Arena arena = Arena.ofConfined()) {
SetDependency(arena.scope());
- returnVal = invokeNative(linkerOpts.isTrivial(), getValidDowncallMemAddr(stateSegmt), retMemAddr, getValidDowncallMemAddr(downcallAddr), cifNativeThunkAddr, args);
+ returnVal = invokeNative(
+ /*[IF JAVA_SPEC_VERSION >= 22]*/
+ linkerOpts.isCritical(),
+ /*[ELSE] JAVA_SPEC_VERSION >= 22 */
+ linkerOpts.isTrivial(),
+ /*[ENDIF] JAVA_SPEC_VERSION >= 22 */
+ getValidDowncallMemAddr(stateSegmt),
+ retMemAddr,
+ getValidDowncallMemAddr(downcallAddr),
+ cifNativeThunkAddr,
+ args);
}
/*[ELSE] JAVA_SPEC_VERSION >= 21 */
acquireScope();
diff --git a/test/functional/Java21Only/build.xml b/test/functional/Java21Only/build.xml
new file mode 100644
index 00000000000..138cd920a3e
--- /dev/null
+++ b/test/functional/Java21Only/build.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+ Tests for Java 21 only
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ant version is ${ant.version}
+ ============COMPILER SETTINGS============
+ ===fork: yes
+ ===executable: ${compiler.javac}
+ ===debug: on
+ ===destdir: ${DEST}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/functional/Java21Only/playlist.xml b/test/functional/Java21Only/playlist.xml
new file mode 100644
index 00000000000..0137ed92b7a
--- /dev/null
+++ b/test/functional/Java21Only/playlist.xml
@@ -0,0 +1,81 @@
+
+
+
+
+ Jep442Tests_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_210.xml$(Q) -testnames Jep442Tests_testLinkerFfi_DownCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 21
+
+
+
+
+ Jep442Tests_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_210.xml$(Q) -testnames Jep442Tests_testLinkerFfi_UpCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 21
+
+
+
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/InvalidDownCallTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/InvalidDownCallTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/InvalidDownCallTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/InvalidDownCallTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiCallTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiCallTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiCallTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiCallTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests1.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests1.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests1.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests1.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests2.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests2.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests2.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests2.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests3.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests3.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests3.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests3.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests4.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests4.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests4.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests4.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests5.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests5.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/MultiThreadingTests5.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/MultiThreadingTests5.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests1.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests1.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests1.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests1.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests2.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests2.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests2.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/PrimitiveTypeTests2.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/StructTests1.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/StructTests1.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/StructTests1.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/StructTests1.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/StructTests2.java b/test/functional/Java21Only/src/org/openj9/test/jep442/downcall/StructTests2.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/downcall/StructTests2.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/downcall/StructTests2.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/InvalidUpCallTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/InvalidUpCallTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/InvalidUpCallTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/InvalidUpCallTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallMHTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallMHTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallMHTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallMHTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests1.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests1.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests1.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests1.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests2.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests2.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests2.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/MultiUpcallThrdsMHTests2.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithMixedSigStruTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithMixedSigStruTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithMixedSigStruTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithMixedSigStruTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithPrimTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithPrimTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithPrimTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithPrimTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithStructTests.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithStructTests.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMHWithStructTests.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMHWithStructTests.java
diff --git a/test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMethodHandles.java b/test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMethodHandles.java
similarity index 100%
rename from test/functional/Java21andUp/src/org/openj9/test/jep442/upcall/UpcallMethodHandles.java
rename to test/functional/Java21Only/src/org/openj9/test/jep442/upcall/UpcallMethodHandles.java
diff --git a/test/functional/Java21Only/testng_210.xml b/test/functional/Java21Only/testng_210.xml
new file mode 100644
index 00000000000..d159882498d
--- /dev/null
+++ b/test/functional/Java21Only/testng_210.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/functional/Java21andUp/playlist.xml b/test/functional/Java21andUp/playlist.xml
index f64ce7d9fc6..4906c3c3849 100644
--- a/test/functional/Java21andUp/playlist.xml
+++ b/test/functional/Java21andUp/playlist.xml
@@ -55,62 +55,4 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
21+
-
-
- Jep442Tests_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_210.xml$(Q) -testnames Jep442Tests_testLinkerFfi_DownCall \
- -groups $(TEST_GROUP) \
- -excludegroups $(DEFAULT_EXCLUDE); \
- $(TEST_STATUS)
-
- bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
-
- sanity
-
-
- functional
-
-
- openj9
-
-
- 21+
-
-
-
-
- Jep442Tests_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_210.xml$(Q) -testnames Jep442Tests_testLinkerFfi_UpCall \
- -groups $(TEST_GROUP) \
- -excludegroups $(DEFAULT_EXCLUDE); \
- $(TEST_STATUS)
-
- bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
-
- sanity
-
-
- functional
-
-
- openj9
-
-
- 21+
-
-
diff --git a/test/functional/Java21andUp/testng_210.xml b/test/functional/Java21andUp/testng_210.xml
index 8d5c80593af..b392280312e 100644
--- a/test/functional/Java21andUp/testng_210.xml
+++ b/test/functional/Java21andUp/testng_210.xml
@@ -23,36 +23,10 @@
-->
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/functional/Java22andUp/build.xml b/test/functional/Java22andUp/build.xml
new file mode 100644
index 00000000000..3bfdecfadde
--- /dev/null
+++ b/test/functional/Java22andUp/build.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+ Tests for Java 22 and up
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ant version is ${ant.version}
+ ============COMPILER SETTINGS============
+ ===fork: yes
+ ===executable: ${compiler.javac}
+ ===debug: on
+ ===destdir: ${DEST}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/functional/Java22andUp/playlist.xml b/test/functional/Java22andUp/playlist.xml
new file mode 100644
index 00000000000..b27a0f5379c
--- /dev/null
+++ b/test/functional/Java22andUp/playlist.xml
@@ -0,0 +1,75 @@
+
+
+
+
+ Jep454Tests_testLinkerFfi_DownCall
+ $(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_220.xml$(Q) -testnames Jep454Tests_testLinkerFfi_DownCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 22+
+
+
+
+
+ Jep454Tests_testLinkerFfi_UpCall
+ $(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_220.xml$(Q) -testnames Jep454Tests_testLinkerFfi_UpCall \
+ -groups $(TEST_GROUP) \
+ -excludegroups $(DEFAULT_EXCLUDE); \
+ $(TEST_STATUS)
+
+ bits.64,^arch.arm,^arch.riscv,^os.zos,^os.sunos
+
+ sanity
+
+
+ functional
+
+
+ openj9
+
+
+ 22+
+
+
+
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/InvalidDownCallTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/InvalidDownCallTests.java
new file mode 100644
index 00000000000..fe77e9eb988
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/InvalidDownCallTests.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.invoke.MethodHandle;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.WrongMethodTypeException;
+
+import java.lang.foreign.Arena;
+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.SegmentAllocator;
+import java.lang.foreign.SequenceLayout;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API for primitive types in downcall,
+ * which verify 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 padding layout.*")
+ public void test_invalidMemoryLayoutForIntType() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, MemoryLayout.paddingLayout(JAVA_INT.byteSize()));
+ MemorySegment functionSymbol = nativeLibLookup.find("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 padding layout.*")
+ public void test_invalidMemoryLayoutForMemAddr() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, MemoryLayout.paddingLayout(JAVA_LONG.byteSize()));
+ 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 padding layout.*")
+ public void test_invalidMemoryLayoutForReturnType() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(MemoryLayout.paddingLayout(JAVA_LONG.byteSize()), JAVA_LONG);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid MemoryLayout");
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test_nullValueForPtrArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ int result = (int)mh.invoke(19202122, null);
+ fail("Failed to throw out NullPointerException in the case of the null value");
+ }
+
+ @Test(expectedExceptions = WrongMethodTypeException.class)
+ public void test_nullValueForStructArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, null);
+ fail("Failed to throw out WrongMethodTypeException in the case of the null value");
+ }
+ }
+
+ public void test_nullSegmentForPtrArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("validateNullAddrArgument").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ int result = (int)mh.invoke(19202122, MemorySegment.NULL);
+ Assert.assertEquals(result, 19202122);
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test_nullSegmentForStructArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, MemorySegment.NULL);
+ fail("Failed to throw out NullPointerException in the case of the null segment");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Heap segment not allowed.*")
+ public void test_heapSegmentForPtrArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment structSegmt = MemorySegment.ofArray(new int[]{11121314, 15161718});
+ int result = (int)mh.invoke(19202122, structSegmt);
+ fail("Failed to throw out IllegalArgumentException in the case of the heap segment");
+ }
+
+ public void test_heapSegmentForStructArgument() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = MemorySegment.ofArray(new int[]{99001122, 33445566});
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 89113354);
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiCallTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiCallTests.java
new file mode 100644
index 00000000000..d87e28e05c9
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiCallTests.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol1 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol2 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol1 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol2 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol3 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol1 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol2 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol1 = nativeLibLookup.find("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);
+ MemorySegment functionSymbol2 = nativeLibLookup.find("add2IntsReturnVoid").get();
+ mh = linker.downcallHandle(functionSymbol2, fd2);
+ mh.invokeExact(454, 398);
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests1.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests1.java
new file mode 100644
index 00000000000..3ea332cb51f
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests1.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(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/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests2.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests2.java
new file mode 100644
index 00000000000..f6743a38c48
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests2.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.Arena;
+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.SegmentAllocator;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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 MemorySegment functionSymbol = SymbolLookup.loaderLookup().find("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() {
+ @Override
+ public void run() {
+ try {
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 89113354);
+ }
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ };
+
+ Thread thr2 = new Thread() {
+ @Override
+ public void run() {
+ try {
+ VarHandle intHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle intHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001123);
+ intHandle2.set(structSegmt2, 0L, 33445567);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224467);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 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/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests3.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests3.java
new file mode 100644
index 00000000000..9f859b83f01
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests3.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests4.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests4.java
new file mode 100644
index 00000000000..65152fa4de3
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests4.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests5.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests5.java
new file mode 100644
index 00000000000..04213e3ce4f
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/MultiThreadingTests5.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN);
+ MemorySegment functionSymbol = nativeLibLookup.find("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/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests1.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests1.java
new file mode 100644
index 00000000000..ad1778aa6a7
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests1.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API for primitive types in downcall.
+ *
+ * Note: the test suite is intended for the following Clinker API:
+ * MethodHandle downcallHandle(MemorySegment symbol, FunctionDescriptor function)
+ */
+@Test(groups = { "level.sanity" })
+public class PrimitiveTypeTests1 {
+ private static Linker linker = Linker.nativeLinker();
+ private static Arena arena = Arena.ofAuto();
+
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromPointerWithOr").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment charSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment byteSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment shortSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment intSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment longSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment floatSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment doubleSegmt = arena.allocateFrom(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 {
+ MemorySegment strlenSymbol = defaultLibLookup.find("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(strlenSymbol, fd);
+ MemorySegment funcSegmt = arena.allocateFrom("JEP454 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(funcSegmt);
+ Assert.assertEquals(strLength, 27);
+ }
+
+ @Test
+ public void test_memoryAllocFreeFromDefaultLib_1() throws Throwable {
+ MemorySegment allocSymbol = defaultLibLookup.find("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = linker.downcallHandle(allocSymbol, allocFuncDesc);
+ MemorySegment allocMemAddr = (MemorySegment)allocHandle.invokeExact(10L);
+ MemorySegment allocMemSegmt = allocMemAddr.reinterpret(10L);
+ allocMemSegmt.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemSegmt.get(JAVA_INT, 0), 15);
+
+ MemorySegment freeSymbol = defaultLibLookup.find("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = linker.downcallHandle(freeSymbol, freeFuncDesc);
+ freeHandle.invoke(allocMemAddr);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_1() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment formatSegmt = arena.allocateFrom("\n%d + %d = %d\n");
+ mh.invoke(formatSegmt, 15, 27, 42);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_LinkerOption_1() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd, Linker.Option.firstVariadicArg(1));
+ MemorySegment formatSegmt = arena.allocateFrom("\n%d + %d = %d\n");
+ mh.invoke(formatSegmt, 15, 27, 42);
+ }
+
+ @Test
+ public void test_validateTrivialOption_1() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("validateTrivialOption").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd, Linker.Option.critical());
+ int result = (int)mh.invokeExact(111);
+ Assert.assertEquals(result, 111);
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests2.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests2.java
new file mode 100644
index 00000000000..55095366a8a
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/PrimitiveTypeTests2.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.downcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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 Arena arena = Arena.ofAuto();
+
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromPointerWithOr").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment charSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment byteSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment shortSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment intSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment longSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment floatSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment doubleSegmt = arena.allocateFrom(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 {
+ MemorySegment strlenSymbol = defaultLibLookup.find("strlen").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS);
+ MethodHandle mh = linker.downcallHandle(fd);
+ MemorySegment funcSegmt = arena.allocateFrom("JEP454 DOWNCALL TEST SUITES");
+ long strLength = (long)mh.invoke(strlenSymbol, funcSegmt);
+ Assert.assertEquals(strLength, 27);
+ }
+
+ @Test
+ public void test_memoryAllocFreeFromDefaultLib_2() throws Throwable {
+ MemorySegment allocSymbol = defaultLibLookup.find("malloc").get();
+ FunctionDescriptor allocFuncDesc = FunctionDescriptor.of(ADDRESS, JAVA_LONG);
+ MethodHandle allocHandle = linker.downcallHandle(allocFuncDesc);
+ MemorySegment allocMemAddr = (MemorySegment)allocHandle.invokeExact(allocSymbol, 10L);
+ MemorySegment allocMemSegmt = allocMemAddr.reinterpret(10L);
+ allocMemSegmt.set(JAVA_INT, 0, 15);
+ Assert.assertEquals(allocMemSegmt.get(JAVA_INT, 0), 15);
+
+ MemorySegment freeSymbol = defaultLibLookup.find("free").get();
+ FunctionDescriptor freeFuncDesc = FunctionDescriptor.ofVoid(ADDRESS);
+ MethodHandle freeHandle = linker.downcallHandle(freeFuncDesc);
+ freeHandle.invoke(freeSymbol, allocMemAddr);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_2() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(fd);
+ MemorySegment formatSegmt = arena.allocateFrom("\n%d + %d = %d\n");
+ mh.invoke(functionSymbol, formatSegmt, 15, 27, 42);
+ }
+
+ @Test
+ public void test_printfFromDefaultLibWithMemAddr_LinkerOption_2() throws Throwable {
+ MemorySegment functionSymbol = defaultLibLookup.find("printf").get();
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT);
+ MethodHandle mh = linker.downcallHandle(fd, Linker.Option.firstVariadicArg(1));
+ MemorySegment formatSegmt = arena.allocateFrom("\n%d + %d = %d\n");
+ mh.invoke(functionSymbol, formatSegmt, 15, 27, 42);
+ }
+
+ @Test
+ public void test_validateTrivialOption_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT);
+ MemorySegment functionSymbol = nativeLibLookup.find("validateTrivialOption").get();
+ MethodHandle mh = linker.downcallHandle(fd, Linker.Option.critical());
+ int result = (int)mh.invokeExact(functionSymbol, 111);
+ Assert.assertEquals(result, 111);
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests1.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests1.java
new file mode 100644
index 00000000000..80d8379091b
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests1.java
@@ -0,0 +1,2959 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.Arena;
+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.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 454: Foreign Linker API 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(boolSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BOOLEAN.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultSegmt.address(), boolSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructPointerWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, true);
+ boolHandle2.set(structSegmt, 0L, 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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ boolHandle3.set(structSegmt1, 0L, true);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+ boolHandle3.set(structSegmt2, 0L, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)8);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)14);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStruct_returnBytePointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)18);
+ byteHandle2.set(structSegmt, 0L, (byte)19);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(byteSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultSegmt.address(), byteSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)11);
+ byteHandle2.set(structSegmt, 0L, (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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ byteHandle3.set(structSegmt1, 0L, (byte)12);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+ byteHandle3.set(structSegmt2, 0L, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'A');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStruct_returnCharPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, 'F');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(charSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_CHAR.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultSegmt.address(), charSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'H');
+ charHandle2.set(structSegmt, 0L, '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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ charHandle3.set(structSegmt1, 0L, 'C');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'B');
+ charHandle2.set(structSegmt2, 0L, 'C');
+ charHandle3.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)8);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)18);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStruct_returnShortPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)18);
+ shortHandle2.set(structSegmt, 0L, (short)19);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 49);
+ Assert.assertEquals(resultSegmt.address(), shortSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)22);
+ shortHandle2.set(structSegmt, 0L, (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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)56);
+ shortHandle2.set(structSegmt1, 0L, (short)45);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)78);
+ shortHandle2.set(structSegmt2, 0L, (short)67);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)134);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)56);
+ shortHandle2.set(structSegmt1, 0L, (short)45);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)78);
+ shortHandle2.set(structSegmt2, 0L, (short)67);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 134);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ShortStructs_returnStruct").get();
+
+ try (Arena arena = Arena.ofConfined()) {
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)25);
+ shortHandle2.set(structSegmt1, 0L, (short)26);
+ shortHandle3.set(structSegmt1, 0L, (short)27);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)34);
+ shortHandle2.set(structSegmt2, 0L, (short)35);
+ shortHandle3.set(structSegmt2, 0L, (short)36);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)59);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (short)61);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1122334);
+ intHandle2.set(structSegmt, 0L, 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.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntShortFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, (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.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndShortIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, (short)32766);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 7654321);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1234567);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStruct_returnIntPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 1122333);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 4455666);
+ intHandle2.set(structSegmt, 0L, 7788999);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(intSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_INT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultSegmt.address(), intSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 11121314);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ intHandle3.set(structSegmt1, 0L, 99001122);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 33445566);
+ intHandle2.set(structSegmt2, 0L, 77889900);
+ intHandle3.set(structSegmt2, 0L, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 1234567890L);
+ longHandle2.set(structSegmt, 0L, 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.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntLongFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, 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.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndLongIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 667788990011L);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 3333333333L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStruct_returnLongPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 6677889900L);
+ longHandle2.set(structSegmt, 0L, 1234567890L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(longSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_LONG.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultSegmt.address(), longSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 224466880022L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 1122334455L);
+ longHandle2.set(structSegmt1, 0L, 5566778899L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 9900112233L);
+ longHandle2.set(structSegmt2, 0L, 3344556677L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ longHandle3.set(structSegmt1, 0L, 112233445566L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+ longHandle3.set(structSegmt2, 0L, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 8.12F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStruct_returnFloatPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 19.34F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(floatSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_FLOAT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultSegmt.address(), floatSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 35.11F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ floatHandle3.set(structSegmt1, 0L, 45.67F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+ floatHandle3.set(structSegmt2, 0L, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 2228.111D);
+ doubleHandle2.set(structSegmt, 0L, 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")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 18.444F);
+ elemHandle2.set(structSegmt, 0L, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("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")) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.byteSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 18);
+ elemHandle2.set(structSegmt, 0L, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFloatFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 118.456D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 218.456D);
+ doubleHandle2.set(structSegmt, 0L, 219.789D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultSegmt.address(), doubleSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 22.111D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ doubleHandle3.set(structSegmt1, 0L, 33.123D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+ doubleHandle3.set(structSegmt2, 0L, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact((SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt, 0L), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests2.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests2.java
new file mode 100644
index 00000000000..5121148d051
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/downcall/StructTests2.java
@@ -0,0 +1,2956 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.Arena;
+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.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 454: Foreign Linker API 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, boolSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BOOLEAN.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultSegmt.address(), boolSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructPointerWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, true);
+ boolHandle2.set(structSegmt, 0L, 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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3BoolStructsWithXor_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ boolHandle3.set(structSegmt1, 0L, true);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+ boolHandle3.set(structSegmt2, 0L, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)8);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)14);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStruct_returnBytePointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)18);
+ byteHandle2.set(structSegmt, 0L, (byte)19);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, byteSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultSegmt.address(), byteSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)11);
+ byteHandle2.set(structSegmt, 0L, (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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStruct").get();
+
+ try (Arena arena = Arena.ofConfined()) {
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ByteStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ byteHandle3.set(structSegmt1, 0L, (byte)12);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+ byteHandle3.set(structSegmt2, 0L, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'A');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStruct_returnCharPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, 'F');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, charSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_CHAR.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultSegmt.address(), charSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'H');
+ charHandle2.set(structSegmt, 0L, '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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3CharStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ charHandle3.set(structSegmt1, 0L, 'C');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'B');
+ charHandle2.set(structSegmt2, 0L, 'C');
+ charHandle3.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)8);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)18);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStruct_returnShortPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)18);
+ shortHandle2.set(structSegmt, 0L, (short)19);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, shortSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 49);
+ Assert.assertEquals(resultSegmt.address(), shortSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)22);
+ shortHandle2.set(structSegmt, 0L, (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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)56);
+ shortHandle2.set(structSegmt1, 0L, (short)45);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)78);
+ shortHandle2.set(structSegmt2, 0L, (short)67);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)134);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)56);
+ shortHandle2.set(structSegmt1, 0L, (short)45);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)78);
+ shortHandle2.set(structSegmt2, 0L, (short)67);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 134);
+ Assert.assertEquals(resultSegmt.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"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ShortStructs_returnStruct").get();
+
+ try (Arena arena = Arena.ofConfined()) {
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)25);
+ shortHandle2.set(structSegmt1, 0L, (short)26);
+ shortHandle3.set(structSegmt1, 0L, (short)27);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)34);
+ shortHandle2.set(structSegmt2, 0L, (short)35);
+ shortHandle3.set(structSegmt2, 0L, (short)36);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)59);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (short)61);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1122334);
+ intHandle2.set(structSegmt, 0L, 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.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntShortFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, (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.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndShortIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, (short)32766);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 7654321);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1234567);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStruct_returnIntPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 1122333);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 4455666);
+ intHandle2.set(structSegmt, 0L, 7788999);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, intSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_INT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultSegmt.address(), intSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 11121314);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3IntStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ intHandle3.set(structSegmt1, 0L, 99001122);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 33445566);
+ intHandle2.set(structSegmt2, 0L, 77889900);
+ intHandle3.set(structSegmt2, 0L, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 1234567890L);
+ longHandle2.set(structSegmt, 0L, 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.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntLongFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, 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.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndLongIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 667788990011L);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 3333333333L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStruct_returnLongPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 6677889900L);
+ longHandle2.set(structSegmt, 0L, 1234567890L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, longSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_LONG.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultSegmt.address(), longSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 224466880022L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 1122334455L);
+ longHandle2.set(structSegmt1, 0L, 5566778899L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 9900112233L);
+ longHandle2.set(structSegmt2, 0L, 3344556677L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3LongStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ longHandle3.set(structSegmt1, 0L, 112233445566L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+ longHandle3.set(structSegmt2, 0L, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 8.12F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStruct_returnFloatPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 19.34F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, floatSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_FLOAT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultSegmt.address(), floatSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 35.11F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3FloatStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ floatHandle3.set(structSegmt1, 0L, 45.67F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+ floatHandle3.set(structSegmt2, 0L, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 2228.111D);
+ doubleHandle2.set(structSegmt, 0L, 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")) : MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 18.444F);
+ elemHandle2.set(structSegmt, 0L, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("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")) : MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ MemoryLayout.paddingLayout(JAVA_INT.byteSize()), JAVA_DOUBLE.withName("elem2"));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 18);
+ elemHandle2.set(structSegmt, 0L, 619.777D);
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFloatFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleIntFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 118.456D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 218.456D);
+ doubleHandle2.set(structSegmt, 0L, 219.789D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, doubleSegmt, structSegmt);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultSegmt.address(), doubleSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 22.111D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStructPointer").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(functionSymbol, structSegmt1, structSegmt2);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3DoubleStructs_returnStruct").get();
+ MethodHandle mh = linker.downcallHandle(fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ doubleHandle3.set(structSegmt1, 0L, 33.123D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+ doubleHandle3.set(structSegmt2, 0L, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invokeExact(functionSymbol, (SegmentAllocator)arena, structSegmt1, structSegmt2);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt, 0L), 88.579D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/InvalidUpCallTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/InvalidUpCallTests.java
new file mode 100644
index 00000000000..99445d281b0
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/InvalidUpCallTests.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+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.invoke.VarHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.Linker;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+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 454: Foreign Linker API in upcall,
+ * which verify the illegal cases including the returned segment, etc.
+ */
+@Test(groups = { "level.sanity" })
+public class InvalidUpCallTests {
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "An exception is thrown from the upcall method")
+ public void test_throwExceptionFromUpcallMethod() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_throwException,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out IllegalArgumentException from the the upcall method");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "An exception is thrown from the upcall method")
+ public void test_nestedUpcall_throwExceptionFromUpcallMethod() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_nestedUpcall,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out IllegalArgumentException from the nested upcall");
+ }
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test_nullValueForReturnPtr() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer_nullValue,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out NullPointerException in the case of the null value upon return");
+ }
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test_nullValueForReturnStruct() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_nullValue,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out NullPointerException in the case of the null value upon return");
+ }
+ }
+
+ public void test_nullSegmentForReturnPtr() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("validateReturnNullAddrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer_nullSegmt,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 11223344);
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 4), 55667788);
+ }
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test_nullSegmentForReturnStruct() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_nullSegmt,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out NullPointerException in the case of the null segment upon return");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Heap segment not allowed.*")
+ public void test_heapSegmentForReturnPtr() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer_heapSegmt,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ fail("Failed to throw out IllegalArgumentException in the case of the heap segment upon return");
+ }
+ }
+
+ public void test_heapSegmentForReturnStruct() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_heapSegmt,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 89113354);
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Not supported for upcall.*")
+ public void test_InvalidLinkerOptions_firstVariadicArg() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena, Linker.Option.firstVariadicArg(0));
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid linker option for upcall.");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Not supported for upcall.*")
+ public void test_InvalidLinkerOptions_captureCallState() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena, Linker.Option.captureCallState("errno"));
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid linker option for upcall.");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Not supported for upcall.*")
+ public void test_InvalidLinkerOptions_isTrivial_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, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena, Linker.Option.critical());
+ fail("Failed to throw out IllegalArgumentException in the case of the invalid linker option for upcall.");
+ }
+ }
+
+ @Test(expectedExceptions = IllegalThreadStateException.class, expectedExceptionsMessageRegExp = ".* wrong thread state for upcall")
+ public void test_InvalidLinkerOptions_isTrivial_2() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("captureTrivialOptionByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd, Linker.Option.critical());
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_captureTrivialOption,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT), arena);
+ int result = (int)mh.invoke(111, upcallFuncAddr);
+ fail("Failed to throw out IllegalThreadStateException in the case of the invalid upcall during the trivial downcall.");
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallMHTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallMHTests.java
new file mode 100644
index 00000000000..358c48aede6
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallMHTests.java
@@ -0,0 +1,550 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API intended for
+ * the situations when the multiple primitive specific upcalls happen within
+ * the same memory arena or from different memory arenas.
+ */
+@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_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), arena);
+ 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), arena);
+ 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), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), arena);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), arena);
+ boolean result = (boolean)mh.invoke(true, false, upcallFuncAddr);
+ Assert.assertEquals(result, true);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt1 = arena.allocateFrom(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), arena);
+ MemorySegment charSegmt2 = arena.allocateFrom(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), arena);
+ MemorySegment charSegmt3 = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'B');
+ char result = (char)mh.invoke(charSegmt, 'D', upcallFuncAddr1);
+ Assert.assertEquals(result, 'C');
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ 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), arena);
+ 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), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ byte result = (byte)mh.invoke((byte)33, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)88);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt1 = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr1 = (MemorySegment)mh.invoke(shortSegmt1, (short)555, upcallFuncAddr1);
+ MemorySegment resultSegmt1 = resultAddr1.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt1.get(JAVA_SHORT, 0), (short)999);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt2 = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr2 = (MemorySegment)mh.invoke(shortSegmt2, (short)555, upcallFuncAddr2);
+ MemorySegment resultSegmt2 = resultAddr2.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt2.get(JAVA_SHORT, 0), (short)999);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt3 = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr3 = (MemorySegment)mh.invoke(shortSegmt3, (short)555, upcallFuncAddr3);
+ MemorySegment resultSegmt3 = resultAddr3.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt3.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), (short)999);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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), arena);
+ 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), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ int result = (int)mh.invoke(111112, 111123, upcallFuncAddr);
+ Assert.assertEquals(result, 222235);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr1);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr2);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr3);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsReturnVoidByUpcallMH_DiffScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(111454, 111398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPointerByUpcallMH_SameScope() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt1 = arena.allocateFrom(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), arena);
+ MemorySegment longSegmt2 = arena.allocateFrom(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), arena);
+ MemorySegment longSegmt3 = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 5742457424L);
+ long result = (long)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ Assert.assertEquals(result, 12409155659L);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ 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), arena);
+ 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), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ float result = (float)mh.invoke(5.74F, upcallFuncAddr);
+ Assert.assertEquals(result, 12.53F, 0.01F);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr1 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt1 = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr1 = (MemorySegment)mh.invoke(doubleSegmt1, 1262.795D, upcallFuncAddr1);
+ MemorySegment resultSegmt1 = resultAddr1.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt1.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ MemorySegment upcallFuncAddr2 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt2 = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr2 = (MemorySegment)mh.invoke(doubleSegmt2, 1262.795D, upcallFuncAddr2);
+ MemorySegment resultSegmt2 = resultAddr2.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt2.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+
+ MemorySegment upcallFuncAddr3 = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt3 = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr3 = (MemorySegment)mh.invoke(doubleSegmt3, 1262.795D, upcallFuncAddr3);
+ MemorySegment resultSegmt3 = resultAddr3.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt3.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 2422.543D, 0.001D);
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests1.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests1.java
new file mode 100644
index 00000000000..68178b08965
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests1.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within different memory arenas, 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_multiUpcallThrdsWithDiffScopes() throws Throwable {
+ Thread thr1 = new Thread() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests2.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests2.java
new file mode 100644
index 00000000000..25b4fe46882
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/MultiUpcallThrdsMHTests2.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API intended for
+ * the situation when the multi-threading specific upcalls happen to the same
+ * upcall method handle within the same memory arena, 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 Arena arena = Arena.ofAuto();
+
+ 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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() {
+ @Override
+ public void run() {
+ try {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithMixedSigStruTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithMixedSigStruTests.java
new file mode 100644
index 00000000000..a7643902a13
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithMixedSigStruTests.java
@@ -0,0 +1,838 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.Arena;
+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.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 454: Foreign Linker API 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(JAVA_SHORT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntShortFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntShortFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, (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(JAVA_SHORT.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndShortIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndShortIntFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, (short)32766);
+ elemHandle2.set(structSegmt, 0L, 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(JAVA_INT.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11223344);
+ elemHandle2.set(structSegmt, 0L, 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(JAVA_INT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndLongIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndLongIntFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 667788990011L);
+ elemHandle2.set(structSegmt, 0L, 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(JAVA_INT.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 111111111);
+ elemHandle2.set(structSegmt, 0L, 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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_INT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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(JAVA_FLOAT.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 18.444F);
+ elemHandle2.set(structSegmt, 0L, 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 = isAixOS ? MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2")) : MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"),
+ JAVA_FLOAT.withName("elem2"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ VarHandle elemHandle1 = structLayout.varHandle(PathElement.groupElement("elem1"));
+ VarHandle elemHandle2 = structLayout.varHandle(PathElement.groupElement("elem2"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 218.555D);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAnd2FloatsDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAnd2FloatsDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11.22F);
+ elemHandle2.set(structSegmt, 0L, 22.33F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDouble2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDouble2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 333.444D);
+ elemHandle2.set(structSegmt, 0L, 11.22F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndInt2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 111111);
+ elemHandle2.set(structSegmt, 0L, 11.22F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11.22F);
+ elemHandle2.set(structSegmt, 0L, 111111);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndIntFloatDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntFloatDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 111111111);
+ elemHandle2.set(structSegmt, 0L, 22.33F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndFloatIntDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatIntDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 22.33F);
+ elemHandle2.set(structSegmt, 0L, 111111111);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndLongDoubleFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndLongDoubleFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 22222222222222L);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndInt3FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndInt3FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 77777777);
+ elemHandle2.set(structSegmt, 0L, 11.22F);
+ elemHandle3.set(structSegmt, 0L, 22.33F);
+ elemHandle4.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLong2FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLong2FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 777777777777L);
+ elemHandle2.set(structSegmt, 0L, 11.25F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAnd3FloatsIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAnd3FloatsIntFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11.22F);
+ elemHandle2.set(structSegmt, 0L, 22.33F);
+ elemHandle3.set(structSegmt, 0L, 44.55F);
+ elemHandle4.set(structSegmt, 0L, 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(JAVA_FLOAT.byteSize()), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndFloatLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndFloatLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 55.11F);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFloatIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFloatIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 333.444D);
+ elemHandle2.set(structSegmt, 0L, 22.33F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 33333.444D);
+ elemHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAnd2FloatsLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAnd2FloatsLongFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11.11F);
+ elemHandle2.set(structSegmt, 0L, 22.11F);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAnd3ShortsCharFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAnd3ShortsCharFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndIntFloatIntFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndIntFloatIntFloatFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 555555555);
+ elemHandle2.set(structSegmt, 0L, 11.222F);
+ elemHandle3.set(structSegmt, 0L, 666666666);
+ elemHandle4.set(structSegmt, 0L, 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"), JAVA_FLOAT.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()),
+ JAVA_DOUBLE.withName("elem2"), JAVA_FLOAT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndIntDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 7777);
+ elemHandle2.set(structSegmt, 0L, 218.555D);
+ elemHandle3.set(structSegmt, 0L, 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(JAVA_FLOAT.byteSize()),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndFloatDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 33.444F);
+ elemHandle2.set(structSegmt, 0L, 218.555D);
+ elemHandle3.set(structSegmt, 0L, 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(JAVA_INT.byteSize()),
+ JAVA_DOUBLE.withName("elem2"), JAVA_INT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndIntDoubleIntFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleIntFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 6666);
+ elemHandle2.set(structSegmt, 0L, 218.555D);
+ elemHandle3.set(structSegmt, 0L, 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(JAVA_FLOAT.byteSize()),
+ JAVA_DOUBLE.withName("elem2"), JAVA_FLOAT.withName("elem3"), MemoryLayout.paddingLayout(JAVA_FLOAT.byteSize()));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndFloatDoubleFloatFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndFloatDoubleFloatFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 11.222F);
+ elemHandle2.set(structSegmt, 0L, 218.555D);
+ elemHandle3.set(structSegmt, 0L, 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 padding in the struct [int, double, long] on AIX/PPC 64-bit is different from
+ * other platforms as follows:
+ * 1) there is no padding between int and double.
+ * 2) there is a 4-byte padding between double and long.
+ */
+ GroupLayout structLayout = isAixOS ? MemoryLayout.structLayout(JAVA_INT.withName("elem1"),
+ JAVA_DOUBLE.withName("elem2"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()), JAVA_LONG.withName("elem3"))
+ : MemoryLayout.structLayout(JAVA_INT.withName("elem1"), MemoryLayout.paddingLayout(JAVA_INT.byteSize()),
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndIntDoubleLongFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndIntDoubleLongFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ elemHandle1.set(structSegmt, 0L, 111111111);
+ elemHandle2.set(structSegmt, 0L, 619.777D);
+ elemHandle3.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("return254BytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_return254BytesFromStruct,
+ FunctionDescriptor.of(structLayout), arena);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke((SegmentAllocator)arena, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("return4KBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_return4KBytesFromStruct,
+ FunctionDescriptor.of(structLayout), arena);
+ MemorySegment byteArrStruSegment = (MemorySegment)mh.invoke((SegmentAllocator)arena, upcallFuncAddr);
+ for (int i = 0; i < 4096; i++) {
+ Assert.assertEquals(byteArrStruSegment.get(JAVA_BYTE, i), (byte)i);
+ }
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithPrimTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithPrimTests.java
new file mode 100644
index 00000000000..23ac902ad47
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithPrimTests.java
@@ -0,0 +1,716 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+
+import java.lang.invoke.MethodHandle;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.Linker;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.SymbolLookup;
+import java.lang.foreign.ValueLayout;
+import static java.lang.foreign.ValueLayout.*;
+
+/**
+ * Test cases for JEP 454: Foreign Linker API 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolsWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolsWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, JAVA_BOOLEAN), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromPointerWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), arena);
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromNativePtrWithOrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPointerWithOr,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), arena);
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BOOLEAN.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addBoolAndBoolFromPtrWithOr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolFromPtrWithOr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolFromPtrWithOr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BOOLEAN, ADDRESS), arena);
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(false, boolSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), true);
+ }
+ }
+
+ @Test
+ public void test_addTwoBytesByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BytesByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Bytes,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, JAVA_BYTE), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ MemorySegment byteSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), arena);
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)35);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_addByteAndByteFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndByteFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndByteFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_BYTE, ADDRESS), arena);
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)35);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke((byte)47, byteSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 82);
+ }
+ }
+
+ @Test
+ public void test_createNewCharFrom2CharsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFrom2CharsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFrom2Chars,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, JAVA_CHAR), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPointer,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, JAVA_CHAR), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'B');
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_CHAR.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_createNewCharFromCharAndCharFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("createNewCharFromCharAndCharFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_createNewCharFromCharAndCharFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_CHAR), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'B');
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(charSegmt, 'D', upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_CHAR.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'C');
+ }
+ }
+
+ @Test
+ public void test_addTwoShortsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Shorts,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, JAVA_SHORT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPointer,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, JAVA_SHORT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addShortAndShortFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_SHORT), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)444);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, (short)555, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 999);
+ }
+ }
+
+ @Test
+ public void test_addTwoIntsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), arena);
+ MemorySegment intSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), arena);
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 222215);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_INT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 555536);
+ }
+ }
+
+ @Test
+ public void test_addIntAndIntFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_INT, ADDRESS), arena);
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 222215);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(333321, intSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_INT.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3IntsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3Ints,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_INT, JAVA_INT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndCharByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndChar,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_CHAR), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntsReturnVoidByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntsReturnVoid,
+ FunctionDescriptor.ofVoid(JAVA_INT, JAVA_INT), arena);
+ mh.invoke(44454, 333398, upcallFuncAddr);
+ }
+ }
+
+ @Test
+ public void test_addTwoLongsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Longs,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, JAVA_LONG), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPointer,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, JAVA_LONG), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 5742457424L);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_LONG.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addLongAndLongFromPtr_RetArgPtr_ByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 5742457424L);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(longSegmt, 6666698235L, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_LONG.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 12409155659L);
+ }
+ }
+
+ @Test
+ public void test_addTwoFloatsByUpcallMH() throws Throwable {
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatsByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Floats,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ MemorySegment floatSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), arena);
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 6.79F);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_FLOAT.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, JAVA_FLOAT, ADDRESS), arena);
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 6.79F);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(5.74F, floatSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_FLOAT.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoublesByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2Doubles,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, JAVA_DOUBLE), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromNativePtrByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, JAVA_DOUBLE), arena);
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoubleFromPtr_RetPtr_ByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoubleFromPtr_RetArgPtr,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_DOUBLE), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 1159.748D);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, 1262.795D, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = defaultLibLookup.find("qsort").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_compare,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS), arena);
+ MemorySegment arraySegmt = arena.allocateFrom(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/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithStructTests.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithStructTests.java
new file mode 100644
index 00000000000..924b7b76157
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMHWithStructTests.java
@@ -0,0 +1,2785 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.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.Arena;
+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.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 454: Foreign Linker API 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 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAnd20BoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAnd20BoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, ADDRESS, structLayout), arena);
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, true);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, false);
+ boolHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment boolSegmt = arena.allocate(JAVA_BOOLEAN);
+ boolSegmt.set(JAVA_BOOLEAN, 0, false);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ structSegmt.set(JAVA_BOOLEAN, 0, false);
+ structSegmt.set(JAVA_BOOLEAN, 1, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(boolSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BOOLEAN.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), true);
+ Assert.assertEquals(resultSegmt.address(), boolSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructPointerWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructPointerWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt, 0L, true);
+ boolHandle2.set(structSegmt, 0L, 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 = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BOOLEAN.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXorByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromNestedStructWithXor_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromNestedStructWithXor_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedBoolArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_BOOLEAN.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addBoolAndBoolsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addBoolAndBoolsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BOOLEAN, JAVA_BOOLEAN, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2BoolStructsWithXor_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2BoolStructsWithXor_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 0), false);
+ Assert.assertEquals(resultSegmt.get(JAVA_BOOLEAN, 1), true);
+ }
+ }
+
+ @Test
+ public void test_add3BoolStructsWithXor_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"),
+ JAVA_BOOLEAN.withName("elem2"), JAVA_BOOLEAN.withName("elem3"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3BoolStructsWithXor_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3BoolStructsWithXor_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt1, 0L, true);
+ boolHandle2.set(structSegmt1, 0L, false);
+ boolHandle3.set(structSegmt1, 0L, true);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ boolHandle1.set(structSegmt2, 0L, true);
+ boolHandle2.set(structSegmt2, 0L, true);
+ boolHandle3.set(structSegmt2, 0L, false);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(boolHandle1.get(resultSegmt, 0L), false);
+ Assert.assertEquals(boolHandle2.get(resultSegmt, 0L), true);
+ Assert.assertEquals(boolHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)8);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAnd20BytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAnd20BytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, ADDRESS, structLayout), arena);
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)18);
+ byteHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteFromPointerAndBytesFromStruct_returnBytePointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteFromPointerAndBytesFromStruct_returnBytePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment byteSegmt = arena.allocateFrom(JAVA_BYTE, (byte)12);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)14);
+ byteHandle2.set(structSegmt, 0L, (byte)16);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(byteSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_BYTE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 42);
+ Assert.assertEquals(resultSegmt.address(), byteSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructPointer,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)11);
+ byteHandle2.set(structSegmt, 0L, (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 = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_BYTE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(byteArray.withName("array_elem1"), JAVA_BYTE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), byteArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedByteArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedByteArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(structArray.withName("struct_array_elem1"), JAVA_BYTE.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), structArray.withName("struct_array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addByteAndBytesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addByteAndBytesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add1ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add1ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ByteStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ByteStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 0), 49);
+ Assert.assertEquals(resultSegmt.get(JAVA_BYTE, 1), 24);
+ }
+ }
+
+ @Test
+ public void test_add3ByteStructs_returnStructByUpcallMH() 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"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ByteStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3ByteStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt1, 0L, (byte)25);
+ byteHandle2.set(structSegmt1, 0L, (byte)11);
+ byteHandle3.set(structSegmt1, 0L, (byte)12);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt2, 0L, (byte)24);
+ byteHandle2.set(structSegmt2, 0L, (byte)13);
+ byteHandle3.set(structSegmt2, 0L, (byte)16);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((byte)byteHandle1.get(resultSegmt, 0L), (byte)49);
+ Assert.assertEquals((byte)byteHandle2.get(resultSegmt, 0L), (byte)24);
+ Assert.assertEquals((byte)byteHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'A');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAnd10CharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAnd10CharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct,
+ FunctionDescriptor.of(JAVA_CHAR, ADDRESS, structLayout), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharFromPointerAndCharsFromStruct_returnCharPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharFromPointerAndCharsFromStruct_returnCharPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment charSegmt = arena.allocateFrom(JAVA_CHAR, 'D');
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'E');
+ charHandle2.set(structSegmt, 0L, 'F');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(charSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_CHAR.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'M');
+ Assert.assertEquals(resultSegmt.address(), charSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructPointer,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ charHandle1.set(structSegmt, 0L, 'H');
+ charHandle2.set(structSegmt, 0L, '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 = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(charArray.withName("array_elem1"), JAVA_CHAR.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), charArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedCharArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedCharArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addCharAndCharsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addCharAndCharsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_CHAR, JAVA_CHAR, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'C');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2CharStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2CharStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'C');
+ charHandle2.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 0), 'C');
+ Assert.assertEquals(resultSegmt.get(JAVA_CHAR, 2), 'E');
+ }
+ }
+
+ @Test
+ public void test_add3CharStructs_returnStructByUpcallMH() throws Throwable {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"),
+ JAVA_CHAR.withName("elem2"), JAVA_CHAR.withName("elem3"));
+ 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3CharStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3CharStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt1, 0L, 'A');
+ charHandle2.set(structSegmt1, 0L, 'B');
+ charHandle3.set(structSegmt1, 0L, 'C');
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ charHandle1.set(structSegmt2, 0L, 'B');
+ charHandle2.set(structSegmt2, 0L, 'C');
+ charHandle3.set(structSegmt2, 0L, 'D');
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(charHandle1.get(resultSegmt, 0L), 'B');
+ Assert.assertEquals(charHandle2.get(resultSegmt, 0L), 'D');
+ Assert.assertEquals(charHandle3.get(resultSegmt, 0L), '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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)888);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAnd10ShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAnd10ShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, ADDRESS, structLayout), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)1118);
+ shortHandle2.set(structSegmt, 0L, (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortFromPointerAndShortsFromStruct_returnShortPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortFromPointerAndShortsFromStruct_returnShortPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment shortSegmt = arena.allocateFrom(JAVA_SHORT, (short)1112);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)1118);
+ shortHandle2.set(structSegmt, 0L, (short)1119);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(shortSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_SHORT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 3349);
+ Assert.assertEquals(resultSegmt.address(), shortSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructPointer,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)2222);
+ shortHandle2.set(structSegmt, 0L, (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 = MemoryLayout.structLayout(nestedStructLayout.withName("struct_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), nestedStructLayout.withName("struct_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(shortArray.withName("array_elem1"), JAVA_SHORT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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 = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), shortArray.withName("array_elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedShortArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedShortArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addShortAndShortsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addShortAndShortsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)356);
+ shortHandle2.set(structSegmt1, 0L, (short)345);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)378);
+ shortHandle2.set(structSegmt2, 0L, (short)367);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)734);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2ShortStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2ShortStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)356);
+ shortHandle2.set(structSegmt1, 0L, (short)345);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)378);
+ shortHandle2.set(structSegmt2, 0L, (short)367);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 0), 734);
+ Assert.assertEquals(resultSegmt.get(JAVA_SHORT, 2), 712);
+ }
+ }
+
+ @Test
+ public void test_add3ShortStructs_returnStructByUpcallMH() 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"));
+
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3ShortStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3ShortStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt1, 0L, (short)325);
+ shortHandle2.set(structSegmt1, 0L, (short)326);
+ shortHandle3.set(structSegmt1, 0L, (short)327);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt2, 0L, (short)334);
+ shortHandle2.set(structSegmt2, 0L, (short)335);
+ shortHandle3.set(structSegmt2, 0L, (short)336);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((short)shortHandle1.get(resultSegmt, 0L), (short)659);
+ Assert.assertEquals((short)shortHandle2.get(resultSegmt, 0L), (short)661);
+ Assert.assertEquals((short)shortHandle3.get(resultSegmt, 0L), (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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1122334);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAnd5IntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAnd5IntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1111111);
+ intHandle2.set(structSegmt, 0L, 2222222);
+ intHandle3.set(structSegmt, 0L, 3333333);
+ intHandle4.set(structSegmt, 0L, 2222222);
+ intHandle5.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct,
+ FunctionDescriptor.of(JAVA_INT, ADDRESS, structLayout), arena);
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 7654321);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 1234567);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntFromPointerAndIntsFromStruct_returnIntPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntFromPointerAndIntsFromStruct_returnIntPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment intSegmt = arena.allocateFrom(JAVA_INT, 1122333);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 4455666);
+ intHandle2.set(structSegmt, 0L, 7788999);
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(intSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_INT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 13366998);
+ Assert.assertEquals(resultSegmt.address(), intSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructPointer,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ intHandle1.set(structSegmt, 0L, 11121314);
+ intHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedIntArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedIntArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addIntAndIntsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addIntAndIntsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_INT, JAVA_INT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 110224466);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 99001122);
+ intHandle2.set(structSegmt2, 0L, 33445566);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_INT, 0), 110224466);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3IntStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt1, 0L, 11223344);
+ intHandle2.set(structSegmt1, 0L, 55667788);
+ intHandle3.set(structSegmt1, 0L, 99001122);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ intHandle1.set(structSegmt2, 0L, 33445566);
+ intHandle2.set(structSegmt2, 0L, 77889900);
+ intHandle3.set(structSegmt2, 0L, 44332211);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(intHandle1.get(resultSegmt, 0L), 44668910);
+ Assert.assertEquals(intHandle2.get(resultSegmt, 0L), 133557688);
+ Assert.assertEquals(intHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 1234567890L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct,
+ FunctionDescriptor.of(JAVA_LONG, ADDRESS, structLayout), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1111111111L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 3333333333L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongFromPointerAndLongsFromStruct_returnLongPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongFromPointerAndLongsFromStruct_returnLongPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment longSegmt = arena.allocateFrom(JAVA_LONG, 1122334455L);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 6677889900L);
+ longHandle2.set(structSegmt, 0L, 1234567890L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(longSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_LONG.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 9034792245L);
+ Assert.assertEquals(resultSegmt.address(), longSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructPointer,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ longHandle1.set(structSegmt, 0L, 224466880022L);
+ longHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedLongArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedLongArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addLongAndLongsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addLongAndLongsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_LONG, JAVA_LONG, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2LongStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2LongStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 1122334455L);
+ longHandle2.set(structSegmt1, 0L, 5566778899L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 9900112233L);
+ longHandle2.set(structSegmt2, 0L, 3344556677L);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_LONG, 0), 11022446688L);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3LongStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3LongStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt1, 0L, 987654321987L);
+ longHandle2.set(structSegmt1, 0L, 123456789123L);
+ longHandle3.set(structSegmt1, 0L, 112233445566L);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ longHandle1.set(structSegmt2, 0L, 224466880022L);
+ longHandle2.set(structSegmt2, 0L, 113355779911L);
+ longHandle3.set(structSegmt2, 0L, 778899001122L);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals(longHandle1.get(resultSegmt, 0L), 1212121202009L);
+ Assert.assertEquals(longHandle2.get(resultSegmt, 0L), 236812569034L);
+ Assert.assertEquals(longHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 8.12F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAnd5FloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAnd5FloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 1.01F);
+ floatHandle2.set(structSegmt, 0L, 1.02F);
+ floatHandle3.set(structSegmt, 0L, 1.03F);
+ floatHandle4.set(structSegmt, 0L, 1.04F);
+ floatHandle5.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, ADDRESS, structLayout), arena);
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatFromPointerAndFloatsFromStruct_returnFloatPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment floatSegmt = arena.allocateFrom(JAVA_FLOAT, 12.12F);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 18.23F);
+ floatHandle2.set(structSegmt, 0L, 19.34F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(floatSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_FLOAT.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.69F, 0.01F);
+ Assert.assertEquals(resultSegmt.address(), floatSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructPointer,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt, 0L, 35.11F);
+ floatHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedFloatArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addFloatAndFloatsFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addFloatAndFloatsFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_FLOAT, JAVA_FLOAT, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ floatHandle3.set(structSegmt1, 0L, 45.67F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+ floatHandle3.set(structSegmt2, 0L, 69.72F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 24.68F, 0.01F);
+ Assert.assertEquals((float)floatHandle3.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((float)floatHandle1.get(resultSegmt, 0L), 49.46F, 0.01F);
+ Assert.assertEquals((float)floatHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2FloatStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2FloatStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt1, 0L, 25.12F);
+ floatHandle2.set(structSegmt1, 0L, 11.23F);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ floatHandle1.set(structSegmt2, 0L, 24.34F);
+ floatHandle2.set(structSegmt2, 0L, 13.45F);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_FLOAT, 0), 49.46F, 0.01F);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 2228.111D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, ADDRESS, structLayout), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 112.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 118.456D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleFromPointerAndDoublesFromStruct_returnDoublePointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment doubleSegmt = arena.allocateFrom(JAVA_DOUBLE, 212.123D);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 218.456D);
+ doubleHandle2.set(structSegmt, 0L, 219.789D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(doubleSegmt, structSegmt, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(JAVA_DOUBLE.byteSize());
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 650.368D, 0.001D);
+ Assert.assertEquals(resultSegmt.address(), doubleSegmt.address());
+ }
+ }
+
+ @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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructPointer,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, ADDRESS), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt, 0L, 22.111D);
+ doubleHandle2.set(structSegmt, 0L, 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromNestedStruct_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromNestedStruct_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedDoubleArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArrayByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrderByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addDoubleAndDoublesFromStructWithNestedStructArray_reverseOrder,
+ FunctionDescriptor.of(JAVA_DOUBLE, JAVA_DOUBLE, structLayout), arena);
+ MemorySegment structSegmt = arena.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2DoubleStructs_returnStructPointerByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2DoubleStructs_returnStructPointer,
+ FunctionDescriptor.of(ADDRESS, ADDRESS, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+
+ MemorySegment resultAddr = (MemorySegment)mh.invoke(structSegmt1, structSegmt2, upcallFuncAddr);
+ MemorySegment resultSegmt = resultAddr.reinterpret(structLayout.byteSize());;
+ Assert.assertEquals(resultSegmt.get(JAVA_DOUBLE, 0), 44.666D, 0.001D);
+ Assert.assertEquals(resultSegmt.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);
+ MemorySegment functionSymbol = nativeLibLookup.find("add3DoubleStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add3DoubleStructs_returnStruct,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment structSegmt1 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt1, 0L, 11.222D);
+ doubleHandle2.set(structSegmt1, 0L, 22.333D);
+ doubleHandle3.set(structSegmt1, 0L, 33.123D);
+ MemorySegment structSegmt2 = arena.allocate(structLayout);
+ doubleHandle1.set(structSegmt2, 0L, 33.444D);
+ doubleHandle2.set(structSegmt2, 0L, 44.555D);
+ doubleHandle3.set(structSegmt2, 0L, 55.456D);
+
+ MemorySegment resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, structSegmt1, structSegmt2, upcallFuncAddr);
+ Assert.assertEquals((double)doubleHandle1.get(resultSegmt, 0L), 44.666D, 0.001D);
+ Assert.assertEquals((double)doubleHandle2.get(resultSegmt, 0L), 66.888D, 0.001D);
+ Assert.assertEquals((double)doubleHandle3.get(resultSegmt, 0L), 88.579D, 0.001D);
+ }
+ }
+
+ @Test
+ public void test_addNegBytesFromStructByUpcallMH() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addNegBytesFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addNegBytesFromStruct,
+ FunctionDescriptor.of(JAVA_BYTE, JAVA_BYTE, structLayout, JAVA_BYTE, JAVA_BYTE), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ byteHandle1.set(structSegmt, 0L, (byte)-8);
+ byteHandle2.set(structSegmt, 0L, (byte)-9);
+
+ byte result = (byte)mh.invoke((byte)-6, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, (byte)-40);
+ }
+ }
+
+ @Test
+ public void test_addNegShortsFromStructByUpcallMH() 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);
+ MemorySegment functionSymbol = nativeLibLookup.find("addNegShortsFromStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+
+ try (Arena arena = Arena.ofConfined()) {
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_addNegShortsFromStruct,
+ FunctionDescriptor.of(JAVA_SHORT, JAVA_SHORT, structLayout, JAVA_SHORT, JAVA_SHORT), arena);
+ MemorySegment structSegmt = arena.allocate(structLayout);
+ shortHandle1.set(structSegmt, 0L, (short)-888);
+ shortHandle2.set(structSegmt, 0L, (short)-999);
+
+ short result = (short)mh.invoke((short)-777, structSegmt, upcallFuncAddr);
+ Assert.assertEquals(result, (short)-4551);
+ }
+ }
+}
diff --git a/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMethodHandles.java b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMethodHandles.java
new file mode 100644
index 00000000000..4169d64d179
--- /dev/null
+++ b/test/functional/Java22andUp/src/org/openj9/test/jep454/upcall/UpcallMethodHandles.java
@@ -0,0 +1,2077 @@
+/*******************************************************************************
+ * Copyright IBM Corp. and others 2023
+ *
+ * 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] https://openjdk.org/legal/assembly-exception.html
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
+ *******************************************************************************/
+package org.openj9.test.jep454.upcall;
+
+import org.testng.Assert;
+
+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.Arena;
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.GroupLayout;
+import java.lang.foreign.Linker;
+import java.lang.foreign.MemoryLayout;
+import java.lang.foreign.MemoryLayout.PathElement;
+import java.lang.foreign.MemorySegment;
+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.Linker.*;
+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 Arena arena = Arena.ofAuto();
+ 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_Segmt_Bool_MemSegmt = methodType(MemorySegment.class, boolean.class, MemorySegment.class);
+ static final MethodType MT_Char_Char_MemSegmt = methodType(char.class, char.class, MemorySegment.class);
+ static final MethodType MT_Segmt_MemSegmt_Char = methodType(MemorySegment.class, MemorySegment.class, char.class);
+ static final MethodType MT_Byte_Byte_MemSegmt = methodType(byte.class, byte.class, MemorySegment.class);
+ static final MethodType MT_Segmt_Byte_MemSegmt = methodType(MemorySegment.class, byte.class, MemorySegment.class);
+ static final MethodType MT_Short_Short_MemSegmt = methodType(short.class, short.class, MemorySegment.class);
+ static final MethodType MT_Segmt_MemSegmt_Short = methodType(MemorySegment.class, MemorySegment.class, short.class);
+ static final MethodType MT_Int_Int_MemSegmt = methodType(int.class, int.class, MemorySegment.class);
+ static final MethodType MT_Segmt_Int_MemSegmt = methodType(MemorySegment.class, int.class, MemorySegment.class);
+ static final MethodType MT_Long_Long_MemSegmt = methodType(long.class, long.class, MemorySegment.class);
+ static final MethodType MT_Segmt_MemSegmt_Long = methodType(MemorySegment.class, MemorySegment.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_Segmt_Float_MemSegmt = methodType(MemorySegment.class, float.class, MemorySegment.class);
+ static final MethodType MT_Double_Double_MemSegmt = methodType(double.class, double.class, MemorySegment.class);
+ static final MethodType MT_Segmt_MemSegmt_Double = methodType(MemorySegment.class, MemorySegment.class, double.class);
+ static final MethodType MT_Segmt_MemSegmt_MemSegmt = methodType(MemorySegment.class, MemorySegment.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_returnStruct_throwException;
+ public static final MethodHandle MH_add2IntStructs_returnStruct_nestedUpcall;
+ public static final MethodHandle MH_add2IntStructs_returnStruct_nullValue;
+ public static final MethodHandle MH_add2IntStructs_returnStruct_nullSegmt;
+ public static final MethodHandle MH_add2IntStructs_returnStruct_heapSegmt;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer_nullValue;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer_nullSegmt;
+ public static final MethodHandle MH_add2IntStructs_returnStructPointer_heapSegmt;
+ 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;
+
+ public static final MethodHandle MH_addNegBytesFromStruct;
+ public static final MethodHandle MH_addNegShortsFromStruct;
+ public static final MethodHandle MH_captureTrivialOption;
+
+ private static Linker linker = Linker.nativeLinker();
+
+ static {
+ System.loadLibrary("clinkerffitests");
+
+ 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, MemorySegment.class)); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetPtr", MT_Segmt_Bool_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolFromPtrWithOr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolFromPtrWithOr_RetArgPtr", MT_Segmt_Bool_MemSegmt); //$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, MemorySegment.class, char.class)); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetPtr", MT_Segmt_MemSegmt_Char); //$NON-NLS-1$
+ MH_createNewCharFromCharAndCharFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "createNewCharFromCharAndCharFromPtr_RetArgPtr", MT_Segmt_MemSegmt_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, MemorySegment.class)); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetPtr", MT_Segmt_Byte_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndByteFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addByteAndByteFromPtr_RetArgPtr", MT_Segmt_Byte_MemSegmt); //$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, MemorySegment.class, short.class)); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetPtr", MT_Segmt_MemSegmt_Short); //$NON-NLS-1$
+ MH_addShortAndShortFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortFromPtr_RetArgPtr", MT_Segmt_MemSegmt_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, MemorySegment.class)); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetPtr", MT_Segmt_Int_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntFromPtr_RetArgPtr", MT_Segmt_Int_MemSegmt); //$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, MemorySegment.class, long.class)); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetPtr", MT_Segmt_MemSegmt_Long); //$NON-NLS-1$
+ MH_addLongAndLongFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongFromPtr_RetArgPtr", MT_Segmt_MemSegmt_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, MemorySegment.class)); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetPtr", MT_Segmt_Float_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatFromPtr_RetArgPtr", MT_Segmt_Float_MemSegmt); //$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, MemorySegment.class, double.class)); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetPtr", MT_Segmt_MemSegmt_Double); //$NON-NLS-1$
+ MH_addDoubleAndDoubleFromPtr_RetArgPtr = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoubleFromPtr_RetArgPtr", MT_Segmt_MemSegmt_Double); //$NON-NLS-1$
+
+ MH_compare = lookup.findStatic(UpcallMethodHandles.class, "compare", methodType(int.class, MemorySegment.class, MemorySegment.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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer = lookup.findStatic(UpcallMethodHandles.class, "addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addBoolAndBoolsFromStructPointerWithXor = lookup.findStatic(UpcallMethodHandles.class, "addBoolAndBoolsFromStructPointerWithXor", methodType(boolean.class, boolean.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addByteFromPointerAndBytesFromStruct_returnBytePointer = lookup.findStatic(UpcallMethodHandles.class, "addByteFromPointerAndBytesFromStruct_returnBytePointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addByteAndBytesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addByteAndBytesFromStructPointer", methodType(byte.class, byte.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addCharFromPointerAndCharsFromStruct_returnCharPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharFromPointerAndCharsFromStruct_returnCharPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addCharAndCharsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addCharAndCharsFromStructPointer", methodType(char.class, char.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addShortFromPointerAndShortsFromStruct_returnShortPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortFromPointerAndShortsFromStruct_returnShortPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addShortAndShortsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addShortAndShortsFromStructPointer", methodType(short.class, short.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addIntFromPointerAndIntsFromStruct_returnIntPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntFromPointerAndIntsFromStruct_returnIntPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addIntAndIntsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addIntAndIntsFromStructPointer", methodType(int.class, int.class, MemorySegment.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_returnStruct_throwException = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct_throwException", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct_nestedUpcall = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct_nestedUpcall", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct_nullValue = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct_nullValue", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct_nullSegmt = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct_nullSegmt", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStruct_heapSegmt = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStruct_heapSegmt", MT_MemSegmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer_nullValue = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer_nullValue", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer_nullSegmt = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer_nullSegmt", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_add2IntStructs_returnStructPointer_heapSegmt = lookup.findStatic(UpcallMethodHandles.class, "add2IntStructs_returnStructPointer_heapSegmt", MT_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addLongFromPointerAndLongsFromStruct_returnLongPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongFromPointerAndLongsFromStruct_returnLongPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addLongAndLongsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addLongAndLongsFromStructPointer", methodType(long.class, long.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addFloatFromPointerAndFloatsFromStruct_returnFloatPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatFromPointerAndFloatsFromStruct_returnFloatPointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addFloatAndFloatsFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addFloatAndFloatsFromStructPointer", methodType(float.class, float.class, MemorySegment.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_Segmt_MemSegmt_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, MemorySegment.class, MemorySegment.class)); //$NON-NLS-1$
+ MH_addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer", MT_Segmt_MemSegmt_MemSegmt); //$NON-NLS-1$
+ MH_addDoubleAndDoublesFromStructPointer = lookup.findStatic(UpcallMethodHandles.class, "addDoubleAndDoublesFromStructPointer", methodType(double.class, double.class, MemorySegment.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_Segmt_MemSegmt_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$
+
+ MH_addNegBytesFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addNegBytesFromStruct", MT_Byte_Byte_MemSegmt.appendParameterTypes(byte.class, byte.class)); //$NON-NLS-1$
+ MH_addNegShortsFromStruct = lookup.findStatic(UpcallMethodHandles.class, "addNegShortsFromStruct", MT_Short_Short_MemSegmt.appendParameterTypes(short.class, short.class)); //$NON-NLS-1$
+ MH_captureTrivialOption = lookup.findStatic(UpcallMethodHandles.class, "captureTrivialOption", methodType(int.class, int.class)); //$NON-NLS-1$
+
+ } catch (IllegalAccessException | NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
+ }
+ private static final SymbolLookup nativeLibLookup = SymbolLookup.loaderLookup();
+
+ public static boolean add2BoolsWithOr(boolean boolArg1, boolean boolArg2) {
+ boolean result = boolArg1 || boolArg2;
+ return result;
+ }
+
+ public static boolean addBoolAndBoolFromPointerWithOr(boolean boolArg1, MemorySegment boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.reinterpret(JAVA_BOOLEAN.byteSize());
+ boolean result = boolArg1 || boolArg2Segmt.get(JAVA_BOOLEAN, 0);
+ return result;
+ }
+
+ public static MemorySegment addBoolAndBoolFromPtrWithOr_RetPtr(boolean boolArg1, MemorySegment boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.reinterpret(JAVA_BOOLEAN.byteSize());
+ boolean result = boolArg1 || boolArg2Segmt.get(JAVA_BOOLEAN, 0);
+ MemorySegment resultSegmt = arena.allocate(JAVA_BOOLEAN);
+ resultSegmt.set(JAVA_BOOLEAN, 0, result);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addBoolAndBoolFromPtrWithOr_RetArgPtr(boolean boolArg1, MemorySegment boolArg2Addr) {
+ MemorySegment boolArg2Segmt = boolArg2Addr.reinterpret(JAVA_BOOLEAN.byteSize());
+ boolean result = boolArg1 || boolArg2Segmt.get(JAVA_BOOLEAN, 0);
+ boolArg2Segmt.set(JAVA_BOOLEAN, 0, result);
+ return boolArg2Segmt;
+ }
+
+ 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(MemorySegment charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.reinterpret(JAVA_CHAR.byteSize());
+ char charArg1 = charArg1Segmt.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 MemorySegment createNewCharFromCharAndCharFromPtr_RetPtr(MemorySegment charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.reinterpret(JAVA_CHAR.byteSize());
+ char charArg1 = charArg1Segmt.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ MemorySegment resultSegmt = arena.allocate(JAVA_CHAR);
+ resultSegmt.set(JAVA_CHAR, 0, result);
+ return resultSegmt;
+ }
+
+ public static MemorySegment createNewCharFromCharAndCharFromPtr_RetArgPtr(MemorySegment charArg1Addr, char charArg2) {
+ MemorySegment charArg1Segmt = charArg1Addr.reinterpret(JAVA_CHAR.byteSize());
+ char charArg1 = charArg1Segmt.get(JAVA_CHAR, 0);
+ int diff = (charArg2 >= charArg1) ? (charArg2 - charArg1) : (charArg1 - charArg2);
+ diff = (diff > 5) ? 5 : diff;
+ char result = (char)(diff + 'A');
+ charArg1Segmt.set(JAVA_CHAR, 0, result);
+ return charArg1Segmt;
+ }
+
+ public static byte add2Bytes(byte byteArg1, byte byteArg2) {
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static byte addByteAndByteFromPointer(byte byteArg1, MemorySegment byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.reinterpret(JAVA_BYTE.byteSize());
+ byte byteArg2 = byteArg2Segmt.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ return byteSum;
+ }
+
+ public static MemorySegment addByteAndByteFromPtr_RetPtr(byte byteArg1, MemorySegment byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.reinterpret(JAVA_BYTE.byteSize());
+ byte byteArg2 = byteArg2Segmt.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ MemorySegment resultSegmt = arena.allocate(JAVA_BYTE);
+ resultSegmt.set(JAVA_BYTE, 0, byteSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addByteAndByteFromPtr_RetArgPtr(byte byteArg1, MemorySegment byteArg2Addr) {
+ MemorySegment byteArg2Segmt = byteArg2Addr.reinterpret(JAVA_BYTE.byteSize());
+ byte byteArg2 = byteArg2Segmt.get(JAVA_BYTE, 0);
+ byte byteSum = (byte)(byteArg1 + byteArg2);
+ byteArg2Segmt.set(JAVA_BYTE, 0, byteSum);
+ return byteArg2Segmt;
+ }
+
+ public static short add2Shorts(short shortArg1, short shortArg2) {
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static short addShortAndShortFromPointer(MemorySegment shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.reinterpret(JAVA_SHORT.byteSize());
+ short shortArg1 = shortArg1Segmt.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ return shortSum;
+ }
+
+ public static MemorySegment addShortAndShortFromPtr_RetPtr(MemorySegment shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.reinterpret(JAVA_SHORT.byteSize());
+ short shortArg1 = shortArg1Segmt.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ MemorySegment resultSegmt = arena.allocate(JAVA_SHORT);
+ resultSegmt.set(JAVA_SHORT, 0, shortSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addShortAndShortFromPtr_RetArgPtr(MemorySegment shortArg1Addr, short shortArg2) {
+ MemorySegment shortArg1Segmt = shortArg1Addr.reinterpret(JAVA_SHORT.byteSize());
+ short shortArg1 = shortArg1Segmt.get(JAVA_SHORT, 0);
+ short shortSum = (short)(shortArg1 + shortArg2);
+ shortArg1Segmt.set(JAVA_SHORT, 0, shortSum);
+ return shortArg1Segmt;
+ }
+
+ public static int add2Ints(int intArg1, int intArg2) {
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static int addIntAndIntFromPointer(int intArg1, MemorySegment intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.reinterpret(JAVA_INT.byteSize());
+ int intArg2 = intArg2Segmt.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ return intSum;
+ }
+
+ public static MemorySegment addIntAndIntFromPtr_RetPtr(int intArg1, MemorySegment intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.reinterpret(JAVA_INT.byteSize());
+ int intArg2 = intArg2Segmt.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ MemorySegment resultSegmt = arena.allocate(JAVA_INT);
+ resultSegmt.set(JAVA_INT, 0, intSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addIntAndIntFromPtr_RetArgPtr(int intArg1, MemorySegment intArg2Addr) {
+ MemorySegment intArg2Segmt = intArg2Addr.reinterpret(JAVA_INT.byteSize());
+ int intArg2 = intArg2Segmt.get(JAVA_INT, 0);
+ int intSum = intArg1 + intArg2;
+ intArg2Segmt.set(JAVA_INT, 0, intSum);
+ return intArg2Segmt;
+ }
+
+ 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(MemorySegment longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.reinterpret(JAVA_LONG.byteSize());
+ long longArg1 = longArg1Segmt.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ return longSum;
+ }
+
+ public static MemorySegment addLongAndLongFromPtr_RetPtr(MemorySegment longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.reinterpret(JAVA_LONG.byteSize());
+ long longArg1 = longArg1Segmt.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ MemorySegment resultSegmt = arena.allocate(JAVA_LONG);
+ resultSegmt.set(JAVA_LONG, 0, longSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addLongAndLongFromPtr_RetArgPtr(MemorySegment longArg1Addr, long longArg2) {
+ MemorySegment longArg1Segmt = longArg1Addr.reinterpret(JAVA_LONG.byteSize());
+ long longArg1 = longArg1Segmt.get(JAVA_LONG, 0);
+ long longSum = longArg1 + longArg2;
+ longArg1Segmt.set(JAVA_LONG, 0, longSum);
+ return longArg1Segmt;
+ }
+
+ public static float add2Floats(float floatArg1, float floatArg2) {
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static float addFloatAndFloatFromPointer(float floatArg1, MemorySegment floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.reinterpret(JAVA_FLOAT.byteSize());
+ float floatArg2 = floatArg2Segmt.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ return floatSum;
+ }
+
+ public static MemorySegment addFloatAndFloatFromPtr_RetPtr(float floatArg1, MemorySegment floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.reinterpret(JAVA_FLOAT.byteSize());
+ float floatArg2 = floatArg2Segmt.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ MemorySegment resultSegmt = arena.allocate(JAVA_FLOAT);
+ resultSegmt.set(JAVA_FLOAT, 0, floatSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addFloatAndFloatFromPtr_RetArgPtr(float floatArg1, MemorySegment floatArg2Addr) {
+ MemorySegment floatArg2Segmt = floatArg2Addr.reinterpret(JAVA_FLOAT.byteSize());
+ float floatArg2 = floatArg2Segmt.get(JAVA_FLOAT, 0);
+ float floatSum = floatArg1 + floatArg2;
+ floatArg2Segmt.set(JAVA_FLOAT, 0, floatSum);
+ return floatArg2Segmt;
+ }
+
+ public static double add2Doubles(double doubleArg1, double doubleArg2) {
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static double addDoubleAndDoubleFromPointer(MemorySegment doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.reinterpret(JAVA_DOUBLE.byteSize());
+ double doubleArg1 = doubleArg1Segmt.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ return doubleSum;
+ }
+
+ public static MemorySegment addDoubleAndDoubleFromPtr_RetPtr(MemorySegment doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.reinterpret(JAVA_DOUBLE.byteSize());
+ double doubleArg1 = doubleArg1Segmt.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ MemorySegment resultSegmt = arena.allocate(JAVA_DOUBLE);
+ resultSegmt.set(JAVA_DOUBLE, 0, doubleSum);
+ return resultSegmt;
+ }
+
+ public static MemorySegment addDoubleAndDoubleFromPtr_RetArgPtr(MemorySegment doubleArg1Addr, double doubleArg2) {
+ MemorySegment doubleArg1Segmt = doubleArg1Addr.reinterpret(JAVA_DOUBLE.byteSize());
+ double doubleArg1 = doubleArg1Segmt.get(JAVA_DOUBLE, 0);
+ double doubleSum = doubleArg1 + doubleArg2;
+ doubleArg1Segmt.set(JAVA_DOUBLE, 0, doubleSum);
+ return doubleArg1Segmt;
+ }
+
+ public static int compare(MemorySegment argAddr1, MemorySegment argAddr2) {
+ MemorySegment arg1Segmt = argAddr1.reinterpret(JAVA_INT.byteSize());
+ MemorySegment arg2Segmt = argAddr2.reinterpret(JAVA_INT.byteSize());
+ int intArg1 = arg1Segmt.get(JAVA_INT, 0);
+ int intArg2 = arg2Segmt.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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_BOOLEAN.byteSize());
+ boolean boolSum = arg1Segmt.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ return boolSum;
+ }
+
+ public static MemorySegment addBoolFromPointerAndBoolsFromStructWithXor_returnBoolPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_BOOLEAN.byteSize());
+ boolean boolSum = arg1Segmt.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Segmt.set(JAVA_BOOLEAN, 0, boolSum);
+ return arg1Addr;
+ }
+
+ public static boolean addBoolAndBoolsFromStructPointerWithXor(boolean arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ boolean boolSum = arg1 ^ arg2Segmt.get(JAVA_BOOLEAN, 0) ^ arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2BoolStructsWithXor_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BOOLEAN.withName("elem1"), JAVA_BOOLEAN.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ boolean boolStruct_Elem1 = arg1Segmt.get(JAVA_BOOLEAN, 0) ^ arg2.get(JAVA_BOOLEAN, 0);
+ boolean boolStruct_Elem2 = arg1Segmt.get(JAVA_BOOLEAN, 1) ^ arg2.get(JAVA_BOOLEAN, 1);
+ arg1Segmt.set(JAVA_BOOLEAN, 0, boolStruct_Elem1);
+ arg1Segmt.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"));
+ MemorySegment boolStructSegmt = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_BYTE.byteSize());
+ byte byteSum = (byte)(arg1Segmt.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ return byteSum;
+ }
+
+ public static MemorySegment addByteFromPointerAndBytesFromStruct_returnBytePointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_BYTE.byteSize());
+ byte byteSum = (byte)(arg1Segmt.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 1));
+ arg1Segmt.set(JAVA_BYTE, 0, byteSum);
+ return arg1Addr;
+ }
+
+ public static byte addByteAndBytesFromStructPointer(byte arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ byte byteSum = (byte)(arg1 + arg2Segmt.get(JAVA_BYTE, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 = arena.allocate(structLayout);
+ 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 MemorySegment add2ByteStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_BYTE.withName("elem1"), JAVA_BYTE.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ byte byteStruct_Elem1 = (byte)(arg1Segmt.get(JAVA_BYTE, 0) + arg2.get(JAVA_BYTE, 0));
+ byte byteStruct_Elem2 = (byte)(arg1Segmt.get(JAVA_BYTE, 1) + arg2.get(JAVA_BYTE, 1));
+ arg1Segmt.set(JAVA_BYTE, 0, byteStruct_Elem1);
+ arg1Segmt.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"));
+ MemorySegment byteStructSegmt = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_CHAR.byteSize());
+ char result = (char)(arg1Segmt.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ return result;
+ }
+
+ public static MemorySegment addCharFromPointerAndCharsFromStruct_returnCharPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_CHAR.byteSize());
+ char result = (char)(arg1Segmt.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 2) - 2 * 'A');
+ arg1Segmt.set(JAVA_CHAR, 0, result);
+ return arg1Addr;
+ }
+
+ public static char addCharAndCharsFromStructPointer(char arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ char result = (char)(arg1 + arg2Segmt.get(JAVA_CHAR, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2CharStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_CHAR.withName("elem1"), JAVA_CHAR.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ char charStruct_Elem1 = (char)(arg1Segmt.get(JAVA_CHAR, 0) + arg2.get(JAVA_CHAR, 0) - 'A');
+ char charStruct_Elem2 = (char)(arg1Segmt.get(JAVA_CHAR, 2) + arg2.get(JAVA_CHAR, 2) - 'A');
+ arg1Segmt.set(JAVA_CHAR, 0, charStruct_Elem1);
+ arg1Segmt.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"));
+ MemorySegment charStructSegmt = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_SHORT.byteSize());
+ short shortSum = (short)(arg1Segmt.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ return shortSum;
+ }
+
+ public static MemorySegment addShortFromPointerAndShortsFromStruct_returnShortPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_SHORT.byteSize());
+ short shortSum = (short)(arg1Segmt.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 2));
+ arg1Segmt.set(JAVA_SHORT, 0, shortSum);
+ return arg1Addr;
+ }
+
+ public static short addShortAndShortsFromStructPointer(short arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ short shortSum = (short)(arg1 + arg2Segmt.get(JAVA_SHORT, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2ShortStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_SHORT.withName("elem1"), JAVA_SHORT.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ short shortStruct_Elem1 = (short)(arg1Segmt.get(JAVA_SHORT, 0) + arg2.get(JAVA_SHORT, 0));
+ short shortStruct_Elem2 = (short)(arg1Segmt.get(JAVA_SHORT, 2) + arg2.get(JAVA_SHORT, 2));
+ arg1Segmt.set(JAVA_SHORT, 0, shortStruct_Elem1);
+ arg1Segmt.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"));
+ MemorySegment shortStructSegmt = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_INT.byteSize());
+ int intSum = arg1Segmt.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ return intSum;
+ }
+
+ public static MemorySegment addIntFromPointerAndIntsFromStruct_returnIntPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_INT.byteSize());
+ int intSum = arg1Segmt.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 4);
+ arg1Segmt.set(JAVA_INT, 0, intSum);
+ return arg1Addr;
+ }
+
+ public static int addIntAndIntsFromStructPointer(int arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ int intSum = arg1 + arg2Segmt.get(JAVA_INT, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2IntStructs_returnStruct_throwException(MemorySegment arg1, MemorySegment arg2) {
+ throw new IllegalArgumentException("An exception is thrown from the upcall method");
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct_nestedUpcall(MemorySegment arg1, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ FunctionDescriptor fd = FunctionDescriptor.of(structLayout, structLayout, structLayout, ADDRESS);
+ MemorySegment functionSymbol = nativeLibLookup.find("add2IntStructs_returnStructByUpcallMH").get();
+ MethodHandle mh = linker.downcallHandle(functionSymbol, fd);
+ MemorySegment upcallFuncAddr = linker.upcallStub(UpcallMethodHandles.MH_add2IntStructs_returnStruct_throwException,
+ FunctionDescriptor.of(structLayout, structLayout, structLayout), arena);
+ MemorySegment resultSegmt = null;
+ try {
+ resultSegmt = (MemorySegment)mh.invoke((SegmentAllocator)arena, arg1, arg2, upcallFuncAddr);
+ } catch (Throwable e) {
+ throw (IllegalArgumentException)e;
+ }
+ return resultSegmt;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct_nullValue(MemorySegment arg1, MemorySegment arg2) {
+ return null;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct_nullSegmt(MemorySegment arg1, MemorySegment arg2) {
+ return MemorySegment.NULL;
+ }
+
+ public static MemorySegment add2IntStructs_returnStruct_heapSegmt(MemorySegment arg1, MemorySegment arg2) {
+ 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);
+ return MemorySegment.ofArray(new int[]{intStruct_Elem1, intStruct_Elem2});
+ }
+
+ public static MemorySegment add2IntStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ int intSum_Elem1 = arg1Segmt.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intSum_Elem2 = arg1Segmt.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ arg1Segmt.set(JAVA_INT, 0, intSum_Elem1);
+ arg1Segmt.set(JAVA_INT, 4, intSum_Elem2);
+ return arg1Addr;
+ }
+
+ public static MemorySegment add2IntStructs_returnStructPointer_nullValue(MemorySegment arg1Addr, MemorySegment arg2) {
+ return null;
+ }
+
+ public static MemorySegment add2IntStructs_returnStructPointer_nullSegmt(MemorySegment arg1Addr, MemorySegment arg2) {
+ return MemorySegment.NULL;
+ }
+
+ public static MemorySegment add2IntStructs_returnStructPointer_heapSegmt(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_INT.withName("elem1"), JAVA_INT.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ int intSum_Elem1 = arg1Segmt.get(JAVA_INT, 0) + arg2.get(JAVA_INT, 0);
+ int intSum_Elem2 = arg1Segmt.get(JAVA_INT, 4) + arg2.get(JAVA_INT, 4);
+ return MemorySegment.ofArray(new int[]{intSum_Elem1, intSum_Elem2});
+ }
+
+ 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 = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_LONG.byteSize());
+ long longSum = arg1Segmt.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ return longSum;
+ }
+
+ public static MemorySegment addLongFromPointerAndLongsFromStruct_returnLongPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_LONG.byteSize());
+ long longSum = arg1Segmt.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 8);
+ arg1Segmt.set(JAVA_LONG, 0, longSum);
+ return arg1Addr;
+ }
+
+ public static long addLongAndLongsFromStructPointer(long arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ long longSum = arg1 + arg2Segmt.get(JAVA_LONG, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2LongStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_LONG.withName("elem1"), JAVA_LONG.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ long longSum_Elem1 = arg1Segmt.get(JAVA_LONG, 0) + arg2.get(JAVA_LONG, 0);
+ long longSum_Elem2 = arg1Segmt.get(JAVA_LONG, 8) + arg2.get(JAVA_LONG, 8);
+ arg1Segmt.set(JAVA_LONG, 0, longSum_Elem1);
+ arg1Segmt.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 = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_FLOAT.byteSize());
+ float floatSum = arg1Segmt.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ return floatSum;
+ }
+
+ public static MemorySegment addFloatFromPointerAndFloatsFromStruct_returnFloatPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_FLOAT.byteSize());
+ float floatSum = arg1Segmt.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 4);
+ arg1Segmt.set(JAVA_FLOAT, 0, floatSum);
+ return arg1Addr;
+ }
+
+ public static float addFloatAndFloatsFromStructPointer(float arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ float floatSum = arg1 + arg2Segmt.get(JAVA_FLOAT, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2FloatStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_FLOAT.withName("elem1"), JAVA_FLOAT.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ float floatSum_Elem1 = arg1Segmt.get(JAVA_FLOAT, 0) + arg2.get(JAVA_FLOAT, 0);
+ float floatSum_Elem2 = arg1Segmt.get(JAVA_FLOAT, 4) + arg2.get(JAVA_FLOAT, 4);
+ arg1Segmt.set(JAVA_FLOAT, 0, floatSum_Elem1);
+ arg1Segmt.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 = arena.allocate(structLayout);
+ 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(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_DOUBLE.byteSize());
+ double doubleSum = arg1Segmt.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ return doubleSum;
+ }
+
+ public static MemorySegment addDoubleFromPointerAndDoublesFromStruct_returnDoublePointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(JAVA_DOUBLE.byteSize());
+ double doubleSum = arg1Segmt.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Segmt.set(JAVA_DOUBLE, 0, doubleSum);
+ return arg1Addr;
+ }
+
+ public static double addDoubleAndDoublesFromStructPointer(double arg1, MemorySegment arg2Addr) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ MemorySegment arg2Segmt = arg2Addr.reinterpret(structLayout.byteSize());
+ double doubleSum = arg1 + arg2Segmt.get(JAVA_DOUBLE, 0) + arg2Segmt.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 = arena.allocate(structLayout);
+ 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 MemorySegment add2DoubleStructs_returnStructPointer(MemorySegment arg1Addr, MemorySegment arg2) {
+ GroupLayout structLayout = MemoryLayout.structLayout(JAVA_DOUBLE.withName("elem1"), JAVA_DOUBLE.withName("elem2"));
+ MemorySegment arg1Segmt = arg1Addr.reinterpret(structLayout.byteSize());
+ double doubleSum_Elem1 = arg1Segmt.get(JAVA_DOUBLE, 0) + arg2.get(JAVA_DOUBLE, 0);
+ double doubleSum_Elem2 = arg1Segmt.get(JAVA_DOUBLE, 8) + arg2.get(JAVA_DOUBLE, 8);
+ arg1Segmt.set(JAVA_DOUBLE, 0, doubleSum_Elem1);
+ arg1Segmt.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 = arena.allocate(structLayout);
+ 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 padding in the struct [int, double, long] on AIX/PPC 64-bit is different from
+ * other platforms as follows:
+ * 1) there is no padding between int and double.
+ * 2) there is a 4-byte padding between double and long.
+ */
+ double structElem2 = arg2.get(JAVA_DOUBLE, isAixOS ? 4 : 8);
+ double structElem3 = 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 = arena.allocate(structLayout);
+
+ 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 = arena.allocate(structLayout);
+
+ for (int i = 0; i < 4096; i++) {
+ byteArrStruSegment.set(JAVA_BYTE, i, (byte)i);
+ }
+ return byteArrStruSegment;
+ }
+
+ public static byte addNegBytesFromStruct(byte arg1, MemorySegment arg2, byte arg3, byte arg4) {
+ byte arg2_elem1 = arg2.get(JAVA_BYTE, 0);
+ byte arg2_elem2 = arg2.get(JAVA_BYTE, 1);
+
+ Assert.assertEquals((byte)-6, ((Byte)arg1).byteValue());
+ Assert.assertEquals((byte)-8, ((Byte)arg2_elem1).byteValue());
+ Assert.assertEquals((byte)-9, ((Byte)arg2_elem2).byteValue());
+ Assert.assertEquals((byte)-8, ((Byte)arg3).byteValue());
+ Assert.assertEquals((byte)-9, ((Byte)arg4).byteValue());
+
+ byte byteSum = (byte)(arg1 + arg2_elem1 + arg2_elem2 + arg3 + arg4);
+ return byteSum;
+ }
+
+ public static short addNegShortsFromStruct(short arg1, MemorySegment arg2, short arg3, short arg4) {
+ short arg2_elem1 = arg2.get(JAVA_SHORT, 0);
+ short arg2_elem2 = arg2.get(JAVA_SHORT, 2);
+
+ Assert.assertEquals((short)-777, ((Short)arg1).shortValue());
+ Assert.assertEquals((short)-888, ((Short)arg2_elem1).shortValue());
+ Assert.assertEquals((short)-999, ((Short)arg2_elem2).shortValue());
+ Assert.assertEquals((short)-888, ((Short)arg3).shortValue());
+ Assert.assertEquals((short)-999, ((Short)arg4).shortValue());
+
+ short shortSum = (short)(arg1 + arg2_elem1 + arg2_elem2 + arg3 + arg4);
+ return shortSum;
+ }
+
+ public static int captureTrivialOption(int intArg1) {
+ Assert.fail("The method shouldn't be invoked during the trivial downcall.");
+ return intArg1;
+ }
+}
diff --git a/test/functional/Java22andUp/testng_220.xml b/test/functional/Java22andUp/testng_220.xml
new file mode 100644
index 00000000000..dff39881abb
--- /dev/null
+++ b/test/functional/Java22andUp/testng_220.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+