From 197a96846d7a88627f5266a8430b8e98f4a65834 Mon Sep 17 00:00:00 2001
From: Not Zed <notzed@gmail.com>
Date: Sun, 25 Sep 2022 20:37:48 +0930
Subject: [PATCH] Update to OpenJDK 19, java.lang.foreign preview API.

---
 config.make.in                                |   2 +-
 nbproject/project.properties                  |   7 +-
 .../classes/au/notzed/nativez/ByteArray.java  |  14 +--
 .../au/notzed/nativez/DoubleArray.java        |  10 +-
 .../classes/au/notzed/nativez/FloatArray.java |  10 +-
 .../classes/au/notzed/nativez/Frame.java      |  71 ++----------
 .../au/notzed/nativez/FunctionPointer.java    |   4 +-
 .../au/notzed/nativez/HandleArray.java        |  26 ++---
 .../classes/au/notzed/nativez/IntArray.java   |  10 +-
 .../classes/au/notzed/nativez/LongArray.java  |   8 +-
 .../classes/au/notzed/nativez/Memory.java     | 104 +++++++++---------
 .../classes/au/notzed/nativez/Native.java     |   6 +-
 .../classes/au/notzed/nativez/Pointer.java    |   7 +-
 .../au/notzed/nativez/PointerArray.java       |   8 +-
 .../classes/au/notzed/nativez/ShortArray.java |  10 +-
 src/notzed.nativez/classes/module-info.java   |   1 -
 src/notzed.nativez/lib/code.api               |  56 +++++-----
 src/notzed.nativez/lib/code.pm                |   4 +-
 src/notzed.nativez/lib/method.pm              |   6 +-
 src/notzed.nativez/lib/types.api              |   4 +-
 20 files changed, 157 insertions(+), 211 deletions(-)

diff --git a/config.make.in b/config.make.in
index 72e4bba..d5828ad 100644
--- a/config.make.in
+++ b/config.make.in
@@ -8,7 +8,7 @@ JAR ?= $(JAVA_HOME)/bin/jar
 JMOD ?= $(JAVA_HOME)/bin/jmod
 GCCPLUGINDIR:=$(shell gcc -print-file-name=plugin)
 
-JAVACFLAGS +=
+JAVACFLAGS += --enable-preview --source 19
 
 # Linux options
 linux-amd64_CPPFLAGS = \
diff --git a/nbproject/project.properties b/nbproject/project.properties
index e20f7a8..e5b298e 100644
--- a/nbproject/project.properties
+++ b/nbproject/project.properties
@@ -40,15 +40,15 @@ includes=**
 jar.compress=false
 javac.classpath=
 # Space-separated list of extra javac options
-javac.compilerargs=-Xlint:unchecked
+javac.compilerargs=-Xlint:unchecked --enable-preview
 javac.deprecation=false
 javac.external.vm=false
 javac.modulepath=
 javac.processormodulepath=
 javac.processorpath=\
     ${javac.classpath}
-javac.source=18
-javac.target=18
+javac.source=19
+javac.target=19
 javac.test.classpath=\
     ${javac.classpath}
 javac.test.modulepath=\
@@ -75,6 +75,7 @@ jlink.additionalparam=
 jlink.launcher=true
 jlink.launcher.name=notzed.nativez
 platform.active=default_platform
+project.license=gpl3-notzed
 run.classpath=
 # Space-separated list of JVM arguments used when running the project.
 # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/ByteArray.java b/src/notzed.nativez/classes/au/notzed/nativez/ByteArray.java
index 0abf605..72aa439 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/ByteArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/ByteArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,11 +35,11 @@ public class ByteArray extends AbstractList<Byte> implements Pointer {
 		return new ByteArray(segment);
 	}
 
-	public static ByteArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static ByteArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length, scope));
 	}
 
-	public static ByteArray createArray(MemoryAddress address, ResourceScope scope) {
+	public static ByteArray createArray(MemoryAddress address, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
 	}
 
@@ -51,16 +51,16 @@ public class ByteArray extends AbstractList<Byte> implements Pointer {
 		return create(alloc.allocateUtf8String(value));
 	}
 
-	public static ByteArray create(String value, ResourceScope scope) {
-		return create(SegmentAllocator.nativeAllocator(scope).allocateUtf8String(value));
+	public static ByteArray create(String value, MemorySession scope) {
+		return create(scope.allocateUtf8String(value));
 	}
 
 	public final MemoryAddress address() {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/DoubleArray.java b/src/notzed.nativez/classes/au/notzed/nativez/DoubleArray.java
index 9a0bfce..9df27ed 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/DoubleArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/DoubleArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,11 +35,11 @@ public class DoubleArray extends AbstractList<Double> implements Pointer {
 		return new DoubleArray(segment);
 	}
 
-	public static DoubleArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static DoubleArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length * Memory.DOUBLE.byteSize(), scope));
 	}
 
