From 2b048d024a1e9a017a67f215f6dbf4ecf33c1e9a Mon Sep 17 00:00:00 2001
From: squid233 <60126026+squid233@users.noreply.github.com>
Date: Thu, 1 Feb 2024 22:49:33 +0800
Subject: [PATCH] Downcall: fix cross-module access
---
README.md | 3 +--
gradle.properties | 2 +-
src/main/java/overrun/marshal/Downcall.java | 14 ++++++++------
.../overrun/marshal/test/DescriptorMapTest.java | 2 +-
.../marshal/test/IndirectInterfaceTest.java | 4 ++--
5 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index a6bfda4..de48e11 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,6 @@ import overrun.marshal.gen.*;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
-import java.lang.foreign.ValueLayout;
/**
* GLFW constants and functions
@@ -95,6 +94,6 @@ Import as a Gradle dependency:
```groovy
dependencies {
- implementation("io.github.over-run:marshal:0.1.0-alpha.15-jdk22")
+ implementation("io.github.over-run:marshal:0.1.0-alpha.16-jdk22")
}
```
diff --git a/gradle.properties b/gradle.properties
index f1d9b00..b959d67 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -12,7 +12,7 @@ projGroupId=io.github.over-run
projArtifactId=marshal
# The project name should only contain lowercase letters, numbers and hyphen.
projName=marshal
-projVersion=0.1.0-alpha.15-jdk22
+projVersion=0.1.0-alpha.16-jdk22
projDesc=Marshaler of native libraries
# Uncomment them if you want to publish to maven repository.
projUrl=https://github.com/Over-Run/marshal
diff --git a/src/main/java/overrun/marshal/Downcall.java b/src/main/java/overrun/marshal/Downcall.java
index b271550..4994372 100644
--- a/src/main/java/overrun/marshal/Downcall.java
+++ b/src/main/java/overrun/marshal/Downcall.java
@@ -46,6 +46,10 @@
*
Loading native library
* You can load native libraries with {@link #load(Class, SymbolLookup)}.
* This method generates a hidden class that loads method handle with the given symbol lookup.
+ *
+ * The generated class implements the target class.
+ * The target class MUST be {@code public}
+ * as the generated class is defined in package {@code overrun.marshal}.
*
Methods
* The loader finds method from the target class and its superclasses.
*
@@ -397,7 +401,7 @@ private static Method findUpcallWrapper(Class> aClass) {
@SuppressWarnings("unchecked")
private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map descriptorMap) {
final ClassFile cf = of();
- final ClassDesc cd_thisClass = ClassDesc.of(targetClass.getPackageName(), DEFAULT_NAME);
+ final ClassDesc cd_thisClass = ClassDesc.of(Downcall.class.getPackageName(), DEFAULT_NAME);
final byte[] bytes = cf.build(cd_thisClass, classBuilder -> {
final List methodList = Arrays.stream(targetClass.getMethods())
.filter(method ->
@@ -420,7 +424,6 @@ private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map
});
final Map methodDataMap = LinkedHashMap.newLinkedHashMap(methodList.size());
- final Map handleDataMap = LinkedHashMap.newLinkedHashMap(methodList.size());
classBuilder.withFlags(ACC_FINAL | ACC_SUPER);
@@ -454,7 +457,6 @@ private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map
);
methodDataMap.put(method, methodData);
- handleDataMap.put(method, methodData);
classBuilder.withField(handleName, CD_MethodHandle,
ACC_PRIVATE | ACC_FINAL);
});
@@ -468,7 +470,7 @@ private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map
.invokespecial(CD_Object, INIT_NAME, MTD_void);
// method handles
- handleDataMap.values().forEach(methodData -> {
+ methodDataMap.values().forEach(methodData -> {
// initialize field
codeBuilder.aload(codeBuilder.receiverSlot())
.aload(codeBuilder.parameterSlot(0))
@@ -866,7 +868,7 @@ private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map
});
// handle loader
- handleDataMap.forEach((method, methodData) -> classBuilder.withMethod(
+ methodDataMap.forEach((method, methodData) -> classBuilder.withMethod(
methodData.loaderName(),
MTD_MethodHandle_SymbolLookup,
ACC_PRIVATE | ACC_STATIC,
@@ -1046,7 +1048,7 @@ private static T loadBytecode(Class> targetClass, SymbolLookup lookup, Map
});
try {
- final MethodHandles.Lookup hiddenClass = MethodHandles.privateLookupIn(targetClass, MethodHandles.lookup())
+ final MethodHandles.Lookup hiddenClass = MethodHandles.lookup()
.defineHiddenClassWithClassData(bytes, Map.copyOf(descriptorMap), true, MethodHandles.Lookup.ClassOption.STRONG);
return (T) hiddenClass.findConstructor(hiddenClass.lookupClass(), MethodType.methodType(void.class, SymbolLookup.class))
.invoke(lookup);
diff --git a/src/test/java/overrun/marshal/test/DescriptorMapTest.java b/src/test/java/overrun/marshal/test/DescriptorMapTest.java
index 4f175fb..81400d9 100644
--- a/src/test/java/overrun/marshal/test/DescriptorMapTest.java
+++ b/src/test/java/overrun/marshal/test/DescriptorMapTest.java
@@ -87,7 +87,7 @@ static boolean acceptLong(long d) {
return d == 84L;
}
- interface Interface {
+ public interface Interface {
static Interface getInstance(ValueLayout returnLayout, ValueLayout acceptLayout) {
return Downcall.load(lookup(returnLayout, acceptLayout), Map.of(
"testReturn", FunctionDescriptor.of(returnLayout),
diff --git a/src/test/java/overrun/marshal/test/IndirectInterfaceTest.java b/src/test/java/overrun/marshal/test/IndirectInterfaceTest.java
index 621fc1d..2d5b8c5 100644
--- a/src/test/java/overrun/marshal/test/IndirectInterfaceTest.java
+++ b/src/test/java/overrun/marshal/test/IndirectInterfaceTest.java
@@ -29,13 +29,13 @@
* @since 0.1.0
*/
public final class IndirectInterfaceTest {
- interface I1 {
+ public interface I1 {
default int fun1() {
return 1;
}
}
- interface I2 extends I1 {
+ public interface I2 extends I1 {
}
I2 INSTANCE = Downcall.load(I2.class, SymbolLookup.loaderLookup());