< prev index next > src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java
Print this page
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;
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;
}
}
private static Object readValue(MemorySegment seg, MemoryLayout layout) {
if (layout instanceof ValueLayout.OfBoolean bl) {
writeValue(arg, layout, argSeg, addr -> {});
}
private static void writeValue(Object arg, MemoryLayout layout, MemorySegment argSeg,
Consumer<MemorySegment> acquireCallback) {
! 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) {
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 >