Skip to content

Commit 376bba1

Browse files
committed
Update to JDK 20
1 parent 8f34e65 commit 376bba1

20 files changed

+487
-160
lines changed

.github/workflows/publish-github.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ jobs:
1717
ref: 'develop'
1818
- uses: actions/setup-java@v3
1919
with:
20-
distribution: 'temurin'
21-
java-version: 19
20+
distribution: 'zulu'
21+
java-version: 20
2222
cache: 'maven'
2323
gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
2424
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase

.github/workflows/publish-maven.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ jobs:
1717
ref: 'develop'
1818
- uses: actions/setup-java@v3
1919
with:
20-
distribution: 'temurin'
21-
java-version: 19
20+
distribution: 'zulu'
21+
java-version: 20
2222
cache: 'maven'
2323
server-id: ossrh
2424
server-username: MAVEN_USERNAME

.github/workflows/publish-minimal-github.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ jobs:
1717
ref: 'minimal'
1818
- uses: actions/setup-java@v3
1919
with:
20-
distribution: 'temurin'
21-
java-version: 19
20+
distribution: 'zulu'
21+
java-version: 20
2222
cache: 'maven'
2323
gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
2424
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase

.github/workflows/publish-minimal-maven.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ jobs:
1717
ref: 'minimal'
1818
- uses: actions/setup-java@v3
1919
with:
20-
distribution: 'temurin'
21-
java-version: 19
20+
distribution: 'zulu'
21+
java-version: 20
2222
cache: 'maven'
2323
server-id: ossrh
2424
server-username: MAVEN_USERNAME

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Based on libayatana-appindicator3-1 (0.5.92-1)
1010
Based on libappindicator3-1 (12.10.1+20.10.20200706.1-0ubuntu1)
1111

1212
# Requires
13-
Java 19 (preview)
13+
Java 20 (preview)
1414
- due to the use of the new Foreign Function & Memory API
1515

1616
# Usage

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
</scm>
3737

3838
<properties>
39-
<maven.compiler.source>19</maven.compiler.source>
40-
<maven.compiler.target>19</maven.compiler.target>
39+
<maven.compiler.source>20</maven.compiler.source>
40+
<maven.compiler.target>20</maven.compiler.target>
4141
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4242

4343
<junit.version>5.9.2</junit.version>
@@ -132,8 +132,8 @@
132132
<artifactId>maven-compiler-plugin</artifactId>
133133
<version>3.11.0</version>
134134
<configuration>
135-
<source>19</source>
136-
<target>19</target>
135+
<source>20</source>
136+
<target>20</target>
137137
<compilerArgs>
138138
--enable-preview
139139
</compilerArgs>

src/main/java/org/purejava/linux/Constants$root.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@
77
import java.nio.ByteOrder;
88
import java.lang.foreign.*;
99
import static java.lang.foreign.ValueLayout.*;
10-
public class Constants$root {
10+
final class Constants$root {
1111

12-
static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN;
13-
static final OfByte C_CHAR$LAYOUT = JAVA_BYTE;
14-
static final OfShort C_SHORT$LAYOUT = JAVA_SHORT.withBitAlignment(16);
15-
static final OfInt C_INT$LAYOUT = JAVA_INT.withBitAlignment(32);
16-
static final OfLong C_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64);
17-
static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG.withBitAlignment(64);
18-
static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT.withBitAlignment(32);
19-
static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE.withBitAlignment(64);
20-
static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64);
12+
// Suppresses default constructor, ensuring non-instantiability.
13+
private Constants$root() {}
14+
static final OfBoolean C_BOOL$LAYOUT = JAVA_BOOLEAN;
15+
static final OfByte C_CHAR$LAYOUT = JAVA_BYTE;
16+
static final OfShort C_SHORT$LAYOUT = JAVA_SHORT;
17+
static final OfInt C_INT$LAYOUT = JAVA_INT;
18+
static final OfLong C_LONG$LAYOUT = JAVA_LONG;
19+
static final OfLong C_LONG_LONG$LAYOUT = JAVA_LONG;
20+
static final OfFloat C_FLOAT$LAYOUT = JAVA_FLOAT;
21+
static final OfDouble C_DOUBLE$LAYOUT = JAVA_DOUBLE;
22+
static final OfAddress C_POINTER$LAYOUT = ADDRESS.withBitAlignment(64).asUnbounded();
2123
}
2224

2325

