diff --git a/pom.xml b/pom.xml index b96d803..e93bd15 100644 --- a/pom.xml +++ b/pom.xml @@ -54,8 +54,8 @@ - 20 - 20 + 21 + 21 UTF-8 UTF-8 3.1.2 diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemory.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemory.java index bf7fbd2..f37abf5 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemory.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemory.java @@ -5,6 +5,7 @@ import com.itemis.fluffyj.exceptions.InstantiationNotPermittedException; import com.itemis.fluffyj.memory.api.FluffySegment; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; /** @@ -36,7 +37,7 @@ public static FluffyMemoryPointerBuilder pointer() { * * @param nativeSeg - The raw {@link MemorySegment} to wrap. */ - public static FluffyMemorySegmentWrapper wrap(MemorySegment nativeSeg) { + public static FluffyMemorySegmentWrapper wrap(final MemorySegment nativeSeg) { requireNonNull(nativeSeg, "nativeSeg"); return new FluffyMemorySegmentWrapper(nativeSeg); } @@ -47,8 +48,8 @@ public static FluffyMemorySegmentWrapper wrap(MemorySegment nativeSeg) { * @param nativePtr - Dereference the address found inside this ptr segment. * @return - Entry point for easy dereferenciation. */ - public static FluffyMemoryDereferencer dereference(MemorySegment nativePtr) { - return new FluffyMemoryDereferencer(wrap(nativePtr), nativePtr); + public static FluffyMemoryDereferencer dereference(final MemorySegment nativePtr) { + return new FluffyMemoryDereferencer(wrap(nativePtr), Arena.ofAuto()); } /** @@ -57,8 +58,8 @@ public static FluffyMemoryDereferencer dereference(MemorySegment nativePtr) { * @param address - Dereference this address. * @return - Entry point for easy dereferenciation. */ - public static FluffyMemoryDereferencer dereference(long address) { - var nativeSeg = MemorySegment.ofAddress(address); + public static FluffyMemoryDereferencer dereference(final long address) { + final var nativeSeg = MemorySegment.ofAddress(address); return dereference(nativeSeg); } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryDereferencer.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryDereferencer.java index 9a3d0d1..7aecf89 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryDereferencer.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryDereferencer.java @@ -2,15 +2,15 @@ import static java.util.Objects.requireNonNull; -import java.lang.foreign.MemorySegment; +import java.lang.foreign.Arena; /** * Provides shortcuts for dereferencing pointers. */ public final class FluffyMemoryDereferencer { - private FluffyMemorySegmentWrapper wrapper; - private MemorySegment nativePtr; + private final FluffyMemorySegmentWrapper wrapper; + private final Arena arena; /** * Construct a new instance. @@ -19,9 +19,9 @@ public final class FluffyMemoryDereferencer { * {@link FluffyMemory#wrap(java.lang.foreign.MemorySegment)}. * @param nativePtr - The segment that was wrapped with the {@code wrapper}. */ - FluffyMemoryDereferencer(FluffyMemorySegmentWrapper wrapper, MemorySegment nativePtr) { + FluffyMemoryDereferencer(final FluffyMemorySegmentWrapper wrapper, final Arena arena) { this.wrapper = requireNonNull(wrapper, "wrapper"); - this.nativePtr = requireNonNull(nativePtr, "nativePtr"); + this.arena = requireNonNull(arena, "arena"); } /** @@ -31,7 +31,7 @@ public final class FluffyMemoryDereferencer { * @param targetType - An instance of this class will be returned. * @return An instance of T that was read from an address of off heap memory. */ - public T as(Class targetType) { - return wrapper.asPointerOf(targetType).allocate(nativePtr.scope()).dereference(); + public T as(final Class targetType) { + return wrapper.asPointerOf(targetType).allocate(arena).dereference(); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryFuncPointerBuilder.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryFuncPointerBuilder.java index babf4e2..308cf76 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryFuncPointerBuilder.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryFuncPointerBuilder.java @@ -1,7 +1,6 @@ package com.itemis.fluffyj.memory; import static java.lang.foreign.Linker.nativeLinker; -import static java.lang.foreign.SegmentScope.global; import static java.lang.invoke.MethodHandles.lookup; import static java.lang.invoke.MethodType.methodType; import static java.util.Arrays.stream; @@ -17,10 +16,10 @@ import com.itemis.fluffyj.memory.internal.FluffyMemoryFuncPointerBuilderStages.ReturnTypeStage; import com.itemis.fluffyj.memory.internal.FluffyMemoryFuncPointerBuilderStages.TypeConverterStage; +import java.lang.foreign.Arena; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.invoke.MethodHandle; import java.lang.reflect.Method; import java.util.List; @@ -50,7 +49,7 @@ public final class FluffyMemoryFuncPointerBuilder * @param conv - A {@link FluffyMemoryTypeConverter} that will be used to convert between JVM * and native type arguments and return types. */ - public FluffyMemoryFuncPointerBuilder(String funcName, FluffyMemoryTypeConverter conv) { + public FluffyMemoryFuncPointerBuilder(final String funcName, final FluffyMemoryTypeConverter conv) { this.funcName = requireNonNull(funcName, "funcName"); this.typeConverter = requireNonNull(conv, "conv"); } @@ -61,30 +60,30 @@ public FluffyMemoryFuncPointerBuilder(String funcName, FluffyMemoryTypeConverter * * @param funcName - Name of the JVM method to point to. */ - public FluffyMemoryFuncPointerBuilder(String funcName) { + public FluffyMemoryFuncPointerBuilder(final String funcName) { this.funcName = requireNonNull(funcName, "funcName"); } @Override - public ArgsStage of(Object receiver) { + public ArgsStage of(final Object receiver) { this.receiver = requireNonNull(receiver, "receiver"); return this; } @Override - public TypeConverterStage ofType(Object receiver) { + public TypeConverterStage ofType(final Object receiver) { this.receiver = requireNonNull(receiver, "receiver"); return this; } @Override - public ArgsStage withTypeConverter(FluffyMemoryTypeConverter conv) { + public ArgsStage withTypeConverter(final FluffyMemoryTypeConverter conv) { this.typeConverter = requireNonNull(conv, "conv"); return this; } @Override - public ReturnTypeStage withArgs(MemoryLayout... args) { + public ReturnTypeStage withArgs(final MemoryLayout... args) { nativeArgTypes = requireNonNull(args, "args"); javaArgTypes = typeConverter.getJvmTypes(args); return this; @@ -97,14 +96,14 @@ public ReturnTypeStage withoutArgs() { @Override public MemorySegment autoBind() { - return autoBindTo(global()); + return autoBindTo(Arena.global()); } @Override - public MemorySegment autoBindTo(SegmentScope scope) { - requireNonNull(scope, "scope"); + public MemorySegment autoBindTo(final Arena arena) { + requireNonNull(arena, "arena"); - var candidateMethods = extractMethodCandidates(); + final var candidateMethods = extractMethodCandidates(); if (candidateMethods.isEmpty()) { throwCannotFindMethod(null); @@ -114,7 +113,7 @@ public MemorySegment autoBindTo(SegmentScope scope) { throw new FluffyMemoryException( "Cannot autobind overloaded method '" + funcName + "'. Please perform manual bind."); } - var method = candidateMethods.get(0); + final var method = candidateMethods.get(0); if (!method.canAccess(receiver)) { throwCannotBindNonAccessibleMethod(); @@ -123,7 +122,7 @@ public MemorySegment autoBindTo(SegmentScope scope) { javaArgTypes = method.getParameterTypes(); try { nativeArgTypes = typeConverter.getNativeTypes(javaArgTypes); - } catch (FluffyMemoryException e) { + } catch (final FluffyMemoryException e) { throw new FluffyMemoryException( "Method '" + funcName + "' of type " + receiver.getClass().getCanonicalName() + " has unsupported argument types.", @@ -133,21 +132,22 @@ public MemorySegment autoBindTo(SegmentScope scope) { if (javaReturnType.equals(Void.class)) { throw new FluffyMemoryException("Return type " + Void.class.getCanonicalName() + " is unsupported. Use " + void.class.getCanonicalName()); - } else if (!(javaReturnType.equals(void.class))) { + } + if (!(javaReturnType.equals(void.class))) { try { nativeReturnType = Optional.of(typeConverter.getNativeType(javaReturnType)); - } catch (FluffyMemoryException e) { + } catch (final FluffyMemoryException e) { throw new FluffyMemoryException( "Method '" + funcName + "' of type " + receiver.getClass().getCanonicalName() + " has unsupported return type.", e); } } - return bindTo(scope); + return bindTo(arena); } @Override - public BinderStage andReturnType(MemoryLayout returnType) { + public BinderStage andReturnType(final MemoryLayout returnType) { requireNonNull(returnType, "returnType"); nativeReturnType = Optional.of(returnType); @@ -162,8 +162,8 @@ public BinderStage andNoReturnType() { } @Override - public MemorySegment bindTo(SegmentScope scope) { - requireNonNull(scope, "scope"); + public MemorySegment bindTo(final Arena arena) { + requireNonNull(arena, "scope"); if (extractMethodCandidates().stream().anyMatch(Method::isSynthetic)) { throwCannotBindSynthMethod(); @@ -172,23 +172,22 @@ public MemorySegment bindTo(SegmentScope scope) { MethodHandle callback = null; try { callback = lookup().bind(receiver, funcName, methodType(javaReturnType, javaArgTypes)); - } catch (NoSuchMethodException e) { + } catch (final NoSuchMethodException e) { throwCannotFindMethod(e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throwCannotBindNonAccessibleMethod(); } if (nativeReturnType.isPresent()) { return nativeLinker() - .upcallStub(callback, FunctionDescriptor.of(nativeReturnType.get(), nativeArgTypes), scope); - } else { - return nativeLinker().upcallStub(callback, FunctionDescriptor.ofVoid(nativeArgTypes), scope); + .upcallStub(callback, FunctionDescriptor.of(nativeReturnType.get(), nativeArgTypes), arena); } + return nativeLinker().upcallStub(callback, FunctionDescriptor.ofVoid(nativeArgTypes), arena); } @Override - public MemorySegment bindToGlobalScope() { - return bindTo(SegmentScope.global()); + public MemorySegment bindToGlobalArena() { + return bindTo(Arena.global()); } private List extractMethodCandidates() { @@ -204,12 +203,11 @@ private void throwCannotBindNonAccessibleMethod() { throw new FluffyMemoryException("Cannot create function pointer to non accessible JVM methods."); } - private void throwCannotFindMethod(Throwable cause) { - var errMsg = "Could not find method '" + funcName + "' in type " + receiver.getClass().getCanonicalName(); + private void throwCannotFindMethod(final Throwable cause) { + final var errMsg = "Could not find method '" + funcName + "' in type " + receiver.getClass().getCanonicalName(); if (cause == null) { throw new FluffyMemoryException(errMsg); - } else { - throw new FluffyMemoryException(errMsg, cause); } + throw new FluffyMemoryException(errMsg, cause); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryPointerBuilder.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryPointerBuilder.java index 4db7809..6008e51 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryPointerBuilder.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryPointerBuilder.java @@ -11,7 +11,7 @@ import com.itemis.fluffyj.memory.internal.PointerOfThing; import com.itemis.fluffyj.memory.internal.impl.CDataTypeConverter; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Intermediate pointer creation helper. @@ -24,7 +24,7 @@ public final class FluffyMemoryPointerBuilder { * @return A {@link FluffyMemoryScalarPointerAllocator} instance that is able to allocate * pointers to data of type {@code T}. */ - public FluffyMemoryScalarPointerAllocator to(FluffyScalarSegment toHere) { + public FluffyMemoryScalarPointerAllocator to(final FluffyScalarSegment toHere) { requireNonNull(toHere, "toHere"); return new FluffyMemoryScalarPointerAllocator<>(toHere); } @@ -35,7 +35,7 @@ public FluffyMemoryScalarPointerAllocator to(FluffyScalarSegment FluffyMemoryVectorPointerAllocator toArray(FluffyVectorSegment toHere) { + public FluffyMemoryVectorPointerAllocator toArray(final FluffyVectorSegment toHere) { requireNonNull(toHere, "toHere"); return new FluffyMemoryVectorPointerAllocator<>(toHere); } @@ -45,7 +45,7 @@ public FluffyMemoryVectorPointerAllocator toArray(FluffyVectorSegment FluffyMemoryScalarPointerAllocator of(Class type) { + public FluffyMemoryScalarPointerAllocator of(final Class type) { return new FluffyMemoryTypedPointerBuilder(NULL.address()).as(type); } @@ -82,7 +82,7 @@ public FluffyMemoryScalarPointerAllocator of(Class type) { * @param funcName - Name of the JVM method to point to. * @return A builder that helps with creating the function pointer. */ - public CFuncStage toCFunc(String funcName) { + public CFuncStage toCFunc(final String funcName) { return new FluffyMemoryFuncPointerBuilder(requireNonNull(funcName, "funcName"), new CDataTypeConverter()); } @@ -93,7 +93,7 @@ public CFuncStage toCFunc(String funcName) { * @param funcName - Name of the JVM method to point to. * @return A builder that helps with creating the function pointer. */ - public FuncStage toFunc(String funcName) { + public FuncStage toFunc(final String funcName) { return new FluffyMemoryFuncPointerBuilder(requireNonNull(funcName, "funcName")); } @@ -108,7 +108,7 @@ public static final class FluffyMemoryTypedPointerBuilder { * * @param address - Created pointer will point to this address. */ - public FluffyMemoryTypedPointerBuilder(long address) { + public FluffyMemoryTypedPointerBuilder(final long address) { requireNonNull(address, "address"); this.address = address; } @@ -120,14 +120,14 @@ public FluffyMemoryTypedPointerBuilder(long address) { * @param type - Type of scalar data to point to. * @return A new builder instance that helps with creating this kind of pointer. */ - public FluffyMemoryScalarPointerAllocator as(Class type) { + public FluffyMemoryScalarPointerAllocator as(final Class type) { return new FluffyMemoryScalarPointerAllocator<>(address, type); } /** * @param byteSize - The size of the array the pointer shall point to in bytes. */ - public FluffyMemoryTypedArrayPointerBuilder asArray(int byteSize) { + public FluffyMemoryTypedArrayPointerBuilder asArray(final int byteSize) { return new FluffyMemoryTypedArrayPointerBuilder(address, byteSize); } } @@ -145,7 +145,7 @@ public static final class FluffyMemoryTypedArrayPointerBuilder { * @param address - Created pointer will point to this address. * @param byteSize - Size of the array to point to in bytes. */ - public FluffyMemoryTypedArrayPointerBuilder(long address, long byteSize) { + public FluffyMemoryTypedArrayPointerBuilder(final long address, final long byteSize) { this.address = requireNonNull(address, "address"); this.byteSize = byteSize; } @@ -156,7 +156,7 @@ public FluffyMemoryTypedArrayPointerBuilder(long address, long byteSize) { * @param - Component type of the array to point to. * @return A new builder instance that helps with creating this kind of pointer. */ - public FluffyMemoryVectorPointerAllocator of(Class arrayType) { + public FluffyMemoryVectorPointerAllocator of(final Class arrayType) { return new FluffyMemoryVectorPointerAllocator<>(address, byteSize, arrayType); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarPointerAllocator.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarPointerAllocator.java index c4d5ed1..938ed62 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarPointerAllocator.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarPointerAllocator.java @@ -11,7 +11,7 @@ import com.itemis.fluffyj.memory.internal.PointerOfLong; import com.itemis.fluffyj.memory.internal.PointerOfString; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Helps with allocating pointers to off heap memory areas. @@ -27,7 +27,7 @@ public final class FluffyMemoryScalarPointerAllocator { * * @param toHere - The constructed pointer will point to the address of this segment. */ - public FluffyMemoryScalarPointerAllocator(FluffyScalarSegment toHere) { + public FluffyMemoryScalarPointerAllocator(final FluffyScalarSegment toHere) { requireNonNull(toHere, "toHere"); initialValue = toHere.rawAddress(); type = toHere.getContainedType(); @@ -39,7 +39,7 @@ public FluffyMemoryScalarPointerAllocator(FluffyScalarSegment toHer * @param address - The constructed pointer will point to this address. * @param typeOfData - Type of data the segment the provided address points to. */ - public FluffyMemoryScalarPointerAllocator(long address, Class typeOfData) { + public FluffyMemoryScalarPointerAllocator(final long address, final Class typeOfData) { initialValue = requireNonNull(address, "address"); type = requireNonNull(typeOfData, "typeOfData"); } @@ -50,7 +50,7 @@ public FluffyMemoryScalarPointerAllocator(long address, Class typeO * @return A new {@link FluffyPointer} instance. */ public FluffyScalarPointer allocate() { - return allocate(SegmentScope.global()); + return allocate(Arena.global()); } /** @@ -62,18 +62,18 @@ public FluffyScalarPointer allocate() { // The cast is indeed unsafe but it won't produce any ClassCastExceptions since the value the // pointer points to will be interpreted as T which may be wrong but does not cause any error. @SuppressWarnings("unchecked") - public FluffyScalarPointer allocate(SegmentScope scope) { - requireNonNull(scope, "scope"); + public FluffyScalarPointer allocate(final Arena arena) { + requireNonNull(arena, "arena"); Object result = null; if (type.isAssignableFrom(Long.class) || type.isAssignableFrom(long.class)) { - result = new PointerOfLong(initialValue, scope); + result = new PointerOfLong(initialValue, arena); } else if (type.isAssignableFrom(Integer.class) || type.isAssignableFrom(int.class)) { - result = new PointerOfInt(initialValue, scope); + result = new PointerOfInt(initialValue, arena); } else if (type.isAssignableFrom(String.class)) { - result = new PointerOfString(initialValue, scope); + result = new PointerOfString(initialValue, arena); } else if (type.isAssignableFrom(Byte.class) || type.isAssignableFrom(byte.class)) { - result = new PointerOfByte(initialValue, scope); + result = new PointerOfByte(initialValue, arena); } else { throw new FluffyMemoryException( "Cannot allocate scalar pointer of unknown type: " + type.getCanonicalName()); diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarSegmentAllocator.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarSegmentAllocator.java index 160e078..84d5a32 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarSegmentAllocator.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryScalarSegmentAllocator.java @@ -9,7 +9,7 @@ import com.itemis.fluffyj.memory.internal.LongSegment; import com.itemis.fluffyj.memory.internal.StringSegment; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Helps with allocating areas of off heap memory. An allocated area of off heap memory is called a @@ -23,7 +23,7 @@ public final class FluffyMemoryScalarSegmentAllocator { /** * @param initialValue - The allocated segment will hold this value. */ - public FluffyMemoryScalarSegmentAllocator(T initialValue) { + public FluffyMemoryScalarSegmentAllocator(final T initialValue) { requireNonNull(initialValue, "initialValue"); this.initialValue = initialValue; } @@ -32,7 +32,7 @@ public FluffyMemoryScalarSegmentAllocator(T initialValue) { * @return A freshly allocated segment attached to the global scope. */ public FluffyScalarSegment allocate() { - return allocate(SegmentScope.global()); + return allocate(Arena.ofAuto()); } /** @@ -41,18 +41,18 @@ public FluffyScalarSegment allocate() { // We cannot convince the compiler at this point anyway so we need to make sure about type // safety via tests @SuppressWarnings("unchecked") - public FluffyScalarSegment allocate(SegmentScope scope) { - requireNonNull(scope, "scope"); + public FluffyScalarSegment allocate(final Arena arena) { + requireNonNull(arena, "arena"); Object result = null; if (initialValue instanceof Long) { - result = new LongSegment((Long) initialValue, scope); + result = new LongSegment((Long) initialValue, arena); } else if (initialValue instanceof Integer) { - result = new IntSegment((Integer) initialValue, scope); + result = new IntSegment((Integer) initialValue, arena); } else if (initialValue instanceof String) { - result = new StringSegment((String) initialValue, scope); + result = new StringSegment((String) initialValue, arena); } else if (initialValue instanceof Byte) { - result = new ByteSegment((Byte) initialValue, scope); + result = new ByteSegment((Byte) initialValue, arena); } else { throw new FluffyMemoryException( "Cannot allocate scalar segment of unknown type: " + initialValue.getClass().getCanonicalName()); diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemorySegmentWrapper.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemorySegmentWrapper.java index b600458..09d14a3 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemorySegmentWrapper.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemorySegmentWrapper.java @@ -14,6 +14,7 @@ import com.itemis.fluffyj.memory.internal.StringSegment; import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; /** * Helps with wrapping "untyped" off heap memory areas ("segments") into {@link FluffySegment}s. @@ -27,7 +28,7 @@ public final class FluffyMemorySegmentWrapper { * * @param nativeSegment - This segment will be wrapped. */ - public FluffyMemorySegmentWrapper(MemorySegment nativeSegment) { + public FluffyMemorySegmentWrapper(final MemorySegment nativeSegment) { requireNonNull(nativeSegment, "nativeSegment"); this.nativeSegment = nativeSegment; } @@ -41,7 +42,7 @@ public FluffyMemorySegmentWrapper(MemorySegment nativeSegment) { */ // The cast is indeed unsafe. We need to make sure with good test coverage. @SuppressWarnings("unchecked") - public FluffyScalarSegment as(Class type) { + public FluffyScalarSegment as(final Class type) { requireNonNull(type, "type"); Object result = null; @@ -59,8 +60,8 @@ public FluffyScalarSegment as(Class type) { return (FluffyScalarSegment) result; } - public FluffyMemoryScalarPointerAllocator asPointerOf(Class type) { - return new FluffyMemoryTypedPointerBuilder(nativeSegment.address()).as(type); + public FluffyMemoryScalarPointerAllocator asPointerOf(final Class type) { + return new FluffyMemoryTypedPointerBuilder(nativeSegment.get(ValueLayout.ADDRESS, 0).address()).as(type); } /** @@ -70,15 +71,14 @@ public FluffyMemoryScalarPointerAllocator asPointerOf(Class */ // The cast is indeed unsafe. We need to make sure with good test coverage. @SuppressWarnings("unchecked") - public FluffyVectorSegment asArray(Class type) { + public FluffyVectorSegment asArray(final Class type) { requireNonNull(type, "type"); Object result = null; - if (type.isAssignableFrom(Byte[].class)) { - result = new BlobSegment(nativeSegment); - } else { + if (!type.isAssignableFrom(Byte[].class)) { throw new FluffyMemoryException("Cannot wrap vector segment of unknown type: " + type.getCanonicalName()); } + result = new BlobSegment(nativeSegment); return (FluffyVectorSegment) result; } } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorPointerAllocator.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorPointerAllocator.java index 6210ee6..4d22b6c 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorPointerAllocator.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorPointerAllocator.java @@ -8,7 +8,7 @@ import com.itemis.fluffyj.memory.error.FluffyMemoryException; import com.itemis.fluffyj.memory.internal.PointerOfBlob; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Helps with allocating pointers to off heap memory areas that hold arrays. @@ -25,7 +25,7 @@ public final class FluffyMemoryVectorPointerAllocator { * * @param toHere - The constructed pointer will point to the address of this segment. */ - public FluffyMemoryVectorPointerAllocator(FluffyVectorSegment toHere) { + public FluffyMemoryVectorPointerAllocator(final FluffyVectorSegment toHere) { requireNonNull(toHere, "toHere"); initialValue = toHere.rawAddress(); byteSize = toHere.byteSize(); @@ -38,7 +38,8 @@ public FluffyMemoryVectorPointerAllocator(FluffyVectorSegment toHer * @param byteSize - The size of the array the pointer shall point to in bytes. * @param arrayType - Type of the array the provided address points to. */ - public FluffyMemoryVectorPointerAllocator(long address, long byteSize, Class arrayType) { + public FluffyMemoryVectorPointerAllocator(final long address, final long byteSize, + final Class arrayType) { this.initialValue = requireNonNull(address, "address"); this.byteSize = byteSize; this.type = requireNonNull(arrayType, "typeOfData"); @@ -50,7 +51,7 @@ public FluffyMemoryVectorPointerAllocator(long address, long byteSize, Class allocate() { - return allocate(SegmentScope.global()); + return allocate(Arena.ofAuto()); } /** @@ -63,16 +64,15 @@ public FluffyVectorPointer allocate() { // pointer points to will be interpreted as T anyway which may be false but does not cause any // error at the time the cast is done. @SuppressWarnings({"unchecked"}) - public FluffyVectorPointer allocate(SegmentScope scope) { - requireNonNull(scope, "scope"); + public FluffyVectorPointer allocate(final Arena arena) { + requireNonNull(arena, "arena"); Object result = null; - if (type.isAssignableFrom(Byte[].class)) { - result = new PointerOfBlob(initialValue, byteSize, scope); - } else { + if (!type.isAssignableFrom(Byte[].class)) { throw new FluffyMemoryException( "Cannot allocate vector pointer of unknown type: " + type.getCanonicalName()); } + result = new PointerOfBlob(initialValue, byteSize, arena); return (FluffyVectorPointer) result; } diff --git a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorSegmentAllocator.java b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorSegmentAllocator.java index edd8289..abc3e47 100644 --- a/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorSegmentAllocator.java +++ b/src/main/java/com/itemis/fluffyj/memory/FluffyMemoryVectorSegmentAllocator.java @@ -6,7 +6,7 @@ import com.itemis.fluffyj.memory.error.FluffyMemoryException; import com.itemis.fluffyj.memory.internal.BlobSegment; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Helps with allocating areas of off heap memory that contain vectorized data, i. e. arrays. @@ -19,7 +19,7 @@ public final class FluffyMemoryVectorSegmentAllocator { /** * @param initialValue - The allocated segment will hold this value. */ - public FluffyMemoryVectorSegmentAllocator(T[] initialValue) { + public FluffyMemoryVectorSegmentAllocator(final T[] initialValue) { requireNonNull(initialValue, "initialValue"); this.initialValue = initialValue; } @@ -28,7 +28,7 @@ public FluffyMemoryVectorSegmentAllocator(T[] initialValue) { * @return A freshly allocated segment attached to the global scope. */ public FluffyVectorSegment allocate() { - return allocate(SegmentScope.global()); + return allocate(Arena.ofAuto()); } /** @@ -37,16 +37,15 @@ public FluffyVectorSegment allocate() { // We cannot convince the compiler at this point anyway so we need to make sure about type // safety via tests @SuppressWarnings("unchecked") - public FluffyVectorSegment allocate(SegmentScope scope) { - requireNonNull(scope, "scope"); + public FluffyVectorSegment allocate(final Arena arena) { + requireNonNull(arena, "arena"); Object result = null; - if (initialValue.getClass().componentType().isAssignableFrom(Byte.class)) { - result = new BlobSegment((Byte[]) initialValue, scope); - } else { + if (!initialValue.getClass().componentType().isAssignableFrom(Byte.class)) { throw new FluffyMemoryException( "Cannot allocate vector segment of unknown type: " + initialValue.getClass().getCanonicalName()); } + result = new BlobSegment((Byte[]) initialValue, arena); return (FluffyVectorSegment) result; } diff --git a/src/main/java/com/itemis/fluffyj/memory/api/FluffyPointer.java b/src/main/java/com/itemis/fluffyj/memory/api/FluffyPointer.java index bb34c25..b8f0de1 100644 --- a/src/main/java/com/itemis/fluffyj/memory/api/FluffyPointer.java +++ b/src/main/java/com/itemis/fluffyj/memory/api/FluffyPointer.java @@ -1,7 +1,6 @@ package com.itemis.fluffyj.memory.api; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; /** * Provides convenience methods that help with working with {@link MemorySegment}s that hold diff --git a/src/main/java/com/itemis/fluffyj/memory/api/FluffySegment.java b/src/main/java/com/itemis/fluffyj/memory/api/FluffySegment.java index db5c344..9813b40 100644 --- a/src/main/java/com/itemis/fluffyj/memory/api/FluffySegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/api/FluffySegment.java @@ -1,7 +1,6 @@ package com.itemis.fluffyj.memory.api; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; /** * A representation of an allocated area of off heap memory. diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/BlobSegment.java b/src/main/java/com/itemis/fluffyj/memory/internal/BlobSegment.java index 0caa875..d0d1112 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/BlobSegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/BlobSegment.java @@ -4,27 +4,27 @@ import com.itemis.fluffyj.memory.internal.impl.FluffyVectorSegmentImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; public class BlobSegment extends FluffyVectorSegmentImpl { - public BlobSegment(MemorySegment backingSeg) { + public BlobSegment(final MemorySegment backingSeg) { super(backingSeg); } - public BlobSegment(Byte[] initialValue, SegmentScope scope) { - this(primitivize(requireNonNull(initialValue, "initialValue")), requireNonNull(scope, "scope")); + public BlobSegment(final Byte[] initialValue, final Arena arena) { + this(primitivize(requireNonNull(initialValue, "initialValue")), requireNonNull(arena, "arena")); } - public BlobSegment(byte[] initialValue, SegmentScope scope) { - super(requireNonNull(initialValue, "initialValue"), requireNonNull(scope, "scope")); + public BlobSegment(final byte[] initialValue, final Arena arena) { + super(requireNonNull(initialValue, "initialValue"), requireNonNull(arena, "arena")); } - private static final byte[] primitivize(Byte[] value) { - var result = new byte[value.length]; + private static final byte[] primitivize(final Byte[] value) { + final var result = new byte[value.length]; for (var i = 0; i < value.length; i++) { result[i] = value[i]; } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/ByteSegment.java b/src/main/java/com/itemis/fluffyj/memory/internal/ByteSegment.java index 07a4d61..d74fd5f 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/ByteSegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/ByteSegment.java @@ -6,8 +6,8 @@ import com.itemis.fluffyj.memory.api.FluffySegment; import com.itemis.fluffyj.memory.internal.impl.FluffySegmentImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -21,8 +21,8 @@ public class ByteSegment extends FluffySegmentImpl implements FluffyScalarSegmen * @param initialValue - The new segment will hold this value. * @param scope - The new segment will be attached to this scope. */ - public ByteSegment(byte initialValue, SegmentScope scope) { - super(new byte[] {initialValue}, requireNonNull(scope, "scope")); + public ByteSegment(final byte initialValue, final Arena arena) { + super(new byte[] {initialValue}, requireNonNull(arena, "arena")); } /** @@ -31,7 +31,7 @@ public ByteSegment(byte initialValue, SegmentScope scope) { * * @param backingSeg - The raw segment to wrap. */ - public ByteSegment(MemorySegment backingSeg) { + public ByteSegment(final MemorySegment backingSeg) { super(backingSeg); } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/FluffyMemoryFuncPointerBuilderStages.java b/src/main/java/com/itemis/fluffyj/memory/internal/FluffyMemoryFuncPointerBuilderStages.java index f0a25a2..f12c081 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/FluffyMemoryFuncPointerBuilderStages.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/FluffyMemoryFuncPointerBuilderStages.java @@ -3,9 +3,9 @@ import com.itemis.fluffyj.exceptions.InstantiationNotPermittedException; import com.itemis.fluffyj.memory.api.FluffyMemoryTypeConverter; +import java.lang.foreign.Arena; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; public final class FluffyMemoryFuncPointerBuilderStages { @@ -32,7 +32,7 @@ public interface ArgsStage { MemorySegment autoBind(); - MemorySegment autoBindTo(SegmentScope scope); + MemorySegment autoBindTo(Arena arena); } public interface ReturnTypeStage { @@ -42,8 +42,8 @@ public interface ReturnTypeStage { } public interface BinderStage { - MemorySegment bindToGlobalScope(); + MemorySegment bindToGlobalArena(); - MemorySegment bindTo(SegmentScope scope); + MemorySegment bindTo(Arena arena); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/IntSegment.java b/src/main/java/com/itemis/fluffyj/memory/internal/IntSegment.java index db65a26..8fa6783 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/IntSegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/IntSegment.java @@ -4,9 +4,8 @@ import com.itemis.fluffyj.memory.api.FluffySegment; import com.itemis.fluffyj.memory.internal.impl.FluffySegmentImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -26,8 +25,8 @@ public class IntSegment extends FluffySegmentImpl implements FluffyScalarSegment * @param initialValue - The new segment will hold this value. * @param scope - The new segment will be attached to this scope. */ - public IntSegment(int initialValue, SegmentScope scope) { - this(SegmentAllocator.nativeAllocator(scope).allocate(ValueLayout.JAVA_INT, initialValue)); + public IntSegment(final int initialValue, final Arena arena) { + this(arena.allocate(ValueLayout.JAVA_INT, initialValue)); } /** @@ -36,7 +35,7 @@ public IntSegment(int initialValue, SegmentScope scope) { * * @param backingSeg - The raw segment to wrap. */ - public IntSegment(MemorySegment backingSeg) { + public IntSegment(final MemorySegment backingSeg) { super(backingSeg); } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/LongSegment.java b/src/main/java/com/itemis/fluffyj/memory/internal/LongSegment.java index 9298d25..142337d 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/LongSegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/LongSegment.java @@ -4,9 +4,8 @@ import com.itemis.fluffyj.memory.api.FluffySegment; import com.itemis.fluffyj.memory.internal.impl.FluffySegmentImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -26,8 +25,8 @@ public class LongSegment extends FluffySegmentImpl implements FluffyScalarSegmen * @param initialValue - The new segment will hold this value. * @param scope - The new segment will be attached to this scope. */ - public LongSegment(long initialValue, SegmentScope scope) { - this(SegmentAllocator.nativeAllocator(scope).allocate(ValueLayout.JAVA_LONG, initialValue)); + public LongSegment(final long initialValue, final Arena arena) { + this(arena.allocate(ValueLayout.JAVA_LONG, initialValue)); } /** @@ -36,7 +35,7 @@ public LongSegment(long initialValue, SegmentScope scope) { * * @param backingSeg - The raw segment to wrap. */ - public LongSegment(MemorySegment backingSeg) { + public LongSegment(final MemorySegment backingSeg) { super(backingSeg); } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfBlob.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfBlob.java index 485c591..55c8a29 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfBlob.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfBlob.java @@ -4,8 +4,8 @@ import com.itemis.fluffyj.memory.internal.impl.FluffyVectorPointerImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; public class PointerOfBlob extends FluffyVectorPointerImpl { @@ -17,14 +17,14 @@ public class PointerOfBlob extends FluffyVectorPointerImpl { * @param byteSize - Size of the vector this pointer points to in bytes. * @param scope - Attach the new pointer to this scope. */ - public PointerOfBlob(long addressPointedTo, long byteSize, SegmentScope scope) { - super(requireNonNull(addressPointedTo, "addressPointedTo"), byteSize, requireNonNull(scope, "scope")); + public PointerOfBlob(final long addressPointedTo, final long byteSize, final Arena arena) { + super(requireNonNull(addressPointedTo, "addressPointedTo"), byteSize, requireNonNull(arena, "arena")); } @Override public Byte[] dereference() { - var valSeg = rawDereference(); - var result = new Byte[(int) byteSize]; + final var valSeg = rawDereference(); + final var result = new Byte[(int) byteSize]; for (var i = 0; i < result.length; i++) { result[i] = valSeg.get(ValueLayout.JAVA_BYTE, i); } @@ -34,6 +34,6 @@ public Byte[] dereference() { @Override public MemorySegment rawDereference() { - return MemorySegment.ofAddress(getRawValue(), byteSize, scope); + return addressSeg.reinterpret(byteSize, arena, null); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfByte.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfByte.java index d8d2c01..042e1b6 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfByte.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfByte.java @@ -1,13 +1,12 @@ package com.itemis.fluffyj.memory.internal; -import static java.lang.foreign.ValueLayout.JAVA_INT; import static java.util.Objects.requireNonNull; import com.itemis.fluffyj.memory.api.FluffyPointer; import com.itemis.fluffyj.memory.internal.impl.FluffyScalarPointerImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -21,9 +20,9 @@ public class PointerOfByte extends FluffyScalarPointerImpl { * @param addressPointedTo - The address the new pointer will point to. * @param scope - Attach the new pointer to this scope. */ - public PointerOfByte(long addressPointedTo, SegmentScope scope) { - super(requireNonNull(addressPointedTo, "addressPointedTo"), JAVA_INT.byteSize(), - requireNonNull(scope, "scope")); + public PointerOfByte(final long addressPointedTo, final Arena arena) { + super(requireNonNull(addressPointedTo, "addressPointedTo"), ValueLayout.JAVA_BYTE.byteSize(), + requireNonNull(arena, "arena")); } @Override @@ -33,6 +32,6 @@ public Byte dereference() { @Override public MemorySegment rawDereference() { - return MemorySegment.ofAddress(getRawValue(), 1, scope); + return MemorySegment.ofAddress(getRawValue()).reinterpret(1, arena, null); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfInt.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfInt.java index b20253f..6e282af 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfInt.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfInt.java @@ -6,8 +6,8 @@ import com.itemis.fluffyj.memory.api.FluffyPointer; import com.itemis.fluffyj.memory.internal.impl.FluffyScalarPointerImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -21,9 +21,9 @@ public class PointerOfInt extends FluffyScalarPointerImpl { * @param addressPointedTo - The address the new pointer will point to. * @param scope - Attach the new pointer to this scope. */ - public PointerOfInt(long addressPointedTo, SegmentScope scope) { + public PointerOfInt(final long addressPointedTo, final Arena arena) { super(requireNonNull(addressPointedTo, "addressPointedTo"), JAVA_INT.byteSize(), - requireNonNull(scope, "scope")); + requireNonNull(arena, "arena")); } @Override @@ -33,6 +33,6 @@ public Integer dereference() { @Override public MemorySegment rawDereference() { - return MemorySegment.ofAddress(getRawValue(), JAVA_INT.byteSize(), scope); + return addressSeg.reinterpret(JAVA_INT.byteSize(), arena, null); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfLong.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfLong.java index e2ad7e2..e0cb561 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfLong.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfLong.java @@ -6,8 +6,8 @@ import com.itemis.fluffyj.memory.api.FluffyPointer; import com.itemis.fluffyj.memory.internal.impl.FluffyScalarPointerImpl; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; /** @@ -21,9 +21,9 @@ public class PointerOfLong extends FluffyScalarPointerImpl { * @param addressPointedTo - The {@link MemorySegment} the new pointer will point to. * @param scope - Attach the new pointer to this scope. */ - public PointerOfLong(long addressPointedTo, SegmentScope scope) { + public PointerOfLong(final long addressPointedTo, final Arena arena) { super(requireNonNull(addressPointedTo, "addressPointedTo"), JAVA_LONG.byteSize(), - requireNonNull(scope, "scope")); + requireNonNull(arena, "arena")); } @Override @@ -33,6 +33,6 @@ public Long dereference() { @Override public MemorySegment rawDereference() { - return MemorySegment.ofAddress(getRawValue(), JAVA_LONG.byteSize(), scope); + return addressSeg.reinterpret(JAVA_LONG.byteSize(), arena, null); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfString.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfString.java index 84515f8..00dad05 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfString.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfString.java @@ -1,19 +1,17 @@ package com.itemis.fluffyj.memory.internal; -import static java.lang.foreign.MemorySegment.allocateNative; -import static java.lang.foreign.MemorySegment.ofAddress; import static java.lang.foreign.ValueLayout.ADDRESS; import static java.lang.foreign.ValueLayout.JAVA_LONG; import static java.util.Objects.requireNonNull; import com.itemis.fluffyj.memory.api.FluffyScalarPointer; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; public class PointerOfString implements FluffyScalarPointer { - private final SegmentScope scope; + private final Arena arena; private final MemorySegment backingSeg; /** @@ -22,16 +20,16 @@ public class PointerOfString implements FluffyScalarPointer { * @param addressPointedTo - The address the new pointer will point to. * @param scope - Attach the new pointer to this scope. */ - public PointerOfString(long addressPointedTo, SegmentScope scope) { - this.scope = requireNonNull(scope, "scope"); + public PointerOfString(final long addressPointedTo, final Arena arena) { + this.arena = requireNonNull(arena, "arena"); - backingSeg = allocateNative(JAVA_LONG, scope); + backingSeg = arena.allocate(JAVA_LONG); backingSeg.set(JAVA_LONG, 0, addressPointedTo); } @Override public boolean isAlive() { - return scope.isAlive(); + return arena.scope().isAlive(); } @Override @@ -41,7 +39,7 @@ public long rawAddress() { @Override public MemorySegment address() { - return ofAddress(rawAddress(), 0, scope); + return MemorySegment.ofAddress(rawAddress()); } @Override @@ -51,7 +49,7 @@ public long getRawValue() { @Override public MemorySegment getValue() { - return ofAddress(getRawValue(), 0, scope); + return backingSeg.reinterpret(JAVA_LONG.byteSize(), arena, null); } @Override @@ -61,6 +59,6 @@ public String dereference() { @Override public MemorySegment rawDereference() { - return backingSeg.get(ADDRESS.asUnbounded(), 0); + return backingSeg.get(ADDRESS, 0); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfThing.java b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfThing.java index f35623c..bcc405e 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfThing.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/PointerOfThing.java @@ -4,7 +4,7 @@ import com.itemis.fluffyj.memory.internal.impl.FluffyPointerImpl; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * An arbitrary pointer that just holds an address and cannot be dereferenced via Fluffy API. It is @@ -17,7 +17,7 @@ public class PointerOfThing extends FluffyPointerImpl { * @param scope - The scope to attach this pointer to. If the scope is closed, the pointer will * not be alive anymore. */ - public PointerOfThing(SegmentScope scope) { - super(0L, requireNonNull(scope, "scope")); + public PointerOfThing(final Arena arena) { + super(0L, requireNonNull(arena, "arena")); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/StringSegment.java b/src/main/java/com/itemis/fluffyj/memory/internal/StringSegment.java index e0e8708..d400ef3 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/StringSegment.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/StringSegment.java @@ -5,13 +5,13 @@ import com.itemis.fluffyj.memory.api.FluffyScalarSegment; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.MemorySegment.Scope; public class StringSegment implements FluffyScalarSegment { - private final SegmentScope scope; + private final Scope scope; private final MemorySegment backingSeg; /** @@ -20,10 +20,9 @@ public class StringSegment implements FluffyScalarSegment { * @param initialValue - The new segment will hold this value. * @param scope - The new segment will be attached to this scope. */ - public StringSegment(String initialValue, SegmentScope scope) { - this.scope = requireNonNull(scope, "scope"); - this.backingSeg = SegmentAllocator.nativeAllocator(scope) - .allocateUtf8String(requireNonNull(initialValue, "initialValue")); + public StringSegment(final String initialValue, final Arena arena) { + this.scope = requireNonNull(arena, "arena").scope(); + this.backingSeg = arena.allocateUtf8String(requireNonNull(initialValue, "initialValue")); } /** @@ -32,9 +31,9 @@ public StringSegment(String initialValue, SegmentScope scope) { * * @param backingSeg - The raw segment to wrap. */ - public StringSegment(MemorySegment backingSeg) { - this.scope = backingSeg.scope(); + public StringSegment(final MemorySegment backingSeg) { this.backingSeg = requireNonNull(backingSeg, "backingSeg"); + this.scope = backingSeg.scope(); } @Override @@ -44,7 +43,7 @@ public Class getContainedType() { @Override public MemorySegment address() { - return ofAddress(rawAddress(), 0, scope); + return ofAddress(rawAddress()); } @Override @@ -54,7 +53,7 @@ public long rawAddress() { @Override public boolean isAlive() { - return backingSeg.scope().isAlive(); + return scope.isAlive(); } @Override diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverter.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverter.java index 3592968..6df6842 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverter.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverter.java @@ -12,10 +12,10 @@ public class CDataTypeConverter implements FluffyMemoryTypeConverter { @Override - public MemoryLayout[] getNativeTypes(Class... jvmTypes) { + public MemoryLayout[] getNativeTypes(final Class... jvmTypes) { requireNonNull(jvmTypes, "jvmTypes"); - var result = new MemoryLayout[jvmTypes.length]; + final var result = new MemoryLayout[jvmTypes.length]; for (var i = 0; i < result.length; i++) { result[i] = getNativeType(jvmTypes[i]); } @@ -24,7 +24,7 @@ public MemoryLayout[] getNativeTypes(Class... jvmTypes) { } @Override - public MemoryLayout getNativeType(Class jvmType) { + public MemoryLayout getNativeType(final Class jvmType) { MemoryLayout result; if (long.class.equals(jvmType) || Long.class.equals(jvmType)) { result = ValueLayout.JAVA_LONG; @@ -41,7 +41,7 @@ public MemoryLayout getNativeType(Class jvmType) { } else if (byte.class.equals(jvmType) || Byte.class.equals(jvmType)) { result = ValueLayout.JAVA_BYTE; } else if (MemorySegment.class.isAssignableFrom(jvmType)) { - result = ValueLayout.ADDRESS.asUnbounded(); + result = ValueLayout.ADDRESS; } else { throw new FluffyMemoryException( "Cannot provide native memory layout for JVM type " + jvmType.getCanonicalName()); @@ -50,7 +50,7 @@ public MemoryLayout getNativeType(Class jvmType) { } @Override - public Class getJvmType(MemoryLayout nativeType) { + public Class getJvmType(final MemoryLayout nativeType) { Class result; if (ValueLayout.JAVA_LONG.equals(nativeType)) { result = long.class; @@ -66,7 +66,7 @@ public Class getJvmType(MemoryLayout nativeType) { result = float.class; } else if (ValueLayout.JAVA_SHORT.equals(nativeType)) { result = short.class; - } else if (ValueLayout.ADDRESS.equals(nativeType) || ValueLayout.ADDRESS.asUnbounded().equals(nativeType)) { + } else if (ValueLayout.ADDRESS.equals(nativeType)) { result = MemorySegment.class; } else { throw new FluffyMemoryException("Cannot provide JVM type for native memory layout " + nativeType.name()); @@ -76,9 +76,9 @@ public Class getJvmType(MemoryLayout nativeType) { } @Override - public Class[] getJvmTypes(MemoryLayout... nativeTypes) { + public Class[] getJvmTypes(final MemoryLayout... nativeTypes) { requireNonNull(nativeTypes, "nativeTypes"); - var result = new Class[nativeTypes.length]; + final var result = new Class[nativeTypes.length]; for (var i = 0; i < nativeTypes.length; i++) { result[i] = getJvmType(nativeTypes[i]); } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyPointerImpl.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyPointerImpl.java index 2d7ea42..47e2f83 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyPointerImpl.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyPointerImpl.java @@ -5,10 +5,8 @@ import com.itemis.fluffyj.memory.api.FluffyPointer; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; -import java.lang.foreign.ValueLayout; /** * Default implementation of a pointer. @@ -16,20 +14,20 @@ public abstract class FluffyPointerImpl implements FluffyPointer { protected final MemorySegment addressSeg; - protected final SegmentScope scope; + protected final Arena arena; /** * @param addressPointedTo - The address this pointer will point to. * @param scope - The scope to attach this pointer to. */ - protected FluffyPointerImpl(long addressPointedTo, SegmentScope scope) { - this.addressSeg = SegmentAllocator.nativeAllocator(scope).allocate(JAVA_LONG, addressPointedTo); - this.scope = scope; + protected FluffyPointerImpl(final long addressPointedTo, final Arena arena) { + this.addressSeg = arena.allocate(JAVA_LONG, addressPointedTo); + this.arena = arena; } @Override public final boolean isAlive() { - return scope.isAlive(); + return arena.scope().isAlive(); } @Override @@ -39,7 +37,7 @@ public final long rawAddress() { @Override public MemorySegment address() { - return ofAddress(rawAddress(), 0, scope); + return ofAddress(rawAddress()); } @Override @@ -49,11 +47,11 @@ public final long getRawValue() { @Override public MemorySegment getValue() { - return addressSeg.get(ValueLayout.ADDRESS.asUnbounded(), 0); + return addressSeg; } @Override public MemorySegment rawDereference() { - return MemorySegment.ofAddress(getRawValue(), Long.MAX_VALUE, scope); + return MemorySegment.ofAddress(getRawValue()).reinterpret(Long.MAX_VALUE, arena, null); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyScalarPointerImpl.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyScalarPointerImpl.java index 913652c..3e0a3a9 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyScalarPointerImpl.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyScalarPointerImpl.java @@ -4,7 +4,7 @@ import com.itemis.fluffyj.memory.api.FluffyScalarPointer; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Default implementation of a scalar pointer. @@ -20,8 +20,8 @@ public abstract class FluffyScalarPointerImpl extends FluffyPointerImpl imple * @param byteSize - Size of the array this pointer points to in bytes. * @param scope - The scope to attach this pointer to. */ - public FluffyScalarPointerImpl(long addressPointedTo, long byteSize, SegmentScope scope) { - super(addressPointedTo, scope); + public FluffyScalarPointerImpl(final long addressPointedTo, final long byteSize, final Arena arena) { + super(addressPointedTo, arena); this.byteSize = requireNonNull(byteSize); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffySegmentImpl.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffySegmentImpl.java index 3c3c435..16c22d7 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffySegmentImpl.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffySegmentImpl.java @@ -4,9 +4,9 @@ import com.itemis.fluffyj.memory.api.FluffySegment; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.MemorySegment.Scope; import java.lang.foreign.ValueLayout; /** @@ -15,14 +15,14 @@ public abstract class FluffySegmentImpl implements FluffySegment { protected final MemorySegment backingSeg; - protected final SegmentScope scope; + protected final Scope scope; /** * Wrap the provided {@link MemorySegment}. * * @param backingSeg - The raw segment to wrap. */ - public FluffySegmentImpl(MemorySegment backingSeg) { + public FluffySegmentImpl(final MemorySegment backingSeg) { this.backingSeg = backingSeg; this.scope = backingSeg.scope(); } @@ -33,8 +33,8 @@ public FluffySegmentImpl(MemorySegment backingSeg) { * @param initialValue - The new segment will hold this value. * @param scope - The new segment will be attached to this scope. */ - public FluffySegmentImpl(byte[] initialValue, SegmentScope scope) { - this(SegmentAllocator.nativeAllocator(scope).allocateArray(ValueLayout.JAVA_BYTE, initialValue)); + public FluffySegmentImpl(final byte[] initialValue, final Arena arena) { + this(arena.allocateArray(ValueLayout.JAVA_BYTE, initialValue)); } @Override @@ -44,7 +44,7 @@ public boolean isAlive() { @Override public MemorySegment address() { - return ofAddress(rawAddress(), 0, scope); + return ofAddress(rawAddress()); } @Override diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorPointerImpl.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorPointerImpl.java index 6a78028..5d132fb 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorPointerImpl.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorPointerImpl.java @@ -4,7 +4,7 @@ import com.itemis.fluffyj.memory.api.FluffyVectorPointer; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; /** * Default implementation of a vector pointer. @@ -21,8 +21,8 @@ public abstract class FluffyVectorPointerImpl extends FluffyPointerImpl imple * @param byteSize - Size of the array this pointer points to in bytes. * @param scope - The scope to attach this pointer to. */ - public FluffyVectorPointerImpl(long addressPointedTo, long byteSize, SegmentScope scope) { - super(addressPointedTo, scope); + public FluffyVectorPointerImpl(final long addressPointedTo, final long byteSize, final Arena arena) { + super(addressPointedTo, arena); this.byteSize = requireNonNull(byteSize); } } diff --git a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorSegmentImpl.java b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorSegmentImpl.java index 47befd3..20fe0f3 100644 --- a/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorSegmentImpl.java +++ b/src/main/java/com/itemis/fluffyj/memory/internal/impl/FluffyVectorSegmentImpl.java @@ -2,8 +2,8 @@ import com.itemis.fluffyj.memory.api.FluffyVectorSegment; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; /** * Default implementation of a generic segment that holds vectorized (i. e. array) data. @@ -12,12 +12,12 @@ */ public abstract class FluffyVectorSegmentImpl extends FluffySegmentImpl implements FluffyVectorSegment { - public FluffyVectorSegmentImpl(MemorySegment backingSeg) { + public FluffyVectorSegmentImpl(final MemorySegment backingSeg) { super(backingSeg); } - public FluffyVectorSegmentImpl(byte[] initialValue, SegmentScope scope) { - super(initialValue, scope); + public FluffyVectorSegmentImpl(final byte[] initialValue, final Arena arena) { + super(initialValue, arena); } @Override diff --git a/src/test/java/com/itemis/fluffyj/memory/ByteManipulationTest.java b/src/test/java/com/itemis/fluffyj/memory/ByteManipulationTest.java index fbe6ace..43b676a 100644 --- a/src/test/java/com/itemis/fluffyj/memory/ByteManipulationTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/ByteManipulationTest.java @@ -15,8 +15,11 @@ class ByteManipulationTest extends FluffyScalarDataManipulationTest { @Override public FluffyMemoryScalarTestValue next() { - var buf = new byte[1]; + final var buf = new byte[1]; rnd.nextBytes(buf); + if (buf[0] < 0) { + buf[0] = (byte) (buf[0] * (-1)); + } return new FluffyMemoryScalarTestValue<>(buf[0], buf); } }, JAVA_BYTE); diff --git a/src/test/java/com/itemis/fluffyj/memory/ClassBasicsTest.java b/src/test/java/com/itemis/fluffyj/memory/ClassBasicsTest.java index 88b2508..40865c1 100644 --- a/src/test/java/com/itemis/fluffyj/memory/ClassBasicsTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/ClassBasicsTest.java @@ -17,6 +17,8 @@ import org.junit.jupiter.api.Test; +import java.lang.foreign.Arena; + class ClassBasicsTest { private static final int A_LONG = 1; @@ -56,8 +58,8 @@ void constructor_with_null_arg_yields_npe() { assertNullArgNotAccepted(() -> new PointerOfLong(NULL.address(), null) {}, "scope"); assertNullArgNotAccepted(() -> new PointerOfBlob(NULL.address(), A_LONG, null) {}, "scope"); assertNullArgNotAccepted(() -> new PointerOfString(NULL.address(), null) {}, "scope"); - assertNullArgNotAccepted(() -> new PointerOfByte(NULL.address(), null) {}, "scope"); - assertNullArgNotAccepted(() -> new FluffyMemoryDereferencer(null, NULL), "wrapper"); + assertNullArgNotAccepted(() -> new PointerOfByte(NULL.address(), null) {}, "arena"); + assertNullArgNotAccepted(() -> new FluffyMemoryDereferencer(null, Arena.global()), "wrapper"); assertNullArgNotAccepted(() -> new FluffyMemoryDereferencer(wrap(NULL), null), "nativePtr"); } } diff --git a/src/test/java/com/itemis/fluffyj/memory/FluffyNativeMethodHandleTest.java b/src/test/java/com/itemis/fluffyj/memory/FluffyNativeMethodHandleTest.java index 3dec480..6830900 100644 --- a/src/test/java/com/itemis/fluffyj/memory/FluffyNativeMethodHandleTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/FluffyNativeMethodHandleTest.java @@ -2,7 +2,6 @@ import static com.itemis.fluffyj.tests.FluffyTestHelper.assertFinal; import static com.itemis.fluffyj.tests.FluffyTestHelper.assertNullArgNotAccepted; -import static java.lang.foreign.MemorySegment.allocateNative; import static java.lang.foreign.ValueLayout.ADDRESS; import static java.lang.invoke.MethodType.methodType; import static org.assertj.core.api.Assertions.assertThat; @@ -48,8 +47,8 @@ void setUp() throws Exception { libMock = mock(SymbolLookup.class); convSpy = spy(new CDataTypeConverter()); - var publicLookup = MethodHandles.publicLookup(); - var methodType = methodType(int.class); + final var publicLookup = MethodHandles.publicLookup(); + final var methodType = methodType(int.class); realMethodHandle = publicLookup.findVirtual(String.class, "length", methodType); when(linkerMock.link(any(), any())).thenReturn(realMethodHandle); @@ -62,31 +61,31 @@ void is_final() { @Test void test_correct_stage_order() { - var knownSymbol = "strlen"; + final var knownSymbol = "strlen"; addKnownSymbol(knownSymbol); - var firstStage = FluffyNativeMethodHandle.fromLib(libMock); + final var firstStage = FluffyNativeMethodHandle.fromLib(libMock); assertThat(firstStage).isInstanceOf(ReturnTypeStage.class); - var secondStage = firstStage.withLinker(linkerMock); + final var secondStage = firstStage.withLinker(linkerMock); assertThat(secondStage).isInstanceOf(LinkerStage.class); - var thirdStage = secondStage.withTypeConverter(convSpy); + final var thirdStage = secondStage.withTypeConverter(convSpy); assertThat(thirdStage).isInstanceOf(FuncStage.class); - var fourthStage = thirdStage.returnType(Integer.class); + final var fourthStage = thirdStage.returnType(Integer.class); assertThat(fourthStage).isInstanceOf(FuncStage.class); - var otherFourthStage = thirdStage.noReturnType(); + final var otherFourthStage = thirdStage.noReturnType(); assertThat(otherFourthStage).isInstanceOf(FuncStage.class); - var fifthStage = fourthStage.func(knownSymbol); + final var fifthStage = fourthStage.func(knownSymbol); assertThat(fifthStage).isInstanceOf(ArgsStage.class); - var sixthStage = fifthStage.args(ADDRESS); + final var sixthStage = fifthStage.args(ADDRESS); assertThat(sixthStage).isInstanceOf(FluffyNativeMethodHandle.class); - var otherSixthStage = fifthStage.noArgs(); + final var otherSixthStage = fifthStage.noArgs(); assertThat(otherSixthStage).isInstanceOf(FluffyNativeMethodHandle.class); } @@ -122,7 +121,7 @@ void does_not_accept_null_func() { @Test void func_loads_symbol_from_lib() { - var expectedSymbolName = "expectedSymbolName"; + final var expectedSymbolName = "expectedSymbolName"; addKnownSymbol(expectedSymbolName); FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) .returnType(Long.class) @@ -133,7 +132,7 @@ void func_loads_symbol_from_lib() { @Test void unknown_func_name_yields_exception() { - var unknownSymbol = "unknownSymbol"; + final var unknownSymbol = "unknownSymbol"; removeSymbol(unknownSymbol); assertThatThrownBy( @@ -146,7 +145,7 @@ void unknown_func_name_yields_exception() { @Test void returnType_calls_typeConverter() { - var returnType = long.class; + final var returnType = long.class; FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) .returnType(returnType); @@ -155,13 +154,13 @@ void returnType_calls_typeConverter() { @Test void cStdLib_shortcut_returns_correct_stage() { - var resultStage = FluffyNativeMethodHandle.fromCStdLib(); + final var resultStage = FluffyNativeMethodHandle.fromCStdLib(); assertThat(resultStage).isInstanceOf(ReturnTypeStage.class); } @Test void cLib_shortcut_returns_correct_stage() { - var resultStage = FluffyNativeMethodHandle.fromCLib(libMock); + final var resultStage = FluffyNativeMethodHandle.fromCLib(libMock); assertThat(resultStage).isInstanceOf(ReturnTypeStage.class); } @@ -179,10 +178,10 @@ void no_return_type_should_not_invoke_conv() { @Test void test_no_return_type() { - var knownSymbol = "knownSymbol"; + final var knownSymbol = "knownSymbol"; addKnownSymbol(knownSymbol); - var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) + final var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) .noReturnType().func(knownSymbol).noArgs(); assertThat(handle).isNotNull(); @@ -190,10 +189,10 @@ void test_no_return_type() { @Test void test_Void_return_type_no_args() { - var knownSymbol = "knownSymbol"; + final var knownSymbol = "knownSymbol"; addKnownSymbol(knownSymbol); - var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) + final var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) .returnType(Void.class).func(knownSymbol).args(); assertThat(handle).isNotNull(); @@ -201,21 +200,21 @@ void test_Void_return_type_no_args() { @Test void test_void_return_type_no_args() { - var knownSymbol = "knownSymbol"; + final var knownSymbol = "knownSymbol"; addKnownSymbol(knownSymbol); - var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) + final var handle = FluffyNativeMethodHandle.fromLib(libMock).withLinker(linkerMock).withTypeConverter(convSpy) .returnType(void.class).func(knownSymbol).args(); assertThat(handle).isNotNull(); } - private void addKnownSymbol(String symbolName) { - var seg = allocateNative(1, scope); + private void addKnownSymbol(final String symbolName) { + final var seg = arena.allocate(1); when(libMock.find(symbolName)).thenReturn(Optional.of(seg)); } - private void removeSymbol(String symbolName) { + private void removeSymbol(final String symbolName) { // The mock statement is required in order for eclipse to accept the next statement. // There seems to be a Java19 related bug wrt Mockito.when Mockito.mock(Supplier.class); diff --git a/src/test/java/com/itemis/fluffyj/memory/FunctionPointerTest.java b/src/test/java/com/itemis/fluffyj/memory/FunctionPointerTest.java index 40c377a..cba1c3c 100644 --- a/src/test/java/com/itemis/fluffyj/memory/FunctionPointerTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/FunctionPointerTest.java @@ -4,7 +4,7 @@ import static com.itemis.fluffyj.tests.FluffyTestHelper.assertFinal; import static com.itemis.fluffyj.tests.FluffyTestHelper.assertIsStaticHelper; import static com.itemis.fluffyj.tests.FluffyTestHelper.assertNullArgNotAccepted; -import static java.lang.foreign.SegmentScope.global; +import static java.lang.foreign.Arena.global; import static java.lang.foreign.ValueLayout.JAVA_BYTE; import static java.lang.foreign.ValueLayout.JAVA_CHAR; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -53,52 +53,52 @@ void builder_is_final() { @Test void test_correct_stage_order() { - var firstStage = pointer().toFunc(TEST_FUNC); + final var firstStage = pointer().toFunc(TEST_FUNC); assertThat(firstStage).isInstanceOf(FluffyMemoryFuncPointerBuilder.class); - var secondStage = firstStage.ofType(new TestType()); + final var secondStage = firstStage.ofType(new TestType()); assertThat(secondStage).isInstanceOf(TypeConverterStage.class); - var thirdStage = secondStage.withTypeConverter(new CDataTypeConverter()); + final var thirdStage = secondStage.withTypeConverter(new CDataTypeConverter()); assertThat(thirdStage).isInstanceOf(ArgsStage.class); - var otherFourthStage = thirdStage.withoutArgs(); + final var otherFourthStage = thirdStage.withoutArgs(); assertThat(otherFourthStage).isInstanceOf(ReturnTypeStage.class); - var fourthStage = thirdStage.withArgs(JAVA_BYTE); + final var fourthStage = thirdStage.withArgs(JAVA_BYTE); assertThat(fourthStage).isInstanceOf(ReturnTypeStage.class); - var otherFifthStage = fourthStage.andNoReturnType(); + final var otherFifthStage = fourthStage.andNoReturnType(); assertThat(otherFifthStage).isInstanceOf(BinderStage.class); - var fifthStage = fourthStage.andReturnType(JAVA_INT); + final var fifthStage = fourthStage.andReturnType(JAVA_INT); assertThat(fifthStage).isInstanceOf(BinderStage.class); - var sixthStage = fifthStage.bindTo(scope); + final var sixthStage = fifthStage.bindTo(arena); assertThat(sixthStage).isInstanceOf(MemorySegment.class); - var otherSixthStage = fifthStage.bindToGlobalScope(); + final var otherSixthStage = fifthStage.bindToGlobalArena(); assertThat(otherSixthStage).isInstanceOf(MemorySegment.class); } @Test void test_bind_to_void_method_with_no_args_use_shortcuts() { - var result = - pointer().toCFunc(NO_ARGS).of(new TestType()).withoutArgs().andNoReturnType().bindToGlobalScope(); + final var result = + pointer().toCFunc(NO_ARGS).of(new TestType()).withoutArgs().andNoReturnType().bindToGlobalArena(); assertThat(result).isNotNull(); } @Test void test_bind_to_void_method_with_no_args_dont_use_shortcuts() { - var result = + final var result = pointer().toCFunc(NO_ARGS).of(new TestType()).withArgs().andNoReturnType().bindTo(global()); assertThat(result).isNotNull(); } @Test void when_manual_bind_unknown_method_then_throw_exception() { - var methodName = "unknownMethod"; + final var methodName = "unknownMethod"; assertThatThrownBy( () -> pointer().toCFunc(methodName).of(this).withArgs().andNoReturnType().bindTo(global())) .isInstanceOf(FluffyMemoryException.class) @@ -108,31 +108,31 @@ void when_manual_bind_unknown_method_then_throw_exception() { @Test void when_manual_bind_private_method_then_throw_exception() { - var methodName = "privateMethod"; + final var methodName = "privateMethod"; assertThatThrownBy( - () -> pointer().toCFunc(methodName).of(new TestType()).withArgs().andNoReturnType().bindToGlobalScope()) + () -> pointer().toCFunc(methodName).of(new TestType()).withArgs().andNoReturnType().bindToGlobalArena()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot create function pointer to non accessible JVM methods."); } @Test void when_manual_bind_synthetic_method_then_throw_exception() { - var methodName = "compare"; + final var methodName = "compare"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new BridgeMethodDemo()).withoutArgs() - .andNoReturnType().bindTo(scope)) + .andNoReturnType().bindTo(arena)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot create function pointer to synthetic JVM methods."); } @Test void test_auto_bind_happy_path() { - var result = pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBind(); + final var result = pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBind(); assertThat(result).isNotNull(); } @Test void test_auto_bind_happy_path_custom_scope() { - var result = pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBindTo(scope); + final var result = pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBindTo(arena); assertThat(result.scope().isAlive()).isTrue(); @@ -143,7 +143,7 @@ void test_auto_bind_happy_path_custom_scope() { @Test void test_auto_bind_no_args_no_return_type() { - var result = pointer().toCFunc(NO_ARGS).of(new TestType()).autoBind(); + final var result = pointer().toCFunc(NO_ARGS).of(new TestType()).autoBind(); assertThat(result).isNotNull(); } @@ -157,7 +157,7 @@ void test_auto_bind_Void_return_type() { @Test void when_auto_bind_overloaded_method_then_throw_exception() { - var methodName = "overloadedMethod"; + final var methodName = "overloadedMethod"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new MethodOverloaded()).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot autobind overloaded method '" + methodName + "'. Please perform manual bind."); @@ -165,7 +165,7 @@ void when_auto_bind_overloaded_method_then_throw_exception() { @Test void when_auto_bind_unknown_method_then_throw_exception() { - var methodName = "unknownMethod"; + final var methodName = "unknownMethod"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(this).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Could not find method '" + methodName + "' in type " + this.getClass().getCanonicalName()); @@ -173,7 +173,7 @@ void when_auto_bind_unknown_method_then_throw_exception() { @Test void when_auto_bind_method_with_unsupported_args_then_throw_exception() { - var methodName = "unsupportedArgs"; + final var methodName = "unsupportedArgs"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new TestType()).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Method '" + methodName + "' of type " + TestType.class.getCanonicalName() @@ -184,7 +184,7 @@ void when_auto_bind_method_with_unsupported_args_then_throw_exception() { @Test void when_auto_bind_method_with_unsupported_returnType_then_throw_exception() { - var methodName = "unsupportedReturnType"; + final var methodName = "unsupportedReturnType"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new TestType()).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Method '" + methodName + "' of type " + TestType.class.getCanonicalName() @@ -195,7 +195,7 @@ void when_auto_bind_method_with_unsupported_returnType_then_throw_exception() { @Test void when_auto_bind_synthetic_method_then_throw_exception() { - var methodName = "compare"; + final var methodName = "compare"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new BridgeMethodDemo()).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot create function pointer to synthetic JVM methods."); @@ -203,7 +203,7 @@ void when_auto_bind_synthetic_method_then_throw_exception() { @Test void when_auto_bind_private_method_then_throw_exception() { - var methodName = "privateMethod"; + final var methodName = "privateMethod"; assertThatThrownBy(() -> pointer().toCFunc(methodName).of(new TestType()).autoBind()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot create function pointer to non accessible JVM methods."); @@ -226,7 +226,7 @@ void toCFunc_of__returns_argsStage() { @Test void withArgs_uses_typeConv() { - var testArg = JAVA_CHAR; + final var testArg = JAVA_CHAR; pointer().toFunc(TEST_FUNC).ofType(new TestType()).withTypeConverter(convMock).withArgs(testArg); verify(convMock).getJvmTypes(testArg); @@ -234,15 +234,15 @@ void withArgs_uses_typeConv() { @Test void autoBindTo_uses_typeConv() { - var convSpy = spy(new CDataTypeConverter()); - pointer().toFunc(TEST_FUNC).ofType(new TestType()).withTypeConverter(convSpy).autoBindTo(scope); + final var convSpy = spy(new CDataTypeConverter()); + pointer().toFunc(TEST_FUNC).ofType(new TestType()).withTypeConverter(convSpy).autoBindTo(arena); verify(convSpy).getNativeTypes(any()); } @Test void andReturnType_uses_typeConv() { - var testReturnType = JAVA_INT; + final var testReturnType = JAVA_INT; pointer().toFunc(TEST_FUNC).ofType(new TestType()).withTypeConverter(convMock).withoutArgs() .andReturnType(testReturnType); @@ -291,7 +291,7 @@ void withArgs_does_not_accept_null() { @Test void autoBindTo_does_not_accept_null() { - assertNullArgNotAccepted(() -> pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBindTo(null), "scope"); + assertNullArgNotAccepted(() -> pointer().toCFunc(TEST_FUNC).of(new TestType()).autoBindTo(null), "arena"); } @Test @@ -303,7 +303,7 @@ void andReturnType_does_not_accept_null() { @Test void bindTo_does_not_accept_null() { assertNullArgNotAccepted( - () -> pointer().toCFunc(TEST_FUNC).of(TEST_FUNC).withoutArgs().andNoReturnType().bindTo(null), "scope"); + () -> pointer().toCFunc(TEST_FUNC).of(TEST_FUNC).withoutArgs().andNoReturnType().bindTo(null), "arena"); } // Will only be used to bind a MethodType in a test @@ -311,7 +311,7 @@ void bindTo_does_not_accept_null() { private static final class MethodOverloaded { void overloadedMethod() {} - int overloadedMethod(int arg) { + int overloadedMethod(final int arg) { return -1; } } @@ -319,9 +319,9 @@ int overloadedMethod(int arg) { // Will only be used to bind a MethodType in a test @SuppressWarnings("unused") private static final class TestType { - private String field = "a synthetic getter will be created for this field as soon as it is accessed"; + private final String field = "a synthetic getter will be created for this field as soon as it is accessed"; - int testFunc(byte arg) { + int testFunc(final byte arg) { return 0; } @@ -331,7 +331,7 @@ Void returnTypeIsObjectVoid() { void noArgs() {} - void unsupportedArgs(String unsupportedArg) {} + void unsupportedArgs(final String unsupportedArg) {} String unsupportedReturnType() { return null; @@ -342,7 +342,7 @@ private void privateMethod() {} public class BridgeMethodDemo implements Comparator { @Override - public int compare(Integer o1, Integer o2) { + public int compare(final Integer o1, final Integer o2) { return 0; } } diff --git a/src/test/java/com/itemis/fluffyj/memory/PointerBasicsTest.java b/src/test/java/com/itemis/fluffyj/memory/PointerBasicsTest.java index 12d5d98..a74f13f 100644 --- a/src/test/java/com/itemis/fluffyj/memory/PointerBasicsTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/PointerBasicsTest.java @@ -2,8 +2,7 @@ import static com.itemis.fluffyj.memory.FluffyMemory.pointer; import static com.itemis.fluffyj.tests.FluffyTestHelper.assertNullArgNotAccepted; -import static java.lang.foreign.SegmentAllocator.nativeAllocator; -import static java.lang.foreign.SegmentScope.global; +import static java.lang.foreign.Arena.global; import static java.lang.foreign.ValueLayout.JAVA_BYTE; import static java.lang.foreign.ValueLayout.JAVA_INT; import static java.lang.foreign.ValueLayout.JAVA_LONG; @@ -35,7 +34,7 @@ void allocate_scalar_pointer_with_unknown_type_yields_exception() { @Test void allocate_scalar_pointer_and_scope_with_unknown_type_yields_exception() { - assertThatThrownBy(() -> pointer().to(0L).as(MyType.class).allocate(scope)) + assertThatThrownBy(() -> pointer().to(0L).as(MyType.class).allocate(arena)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot allocate scalar pointer of unknown type: " + MyType.class.getCanonicalName()); } @@ -49,32 +48,32 @@ void allocate_vector_pointer_with_unknown_type_yields_exception() { @Test void allocate_vector_pointer_and_scope_with_unknown_type_yields_exception() { - assertThatThrownBy(() -> pointer().to(0L).asArray(1).of(MyType[].class).allocate(scope)) + assertThatThrownBy(() -> pointer().to(0L).asArray(1).of(MyType[].class).allocate(arena)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot allocate vector pointer of unknown type: " + MyType[].class.getCanonicalName()); } @Test void to_null_seg_yields_npe() { - var underTest = new FluffyMemoryPointerBuilder(); + final var underTest = new FluffyMemoryPointerBuilder(); assertNullArgNotAccepted(() -> underTest.to((FluffyScalarSegment) null), "toHere"); } @Test void to_null_array_seg_yields_npe() { - var underTest = new FluffyMemoryPointerBuilder(); + final var underTest = new FluffyMemoryPointerBuilder(); assertNullArgNotAccepted(() -> underTest.toArray((FluffyVectorSegment) null), "toHere"); } @Test void can_create_empty_pointer() { - var result = pointer().allocate(); + final var result = pointer().allocate(); assertThat(result).isInstanceOf(FluffyPointer.class); } @Test void can_create_scoped_empty_pointer() { - var result = pointer().allocate(scope); + final var result = pointer().allocate(arena); assertThat(result).isInstanceOf(FluffyPointer.class); } @@ -85,18 +84,18 @@ void empty_pointer_creation_does_not_accept_null_scope() { @ParameterizedTest @MethodSource("typeMappings") - void dereference_should_support_known_types(MemorySegment dataSeg, Class inputType, - Class expectedOutputType) { - var actualOutputType = FluffyMemory.dereference(dataSeg).as(inputType); + void dereference_should_support_known_types(final MemorySegment dataSeg, final Class inputType, + final Class expectedOutputType) { + final var actualOutputType = FluffyMemory.dereference(dataSeg).as(inputType); assertThat(actualOutputType.getClass()).isEqualTo(expectedOutputType); } private static Stream typeMappings() { - var longSeg = nativeAllocator(global()).allocate(JAVA_LONG, 123L); - var intSeg = nativeAllocator(global()).allocate(JAVA_INT, 123); - var byteSeg = nativeAllocator(global()).allocate(JAVA_BYTE, (byte) 123); - var stringSeg = nativeAllocator(global()).allocateUtf8String("123"); + final var longSeg = global().allocate(JAVA_LONG, 123L); + final var intSeg = global().allocate(JAVA_INT, 123); + final var byteSeg = global().allocate(JAVA_BYTE, (byte) 123); + final var stringSeg = global().allocateUtf8String("123"); return Stream.of( Arguments.of(longSeg, long.class, Long.class), diff --git a/src/test/java/com/itemis/fluffyj/memory/PointerOfThingTest.java b/src/test/java/com/itemis/fluffyj/memory/PointerOfThingTest.java index 8f6a12b..05d066e 100644 --- a/src/test/java/com/itemis/fluffyj/memory/PointerOfThingTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/PointerOfThingTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; import java.lang.foreign.ValueLayout; import java.util.Random; @@ -17,12 +16,12 @@ public class PointerOfThingTest extends MemoryScopeEnabledTest { @Test void constructor_does_not_accept_null_scope() { - assertNullArgNotAccepted(() -> new PointerOfThing(null), "scope"); + assertNullArgNotAccepted(() -> new PointerOfThing(null), "arena"); } @Test void is_alive_is_tied_to_scope() { - var underTest = new PointerOfThing(scope); + final var underTest = new PointerOfThing(arena); assertThat(underTest.isAlive()).isTrue(); arena.close(); @@ -31,56 +30,57 @@ void is_alive_is_tied_to_scope() { @Test void rawAddress_returns_a_value() { - var underTest = new PointerOfThing(scope); + final var underTest = new PointerOfThing(arena); assertThat(underTest.rawAddress()).isInstanceOf(Long.class); } @Test void address_returns_a_value() { - var underTest = new PointerOfThing(scope); + final var underTest = new PointerOfThing(arena); assertThat(underTest.address()).isInstanceOf(MemorySegment.class); } @Test void address_rawAddress_equality() { - var underTest = new PointerOfThing(scope); + final var underTest = new PointerOfThing(arena); assertThat(underTest.address().address()).isEqualTo(underTest.rawAddress()); } @Test void getRawValue_returns_a_value_that_is_not_pointers_address() { - var underTest = new PointerOfThing(scope); - var rawValue = underTest.getRawValue(); + final var underTest = new PointerOfThing(arena); + final var rawValue = underTest.getRawValue(); assertThat(rawValue).isInstanceOf(Long.class); assertThat(rawValue).isNotSameAs(underTest.rawAddress()); } @Test void getValue_returns_a_value_that_is_not_pointers_address() { - var underTest = new PointerOfThing(scope); - var value = underTest.getValue(); + final var underTest = new PointerOfThing(arena); + final var value = underTest.getValue(); assertThat(value).isInstanceOf(MemorySegment.class); assertThat(value).isNotSameAs(underTest.address()); } @Test void getValue_of_a_freshly_instantiated_pointer_returns_zero() { - var underTest = new PointerOfThing(scope); - var value = underTest.getValue(); + final var underTest = new PointerOfThing(arena); + final var value = underTest.getValue(); assertThat(value.address()).isEqualTo(0); } @Test void rawDereference_returns_segment_pointed_to() { - var underTest = new PointerOfThing(scope); + final var underTest = new PointerOfThing(arena); - var expectedVal = new Random().nextInt(); - var nativeSeg = SegmentAllocator.nativeAllocator(scope).allocate(ValueLayout.JAVA_INT, expectedVal); - var underTestAsFfmSeg = - MemorySegment.ofAddress(underTest.rawAddress(), ValueLayout.ADDRESS.asUnbounded().byteSize(), scope); + final var expectedVal = new Random().nextInt(); + final var nativeSeg = arena.allocate(ValueLayout.JAVA_INT, expectedVal); + final var underTestAsFfmSeg = + underTest.getValue(); underTestAsFfmSeg.set(ValueLayout.JAVA_LONG, 0, nativeSeg.address()); - var result = underTest.rawDereference(); + underTestAsFfmSeg.get(ValueLayout.JAVA_LONG, 0); + final var result = underTest.rawDereference(); assertThat(result.get(ValueLayout.JAVA_INT, 0)).isEqualTo(expectedVal); } diff --git a/src/test/java/com/itemis/fluffyj/memory/RealWorldScenariosTest.java b/src/test/java/com/itemis/fluffyj/memory/RealWorldScenariosTest.java index 00e68f6..40c3106 100644 --- a/src/test/java/com/itemis/fluffyj/memory/RealWorldScenariosTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/RealWorldScenariosTest.java @@ -5,7 +5,6 @@ import static com.itemis.fluffyj.memory.FluffyMemory.wrap; import static com.itemis.fluffyj.memory.FluffyNativeMethodHandle.fromCStdLib; import static java.lang.foreign.Linker.nativeLinker; -import static java.lang.foreign.SegmentAllocator.nativeAllocator; import static java.lang.foreign.ValueLayout.ADDRESS; import static java.lang.foreign.ValueLayout.JAVA_INT; import static java.util.Arrays.sort; @@ -33,11 +32,11 @@ public class RealWorldScenariosTest extends MemoryScopeEnabledTest { @Test void can_call_strlen_with_address_of_string_seg() { - var expectedStringLength = new Random().nextInt(MAX_RND_STR_LENGTH); - var rndStr = randomAlphanumeric(expectedStringLength); + final var expectedStringLength = new Random().nextInt(MAX_RND_STR_LENGTH); + final var rndStr = randomAlphanumeric(expectedStringLength); - var cStr = new StringSegment(rndStr, scope); - var ptrCStr = new PointerOfString(cStr.rawAddress(), scope); + final var cStr = new StringSegment(rndStr, arena); + final var ptrCStr = new PointerOfString(cStr.rawAddress(), arena); assertThat(strlen(cStr.address())).isEqualTo(expectedStringLength); assertThat(strlen(ptrCStr.getValue())).isEqualTo(expectedStringLength); @@ -45,13 +44,13 @@ void can_call_strlen_with_address_of_string_seg() { @Test void can_call_strlen_with_results_of_fluffy_memory_builder() { - var expectedStringLength = new Random().nextInt(MAX_RND_STR_LENGTH); - var rndStr = randomAlphanumeric(expectedStringLength); + final var expectedStringLength = new Random().nextInt(MAX_RND_STR_LENGTH); + final var rndStr = randomAlphanumeric(expectedStringLength); - var cStr = segment().of(rndStr).allocate(scope); - var ptrCStr = pointer().to(cStr).allocate(scope); - var strSeg = nativeAllocator(scope).allocateUtf8String(rndStr); - var wrappedStrSeg = wrap(strSeg).as(String.class); + final var cStr = segment().of(rndStr).allocate(arena); + final var ptrCStr = pointer().to(cStr).allocate(arena); + final var strSeg = arena.allocateUtf8String(rndStr); + final var wrappedStrSeg = wrap(strSeg).as(String.class); assertThat(strlen(cStr.address())).isEqualTo(expectedStringLength); assertThat(strlen(ptrCStr.getValue())).isEqualTo(expectedStringLength); @@ -60,14 +59,15 @@ void can_call_strlen_with_results_of_fluffy_memory_builder() { @Test void call_throws_exception_when_error_is_encountered() { - var underTest = + final var underTest = FluffyNativeMethodHandle .fromCStdLib() .returnType(long.class) .func("strlen") .args(ADDRESS); - var expectedCause = new WrongMethodTypeException("cannot convert MethodHandle(MemorySegment)long to ()Object"); + final var expectedCause = + new WrongMethodTypeException("cannot convert MethodHandle(MemorySegment)long to ()Object"); assertThatThrownBy(() -> underTest.call()) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Calling native code failed: " + ThrowablePrettyfier.pretty(expectedCause)) @@ -76,28 +76,28 @@ void call_throws_exception_when_error_is_encountered() { @Test void handle_construction_via_shortcut_works() { - var testStr = "testString"; - var ptr = segment().of(testStr).allocate(scope).address(); + final var testStr = "testString"; + final var ptr = segment().of(testStr).allocate(arena).address(); assertThat(strlen_shortcut_construction(ptr)).isEqualTo(testStr.length()); } @Test void test_qsort() { - var primitiveBuf = new byte[new Random().nextInt(MAX_RND_STR_LENGTH) + 1]; + final var primitiveBuf = new byte[new Random().nextInt(MAX_RND_STR_LENGTH) + 1]; new Random().nextBytes(primitiveBuf); - var buf = toObject(primitiveBuf); + final var buf = toObject(primitiveBuf); - var expectedResult = toObject(primitiveBuf); + final var expectedResult = toObject(primitiveBuf); sort(expectedResult); - var bufSeg = segment().ofArray(buf).allocate(); - var qsort = fromCStdLib() + final var bufSeg = segment().ofArray(buf).allocate(); + final var qsort = fromCStdLib() .noReturnType() .func("qsort") .args(ADDRESS, JAVA_INT, JAVA_INT, ADDRESS); - var autoCompar = createComparPointerAuto(); - var manualCompar = createComparPointerManual(); + final var autoCompar = createComparPointerAuto(); + final var manualCompar = createComparPointerManual(); qsort.call(bufSeg.address(), buf.length, 1, autoCompar); var actualResult = bufSeg.getValue(); @@ -112,7 +112,7 @@ private MemorySegment createComparPointerAuto() { return pointer() .toCFunc("qsort_compar") .of(this) - .autoBindTo(scope); + .autoBindTo(arena); } private MemorySegment createComparPointerManual() { @@ -122,12 +122,12 @@ private MemorySegment createComparPointerManual() { .withTypeConverter(new CDataTypeConverter()) .withArgs(ADDRESS, ADDRESS) .andReturnType(JAVA_INT) - .bindTo(scope); + .bindTo(arena); } - int qsort_compar(MemorySegment left, MemorySegment right) { - var leftByte = wrap(left).asPointerOf(Byte.class).allocate(scope).dereference(); - var rightByte = wrap(right).asPointerOf(Byte.class).allocate(scope).dereference(); + int qsort_compar(final MemorySegment left, final MemorySegment right) { + final var leftByte = wrap(left).asPointerOf(Byte.class).allocate(arena).dereference(); + final var rightByte = wrap(right).asPointerOf(Byte.class).allocate(arena).dereference(); var result = 0; if (leftByte < rightByte) { result = -1; @@ -137,8 +137,8 @@ int qsort_compar(MemorySegment left, MemorySegment right) { return result; } - private long strlen_shortcut_construction(MemorySegment pointerToString) { - var underTest = + private long strlen_shortcut_construction(final MemorySegment pointerToString) { + final var underTest = FluffyNativeMethodHandle .fromCStdLib() .returnType(long.class) @@ -148,8 +148,8 @@ private long strlen_shortcut_construction(MemorySegment pointerToString) { return underTest.call(pointerToString); } - private long strlen(MemorySegment pointerToString) { - var underTest = + private long strlen(final MemorySegment pointerToString) { + final var underTest = FluffyNativeMethodHandle .fromLib(nativeLinker().defaultLookup()) .withLinker((symbol, srcFuncType) -> nativeLinker().downcallHandle(symbol, srcFuncType)) diff --git a/src/test/java/com/itemis/fluffyj/memory/SegmentBasicsTest.java b/src/test/java/com/itemis/fluffyj/memory/SegmentBasicsTest.java index d1e213b..b7a4025 100644 --- a/src/test/java/com/itemis/fluffyj/memory/SegmentBasicsTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/SegmentBasicsTest.java @@ -3,7 +3,6 @@ import static com.itemis.fluffyj.memory.FluffyMemory.segment; import static com.itemis.fluffyj.memory.FluffyMemory.wrap; import static com.itemis.fluffyj.tests.FluffyTestHelper.assertNullArgNotAccepted; -import static java.lang.foreign.MemorySegment.allocateNative; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -27,22 +26,22 @@ class SegmentBasicsTest extends MemoryScopeEnabledTest { @BeforeEach void setUp() { - nativeSeg = allocateNative(1, scope); + nativeSeg = arena.allocate(1); } @Test void address_rawAddress_equality() { - var segment = new FluffyMemoryScalarSegmentAllocator<>("test").allocate(scope); + final var segment = new FluffyMemoryScalarSegmentAllocator<>("test").allocate(arena); assertThat(segment.address().address()).isEqualTo(segment.rawAddress()); } @Test void allocate_with_null_yields_npe() { - var pointerAlloc = new FluffyMemoryScalarPointerAllocator<>(0L, Object.class); - assertNullArgNotAccepted(() -> pointerAlloc.allocate(null), "scope"); + final var pointerAlloc = new FluffyMemoryScalarPointerAllocator<>(0L, Object.class); + assertNullArgNotAccepted(() -> pointerAlloc.allocate(null), "arena"); - var segmentAlloc = new FluffyMemoryScalarSegmentAllocator<>(0L); - assertNullArgNotAccepted(() -> segmentAlloc.allocate(null), "scope"); + final var segmentAlloc = new FluffyMemoryScalarSegmentAllocator<>(0L); + assertNullArgNotAccepted(() -> segmentAlloc.allocate(null), "arena"); } @Test @@ -54,14 +53,14 @@ void allocate_scalar_seg_with_unknown_type_yields_exception() { @Test void allocate_scalar_seg_with_scope_and_unknown_type_yields_exception() { - assertThatThrownBy(() -> segment().of(new MyType()).allocate(scope)) + assertThatThrownBy(() -> segment().of(new MyType()).allocate(arena)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot allocate scalar segment of unknown type: " + MyType.class.getCanonicalName()); } @Test void allocate_vector_seg_with_scope_and_unknown_type_yields_exception() { - assertThatThrownBy(() -> segment().ofArray(new MyType[0]).allocate(scope)) + assertThatThrownBy(() -> segment().ofArray(new MyType[0]).allocate(arena)) .isInstanceOf(FluffyMemoryException.class) .hasMessage( "Cannot allocate vector segment of unknown type: " + MyType.class.arrayType().getCanonicalName()); @@ -78,13 +77,13 @@ void allocate_vector_seg_with_unknown_type_yields_exception() { @Test void to_null_seg_yields_npe() { - var underTest = new FluffyMemoryPointerBuilder(); + final var underTest = new FluffyMemoryPointerBuilder(); assertNullArgNotAccepted(() -> underTest.to((FluffyScalarSegment) null), "toHere"); } @Test void to_null_array_seg_yields_npe() { - var underTest = new FluffyMemoryPointerBuilder(); + final var underTest = new FluffyMemoryPointerBuilder(); assertNullArgNotAccepted(() -> underTest.toArray((FluffyVectorSegment) null), "toHere"); } @@ -117,8 +116,8 @@ void wrap_to_unknown_vector_type_yields_exception() { @ParameterizedTest @MethodSource("typeMappings") - void wrap_should_support_known_types(Class inputType, Class expectedOutputType) { - var actualOutputType = wrap(nativeSeg).as(inputType).getContainedType(); + void wrap_should_support_known_types(final Class inputType, final Class expectedOutputType) { + final var actualOutputType = wrap(nativeSeg).as(inputType).getContainedType(); assertThat(actualOutputType).isEqualTo(expectedOutputType); } diff --git a/src/test/java/com/itemis/fluffyj/memory/StringManipulationTest.java b/src/test/java/com/itemis/fluffyj/memory/StringManipulationTest.java index 392efc2..b27cea1 100644 --- a/src/test/java/com/itemis/fluffyj/memory/StringManipulationTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/StringManipulationTest.java @@ -6,8 +6,7 @@ import com.itemis.fluffyj.memory.tests.FluffyMemoryScalarTestValue; import com.itemis.fluffyj.memory.tests.FluffyScalarDataManipulationTest; -import java.lang.foreign.SegmentAllocator; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.Arena; import java.lang.foreign.ValueLayout; public class StringManipulationTest extends FluffyScalarDataManipulationTest { @@ -18,9 +17,9 @@ protected StringManipulationTest() { super(new FluffyMemoryScalarTestValueIterator() { @Override public FluffyMemoryScalarTestValue next() { - var typedValue = randomAlphanumeric(RND_STR_LENGTH); - var cString = SegmentAllocator.nativeAllocator(SegmentScope.auto()).allocateUtf8String(typedValue); - var rawValue = new byte[(int) cString.byteSize()]; + final var typedValue = randomAlphanumeric(RND_STR_LENGTH); + final var cString = Arena.ofAuto().allocateUtf8String(typedValue); + final var rawValue = new byte[(int) cString.byteSize()]; cString.asByteBuffer().get(rawValue); return new FluffyMemoryScalarTestValue<>(typedValue, rawValue); } diff --git a/src/test/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverterTest.java b/src/test/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverterTest.java index 23d735c..eae2a83 100644 --- a/src/test/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverterTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/internal/impl/CDataTypeConverterTest.java @@ -39,17 +39,17 @@ void setUp() { @ParameterizedTest @MethodSource("expectedTypeMappings") - void native_type_to_jvm_type_and_back(Class jvmInputType, MemoryLayout expectedNativeType, - Class expectedJvmType) { - var actualNativeType = underTest.getNativeType(jvmInputType); + void native_type_to_jvm_type_and_back(final Class jvmInputType, final MemoryLayout expectedNativeType, + final Class expectedJvmType) { + final var actualNativeType = underTest.getNativeType(jvmInputType); assertThat(actualNativeType).isEqualTo(expectedNativeType); assertThat(underTest.getJvmType(actualNativeType)).isEqualTo(expectedJvmType); } @Test void native_type_to_jvm_type_and_back_special_address_case() { - var actualNativeType = underTest.getNativeType(MemorySegment.class); - assertThat(actualNativeType).isEqualTo(ValueLayout.ADDRESS.asUnbounded()); + final var actualNativeType = underTest.getNativeType(MemorySegment.class); + assertThat(actualNativeType).isEqualTo(ValueLayout.ADDRESS); assertThat(underTest.getJvmType(ValueLayout.ADDRESS)).isEqualTo(MemorySegment.class); } @@ -60,7 +60,7 @@ void JVM_type_of_pointer_is_memory_segment() { @Test void memory_layout_of_unknown_type_yields_exception() { - var unknownType = Object.class; + final var unknownType = Object.class; assertThatThrownBy(() -> underTest.getNativeType(unknownType)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot provide native memory layout for JVM type " + unknownType.getCanonicalName()); @@ -68,7 +68,7 @@ void memory_layout_of_unknown_type_yields_exception() { @Test void JVM_type_of_unknown_memory_layout_yields_exception() { - var unknownMemoryLayout = sequenceLayout(3, JAVA_INT); + final var unknownMemoryLayout = sequenceLayout(3, JAVA_INT); assertThatThrownBy(() -> underTest.getJvmType(unknownMemoryLayout)) .isInstanceOf(FluffyMemoryException.class) @@ -77,7 +77,8 @@ void JVM_type_of_unknown_memory_layout_yields_exception() { @ParameterizedTest @MethodSource("expectedTypeMappings") - void jvmTypes_returns_correct_types(Class unused, MemoryLayout input, Class expectedOutput) { + void jvmTypes_returns_correct_types(final Class unused, final MemoryLayout input, + final Class expectedOutput) { assertThat(underTest.getJvmTypes(input)).isEqualTo(new Class[] {expectedOutput}); } @@ -130,7 +131,8 @@ void nativeTypes_with_null_yields_npe() { @ParameterizedTest @MethodSource("expectedTypeMappings") - void nativeTypes_with_one_type_yields_correct_type(Class input, MemoryLayout expectedOutput, Class unused) { + void nativeTypes_with_one_type_yields_correct_type(final Class input, final MemoryLayout expectedOutput, + final Class unused) { assertThat(underTest.getNativeTypes(input)).hasOnlyOneElementSatisfying(elm -> elm.equals(expectedOutput)); } @@ -142,7 +144,7 @@ void nativeTypes_returns_converted_types_in_correct_order() { @Test void nativeTypes_throws_exception_on_unknown_type() { - var unknownJvmType = String.class; + final var unknownJvmType = String.class; assertThatThrownBy(() -> underTest.getNativeTypes(long.class, unknownJvmType, double.class)) .isInstanceOf(FluffyMemoryException.class) .hasMessage("Cannot provide native memory layout for JVM type " + unknownJvmType.getCanonicalName()); @@ -164,6 +166,6 @@ private static Stream expectedTypeMappings() { Arguments.of(Short.class, JAVA_SHORT, short.class), Arguments.of(byte.class, JAVA_BYTE, byte.class), Arguments.of(Byte.class, JAVA_BYTE, byte.class), - Arguments.of(MemorySegment.class, ADDRESS.asUnbounded(), MemorySegment.class)); + Arguments.of(MemorySegment.class, ADDRESS, MemorySegment.class)); } } diff --git a/src/test/java/com/itemis/fluffyj/memory/tests/FluffyScalarDataManipulationTest.java b/src/test/java/com/itemis/fluffyj/memory/tests/FluffyScalarDataManipulationTest.java index 434def8..b068857 100644 --- a/src/test/java/com/itemis/fluffyj/memory/tests/FluffyScalarDataManipulationTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/tests/FluffyScalarDataManipulationTest.java @@ -4,7 +4,6 @@ import static com.itemis.fluffyj.memory.FluffyMemory.pointer; import static com.itemis.fluffyj.memory.FluffyMemory.segment; import static com.itemis.fluffyj.memory.FluffyMemory.wrap; -import static java.lang.foreign.MemorySegment.allocateNative; import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; @@ -16,9 +15,9 @@ import org.junit.jupiter.api.Test; +import java.lang.foreign.Arena; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; import java.util.Iterator; @@ -29,8 +28,8 @@ public abstract class FluffyScalarDataManipulationTest extends MemoryScopeEna private final FluffyMemoryScalarTestValue firstTestValue; private final Class testValueType; - protected FluffyScalarDataManipulationTest(Iterator> testValueIter, - MemoryLayout segmentLayout) { + protected FluffyScalarDataManipulationTest(final Iterator> testValueIter, + final MemoryLayout segmentLayout) { this.testValueIter = requireNonNull(testValueIter, "testValueIter"); this.segmentLayout = requireNonNull(segmentLayout, "segmentLayout"); this.firstTestValue = testValueIter.next(); @@ -39,28 +38,28 @@ protected FluffyScalarDataManipulationTest(Iterator allocateSeg() { return segment().of(firstTestValue.typedValue()).allocate(); } - protected final FluffyScalarSegment allocateScopedSeg(SegmentScope scope) { - return segment().of(firstTestValue.typedValue()).allocate(scope); + protected final FluffyScalarSegment allocateScopedSeg(final Arena arena) { + return segment().of(firstTestValue.typedValue()).allocate(arena); } - protected final FluffyScalarSegment wrapNativeSeg(MemorySegment nativeSeg) { + protected final FluffyScalarSegment wrapNativeSeg(final MemorySegment nativeSeg) { return wrap(nativeSeg).as(testValueType); } - protected final FluffyScalarPointer allocatePointer(long address) { + protected final FluffyScalarPointer allocatePointer(final long address) { return pointer().to(address).as(testValueType).allocate(); } - protected final FluffyScalarPointer allocateScopedPointer(long address, - SegmentScope scope) { - return pointer().to(address).as(testValueType).allocate(scope); + protected final FluffyScalarPointer allocateScopedPointer(final long address, + final Arena arena) { + return pointer().to(address).as(testValueType).allocate(arena); } - protected final FluffyScalarPointer allocatePointer(FluffyScalarSegment seg) { + protected final FluffyScalarPointer allocatePointer(final FluffyScalarSegment seg) { return pointer().to(seg).allocate(); } diff --git a/src/test/java/com/itemis/fluffyj/memory/tests/FluffyVectorDataManipulationTest.java b/src/test/java/com/itemis/fluffyj/memory/tests/FluffyVectorDataManipulationTest.java index 19b9789..84a1c31 100644 --- a/src/test/java/com/itemis/fluffyj/memory/tests/FluffyVectorDataManipulationTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/tests/FluffyVectorDataManipulationTest.java @@ -3,7 +3,6 @@ import static com.itemis.fluffyj.memory.FluffyMemory.pointer; import static com.itemis.fluffyj.memory.FluffyMemory.segment; import static com.itemis.fluffyj.memory.FluffyMemory.wrap; -import static java.lang.foreign.MemorySegment.allocateNative; import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; @@ -14,9 +13,9 @@ import org.junit.jupiter.api.Test; +import java.lang.foreign.Arena; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentScope; import java.lang.foreign.ValueLayout; import java.util.Iterator; @@ -27,8 +26,8 @@ public abstract class FluffyVectorDataManipulationTest extends MemoryScopeEna private final FluffyMemoryVectorTestValue firstTestValue; private final Class testValueType; - protected FluffyVectorDataManipulationTest(Iterator> testValueIter, - MemoryLayout segmentLayout) { + protected FluffyVectorDataManipulationTest(final Iterator> testValueIter, + final MemoryLayout segmentLayout) { this.testValueIter = requireNonNull(testValueIter, "testValueIter"); this.segmentLayout = requireNonNull(segmentLayout, "segmentLayout"); this.firstTestValue = testValueIter.next(); @@ -37,28 +36,28 @@ protected FluffyVectorDataManipulationTest(Iterator allocateSeg() { return segment().ofArray(firstTestValue.typedValue()).allocate(); } - protected final FluffyVectorSegment allocateScopeSeg(SegmentScope scope) { - return segment().ofArray(firstTestValue.typedValue()).allocate(scope); + protected final FluffyVectorSegment allocateScopedSeg(final Arena arena) { + return segment().ofArray(firstTestValue.typedValue()).allocate(arena); } - protected final FluffyVectorSegment wrapNativeSeg(MemorySegment nativeSeg) { + protected final FluffyVectorSegment wrapNativeSeg(final MemorySegment nativeSeg) { return wrap(nativeSeg).asArray(testValueType); } - protected final FluffyVectorPointer allocatePointer(long address) { + protected final FluffyVectorPointer allocatePointer(final long address) { return pointer().to(address).asArray(firstTestValue.length()).of(testValueType).allocate(); } - protected final FluffyVectorPointer allocateScopePointer(long address, - SegmentScope scope) { - return pointer().to(address).asArray(firstTestValue.length()).of(testValueType).allocate(scope); + protected final FluffyVectorPointer allocateScopedPointer(final long address, + final Arena arena) { + return pointer().to(address).asArray(firstTestValue.length()).of(testValueType).allocate(arena); } - protected final FluffyVectorPointer allocatePointer(FluffyVectorSegment seg) { + protected final FluffyVectorPointer allocatePointer(final FluffyVectorSegment seg) { return pointer().toArray(seg).allocate(); } diff --git a/src/test/java/com/itemis/fluffyj/memory/tests/MemoryScopeEnabledTest.java b/src/test/java/com/itemis/fluffyj/memory/tests/MemoryScopeEnabledTest.java index 9f747c0..ae7ddc0 100644 --- a/src/test/java/com/itemis/fluffyj/memory/tests/MemoryScopeEnabledTest.java +++ b/src/test/java/com/itemis/fluffyj/memory/tests/MemoryScopeEnabledTest.java @@ -6,16 +6,16 @@ import org.junit.jupiter.api.BeforeEach; import java.lang.foreign.Arena; -import java.lang.foreign.SegmentScope; +import java.lang.foreign.MemorySegment.Scope; public abstract class MemoryScopeEnabledTest { protected Arena arena; - protected SegmentScope scope; + protected Scope scope; @BeforeEach void setUpScope() { - arena = Arena.openConfined(); + arena = Arena.ofShared(); scope = arena.scope(); } @@ -24,7 +24,7 @@ void tearDownScope() { if (arena != null && scope != null && scope.isAlive()) { try { arena.close(); - } catch (Exception e) { + } catch (final Exception e) { fail("Could not close test arena.", e); } }