< prev index next >

src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java

Print this page
@@ -43,14 +43,24 @@
  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.MethodType;
  import java.lang.ref.Reference;
  import java.nio.ByteOrder;
  import java.util.ArrayList;
+ import java.util.HashMap;
  import java.util.List;
+ import java.util.Map;
  import java.util.function.Consumer;
  
  import static java.lang.foreign.ValueLayout.ADDRESS;
+ import static java.lang.foreign.ValueLayout.JAVA_BOOLEAN;
+ import static java.lang.foreign.ValueLayout.JAVA_BYTE;
+ import static java.lang.foreign.ValueLayout.JAVA_CHAR;
+ import static java.lang.foreign.ValueLayout.JAVA_DOUBLE;
+ import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
+ import static java.lang.foreign.ValueLayout.JAVA_INT;
+ import static java.lang.foreign.ValueLayout.JAVA_LONG;
+ import static java.lang.foreign.ValueLayout.JAVA_SHORT;
  import static java.lang.invoke.MethodHandles.foldArguments;
  
  public final class FallbackLinker extends AbstractLinker {
  
      private static final MethodHandle MH_DO_DOWNCALL;

@@ -229,34 +239,29 @@
          writeValue(arg, layout, argSeg, addr -> {});
      }
  
      private static void writeValue(Object arg, MemoryLayout layout, MemorySegment argSeg,
                                     Consumer<MemorySegment> acquireCallback) {
-         if (layout instanceof ValueLayout.OfBoolean bl) {
-             argSeg.set(bl, 0, (Boolean) arg);
-         } else if (layout instanceof ValueLayout.OfByte bl) {
-             argSeg.set(bl, 0, (Byte) arg);
-         } else if (layout instanceof ValueLayout.OfShort sl) {
-             argSeg.set(sl, 0, (Short) arg);
-         } else if (layout instanceof ValueLayout.OfChar cl) {
-             argSeg.set(cl, 0, (Character) arg);
-         } else if (layout instanceof ValueLayout.OfInt il) {
-             argSeg.set(il, 0, (Integer) arg);
-         } else if (layout instanceof ValueLayout.OfLong ll) {
-             argSeg.set(ll, 0, (Long) arg);
-         } else if (layout instanceof ValueLayout.OfFloat fl) {
-             argSeg.set(fl, 0, (Float) arg);
-         } else if (layout instanceof ValueLayout.OfDouble dl) {
-             argSeg.set(dl, 0, (Double) arg);
-         } else if (layout instanceof AddressLayout al) {
-             MemorySegment addrArg = (MemorySegment) arg;
-             acquireCallback.accept(addrArg);
-             argSeg.set(al, 0, addrArg);
-         } else if (layout instanceof GroupLayout) {
-             MemorySegment.copy((MemorySegment) arg, 0, argSeg, 0, argSeg.byteSize()); // by-value struct
-         } else {
-             assert layout == null;
+         switch (layout) {
+             case ValueLayout.OfBoolean bl -> argSeg.set(bl, 0, (Boolean) arg);
+             case ValueLayout.OfByte    bl -> argSeg.set(bl, 0, (Byte) arg);
+             case ValueLayout.OfShort   sl -> argSeg.set(sl, 0, (Short) arg);
+             case ValueLayout.OfChar    cl -> argSeg.set(cl, 0, (Character) arg);
+             case ValueLayout.OfInt     il -> argSeg.set(il, 0, (Integer) arg);
+             case ValueLayout.OfLong    ll -> argSeg.set(ll, 0, (Long) arg);
+             case ValueLayout.OfFloat   fl -> argSeg.set(fl, 0, (Float) arg);
+             case ValueLayout.OfDouble  dl -> argSeg.set(dl, 0, (Double) arg);
+             case AddressLayout         al -> {
+                 MemorySegment addrArg = (MemorySegment) arg;
+                 acquireCallback.accept(addrArg);
+                 argSeg.set(al, 0, addrArg);
+             }
+             case GroupLayout           __ ->
+                     MemorySegment.copy((MemorySegment) arg, 0, argSeg, 0, argSeg.byteSize()); // by-value struct
+             case null, default -> {
+                 assert layout == null;
+             }
          }
      }
  
      private static Object readValue(MemorySegment seg, MemoryLayout layout) {
          if (layout instanceof ValueLayout.OfBoolean bl) {

@@ -281,6 +286,43 @@
              return seg;
          }
          assert layout == null;
          return null;
      }
+ 
+     @Override
+     public Map<String, MemoryLayout> canonicalLayouts() {
+         return CANONICAL_LAYOUTS;
+     }
+ 
+     static final Map<String, MemoryLayout> CANONICAL_LAYOUTS = new HashMap<>();
+ 
+     static {
+         CANONICAL_LAYOUTS.put("bool", JAVA_BOOLEAN);
+         CANONICAL_LAYOUTS.put("char", JAVA_BYTE);
+         CANONICAL_LAYOUTS.put("float", JAVA_FLOAT);
+         CANONICAL_LAYOUTS.put("double", JAVA_DOUBLE);
+         CANONICAL_LAYOUTS.put("long long", JAVA_LONG);
+         CANONICAL_LAYOUTS.put("void*", ADDRESS);
+         // platform-dependent sizes
+         CANONICAL_LAYOUTS.put("size_t", FFIType.SIZE_T);
+         CANONICAL_LAYOUTS.put("short", FFIType.layoutFor(LibFallback.shortSize()));
+         CANONICAL_LAYOUTS.put("int", FFIType.layoutFor(LibFallback.intSize()));
+         CANONICAL_LAYOUTS.put("long", FFIType.layoutFor(LibFallback.longSize()));
+         int wchar_size = LibFallback.wcharSize();
+         if (wchar_size == 2) {
+             // prefer JAVA_CHAR
+             CANONICAL_LAYOUTS.put("wchar_t", JAVA_CHAR);
+         } else {
+             CANONICAL_LAYOUTS.put("wchar_t", FFIType.layoutFor(wchar_size));
+         }
+         // JNI types
+         CANONICAL_LAYOUTS.put("jboolean", JAVA_BOOLEAN);
+         CANONICAL_LAYOUTS.put("jchar", JAVA_CHAR);
+         CANONICAL_LAYOUTS.put("jbyte", JAVA_BYTE);
+         CANONICAL_LAYOUTS.put("jshort", JAVA_SHORT);
+         CANONICAL_LAYOUTS.put("jint", JAVA_INT);
+         CANONICAL_LAYOUTS.put("jlong", JAVA_LONG);
+         CANONICAL_LAYOUTS.put("jfloat", JAVA_FLOAT);
+         CANONICAL_LAYOUTS.put("jdouble", JAVA_DOUBLE);
+     }
  }
< prev index next >