src/main/java/org/purejava/linux/GCallback.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,22 @@
77
import java.nio.ByteOrder;
88
import java.lang.foreign.*;
99
import static java.lang.foreign.ValueLayout.*;
10+
/**
11+
* {@snippet :
12+
* void (*GCallback)();
13+
* }
14+
*/
1015
public interface GCallback {
1116

1217
void apply();
13-
static MemorySegment allocate(GCallback fi, MemorySession session) {
14-
return RuntimeHelper.upcallStub(GCallback.class, fi, constants$0.GCallback$FUNC, session);
18+
static MemorySegment allocate(GCallback fi, SegmentScope scope) {
19+
return RuntimeHelper.upcallStub(constants$0.GCallback_UP$MH, fi, constants$0.GCallback$FUNC, scope);
1520
}
16-
static GCallback ofAddress(MemoryAddress addr, MemorySession session) {
17-
MemorySegment symbol = MemorySegment.ofAddress(addr, 0, session);
21+
static GCallback ofAddress(MemorySegment addr, SegmentScope scope) {
22+
MemorySegment symbol = MemorySegment.ofAddress(addr.address(), 0, scope);
1823
return () -> {
1924
try {
20-
constants$0.GCallback$MH.invokeExact((Addressable)symbol);
25+
constants$0.GCallback_DOWN$MH.invokeExact(symbol);
2126
} catch (Throwable ex$) {
2227
throw new AssertionError("should not reach here", ex$);
2328
}

src/main/java/org/purejava/linux/RuntimeHelper.java

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
package org.purejava.linux;
21
// Generated by jextract
2+
package org.purejava.linux;
33

44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
@@ -13,16 +13,16 @@
1313

1414
final class RuntimeHelper {
1515

16-
private RuntimeHelper() {}
17-
private final static Linker LINKER = Linker.nativeLinker();
18-
private final static ClassLoader LOADER = RuntimeHelper.class.getClassLoader();
19-
private final static MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup();
20-
private final static SymbolLookup SYMBOL_LOOKUP;
16+
private static final Linker LINKER = Linker.nativeLinker();
17+
private static final ClassLoader LOADER = RuntimeHelper.class.getClassLoader();
18+
private static final MethodHandles.Lookup MH_LOOKUP = MethodHandles.lookup();
19+
private static final SymbolLookup SYMBOL_LOOKUP;
20+
private static final SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); };
2121
private static boolean isLoaded = false;
2222
private static final Logger LOG = LoggerFactory.getLogger(RuntimeHelper.class);
2323

2424
final static SegmentAllocator CONSTANT_ALLOCATOR =
25-
(size, align) -> MemorySegment.allocateNative(size, align, MemorySession.openImplicit());
25+
(size, align) -> MemorySegment.allocateNative(size, align, SegmentScope.auto());
2626

2727
static {
2828
try {
@@ -40,55 +40,63 @@ private RuntimeHelper() {}
4040
}
4141
}
4242
SymbolLookup loaderLookup = SymbolLookup.loaderLookup();
43-
SYMBOL_LOOKUP = name -> loaderLookup.lookup(name).or(() -> LINKER.defaultLookup().lookup(name));
43+
SYMBOL_LOOKUP = name -> loaderLookup.find(name).or(() -> LINKER.defaultLookup().find(name));
4444
}
4545

46+
// Suppresses default constructor, ensuring non-instantiability.
47+
private RuntimeHelper() {}
48+
4649
static <T> T requireNonNull(T obj, String symbolName) {
4750
if (obj == null) {
4851
throw new UnsatisfiedLinkError("unresolved symbol: " + symbolName);
4952
}
5053
return obj;
5154
}
5255

53-
private final static SegmentAllocator THROWING_ALLOCATOR = (x, y) -> { throw new AssertionError("should not reach here"); };
54-
55-
static final MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) {
56-
return SYMBOL_LOOKUP.lookup(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), MemorySession.openShared())).orElse(null);
56+
static MemorySegment lookupGlobalVariable(String name, MemoryLayout layout) {
57+
return SYMBOL_LOOKUP.find(name).map(symbol -> MemorySegment.ofAddress(symbol.address(), layout.byteSize(), symbol.scope())).orElse(null);
5758
}
5859

59-
static final MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) {
60-
return SYMBOL_LOOKUP.lookup(name).
60+
static MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) {
61+
return SYMBOL_LOOKUP.find(name).
6162
map(addr -> LINKER.downcallHandle(addr, fdesc)).
6263
orElse(null);
6364
}
6465

