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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +