28 import jdk.incubator.foreign.ForeignLinker;
29 import jdk.incubator.foreign.FunctionDescriptor;
30 import jdk.incubator.foreign.GroupLayout;
31 import jdk.incubator.foreign.MemoryAddress;
32 import jdk.incubator.foreign.MemoryHandles;
33 import jdk.incubator.foreign.MemoryLayout;
34 import jdk.incubator.foreign.MemorySegment;
35 import jdk.incubator.foreign.SequenceLayout;
36 import jdk.incubator.foreign.ValueLayout;
37 import jdk.internal.foreign.MemoryAddressImpl;
38 import jdk.internal.foreign.Utils;
39 import jdk.internal.foreign.abi.aarch64.AArch64Linker;
40 import jdk.internal.foreign.abi.x64.sysv.SysVVaList;
41 import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker;
42 import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker;
43
44 import java.lang.invoke.MethodHandle;
45 import java.lang.invoke.MethodHandles;
46 import java.lang.invoke.MethodType;
47 import java.lang.invoke.VarHandle;
48 import java.util.List;
49 import java.util.function.Consumer;
50 import java.util.stream.IntStream;
51
52 import static java.lang.invoke.MethodHandles.collectArguments;
53 import static java.lang.invoke.MethodHandles.identity;
54 import static java.lang.invoke.MethodHandles.insertArguments;
55 import static java.lang.invoke.MethodHandles.permuteArguments;
56 import static java.lang.invoke.MethodType.methodType;
57 import static jdk.incubator.foreign.CSupport.*;
58
59 public class SharedUtils {
60
61 private static final MethodHandle MH_ALLOC_BUFFER;
62 private static final MethodHandle MH_BASEADDRESS;
63 private static final MethodHandle MH_BUFFER_COPY;
64
65 static {
66 try {
67 var lookup = MethodHandles.lookup();
68 MH_ALLOC_BUFFER = lookup.findStatic(SharedUtils.class, "allocateNative",
69 methodType(MemorySegment.class, MemoryLayout.class));
70 MH_BASEADDRESS = lookup.findVirtual(MemorySegment.class, "baseAddress",
71 methodType(MemoryAddress.class));
72 MH_BUFFER_COPY = lookup.findStatic(SharedUtils.class, "bufferCopy",
73 methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class));
74 } catch (ReflectiveOperationException e) {
75 throw new BootstrapMethodError(e);
76 }
77 }
78
79 // workaround for https://bugs.openjdk.java.net/browse/JDK-8239083
80 private static MemorySegment allocateNative(MemoryLayout layout) {
81 return MemorySegment.allocateNative(layout);
82 }
83
84 /**
295
296 public static MethodHandle unboxVaLists(MethodType type, MethodHandle handle, MethodHandle unboxer) {
297 for (int i = 0; i < type.parameterCount(); i++) {
298 if (type.parameterType(i) == VaList.class) {
299 handle = MethodHandles.filterArguments(handle, i, unboxer);
300 }
301 }
302 return handle;
303 }
304
305 public static MethodHandle boxVaLists(MethodHandle handle, MethodHandle boxer) {
306 MethodType type = handle.type();
307 for (int i = 0; i < type.parameterCount(); i++) {
308 if (type.parameterType(i) == VaList.class) {
309 handle = MethodHandles.filterArguments(handle, i, boxer);
310 }
311 }
312 return handle;
313 }
314
315 public static class SimpleVaArg {
316 public final Class<?> carrier;
317 public final MemoryLayout layout;
318 public final Object value;
319
320 public SimpleVaArg(Class<?> carrier, MemoryLayout layout, Object value) {
321 this.carrier = carrier;
322 this.layout = layout;
323 this.value = value;
324 }
325
326 public VarHandle varHandle() {
327 return carrier == MemoryAddress.class
328 ? MemoryHandles.asAddressVarHandle(layout.varHandle(primitiveCarrierForSize(layout.byteSize())))
329 : layout.varHandle(carrier);
330 }
331 }
332
333 public static class EmptyVaList implements CSupport.VaList {
334
375 @Override
376 public boolean isAlive() {
377 return true;
378 }
379
380 @Override
381 public void close() {
382 throw uoe();
383 }
384
385 @Override
386 public VaList copy() {
387 return this;
388 }
389
390 @Override
391 public MemoryAddress address() {
392 return address;
393 }
394 }
395 }
|
28 import jdk.incubator.foreign.ForeignLinker;
29 import jdk.incubator.foreign.FunctionDescriptor;
30 import jdk.incubator.foreign.GroupLayout;
31 import jdk.incubator.foreign.MemoryAddress;
32 import jdk.incubator.foreign.MemoryHandles;
33 import jdk.incubator.foreign.MemoryLayout;
34 import jdk.incubator.foreign.MemorySegment;
35 import jdk.incubator.foreign.SequenceLayout;
36 import jdk.incubator.foreign.ValueLayout;
37 import jdk.internal.foreign.MemoryAddressImpl;
38 import jdk.internal.foreign.Utils;
39 import jdk.internal.foreign.abi.aarch64.AArch64Linker;
40 import jdk.internal.foreign.abi.x64.sysv.SysVVaList;
41 import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker;
42 import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker;
43
44 import java.lang.invoke.MethodHandle;
45 import java.lang.invoke.MethodHandles;
46 import java.lang.invoke.MethodType;
47 import java.lang.invoke.VarHandle;
48 import java.nio.ByteOrder;
49 import java.util.List;
50 import java.util.function.Consumer;
51 import java.util.stream.IntStream;
52
53 import static java.lang.invoke.MethodHandles.collectArguments;
54 import static java.lang.invoke.MethodHandles.identity;
55 import static java.lang.invoke.MethodHandles.insertArguments;
56 import static java.lang.invoke.MethodHandles.permuteArguments;
57 import static java.lang.invoke.MethodType.methodType;
58 import static jdk.incubator.foreign.CSupport.*;
59
60 public class SharedUtils {
61
62 private static final MethodHandle MH_ALLOC_BUFFER;
63 private static final MethodHandle MH_BASEADDRESS;
64 private static final MethodHandle MH_BUFFER_COPY;
65
66 private static final VarHandle VH_BYTE = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder());
67 private static final VarHandle VH_CHAR = MemoryHandles.varHandle(char.class, ByteOrder.nativeOrder());
68 private static final VarHandle VH_SHORT = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder());
69 private static final VarHandle VH_INT = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
70 private static final VarHandle VH_LONG = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
71 private static final VarHandle VH_FLOAT = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder());
72 private static final VarHandle VH_DOUBLE = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder());
73
74 static {
75 try {
76 var lookup = MethodHandles.lookup();
77 MH_ALLOC_BUFFER = lookup.findStatic(SharedUtils.class, "allocateNative",
78 methodType(MemorySegment.class, MemoryLayout.class));
79 MH_BASEADDRESS = lookup.findVirtual(MemorySegment.class, "baseAddress",
80 methodType(MemoryAddress.class));
81 MH_BUFFER_COPY = lookup.findStatic(SharedUtils.class, "bufferCopy",
82 methodType(MemoryAddress.class, MemoryAddress.class, MemorySegment.class));
83 } catch (ReflectiveOperationException e) {
84 throw new BootstrapMethodError(e);
85 }
86 }
87
88 // workaround for https://bugs.openjdk.java.net/browse/JDK-8239083
89 private static MemorySegment allocateNative(MemoryLayout layout) {
90 return MemorySegment.allocateNative(layout);
91 }
92
93 /**
304
305 public static MethodHandle unboxVaLists(MethodType type, MethodHandle handle, MethodHandle unboxer) {
306 for (int i = 0; i < type.parameterCount(); i++) {
307 if (type.parameterType(i) == VaList.class) {
308 handle = MethodHandles.filterArguments(handle, i, unboxer);
309 }
310 }
311 return handle;
312 }
313
314 public static MethodHandle boxVaLists(MethodHandle handle, MethodHandle boxer) {
315 MethodType type = handle.type();
316 for (int i = 0; i < type.parameterCount(); i++) {
317 if (type.parameterType(i) == VaList.class) {
318 handle = MethodHandles.filterArguments(handle, i, boxer);
319 }
320 }
321 return handle;
322 }
323
324 static void checkType(Class<?> actualType, Class<?> expectedType) {
325 if (expectedType != actualType) {
326 throw new IllegalArgumentException(
327 String.format("Invalid operand type: %s. %s expected", actualType, expectedType));
328 }
329 }
330
331 public static class SimpleVaArg {
332 public final Class<?> carrier;
333 public final MemoryLayout layout;
334 public final Object value;
335
336 public SimpleVaArg(Class<?> carrier, MemoryLayout layout, Object value) {
337 this.carrier = carrier;
338 this.layout = layout;
339 this.value = value;
340 }
341
342 public VarHandle varHandle() {
343 return carrier == MemoryAddress.class
344 ? MemoryHandles.asAddressVarHandle(layout.varHandle(primitiveCarrierForSize(layout.byteSize())))
345 : layout.varHandle(carrier);
346 }
347 }
348
349 public static class EmptyVaList implements CSupport.VaList {
350
391 @Override
392 public boolean isAlive() {
393 return true;
394 }
395
396 @Override
397 public void close() {
398 throw uoe();
399 }
400
401 @Override
402 public VaList copy() {
403 return this;
404 }
405
406 @Override
407 public MemoryAddress address() {
408 return address;
409 }
410 }
411
412 static void writeOverSized(MemoryAddress ptr, Class<?> type, Object o) {
413 // use VH_LONG for integers to zero out the whole register in the process
414 if (type == long.class) {
415 VH_LONG.set(ptr, (long) o);
416 } else if (type == int.class) {
417 VH_LONG.set(ptr, (long) (int) o);
418 } else if (type == short.class) {
419 VH_LONG.set(ptr, (long) (short) o);
420 } else if (type == char.class) {
421 VH_LONG.set(ptr, (long) (char) o);
422 } else if (type == byte.class) {
423 VH_LONG.set(ptr, (long) (byte) o);
424 } else if (type == float.class) {
425 VH_FLOAT.set(ptr, (float) o);
426 } else if (type == double.class) {
427 VH_DOUBLE.set(ptr, (double) o);
428 } else {
429 throw new IllegalArgumentException("Unsupported carrier: " + type);
430 }
431 }
432
433 static void write(MemoryAddress ptr, Class<?> type, Object o) {
434 if (type == long.class) {
435 VH_LONG.set(ptr, (long) o);
436 } else if (type == int.class) {
437 VH_INT.set(ptr, (int) o);
438 } else if (type == short.class) {
439 VH_SHORT.set(ptr, (short) o);
440 } else if (type == char.class) {
441 VH_CHAR.set(ptr, (char) o);
442 } else if (type == byte.class) {
443 VH_BYTE.set(ptr, (byte) o);
444 } else if (type == float.class) {
445 VH_FLOAT.set(ptr, (float) o);
446 } else if (type == double.class) {
447 VH_DOUBLE.set(ptr, (double) o);
448 } else {
449 throw new IllegalArgumentException("Unsupported carrier: " + type);
450 }
451 }
452
453 static Object read(MemoryAddress ptr, Class<?> type) {
454 if (type == long.class) {
455 return (long) VH_LONG.get(ptr);
456 } else if (type == int.class) {
457 return (int) VH_INT.get(ptr);
458 } else if (type == short.class) {
459 return (short) VH_SHORT.get(ptr);
460 } else if (type == char.class) {
461 return (char) VH_CHAR.get(ptr);
462 } else if (type == byte.class) {
463 return (byte) VH_BYTE.get(ptr);
464 } else if (type == float.class) {
465 return (float) VH_FLOAT.get(ptr);
466 } else if (type == double.class) {
467 return (double) VH_DOUBLE.get(ptr);
468 } else {
469 throw new IllegalArgumentException("Unsupported carrier: " + type);
470 }
471 }
472 }
|