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

8261906: Improve jextract support for virtual functions #456

Closed
wants to merge 13 commits into from
Closed
Changes from 1 commit
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
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ public class FunctionalInterfaceBuilder extends NestedClassBuilder {
JavaSourceBuilder classEnd() {
emitFunctionalInterfaceMethod();
emitFunctionalFactories();
emitFunctionaRestrictedFactory();
emitFunctionalRestrictedFactory();
return super.classEnd();
}

@@ -95,7 +95,7 @@ private void emitFunctionalFactories() {
});
}

private void emitFunctionaRestrictedFactory() {
private void emitFunctionalRestrictedFactory() {
emitWithConstantClass(className(), constantBuilder -> {
Constant mhConstant = constantBuilder.addMethodHandle(className(), className(), FunctionInfo.ofFunctionPointer(fiType, fiDesc), true);
incrAlign();
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@ public class OutputFactory implements Declaration.Visitor<Void, Declaration> {
private final String pkgName;
private final Map<Declaration, String> structClassNames = new HashMap<>();
private final Set<Declaration.Typedef> unresolvedStructTypedefs = new HashSet<>();
private final Map<Type, String> functionTypeDefNames = new HashMap<>();

private void addStructDefinition(Declaration decl, String name) {
structClassNames.put(decl, name);
@@ -84,6 +85,18 @@ private String structDefinitionName(Declaration decl) {
return structClassNames.get(decl);
}

private void addFunctionTypedef(Type.Delegated typedef, String name) {
functionTypeDefNames.put(typedef, name);
}

private boolean functionTypedefSeen(Type.Delegated typedef) {
return functionTypeDefNames.containsKey(typedef);
}

private String functionTypedefName(Type.Delegated decl) {
return functionTypeDefNames.get(decl);
}

// have we seen this Variable earlier?
protected boolean variableSeen(Declaration.Variable tree) {
return !variables.add(tree.name());
@@ -278,8 +291,8 @@ public Void visitFunction(Declaration.Function funcTree, Declaration parent) {
Optional<String> getAsFunctionPointerTypedef(Type type) {
if (type instanceof Type.Delegated delegated &&
delegated.kind() == Type.Delegated.Kind.TYPEDEF &&
getAsFunctionPointer(delegated.type()) != null) {
return delegated.name();
functionTypedefSeen(delegated)) {
return Optional.of(functionTypedefName(delegated));
} else {
return Optional.empty();
}
@@ -344,7 +357,10 @@ public Void visitTypedef(Declaration.Typedef tree, Declaration parent) {
} else {
Type.Function func = getAsFunctionPointer(type);
if (func != null) {
generateFunctionalInterface(func, tree.name());
String funcIntfName = generateFunctionalInterface(func, tree.name());
if (funcIntfName != null) {
addFunctionTypedef(Type.typedef(tree.name(), tree.type()), funcIntfName);
}
}
}
return null;
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@
*/
public class TestFuncPointerInvokers {
@Test
public void testStructField() {
public void testStructFieldTypedef() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
MemorySegment bar = Bar.allocate(scope);
@@ -57,7 +57,7 @@ public void testStructField() {
}

@Test
public void testStructFieldFI() {
public void testStructFieldFITypedef() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
MemorySegment bar = Bar.allocate(scope);
@@ -68,7 +68,7 @@ public void testStructFieldFI() {
}

@Test
public void testGlobal() {
public void testGlobalTypedef() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
f$set(Foo.allocate((i) -> val.set(i), scope).address());
@@ -78,12 +78,54 @@ public void testGlobal() {
}

@Test
public void testGlobalFI() {
public void testGlobalFITypedef() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
f$set(Foo.allocate((i) -> val.set(i), scope).address());
Foo.ofAddressRestricted(f$get()).apply(42);
assertEquals(val.get(), 42);
}
}

@Test
public void testStructFieldFunctionPointer() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
MemorySegment baz = Baz.allocate(scope);
Baz.fp$set(baz, Baz.fp.allocate((i) -> val.set(i), scope).address());
Baz.fp(baz).apply(42);
assertEquals(val.get(), 42);
}
}

@Test
public void testStructFieldFIFunctionPointer() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
MemorySegment baz = Baz.allocate(scope);
Baz.fp$set(baz, Baz.fp.allocate((i) -> val.set(i), scope).address());
Baz.fp.ofAddressRestricted(Baz.fp$get(baz)).apply(42);
assertEquals(val.get(), 42);
}
}

@Test
public void testGlobalFunctionPointer() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
fp$set(fp.allocate((i) -> val.set(i), scope).address());
fp().apply(42);
assertEquals(val.get(), 42);
}
}

@Test
public void testGlobalFIFunctionPointer() {
try (NativeScope scope = NativeScope.unboundedScope()) {
AtomicInteger val = new AtomicInteger(-1);
fp$set(fp.allocate((i) -> val.set(i), scope).address());
fp.ofAddressRestricted(fp$get()).apply(42);
assertEquals(val.get(), 42);
}
}
}
8 changes: 7 additions & 1 deletion test/jdk/tools/jextract/funcPointerInvokers/func.h
Original file line number Diff line number Diff line change
@@ -39,6 +39,12 @@ struct Bar {

EXPORT Foo f;

struct Baz {
void (*fp)(int arg);
};

EXPORT void (*fp)(int arg);

#ifdef __cplusplus
}
#endif // __cplusplus
#endif // __cplusplus