From 4adca0d10b90f44e9dd4d7550b9648ce7b9c5b0e Mon Sep 17 00:00:00 2001 From: squid233 <60126026+squid233@users.noreply.github.com> Date: Fri, 5 Jan 2024 23:16:54 +0800 Subject: [PATCH] Replace reinterpret with withTargetLayout --- .../overrun/marshal/test/CDowncallTest.java | 1 + .../marshal/test/GLFWErrorCallback.java | 5 ++- src/main/java/overrun/marshal/Downcall.java | 3 +- .../overrun/marshal/DowncallProcessor.java | 39 +++++++++++-------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/demo/src/main/java/overrun/marshal/test/CDowncallTest.java b/demo/src/main/java/overrun/marshal/test/CDowncallTest.java index 96832cb..ff0e552 100644 --- a/demo/src/main/java/overrun/marshal/test/CDowncallTest.java +++ b/demo/src/main/java/overrun/marshal/test/CDowncallTest.java @@ -125,6 +125,7 @@ interface CDowncallTest { void testCriticalFalse(); @Entrypoint("testReturnSizedArr") + @SizedSeg(4 * Integer.BYTES) MemorySegment ntestReturnSizedArr(); @Overload("ntestReturnSizedArr") diff --git a/demo/src/main/java/overrun/marshal/test/GLFWErrorCallback.java b/demo/src/main/java/overrun/marshal/test/GLFWErrorCallback.java index 9be6f0e..279341b 100644 --- a/demo/src/main/java/overrun/marshal/test/GLFWErrorCallback.java +++ b/demo/src/main/java/overrun/marshal/test/GLFWErrorCallback.java @@ -16,6 +16,7 @@ package overrun.marshal.test; +import overrun.marshal.SizedSeg; import overrun.marshal.Upcall; import java.lang.foreign.Arena; @@ -34,8 +35,8 @@ public interface GLFWErrorCallback extends Upcall { void invoke(int error, String description); @Stub - default void invoke(int error, MemorySegment description) { - invoke(error, description.reinterpret(Long.MAX_VALUE).getString(0)); + default void invoke(int error, @SizedSeg(Long.MAX_VALUE) MemorySegment description) { + invoke(error, description.getString(0)); } @Override diff --git a/src/main/java/overrun/marshal/Downcall.java b/src/main/java/overrun/marshal/Downcall.java index e2e0134..45e37ed 100644 --- a/src/main/java/overrun/marshal/Downcall.java +++ b/src/main/java/overrun/marshal/Downcall.java @@ -42,7 +42,7 @@ * Methods without {@link Overload @Overload} marked * converts parameters of {@link String} and array types into {@link java.lang.foreign.MemorySegment MemorySegment}. *

Parameter Annotations

- * See {@link Sized @Sized} and {@link Ref @Ref}. + * See {@link Sized @Sized}, {@link SizedSeg @SizedSeg} and {@link Ref @Ref}. *

Example

*
{@code
  * @Downcall(libname = "libGL.so", name = "GL")
@@ -59,6 +59,7 @@
  * @see Entrypoint
  * @see Overload
  * @see Sized
+ * @see SizedSeg
  * @see Ref
  * @since 0.1.0
  */
diff --git a/src/main/java/overrun/marshal/DowncallProcessor.java b/src/main/java/overrun/marshal/DowncallProcessor.java
index f1621bc..5ace70b 100644
--- a/src/main/java/overrun/marshal/DowncallProcessor.java
+++ b/src/main/java/overrun/marshal/DowncallProcessor.java
@@ -245,16 +245,7 @@ private void writeFile(
                                     .map(p -> Spec.literal(p.getSimpleName().toString()))
                                     .collect(Collectors.toList()));
                             if (notVoid) {
-                                final Spec castSpec = Spec.cast(javaReturnType, invokeExact);
-                                if (eIsStruct) {
-                                    targetStatement.addStatement(Spec.returnStatement(new InvokeSpec(Spec.parentheses(castSpec), "reinterpret")
-                                        .addArgument(new InvokeSpec(Spec.accessSpec(eStructRef.value(), "LAYOUT"), "byteSize"))));
-                                } else if (eSizedSeg != null || eSized != null) {
-                                    targetStatement.addStatement(Spec.returnStatement(new InvokeSpec(Spec.parentheses(castSpec), "reinterpret")
-                                        .addArgument(getConstExp(eSizedSeg != null ? eSizedSeg.value() : eSized.value()))));
-                                } else {
-                                    targetStatement.addStatement(Spec.returnStatement(castSpec));
-                                }
+                                targetStatement.addStatement(Spec.returnStatement(Spec.cast(javaReturnType, invokeExact)));
                             } else {
                                 targetStatement.addStatement(Spec.statement(invokeExact));
                             }
@@ -447,12 +438,6 @@ private void writeFile(
                                 .addArgument(finalInvocation);
                         } else if (isArray(returnType)) {
                             final TypeMirror arrayComponentType = getArrayComponentType(returnType);
-                            if (eSized != null) {
-                                finalInvocation = new InvokeSpec(finalInvocation, "reinterpret")
-                                    .addArgument(Spec.operatorSpec("*",
-                                        Spec.literal(getConstExp(eSized.value())),
-                                        new InvokeSpec(toValueLayoutStr(arrayComponentType), "byteSize")));
-                            }
                             if (isBooleanArray(returnType)) {
                                 finalInvocation = new InvokeSpec(BoolHelper.class, "toArray")
                                     .addArgument(finalInvocation);
@@ -620,7 +605,27 @@ private void addMethodHandles(TypeElement type, List methods,
                         .addArgument(new InvokeSpec(FunctionDescriptor.class,
                             returnType.getKind() == TypeKind.VOID ? "ofVoid" : "of").also(invokeSpec -> {
                             if (returnType.getKind() != TypeKind.VOID) {
-                                invokeSpec.addArgument(toValueLayoutStr(returnType));
+                                final StructRef structRef = v.getAnnotation(StructRef.class);
+                                final boolean isStruct = structRef != null;
+                                final String valueLayoutStr = isStruct ? "ValueLayout.ADDRESS" : toValueLayoutStr(returnType);
+                                final SizedSeg sizedSeg = v.getAnnotation(SizedSeg.class);
+                                final Sized sized = v.getAnnotation(Sized.class);
+                                if (isStruct) {
+                                    invokeSpec.addArgument(new InvokeSpec(valueLayoutStr, "withTargetLayout")
+                                        .addArgument(Spec.accessSpec(structRef.value(), "LAYOUT")));
+                                } else if (sizedSeg != null && isMemorySegment(returnType)) {
+                                    invokeSpec.addArgument(new InvokeSpec(valueLayoutStr, "withTargetLayout")
+                                        .addArgument(new InvokeSpec(MemoryLayout.class, "sequenceLayout")
+                                            .addArgument(getConstExp(sizedSeg.value()))
+                                            .addArgument(Spec.accessSpec(ValueLayout.class, "JAVA_BYTE"))));
+                                } else if (sized != null && isArray(returnType)) {
+                                    invokeSpec.addArgument(new InvokeSpec(valueLayoutStr, "withTargetLayout")
+                                        .addArgument(new InvokeSpec(MemoryLayout.class, "sequenceLayout")
+                                            .addArgument(getConstExp(sized.value()))
+                                            .addArgument(Spec.accessSpec(ValueLayout.class, toValueLayoutStr(getArrayComponentType(returnType))))));
+                                } else {
+                                    invokeSpec.addArgument(valueLayoutStr);
+                                }
                             }
                             v.getParameters().forEach(e -> invokeSpec.addArgument(toValueLayoutStr(e.asType())));
                         })).also(invokeSpec -> {