65-
static final MethodHandle downcallHandle(FunctionDescriptor fdesc) {
66+
static MethodHandle downcallHandle(FunctionDescriptor fdesc) {
6667
return LINKER.downcallHandle(fdesc);
6768
}
6869

69-
static final MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) {
70-
return SYMBOL_LOOKUP.lookup(name).
70+
static MethodHandle downcallHandleVariadic(String name, FunctionDescriptor fdesc) {
71+
return SYMBOL_LOOKUP.find(name).
7172
map(addr -> VarargsInvoker.make(addr, fdesc)).
7273
orElse(null);
7374
}
7475

75-
static final <Z> MemorySegment upcallStub(Class<Z> fi, Z z, FunctionDescriptor fdesc, MemorySession session) {
76+
static MethodHandle upcallHandle(Class<?> fi, String name, FunctionDescriptor fdesc) {
7677
try {
77-
MethodHandle handle = MH_LOOKUP.findVirtual(fi, "apply", Linker.upcallType(fdesc));
78-
handle = handle.bindTo(z);
79-
return LINKER.upcallStub(handle, fdesc, session);
78+
return MH_LOOKUP.findVirtual(fi, name, fdesc.toMethodType());
8079
} catch (Throwable ex) {
8180
throw new AssertionError(ex);
8281
}
8382
}
8483

85-
static MemorySegment asArray(MemoryAddress addr, MemoryLayout layout, int numElements, MemorySession session) {
86-
return MemorySegment.ofAddress(addr, numElements * layout.byteSize(), session);
84+
static <Z> MemorySegment upcallStub(MethodHandle fiHandle, Z z, FunctionDescriptor fdesc, SegmentScope scope) {
85+
try {
86+
fiHandle = fiHandle.bindTo(z);
87+
return LINKER.upcallStub(fiHandle, fdesc, scope);
88+
} catch (Throwable ex) {
89+
throw new AssertionError(ex);
90+
}
91+
}
92+
93+
static MemorySegment asArray(MemorySegment addr, MemoryLayout layout, int numElements, SegmentScope scope) {
94+
return MemorySegment.ofAddress(addr.address(), numElements * layout.byteSize(), scope);
8795
}
8896

8997
// Internals only below this point
9098

91-
private static class VarargsInvoker {
99+
private static final class VarargsInvoker {
92100
private static final MethodHandle INVOKE_MH;
93101
private final MemorySegment symbol;
94102
private final FunctionDescriptor function;
@@ -114,7 +122,9 @@ static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) {
114122
mtype = mtype.appendParameterTypes(carrier(layout, false));
115123
}
116124
mtype = mtype.appendParameterTypes(Object[].class);
117-
if (mtype.returnType().equals(MemorySegment.class)) {
125+
boolean needsAllocator = function.returnLayout().isPresent() &&
126+
function.returnLayout().get() instanceof GroupLayout;
127+
if (needsAllocator) {
118128
mtype = mtype.insertParameterTypes(0, SegmentAllocator.class);
119129
} else {
120130
handle = MethodHandles.insertArguments(handle, 0, THROWING_ALLOCATOR);
@@ -124,8 +134,7 @@ static MethodHandle make(MemorySegment symbol, FunctionDescriptor function) {
124134

125135
static Class<?> carrier(MemoryLayout layout, boolean ret) {
126136
if (layout instanceof ValueLayout valueLayout) {
127-
return (ret || valueLayout.carrier() != MemoryAddress.class) ?
128-
valueLayout.carrier() : Addressable.class;
137+
return valueLayout.carrier();
129138
} else if (layout instanceof GroupLayout) {
130139
return MemorySegment.class;
131140
} else {
@@ -160,7 +169,9 @@ private Object invoke(SegmentAllocator allocator, Object[] args) throws Throwabl
160169
FunctionDescriptor.ofVoid(argLayouts) :
161170
FunctionDescriptor.of(function.returnLayout().get(), argLayouts);
162171
MethodHandle mh = LINKER.downcallHandle(symbol, f);
163-
if (mh.type().returnType() == MemorySegment.class) {
172+
boolean needsAllocator = function.returnLayout().isPresent() &&
173+
function.returnLayout().get() instanceof GroupLayout;
174+
if (needsAllocator) {
164175
mh = mh.bindTo(allocator);
165176
}
166177
// flatten argument list so that it can be passed to an asSpreader MH
@@ -210,10 +221,7 @@ private Class<?> normalize(Class<?> c) {
210221
if (c.isPrimitive()) {
211222
return promote(c);
212223
}
213-
if (MemoryAddress.class.isAssignableFrom(c)) {
214-
return MemoryAddress.class;
215-
}
216-
if (MemorySegment.class.isAssignableFrom(c)) {
224+
if (c == MemorySegment.class) {
217225
return MemorySegment.class;
218226
}
219227
throw new IllegalArgumentException("Invalid type for ABI: " + c.getTypeName());
@@ -224,7 +232,7 @@ private MemoryLayout variadicLayout(Class<?> c) {
224232
return JAVA_LONG;
225233
} else if (c == double.class) {
226234
return JAVA_DOUBLE;
227-
} else if (MemoryAddress.class.isAssignableFrom(c)) {
235+
} else if (c == MemorySegment.class) {
228236
return ADDRESS;
229237
} else {
230238
throw new IllegalArgumentException("Unhandled variadic argument class: " + c);

0 commit comments

Comments
 (0)