Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8248710: jextract should not generate Cstring, Cpointer, Cint C-X utility classes #228

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
653 changes: 331 additions & 322 deletions doc/panama_jextract.html

Large diffs are not rendered by default.

170 changes: 90 additions & 80 deletions doc/panama_jextract.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -110,11 +110,18 @@ public void addStaticFunctionWrapper(String javaName, String nativeName, MethodT
decrAlign();
}

public void emitPrimitiveTypedef(Type.Primitive primType, String className) {
public void emitPrimitiveTypedef(Type.Primitive primType, String name) {
Type.Primitive.Kind kind = primType.kind();
if (primitiveKindSupported(kind)) {
String superClassName = "C" + kind.typeName().replace(" ", "_");
emitTypedef(className, superClassName);
if (primitiveKindSupported(kind) && !kind.layout().isEmpty()) {
incrAlign();
indent();
sb.append(PUB_MODS);
sb.append("ValueLayout ");
sb.append(name);
sb.append(" = ");
sb.append(TypeTranslator.typeToLayoutName(kind));
sb.append(";\n");
decrAlign();
}
}

Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ protected boolean functionSeen(Declaration.Function tree) {
static JavaFileObject[] generateWrapped(Declaration.Scoped decl, String clsName, String pkgName, List<String> libraryNames) {
String qualName = pkgName.isEmpty() ? clsName : pkgName + "." + clsName;
ConstantHelper constantHelper = new ConstantHelper(qualName,
ClassDesc.of(pkgName, "RuntimeHelper"), ClassDesc.of(pkgName, "Cstring"),
ClassDesc.of(pkgName, "RuntimeHelper"), ClassDesc.of("jdk.incubator.foreign", "CSupport"),
libraryNames.toArray(String[]::new));
return new OutputFactory(clsName, pkgName,
new HeaderBuilder(clsName, pkgName, constantHelper), constantHelper).generate(decl);
@@ -156,9 +156,6 @@ public JavaFileObject[] generate(Declaration.Scoped decl) {
files.add(builder.build());
files.addAll(constantHelper.getClasses());
files.add(fileFromString(pkgName,"RuntimeHelper", getRuntimeHelperSource()));
files.add(getCstringFile(pkgName));
files.add(getCpointerFile(pkgName));
files.addAll(getPrimitiveTypeFiles(pkgName));
return files.toArray(new JavaFileObject[0]);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
@@ -182,45 +179,6 @@ private void generateDecl(Declaration tree) {
}
}

private JavaFileObject getCstringFile(String pkgName) throws IOException, URISyntaxException {
return getTemplateFile(pkgName, "Cstring", "resources/Cstring.java.template");
}

private JavaFileObject getCpointerFile(String pkgName) throws IOException, URISyntaxException {
return getTemplateFile(pkgName, "Cpointer", "resources/Cpointer.java.template");
}

private JavaFileObject getTemplateFile(String pkgName, String className, String path) throws IOException, URISyntaxException {
var cstringFile = OutputFactory.class.getResource(path);
var lines = Files.readAllLines(Paths.get(cstringFile.toURI()));
String pkgPrefix = pkgName.isEmpty()? "" : "package " + pkgName + ";\n";
String contents = pkgPrefix +
lines.stream().collect(Collectors.joining("\n"));
return fileFromString(pkgName,className, contents);
}

private List<JavaFileObject> getPrimitiveTypeFiles(String pkgName) throws IOException, URISyntaxException {
var abi = SharedUtils.getSystemLinker();
var cXJavaFile = OutputFactory.class.getResource("resources/C-X.java.template");
var lines = Files.readAllLines(Paths.get(cXJavaFile.toURI()));

List<JavaFileObject> files = new ArrayList<>();
String pkgPrefix = pkgName.isEmpty()? "" : "package " + pkgName + ";\n";
for (Primitive.Kind type : Primitive.Kind.values()) {
if (type.layout().isEmpty()) continue;
String typeName = type.typeName().toLowerCase().replace(' ', '_');
MemoryLayout layout = type.layout().get();
String contents = pkgPrefix +
lines.stream().collect(Collectors.joining("\n")).
replace("-X", typeName).
replace("${C_LANG}", C_LANG_CONSTANTS_HOLDER).
replace("${LAYOUT}", TypeTranslator.typeToLayoutName(type)).
replace("${CARRIER}", classForType(type, layout).getName());
files.add(fileFromString(pkgName,"C" + typeName, contents));
}
return files;
}

private static Class<?> classForType(Primitive.Kind type, MemoryLayout layout) {
boolean isFloat = switch(type) {
case Float, Double, LongDouble -> true;

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -81,6 +81,19 @@ public class RuntimeHelper {
}
}

public static MemoryAddress asArrayRestricted(MemoryAddress addr, MemoryLayout layout, int numElements) {
return MemorySegment.ofNativeRestricted(addr, numElements * layout.byteSize(),
Thread.currentThread(), null, null).baseAddress();
}

public static MemoryAddress asArray(MemoryAddress addr, MemoryLayout layout, int numElements) {
var seg = addr.segment();
if (seg == null) {
throw new IllegalArgumentException("no underlying segment for the address");
}
return seg.asSlice(addr.segmentOffset(), numElements * layout.byteSize()).baseAddress();
}

private static class VarargsInvoker {
private static final MethodHandle INVOKE_MH;
private final MemoryAddress symbol;
7 changes: 3 additions & 4 deletions test/jdk/tools/jextract/Test8244412.java
Original file line number Diff line number Diff line change
@@ -41,10 +41,9 @@ public void testPrimitiveTypedefs() {
Path typedefsH = getInputFilePath("typedefs.h");
run("-d", typedefsOutput.toString(), typedefsH.toString()).checkSuccess();
try(Loader loader = classLoader(typedefsOutput)) {
Class<?> bytetCls = loader.loadClass("typedefs_h$byte_t");
assertNotNull(bytetCls);
Class<?> sizetCls = loader.loadClass("typedefs_h$mysize_t");
assertNotNull(sizetCls);
Class<?> headerCls = loader.loadClass("typedefs_h");
assertNotNull(findField(headerCls, "byte_t"));
assertNotNull(findField(headerCls, "mysize_t"));
} finally {
deleteDir(typedefsOutput);
}
32 changes: 17 additions & 15 deletions test/jdk/tools/jextract/test8241925/LibTest8241925Test.java
Original file line number Diff line number Diff line change
@@ -23,11 +23,13 @@

import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import jdk.incubator.foreign.MemoryAccess;
import jdk.incubator.foreign.NativeScope;
import org.testng.annotations.Test;
import test.jextract.test8241925.*;
import static org.testng.Assert.assertEquals;
import static test.jextract.test8241925.test8241925_h.*;
import static jdk.incubator.foreign.CSupport.*;

/*
* @test
@@ -42,38 +44,38 @@ public class LibTest8241925Test {
@Test
public void test() {
try (var scope = NativeScope.unboundedScope()) {
var addr = Cint.allocate(12, scope);
assertEquals(Cint.get(addr), 12);
var addr = scope.allocate(C_INT, 12);
assertEquals(MemoryAccess.getInt(addr, 0), 12);
square(addr);
assertEquals(Cint.get(addr), 144);
assertEquals(MemoryAccess.getInt(addr, 0), 144);

addr = Cdouble.allocate(12.0, scope);
assertEquals(Cdouble.get(addr), 12.0, 0.1);
addr = scope.allocate(C_DOUBLE, 12.0);
assertEquals(MemoryAccess.getDouble(addr, 0), 12.0, 0.1);
square_fp(addr);
assertEquals(Cdouble.get(addr), 144.0, 0.1);
assertEquals(MemoryAccess.getDouble(addr, 0), 144.0, 0.1);

int[] intArray = { 34, 67, 78, 8 };
addr = Cint.allocateArray(intArray, scope);
addr = scope.allocateArray(C_INT, intArray);
int sum = sum(addr, intArray.length);
assertEquals(sum, IntStream.of(intArray).sum());
int[] convertedArray = Cint.toJavaArray(addr.segment());
int[] convertedArray = addr.segment().toIntArray();
assertEquals(convertedArray, intArray);

double[] dblArray = { 34.5, 67.56, 78.2, 8.45 };
addr = Cdouble.allocateArray(dblArray, scope);
addr = scope.allocateArray(C_DOUBLE, dblArray);
double sumd = sum_fp(addr, dblArray.length);
assertEquals(sumd, DoubleStream.of(dblArray).sum(), 0.1);
double[] convertedDblArray = Cdouble.toJavaArray(addr.segment());
double[] convertedDblArray = addr.segment().toDoubleArray();
for (int i = 0; i < dblArray.length; i++) {
assertEquals(dblArray[i], convertedDblArray[i], 0.1);
}

assertEquals(Cstring.toJavaStringRestricted(name()), "java");
assertEquals(toJavaStringRestricted(name()), "java");

var dest = Cchar.allocateArray(12, scope);
Cstring.copy(dest, "hello ");
var src = Cstring.toCString("world", scope);
assertEquals(Cstring.toJavaStringRestricted(concatenate(dest, src)), "hello world");
var dest = scope.allocateArray(C_CHAR, 12);
dest.segment().copyFrom(toCString("hello "));
var src = toCString("world", scope);
assertEquals(toJavaStringRestricted(concatenate(dest, src)), "hello world");
}
}
}
11 changes: 5 additions & 6 deletions test/jdk/tools/jextract/test8244412/LibTest8244412Test.java
Original file line number Diff line number Diff line change
@@ -22,11 +22,11 @@
*/


import jdk.incubator.foreign.MemoryAccess;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.NativeScope;

import org.testng.annotations.Test;
import test.jextract.test8244412.Clong_long;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static test.jextract.test8244412.test8244412_h.*;
@@ -44,11 +44,10 @@ public class LibTest8244412Test {
@Test
public void test() {
try (var scope = NativeScope.unboundedScope()) {
var addr = mysize_t.allocate(0L, scope);
assertEquals(mysize_t.get(addr), 0L);
mysize_t.set(addr, 13455566L);
assertEquals(mysize_t.get(addr), 13455566L);
assertTrue(mysize_t.sizeof() == Clong_long.sizeof());
var addr = scope.allocate(mysize_t, 0L);
assertEquals(MemoryAccess.getLong(addr, 0), 0L);
MemoryAccess.setLong(addr, 0, 13455566L);
assertEquals(MemoryAccess.getLong(addr, 0), 13455566L);
}
}
}
2 changes: 1 addition & 1 deletion test/jdk/tools/jextract/test8244959/Test8244959.java
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@
import jdk.incubator.foreign.MemorySegment;

import static org.testng.Assert.assertEquals;
import static test.jextract.printf.Cstring.*;
import static test.jextract.printf.printf_h.*;
import static jdk.incubator.foreign.CSupport.*;

/*
* @test
7 changes: 4 additions & 3 deletions test/jdk/tools/jextract/test8245003/Test8245003.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import test.jextract.test8245003.*;
import static org.testng.Assert.assertEquals;
import static test.jextract.test8245003.test8245003_h.*;
import static jdk.incubator.foreign.CSupport.*;

/*
* @test
@@ -55,8 +56,8 @@ public void testStructAccessor() {
@Test
public void testArrayAccessor() {
var addr = iarr$ADDR();
assertEquals(addr.segment().byteSize(), Cint.sizeof()*5);
int[] arr = Cint.toJavaArray(addr.segment());
assertEquals(addr.segment().byteSize(), C_INT.byteSize()*5);
int[] arr = addr.segment().toIntArray();
assertEquals(arr.length, 5);
assertEquals(arr[0], 2);
assertEquals(arr[1], -2);
@@ -68,7 +69,7 @@ public void testArrayAccessor() {
assertEquals(addr.segment().byteSize(), Foo.sizeof());
assertEquals(Foo.count$get(addr), 37);
var greeting = Foo.greeting$addr(addr);
byte[] barr = Cchar.toJavaArray(greeting.segment());
byte[] barr = greeting.segment().toByteArray();
assertEquals(new String(barr), "hello");
}
}
30 changes: 15 additions & 15 deletions test/jdk/tools/jextract/test8246341/LibTest8246341Test.java
Original file line number Diff line number Diff line change
@@ -21,14 +21,15 @@
* questions.
*/

import jdk.incubator.foreign.MemoryAccess;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.NativeScope;
import org.testng.annotations.Test;
import test.jextract.test8246341.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static test.jextract.test8246341.test8246341_h.*;
import static test.jextract.test8246341.Cstring.toJavaStringRestricted;
import static jdk.incubator.foreign.CSupport.*;

/*
* @test
@@ -41,17 +42,21 @@
* @run testng/othervm -Dforeign.restricted=permit LibTest8246341Test
*/
public class LibTest8246341Test {
private static MemoryAddress getPointerAt(MemoryAddress addr, int element) {
return MemoryAccess.getAddress(addr, element*C_POINTER.byteSize());
}

@Test
public void testPointerArray() {
boolean[] callbackCalled = new boolean[1];
try (var callback = func$callback.allocate((argc, argv) -> {
callbackCalled[0] = true;
var addr = Cpointer.asArrayRestricted(argv, argc);
var addr = RuntimeHelper.asArrayRestricted(argv, C_POINTER, argc);
assertEquals(argc, 4);
assertEquals(toJavaStringRestricted(Cpointer.get(addr, 0)), "java");
assertEquals(toJavaStringRestricted(Cpointer.get(addr, 1)), "python");
assertEquals(toJavaStringRestricted(Cpointer.get(addr, 2)), "javascript");
assertEquals(toJavaStringRestricted(Cpointer.get(addr, 3)), "c++");
assertEquals(toJavaStringRestricted(getPointerAt(addr, 0)), "java");
assertEquals(toJavaStringRestricted(getPointerAt(addr, 1)), "python");
assertEquals(toJavaStringRestricted(getPointerAt(addr, 2)), "javascript");
assertEquals(toJavaStringRestricted(getPointerAt(addr, 3)), "c++");
})) {
func(callback.baseAddress());
}
@@ -60,16 +65,11 @@ public void testPointerArray() {

@Test
public void testPointerAllocate() {
try (var scope = NativeScope.boundedScope(Cpointer.sizeof())) {
var addr = Cpointer.allocate(MemoryAddress.NULL, scope);
fillin(addr);
assertEquals(toJavaStringRestricted(Cpointer.get(addr)), "hello world");
}

try (var seg = Cpointer.allocate(MemoryAddress.NULL)) {
var addr = seg.baseAddress();
try (var scope = NativeScope.boundedScope(C_POINTER.byteSize())) {
var addr = scope.allocate(C_POINTER);
MemoryAccess.setAddress(addr, 0, MemoryAddress.NULL);
fillin(addr);
assertEquals(toJavaStringRestricted(Cpointer.get(addr)), "hello world");
assertEquals(toJavaStringRestricted(getPointerAt(addr, 0)), "hello world");
}
}
}