< prev index next > test/jdk/java/foreign/StdLibTest.java
Print this page
* questions.
*/
/*
* @test
- * @enablePreview
- * @requires jdk.foreign.linker != "UNSUPPORTED"
* @run testng/othervm --enable-native-access=ALL-UNNAMED StdLibTest
*/
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import org.testng.annotations.*;
import static org.testng.Assert.*;
- @Test
public class StdLibTest extends NativeTestHelper {
final static Linker abi = Linker.nativeLinker();
private StdLibHelper stdLibHelper = new StdLibHelper();
fail("All values are the same! " + val);
}
@Test(dataProvider = "printfArgs")
void test_printf(List<PrintfArg> args) throws Throwable {
! String formatArgs = args.stream()
! .map(a -> a.format)
.collect(Collectors.joining(","));
! String formatString = "hello(" + formatArgs + ")\n";
! String expected = String.format(formatString, args.stream()
.map(a -> a.javaValue).toArray());
! int found = stdLibHelper.printf(formatString, args);
assertEquals(found, expected.length());
}
@Test
void testSystemLibraryBadLookupName() {
fail("All values are the same! " + val);
}
@Test(dataProvider = "printfArgs")
void test_printf(List<PrintfArg> args) throws Throwable {
! String javaFormatArgs = args.stream()
! .map(a -> a.javaFormat)
+ .collect(Collectors.joining(","));
+ String nativeFormatArgs = args.stream()
+ .map(a -> a.nativeFormat)
.collect(Collectors.joining(","));
! String javaFormatString = "hello(" + javaFormatArgs + ")\n";
+ String nativeFormatString = "hello(" + nativeFormatArgs + ")\n";
! String expected = String.format(javaFormatString, args.stream()
.map(a -> a.javaValue).toArray());
! int found = stdLibHelper.printf(nativeFormatString, args);
assertEquals(found, expected.length());
}
@Test
void testSystemLibraryBadLookupName() {
FunctionDescriptor.of(C_INT, C_POINTER));
final static MethodHandle gmtime = abi.downcallHandle(abi.defaultLookup().find("gmtime").get(),
FunctionDescriptor.of(C_POINTER.withTargetLayout(Tm.LAYOUT), C_POINTER));
final static MethodHandle qsort = abi.downcallHandle(abi.defaultLookup().find("qsort").get(),
! FunctionDescriptor.ofVoid(C_POINTER, C_LONG_LONG, C_LONG_LONG, C_POINTER));
final static FunctionDescriptor qsortComparFunction = FunctionDescriptor.of(C_INT,
C_POINTER.withTargetLayout(C_INT), C_POINTER.withTargetLayout(C_INT));
final static MethodHandle qsortCompar;
FunctionDescriptor.of(C_INT, C_POINTER));
final static MethodHandle gmtime = abi.downcallHandle(abi.defaultLookup().find("gmtime").get(),
FunctionDescriptor.of(C_POINTER.withTargetLayout(Tm.LAYOUT), C_POINTER));
+ // void qsort( void *ptr, size_t count, size_t size, int (*comp)(const void *, const void *) );
final static MethodHandle qsort = abi.downcallHandle(abi.defaultLookup().find("qsort").get(),
! FunctionDescriptor.ofVoid(C_POINTER, C_SIZE_T, C_SIZE_T, C_POINTER));
final static FunctionDescriptor qsortComparFunction = FunctionDescriptor.of(C_INT,
C_POINTER.withTargetLayout(C_INT), C_POINTER.withTargetLayout(C_INT));
final static MethodHandle qsortCompar;
}
String strcat(String s1, String s2) throws Throwable {
try (var arena = Arena.ofConfined()) {
MemorySegment buf = arena.allocate(s1.length() + s2.length() + 1);
! buf.setUtf8String(0, s1);
! MemorySegment other = arena.allocateUtf8String(s2);
! return ((MemorySegment)strcat.invokeExact(buf, other)).getUtf8String(0);
}
}
int strcmp(String s1, String s2) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment ns1 = arena.allocateUtf8String(s1);
! MemorySegment ns2 = arena.allocateUtf8String(s2);
return (int)strcmp.invokeExact(ns1, ns2);
}
}
int puts(String msg) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment s = arena.allocateUtf8String(msg);
return (int)puts.invokeExact(s);
}
}
int strlen(String msg) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment s = arena.allocateUtf8String(msg);
return (int)strlen.invokeExact(s);
}
}
Tm gmtime(long arg) throws Throwable {
}
String strcat(String s1, String s2) throws Throwable {
try (var arena = Arena.ofConfined()) {
MemorySegment buf = arena.allocate(s1.length() + s2.length() + 1);
! buf.setString(0, s1);
! MemorySegment other = arena.allocateFrom(s2);
! return ((MemorySegment)strcat.invokeExact(buf, other)).getString(0);
}
}
int strcmp(String s1, String s2) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment ns1 = arena.allocateFrom(s1);
! MemorySegment ns2 = arena.allocateFrom(s2);
return (int)strcmp.invokeExact(ns1, ns2);
}
}
int puts(String msg) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment s = arena.allocateFrom(msg);
return (int)puts.invokeExact(s);
}
}
int strlen(String msg) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment s = arena.allocateFrom(msg);
return (int)strlen.invokeExact(s);
}
}
Tm gmtime(long arg) throws Throwable {
}
int[] qsort(int[] arr) throws Throwable {
//init native array
try (var arena = Arena.ofConfined()) {
! MemorySegment nativeArr = arena.allocateArray(C_INT, arr);
//call qsort
MemorySegment qsortUpcallStub = abi.upcallStub(qsortCompar, qsortComparFunction, arena);
! qsort.invokeExact(nativeArr, (long)arr.length, C_INT.byteSize(), qsortUpcallStub);
//convert back to Java array
return nativeArr.toArray(C_INT);
}
}
}
int[] qsort(int[] arr) throws Throwable {
//init native array
try (var arena = Arena.ofConfined()) {
! MemorySegment nativeArr = arena.allocateFrom(C_INT, arr);
//call qsort
MemorySegment qsortUpcallStub = abi.upcallStub(qsortCompar, qsortComparFunction, arena);
! // both of these fit in an int
+ // automatically widen them to long on x64
+ int count = arr.length;
+ int size = (int) C_INT.byteSize();
+ qsort.invoke(nativeArr, count, size, qsortUpcallStub);
//convert back to Java array
return nativeArr.toArray(C_INT);
}
}
return (int)rand.invokeExact();
}
int printf(String format, List<PrintfArg> args) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment formatStr = arena.allocateUtf8String(format);
return (int)specializedPrintf(args).invokeExact(formatStr,
args.stream().map(a -> a.nativeValue(arena)).toArray());
}
}
return (int)rand.invokeExact();
}
int printf(String format, List<PrintfArg> args) throws Throwable {
try (var arena = Arena.ofConfined()) {
! MemorySegment formatStr = arena.allocateFrom(format);
return (int)specializedPrintf(args).invokeExact(formatStr,
args.stream().map(a -> a.nativeValue(arena)).toArray());
}
}
.map(l -> new Object[] { l })
.toArray(Object[][]::new);
}
enum PrintfArg {
! INT(int.class, C_INT, "%d", arena -> 42, 42),
! LONG(long.class, C_LONG_LONG, "%d", arena -> 84L, 84L),
! DOUBLE(double.class, C_DOUBLE, "%.4f", arena -> 1.2345d, 1.2345d),
! STRING(MemorySegment.class, C_POINTER, "%s", arena -> arena.allocateUtf8String("str"), "str");
final Class<?> carrier;
final ValueLayout layout;
! final String format;
final Function<Arena, ?> nativeValueFactory;
final Object javaValue;
! <Z, L extends ValueLayout> PrintfArg(Class<?> carrier, L layout, String format, Function<Arena, Z> nativeValueFactory, Object javaValue) {
this.carrier = carrier;
this.layout = layout;
! this.format = format;
this.nativeValueFactory = nativeValueFactory;
this.javaValue = javaValue;
}
public Object nativeValue(Arena arena) {
.map(l -> new Object[] { l })
.toArray(Object[][]::new);
}
enum PrintfArg {
! INT(int.class, C_INT, "%d", "%d", arena -> 42, 42),
! LONG(long.class, C_LONG_LONG, "%lld", "%d", arena -> 84L, 84L),
! DOUBLE(double.class, C_DOUBLE, "%.4f", "%.4f", arena -> 1.2345d, 1.2345d),
! STRING(MemorySegment.class, C_POINTER, "%s", "%s", arena -> arena.allocateFrom("str"), "str");
final Class<?> carrier;
final ValueLayout layout;
! final String nativeFormat;
+ final String javaFormat;
final Function<Arena, ?> nativeValueFactory;
final Object javaValue;
! <Z, L extends ValueLayout> PrintfArg(Class<?> carrier, L layout, String nativeFormat, String javaFormat,
+ Function<Arena, Z> nativeValueFactory, Object javaValue) {
this.carrier = carrier;
this.layout = layout;
! this.nativeFormat = nativeFormat;
+ this.javaFormat = javaFormat;
this.nativeValueFactory = nativeValueFactory;
this.javaValue = javaValue;
}
public Object nativeValue(Arena arena) {
< prev index next >