-	public static DoubleArray createArray(MemoryAddress address, ResourceScope scope) {
+	public static DoubleArray createArray(MemoryAddress address, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
 	}
 
@@ -55,8 +55,8 @@ public class DoubleArray extends AbstractList<Double> implements Pointer {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/FloatArray.java b/src/notzed.nativez/classes/au/notzed/nativez/FloatArray.java
index e81a57e..13a510a 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/FloatArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/FloatArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,11 +35,11 @@ public class FloatArray extends AbstractList<Float> implements Pointer {
 		return new FloatArray(segment);
 	}
 
-	public static FloatArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static FloatArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length * Memory.FLOAT.byteSize(), scope));
 	}
 
-	public static FloatArray createArray(MemoryAddress address, ResourceScope scope) {
+	public static FloatArray createArray(MemoryAddress address, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
 	}
 
@@ -55,8 +55,8 @@ public class FloatArray extends AbstractList<Float> implements Pointer {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/Frame.java b/src/notzed.nativez/classes/au/notzed/nativez/Frame.java
index 7ce52b9..bf65a66 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/Frame.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/Frame.java
@@ -16,8 +16,8 @@
  */
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
-import static jdk.incubator.foreign.ValueLayout.OfAddress;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.OfAddress;
 
 /**
  * This is a per-thread stack-based allocator.
@@ -33,11 +33,11 @@ import static jdk.incubator.foreign.ValueLayout.OfAddress;
  */
 public class Frame implements AutoCloseable, SegmentAllocator {
 
-	private final ResourceScope scope;
+	private final MemorySession scope;
 	private final SegmentAllocator alloc;
 
 	Frame() {
-		this.scope = ResourceScope.newConfinedScope();
+		this.scope = MemorySession.openConfined();
 		this.alloc = SegmentAllocator.newNativeArena(scope);
 	}
 
@@ -45,7 +45,7 @@ public class Frame implements AutoCloseable, SegmentAllocator {
 		return new Frame();
 	}
 
-	public ResourceScope scope() {
+	public MemorySession scope() {
 		return scope;
 	}
 
@@ -59,63 +59,6 @@ public class Frame implements AutoCloseable, SegmentAllocator {
 		scope.close();
 	}
 
-	// private final long tos;
-	// private Stack stack;
-	// private ResourceScope overflow;
-
-	// Frame(long tos, Stack stack) {
-	// 	this.tos = tos;
-	// 	this.stack = stack;
-	// }
-
-	// private static final ResourceScope scope = ResourceScope.newSharedScope(Cleaner.create());
-	// private static final ThreadLocal<Stack> stacks = ThreadLocal.withInitial(() -> new Stack(scope));
-
-	// public static Frame frame() {
-	// 	//return stacks.get().createFrame();
-	// }
-
-	// private static class Stack {
-	// 	private final MemorySegment stack;
-	// 	private long sp;
-	// 	private Thread thread = Thread.currentThread();
-
-	// 	Stack(ResourceScope scope) {
-	// 		stack = MemorySegment.allocateNative(4096, 4096, scope);
-	// 		sp = 4096;
-	// 	}
-	// 	Frame createFrame() {
-	// 		return new Frame(sp, this);
-	// 	}
-	// }
-
-	// @Override
-	// public MemorySegment allocate(long size, long alignment) {
-	// 	if (stack.thread != Thread.currentThread())
-	// 		throw new IllegalStateException();
-	// 	if (alignment != Long.highestOneBit(alignment))
-	// 		throw new IllegalArgumentException();
-	// 	if (stack.sp >= size) {
-	// 		stack.sp = (stack.sp - size) & ~(alignment - 1);
-	// 		return stack.stack.asSlice(stack.sp, size).fill((byte)0);
-	// 	} else {
-	// 		// or arena allocator?
-	// 		if (overflow == null)
-	// 			overflow = ResourceScope.newConfinedScope();
-	// 		return MemorySegment.allocateNative(size, alignment, overflow);
-	// 	}
-	// }
-
-	// @Override
-	// public void close() {
-	// 	stack.sp = tos;
-	// 	stack = null;
-	// 	if (overflow != null) {
-	// 		overflow.close();
-	// 		overflow = null;
-	// 	}
-	// }
-
 	public MemorySegment allocateInt() {
 		return allocate(Memory.INT);
 	}
@@ -224,7 +167,7 @@ public class Frame implements AutoCloseable, SegmentAllocator {
 
 	public static MemorySegment copy(MemorySegment ctx, String string) {
 		if (string != null) {
-			SegmentAllocator alloc = SegmentAllocator.nativeAllocator(ctx.scope());
+			SegmentAllocator alloc = ctx.session();
 
 			return alloc.allocateUtf8String(string);
 		} else {
@@ -235,7 +178,7 @@ public class Frame implements AutoCloseable, SegmentAllocator {
 	public static MemorySegment copy(MemorySegment ctx, String[] array) {
 		System.out.printf("copy array %s\n", array != null ? array.length : "");
 		if (array != null) {
-			SegmentAllocator alloc = SegmentAllocator.nativeAllocator(ctx.scope());
+			SegmentAllocator alloc = ctx.session();
 			MemorySegment list = alloc.allocateArray(Memory.POINTER, array.length);
 			for (int i = 0; i < array.length; i++) {
 				System.out.printf(" [%d] '%s'\n", i, array[i]);
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/FunctionPointer.java b/src/notzed.nativez/classes/au/notzed/nativez/FunctionPointer.java
index dd36722..7a7ae06 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/FunctionPointer.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/FunctionPointer.java
@@ -1,7 +1,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.NativeSymbol;
+import java.lang.foreign.MemorySegment;
 
-public record FunctionPointer<T>(NativeSymbol symbol, T function) {
+public record FunctionPointer<T>(MemorySegment	 symbol, T function) {
 }
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/HandleArray.java b/src/notzed.nativez/classes/au/notzed/nativez/HandleArray.java
index 7434f65..e1e0ade 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/HandleArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/HandleArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -32,36 +32,36 @@ import java.util.List;
  */
 public class HandleArray<T extends Pointer> extends AbstractList<T> implements Pointer {
 	public final MemorySegment segment;
-	final ResourceScope scope;
-	BiFunction<MemoryAddress,ResourceScope,T> create;
+	final MemorySession scope;
+	BiFunction<MemoryAddress,MemorySession,T> create;
 
-	private HandleArray(MemorySegment segment, BiFunction<MemoryAddress,ResourceScope,T> create, ResourceScope scope) {
+	private HandleArray(MemorySegment segment, BiFunction<MemoryAddress,MemorySession,T> create, MemorySession scope) {
 		this.segment = segment;
 		this.create = create;
 		this.scope = scope;
 	}
 
-	public static <T extends Pointer> HandleArray<T> create(MemorySegment segment, BiFunction<MemoryAddress,ResourceScope,T> create) {
-		return new HandleArray<>(segment, create, segment.scope());
+	public static <T extends Pointer> HandleArray<T> create(MemorySegment segment, BiFunction<MemoryAddress,MemorySession,T> create) {
+		return new HandleArray<>(segment, create, segment.session());
 	}
 
-	public static <T extends Pointer> HandleArray<T> create(MemorySegment segment, BiFunction<MemoryAddress,ResourceScope,T> create, ResourceScope scope) {
+	public static <T extends Pointer> HandleArray<T> create(MemorySegment segment, BiFunction<MemoryAddress,MemorySession,T> create, MemorySession scope) {
 		return new HandleArray<>(segment, create, scope);
 	}
 
-	public static <T extends Pointer> HandleArray<T> createArray(long size, SegmentAllocator alloc, BiFunction<MemoryAddress,ResourceScope,T> create) {
+	public static <T extends Pointer> HandleArray<T> createArray(long size, SegmentAllocator alloc, BiFunction<MemoryAddress,MemorySession,T> create) {
 		return create(alloc.allocateArray(Memory.POINTER, size), create);
 	}
 
-	public static <T extends Pointer> HandleArray<T> createArray(long size, SegmentAllocator alloc, BiFunction<MemoryAddress,ResourceScope,T> create, ResourceScope scope) {
+	public static <T extends Pointer> HandleArray<T> createArray(long size, SegmentAllocator alloc, BiFunction<MemoryAddress,MemorySession,T> create, MemorySession scope) {
 		return create(alloc.allocateArray(Memory.POINTER, size), create, scope);
 	}
 
-	public static <T extends Pointer> HandleArray<T> createArray(MemoryAddress address, long size, BiFunction<MemoryAddress,ResourceScope,T> create, ResourceScope scope) {
+	public static <T extends Pointer> HandleArray<T> createArray(MemoryAddress address, long size, BiFunction<MemoryAddress,MemorySession,T> create, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, size * Memory.POINTER.byteSize(), scope), create);
 	}
 
-	public static <T extends Pointer> HandleArray<T> create(SegmentAllocator alloc, BiFunction<MemoryAddress,ResourceScope,T> create, T... values) {
+	public static <T extends Pointer> HandleArray<T> create(SegmentAllocator alloc, BiFunction<MemoryAddress,MemorySession,T> create, T... values) {
 		HandleArray<T> array = create(alloc.allocateArray(Memory.POINTER, values.length), create);
 		for (int i=0;i<values.length;i++)
 			array.setAtIndex(i, values[i]);
@@ -81,8 +81,8 @@ public class HandleArray<T extends Pointer> extends AbstractList<T> implements P
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/IntArray.java b/src/notzed.nativez/classes/au/notzed/nativez/IntArray.java
index 0f73c4b..c4378a2 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/IntArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/IntArray.java
@@ -16,7 +16,7 @@
  */
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,11 +35,11 @@ public class IntArray extends AbstractList<Integer> implements Pointer {
 		return new IntArray(segment);
 	}
 
-	public static IntArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static IntArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length * Memory.INT.byteSize(), scope));
 	}
 
-	public static IntArray createArray(MemoryAddress address, ResourceScope scope) {
+	public static IntArray createArray(MemoryAddress address, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
 	}
 
@@ -67,8 +67,8 @@ public class IntArray extends AbstractList<Integer> implements Pointer {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/LongArray.java b/src/notzed.nativez/classes/au/notzed/nativez/LongArray.java
index 9885ced..7ed18f8 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/LongArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/LongArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,7 +35,7 @@ public class LongArray extends AbstractList<Long> implements Pointer {
 		return new LongArray(segment);
 	}
 
-	public static LongArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static LongArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length * Memory.LONG.byteSize(), scope));
 	}
 
@@ -51,8 +51,8 @@ public class LongArray extends AbstractList<Long> implements Pointer {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/Memory.java b/src/notzed.nativez/classes/au/notzed/nativez/Memory.java
index b52412a..841284e 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/Memory.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/Memory.java
@@ -17,13 +17,10 @@
 package au.notzed.nativez;
 
 import java.lang.invoke.*;
-import java.lang.ref.Cleaner;
-import jdk.incubator.foreign.*;
-import static jdk.incubator.foreign.ValueLayout.*;
+import java.lang.foreign.*;
+import static java.lang.foreign.ValueLayout.*;
 
-import java.util.AbstractList;
 import java.util.function.Function;
-import java.util.function.BiFunction;
 import java.util.List;
 
 public class Memory {
@@ -37,70 +34,70 @@ public class Memory {
 	public static final OfDouble DOUBLE = JAVA_DOUBLE.withBitAlignment(64);
 	public static final OfAddress POINTER = ADDRESS.withBitAlignment(64);
 
-	static final ResourceScope sharedScope = ResourceScope.newSharedScope(); // cleaner?
+	static final MemorySession sharedScope = MemorySession.openShared(); // cleaner?
 	// Note: currently can't create zero-length segments
-	static final MemorySegment NULL = MemorySegment.ofAddress(MemoryAddress.NULL, 1, ResourceScope.globalScope());
+	static final MemorySegment NULL = MemorySegment.ofAddress(MemoryAddress.NULL, 1, MemorySession.global());
 
-	public static ResourceScope sharedScope() {
+	public static MemorySession sharedScope() {
 		return sharedScope;
 	}
 
 	public static MethodHandle downcall(FunctionDescriptor desc) {
-		return CLinker.systemCLinker().downcallHandle(desc);
+		return Linker.nativeLinker().downcallHandle(desc);
 	}
 
 	public static MethodHandle downcall(String name, FunctionDescriptor desc) {
 		return SymbolLookup.loaderLookup().lookup(name)
-			.map(sym -> CLinker.systemCLinker().downcallHandle(sym, desc))
+			.map(sym -> Linker.nativeLinker().downcallHandle(sym, desc))
 			.orElse(null);
 	}
 
-	public static MethodHandle downcall(NativeSymbol sym, FunctionDescriptor desc) {
-		return CLinker.systemCLinker().downcallHandle(sym, desc);
+	public static MethodHandle downcall(Addressable sym, FunctionDescriptor desc) {
+		return Linker.nativeLinker().downcallHandle(sym, desc);
 	}
 
-	public static MethodHandle downcall(String name, MemoryAddress sym, FunctionDescriptor desc, ResourceScope scope) {
+	public static MethodHandle downcall(String name, MemoryAddress sym, FunctionDescriptor desc, MemorySession scope) {
 		return sym != MemoryAddress.NULL
-			? CLinker.systemCLinker().downcallHandle(NativeSymbol.ofAddress(name, sym, scope), desc)
+			? Linker.nativeLinker().downcallHandle(MemorySegment.ofAddress(sym, 0, scope), desc)
 			: null;
 	}
 
-	public static MethodHandle downcall(String name, FunctionDescriptor desc, Function<String, MemoryAddress> resolve, ResourceScope scope) {
+	public static MethodHandle downcall(String name, FunctionDescriptor desc, Function<String, MemoryAddress> resolve, MemorySession scope) {
 		MemoryAddress sym = resolve.apply(name);
 		return sym != MemoryAddress.NULL
-			? CLinker.systemCLinker().downcallHandle(NativeSymbol.ofAddress(name, sym, scope), desc)
+			? Linker.nativeLinker().downcallHandle(MemorySegment.ofAddress(sym, 0, scope), desc)
 			: null;
 	}
 
 	static final MethodHandles.Lookup lookup = MethodHandles.lookup();
 
-	public static NativeSymbol upcall(Object instance, FunctionDescriptor desc, ResourceScope scope) {
+	public static MemorySegment upcall(Object instance, FunctionDescriptor desc, MemorySession scope) {
 		try {
 			java.lang.reflect.Method m = instance.getClass().getMethods()[0];
 			MethodHandle handle = lookup.findVirtual(instance.getClass(), "call", MethodType.methodType(m.getReturnType(), m.getParameterTypes()))
 				.bindTo(instance);
-			return CLinker.systemCLinker().upcallStub(handle, desc, scope);
+			return Linker.nativeLinker().upcallStub(handle, desc, scope);
 		} catch (Throwable t) {
 			throw new AssertionError(t);
 		}
 	}
 
-	public static NativeSymbol upcall(MethodHandles.Lookup lookup, Object instance, String signature, FunctionDescriptor desc, ResourceScope scope) {
+	public static MemorySegment upcall(MethodHandles.Lookup lookup, Object instance, String signature, FunctionDescriptor desc, MemorySession scope) {
 		try {
 			java.lang.reflect.Method m = instance.getClass().getMethods()[0];
 			MethodHandle handle = lookup.findVirtual(instance.getClass(), m.getName(), MethodType.fromMethodDescriptorString(signature, Memory.class.getClassLoader()))
 				.bindTo(instance);
-			return CLinker.systemCLinker().upcallStub(handle, desc, scope);
+			return Linker.nativeLinker().upcallStub(handle, desc, scope);
 		} catch (Throwable t) {
 			throw new AssertionError(t);
 		}
 	}
 
-	public static NativeSymbol upcall(MethodHandles.Lookup lookup, Object instance, String method, String signature, FunctionDescriptor desc, ResourceScope scope) {
+	public static MemorySegment upcall(MethodHandles.Lookup lookup, Object instance, String method, String signature, FunctionDescriptor desc, MemorySession scope) {
 		try {
 			MethodHandle handle = lookup.findVirtual(instance.getClass(), method, MethodType.fromMethodDescriptorString(signature, Memory.class.getClassLoader()))
 				.bindTo(instance);
-			return CLinker.systemCLinker().upcallStub(handle, desc, scope);
+			return Linker.nativeLinker().upcallStub(handle, desc, scope);
 		} catch (Throwable t) {
 			throw new AssertionError(t);
 		}
@@ -141,6 +138,14 @@ public class Memory {
 		return s != null ? s.byteSize() : 0;
 	}
 
+	public static MemorySegment slice(MemorySegment segment, MethodHandle sliceHandle) {
+			try {
+				return (MemorySegment)sliceHandle.invokeExact(segment);
+			} catch (Throwable ex) {
+				throw new RuntimeException(ex);
+			}
+	}
+
 	public static String copyString(MemoryAddress string) {
 		return string != MemoryAddress.NULL ? string.getUtf8String(0) : null;
 	}
@@ -188,7 +193,7 @@ public class Memory {
 					//sb.append(prefix).append(l.name().get()).append(": {\n");
 					format(sb, l, g, prefix + "  ");
 					//sb.append(prefix).append("}\n");
-				} else if (m instanceof jdk.incubator.foreign.SequenceLayout l) {
+				} else if (m instanceof java.lang.foreign.SequenceLayout l) {
 					var sh = layout.sliceHandle(MemoryLayout.PathElement.groupElement(l.name().get()));
 					var g = (MemorySegment)sh.invokeExact(s);
 
@@ -205,35 +210,34 @@ public class Memory {
 
 	static void format(StringBuilder sb, SequenceLayout layout, MemorySegment s, String prefix) {
 		sb.append(prefix).append(layout.name().orElse("?")).append(" [\n");
-		layout.elementCount().ifPresent(len -> {
-			try {
-				MemoryLayout el = layout.elementLayout();
-
-				if (el instanceof ValueLayout l) {
-					var vh = layout.varHandle(MemoryLayout.PathElement.sequenceElement());
-
-					for (long i = 0; i < len; i++) {
-						sb.append(prefix).append("  ").append(vh.get(s, i)).append("\n");
-					}
-				} else if (el instanceof GroupLayout l) {
-					MethodHandle eh = layout.sliceHandle(MemoryLayout.PathElement.sequenceElement());
-
-					for (long i = 0; i < len; i++) {
-						MemorySegment e = (MemorySegment)eh.invokeExact(s, i);
-						format(sb, l, e, prefix + "  ");
-					}
-				} else if (el instanceof SequenceLayout l) {
-					MethodHandle eh = layout.sliceHandle(MemoryLayout.PathElement.sequenceElement());
-
-					for (long i = 0; i < len; i++) {
-						MemorySegment e = (MemorySegment)eh.invokeExact(s, i);
-						format(sb, l, e, prefix + "  ");
-					}
+		long len = layout.elementCount();
+		try {
+			MemoryLayout el = layout.elementLayout();
+
+			if (el instanceof ValueLayout l) {
+				var vh = layout.varHandle(MemoryLayout.PathElement.sequenceElement());
+
+				for (long i = 0; i < len; i++) {
+					sb.append(prefix).append("  ").append(vh.get(s, i)).append("\n");
+				}
+			} else if (el instanceof GroupLayout l) {
+				MethodHandle eh = layout.sliceHandle(MemoryLayout.PathElement.sequenceElement());
+
+				for (long i = 0; i < len; i++) {
+					MemorySegment e = (MemorySegment)eh.invokeExact(s, i);
+					format(sb, l, e, prefix + "  ");
+				}
+			} else if (el instanceof SequenceLayout l) {
+				MethodHandle eh = layout.sliceHandle(MemoryLayout.PathElement.sequenceElement());
+
+				for (long i = 0; i < len; i++) {
+					MemorySegment e = (MemorySegment)eh.invokeExact(s, i);
+					format(sb, l, e, prefix + "  ");
 				}
-			} catch (Throwable ex) {
-				ex.printStackTrace();
 			}
-		});
+		} catch (Throwable ex) {
+			ex.printStackTrace();
+		}
 		sb.append(prefix).append("]\n");
 	}
 
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/Native.java b/src/notzed.nativez/classes/au/notzed/nativez/Native.java
index 191728b..cf1dbff 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/Native.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/Native.java
@@ -24,7 +24,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.function.Function;
 import java.util.function.IntFunction;
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
@@ -63,8 +63,8 @@ public class Native implements Pointer {
 		return p;
 	}
 
-	public ResourceScope scope() {
-		return ResourceScope.globalScope();
+	public MemorySession scope() {
+		return MemorySession.global();
 	}
 
 	/* ********************************************************************** */
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/Pointer.java b/src/notzed.nativez/classes/au/notzed/nativez/Pointer.java
index 5b003dc..8837fcc 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/Pointer.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/Pointer.java
@@ -1,16 +1,15 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.ResourceScope;
+import java.lang.foreign.*;
 
 /**
  * Because you can't implement foriegn.Addressable for some silly reason
  */
 public interface Pointer {
 	MemoryAddress address();
-	default ResourceScope scope() {
-		return ResourceScope.globalScope();
+	default MemorySession scope() {
+		return MemorySession.global();
 	}
 	//default long length() {
 	//	return 1;
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/PointerArray.java b/src/notzed.nativez/classes/au/notzed/nativez/PointerArray.java
index cdc4189..7d45387 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/PointerArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/PointerArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,7 +35,7 @@ public class PointerArray extends AbstractList<MemoryAddress> implements Pointer
 		return new PointerArray(segment);
 	}
 
-	public static PointerArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static PointerArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length, scope));
 	}
 
@@ -51,8 +51,8 @@ public class PointerArray extends AbstractList<MemoryAddress> implements Pointer
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/au/notzed/nativez/ShortArray.java b/src/notzed.nativez/classes/au/notzed/nativez/ShortArray.java
index f93599d..57fb90d 100644
--- a/src/notzed.nativez/classes/au/notzed/nativez/ShortArray.java
+++ b/src/notzed.nativez/classes/au/notzed/nativez/ShortArray.java
@@ -17,7 +17,7 @@
 
 package au.notzed.nativez;
 
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 
 import java.util.AbstractList;
 import java.util.function.Function;
@@ -35,11 +35,11 @@ public class ShortArray extends AbstractList<Short> implements Pointer {
 		return new ShortArray(segment);
 	}
 
-	public static ShortArray createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static ShortArray createArray(MemoryAddress address, long length, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, length * Memory.SHORT.byteSize(), scope));
 	}
 
-	public static ShortArray createArray(MemoryAddress address, ResourceScope scope) {
+	public static ShortArray createArray(MemoryAddress address, MemorySession scope) {
 		return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
 	}
 
@@ -55,8 +55,8 @@ public class ShortArray extends AbstractList<Short> implements Pointer {
 		return segment.address();
 	}
 
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	@Override
diff --git a/src/notzed.nativez/classes/module-info.java b/src/notzed.nativez/classes/module-info.java
index 7edcf0a..5854019 100644
--- a/src/notzed.nativez/classes/module-info.java
+++ b/src/notzed.nativez/classes/module-info.java
@@ -1,5 +1,4 @@
 
 module notzed.nativez {
-	requires transitive jdk.incubator.foreign;
 	exports au.notzed.nativez;
 }
diff --git a/src/notzed.nativez/lib/code.api b/src/notzed.nativez/lib/code.api
index 651dd55..f735f0f 100644
--- a/src/notzed.nativez/lib/code.api
+++ b/src/notzed.nativez/lib/code.api
@@ -53,8 +53,8 @@ code method {
 
 	# callback function/types
 	downcall {{
-	public static FunctionPointer<{rename}> downcall(MemoryAddress addr$, ResourceScope scope$) {
-		NativeSymbol symbol$ = NativeSymbol.ofAddress("{rename}", addr$, scope$);
+	public static FunctionPointer<{rename}> downcall(MemoryAddress addr$, MemorySession scope$) {
+		MemorySegment symbol$ = MemorySegment.ofAddress(addr$, 0, scope$);
 		MethodHandle {rename}$FH = Memory.downcall(symbol$, descriptor());
 		return new FunctionPointer<{rename}>(
 			symbol$,
@@ -78,13 +78,13 @@ code method {
 	}}
 
 	upcall {{
-	public static FunctionPointer<{rename}> upcall({rename} target$, ResourceScope scope$) {
+	public static FunctionPointer<{rename}> upcall({rename} target$, MemorySession scope$) {
 		interface Trampoline {
 			{java-result} call({native-arguments});
 		}
 		Trampoline trampoline = ({native-arguments}) -> {
 			// frame?  scope?
-			try (ResourceScope upcallScope$ = ResourceScope.newConfinedScope()) {
+			try (MemorySession upcallScope$ = MemorySession.openConfined()) {
 				{trampoline-result-define}target$.call({java-call});
 				{trampoline-result-return}
 			}
@@ -110,7 +110,7 @@ code method {
 code class {
 	library {{
 package {package};
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import java.lang.invoke.*;
 import au.notzed.nativez.*;
 {imports}
@@ -125,17 +125,17 @@ public class {name} {
 		func:template=code:method=invoke-dynamic
 		init:template=code:method=invoke-dynamic-init {{
 package {package};
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import java.lang.invoke.*;
 import java.util.function.Function;
 import au.notzed.nativez.*;
 {imports}
 
 public class {name} {
-	{name}(Function<String,MemoryAddress> resolve, ResourceScope scope) {
+	{name}(Function<String,MemoryAddress> resolve, MemorySession scope) {
 {init}
 	}
-	public static {name} create(Function<String,MemoryAddress> resolve, ResourceScope scope) {
+	public static {name} create(Function<String,MemoryAddress> resolve, MemorySession scope) {
 		return new {name}(resolve, scope);
 	}
 {defines}
@@ -153,8 +153,8 @@ public interface {name} {
 	}}
 	struct {{
 package {package};
-import jdk.incubator.foreign.*;
-import jdk.incubator.foreign.MemoryLayout.*;
+import java.lang.foreign.*;
+import java.lang.foreign.MemoryLayout.*;
 import java.lang.invoke.*;
 import au.notzed.nativez.*;
 
@@ -171,7 +171,7 @@ public class {rename} implements Pointer {
 		return new {rename}(segment);
 	}
 
-	public static {rename} create(MemoryAddress address, ResourceScope scope) {
+	public static {rename} create(MemoryAddress address, MemorySession scope) {
 		return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope)) : null;
 	}
 
@@ -185,8 +185,8 @@ public class {rename} implements Pointer {
 	}
 
 	@Override
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	public final MemorySegment segment() {
@@ -203,8 +203,8 @@ public class {rename} implements Pointer {
 }}
 	struct-array {{
 package {package};
-import jdk.incubator.foreign.*;
-import jdk.incubator.foreign.MemoryLayout.*;
+import java.lang.foreign.*;
+import java.lang.foreign.MemoryLayout.*;
 import java.lang.invoke.*;
 import au.notzed.nativez.*;
 
@@ -221,7 +221,7 @@ public class {rename} implements Pointer, Array<{rename}> {
 		return new {rename}(segment);
 	}
 
-	public static {rename} create(MemoryAddress address, ResourceScope scope) {
+	public static {rename} create(MemoryAddress address, MemorySession scope) {
 		return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope)) : null;
 	}
 
@@ -229,11 +229,11 @@ public class {rename} implements Pointer, Array<{rename}> {
 		return create(frame.allocate(LAYOUT));
 	}
 
-	public static {rename} createArray(MemoryAddress address, ResourceScope scope) {
+	public static {rename} createArray(MemoryAddress address, MemorySession scope) {
 		return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)) : null;
 	}
 
-	public static {rename} createArray(MemoryAddress address, long length, ResourceScope scope) {
+	public static {rename} createArray(MemoryAddress address, long length, MemorySession scope) {
 		return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize() * length, scope)) : null;
 	}
 
@@ -247,8 +247,8 @@ public class {rename} implements Pointer, Array<{rename}> {
 	}
 
 	@Override
-	public final ResourceScope scope() {
-		return segment.scope();
+	public final MemorySession scope() {
+		return segment.session();
 	}
 
 	public final MemorySegment segment() {
@@ -279,28 +279,28 @@ public class {rename} implements Pointer, Array<{rename}> {
 {layout}
 {accessors}
 {methods}
-	final static MethodHandle {name}$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(PathElement.sequenceElement());
+	final static MethodHandle {name}$SH = MemoryLayout.sequenceLayout(-1, LAYOUT).sliceHandle(PathElement.sequenceElement());
 {varhandles}
 }
 }}
 	handle {{
 package {package};
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import java.lang.invoke.*;
 import au.notzed.nativez.*;
 
 public class {rename} implements Pointer {
 
 	MemoryAddress address;
-	ResourceScope scope;
+	MemorySession scope;
 
-	private {rename}(MemoryAddress address, ResourceScope scope) {
+	private {rename}(MemoryAddress address, MemorySession scope) {
 		this.address = address;
 		this.scope = scope;
 {init}
 	}
 
-	public static {rename} create(MemoryAddress address, ResourceScope scope) {
+	public static {rename} create(MemoryAddress address, MemorySession scope) {
 		return MemoryAddress.NULL != address ? new {rename}(address, scope) : null;
 	}
 
@@ -314,7 +314,7 @@ public class {rename} implements Pointer {
 	}
 
 	@Override
-	public ResourceScope scope() {
+	public MemorySession scope() {
 		return scope;
 	}
 
@@ -325,7 +325,7 @@ public class {rename} implements Pointer {
 }}
 	call {{
 package {package};
-import jdk.incubator.foreign.*;
+import java.lang.foreign.*;
 import java.lang.invoke.*;
 import au.notzed.nativez.*;
 
@@ -351,7 +351,7 @@ code getset {
 	}
 	}}
 	geti set=value={getnative} set=segment=segment {{
-	# TODO: final static VarHandle {name}$VI = MemoryLayout.sequenceLayout(LAYOUT).varHandle(PathElement.sequenceElement(), PathElement.groupElement("{name}"));
+	# TODO: final static VarHandle {name}$VI = MemoryLayout.sequenceLayout(-1, LAYOUT).varHandle(PathElement.sequenceElement(), PathElement.groupElement("{name}"));
 	public {type} get{rename}AtIndex(long index) {
 		// option a: resolve an offset segment and asme as above with set=segment=segment
 		// option b: an indexed varhandle
diff --git a/src/notzed.nativez/lib/code.pm b/src/notzed.nativez/lib/code.pm
index 9adb04a..57af37c 100644
--- a/src/notzed.nativez/lib/code.pm
+++ b/src/notzed.nativez/lib/code.pm
@@ -52,8 +52,8 @@ my %typeSignature = (
 	'float' => 'F',
 	'double' => 'D',
 	'void' => 'V',
-	'MemorySegment' => 'Ljdk/incubator/foreign/MemorySegment;',
-	'MemoryAddress' => 'Ljdk/incubator/foreign/MemoryAddress;',
+	'MemorySegment' => 'Ljava/lang/foreign/MemorySegment;',
+	'MemoryAddress' => 'Ljava/lang/foreign/MemoryAddress;',
 );
 
 # creates per-field type info, used by methods and structs
diff --git a/src/notzed.nativez/lib/method.pm b/src/notzed.nativez/lib/method.pm
index 608cb78..263b632 100644
--- a/src/notzed.nativez/lib/method.pm
+++ b/src/notzed.nativez/lib/method.pm
@@ -14,7 +14,7 @@ sub fieldScope {
 	} elsif ($m->{scope} eq 'instance') {
 		'scope()';
 	} else {
-		'ResourceScope.globalScope()';
+		'MemorySession.global()';
 	}
 }
 sub fieldScopeAction {
@@ -56,7 +56,7 @@ sub new {
 	$info->{rename} = $c->{rename};
 
 	my @list =  map { apply('{type} {name}', $_) } grep { $_->{field}->{output} } @members;
-	push @list, 'ResourceScope scope$' if ($c->{scope} =~ m/explicit/);
+	push @list, 'MemorySession scope$' if ($c->{scope} =~ m/explicit/);
 	$info->{'java-arguments'} = join ', ', @list;
 	$info->{'native-arguments'} = join ', ', map { apply('{carrier} {name}', $_) } @members;
 
@@ -67,7 +67,7 @@ sub new {
 		my $m = $_->{field};
 
 		if ($m->{instance}) {
-			"(jdk.incubator.foreign.Addressable)address()";
+			"(java.lang.foreign.Addressable)address()";
 		} elsif ($m->{implied}) {
 			$m->{implied};
 		} else {
diff --git a/src/notzed.nativez/lib/types.api b/src/notzed.nativez/lib/types.api
index 9c3c91a..351e045 100644
--- a/src/notzed.nativez/lib/types.api
+++ b/src/notzed.nativez/lib/types.api
@@ -27,7 +27,7 @@ type /bitfield/ copy=<common> {
 	setnative	{{
 		"$m->{name}\$VH.set({segment}, ({type})((({type}){name}\$VH.get({segment}) & ~{setmask}) | ((({value}) << {setoffset}) & {setmask})))"
 	}}
-	varhandle	{{ "final static VarHandle {name}\$VH = MemoryLayout.sequenceLayout(Memory.".uc(bitfieldType($m)).").varHandle(MemoryLayout.PathElement.sequenceElement({varindex}));\n" }}
+	varhandle	{{ "final static VarHandle {name}\$VH = MemoryLayout.sequenceLayout(-1, Memory.".uc(bitfieldType($m)).").varHandle(MemoryLayout.PathElement.sequenceElement({varindex}));\n" }}
 }
 
 # void, only for return type
@@ -206,7 +206,7 @@ type /^u64:(?<ctype>i8)$/ copy=<pointer> {
 	tonative	{{ '(Addressable)({value} != null ? frame$.copy({value}) : MemoryAddress.NULL)' }}
 
 	setnative	{{ '{name}$VH.set({segment}, {copynative})' }}
-	copynative	{{ 'SegmentAllocator.nativeAllocator(segment.scope()).allocateUtf8String({value})' }}
+	copynative	{{ 'segment.session().allocateUtf8String({value})' }}
 
 	tojava		{{ '({value}).getUtf8String(0L)' }}
 }
-- 
2.39.5