Skip to content

Commit 642d18f

Browse files
committed
Support sending memoryviews to NFI
1 parent 31b2b5f commit 642d18f

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/memory/PointerNodes.java

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.Storage;
1919
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer.ZeroStorage;
2020
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
21+
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
2122
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
23+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
24+
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
2225
import com.oracle.graal.python.nodes.ErrorMessages;
2326
import com.oracle.graal.python.nodes.PRaiseNode;
2427
import com.oracle.graal.python.nodes.util.CastToJavaUnsignedLongNode;
28+
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
29+
import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage;
2530
import com.oracle.graal.python.util.PythonUtils;
2631
import com.oracle.truffle.api.CompilerDirectives;
2732
import com.oracle.truffle.api.dsl.Cached;
@@ -32,6 +37,8 @@
3237
import com.oracle.truffle.api.dsl.GenerateUncached;
3338
import com.oracle.truffle.api.dsl.ImportStatic;
3439
import com.oracle.truffle.api.dsl.Specialization;
40+
import com.oracle.truffle.api.interop.InteropLibrary;
41+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
3542
import com.oracle.truffle.api.library.CachedLibrary;
3643
import com.oracle.truffle.api.nodes.Node;
3744

@@ -602,9 +609,33 @@ static long doPointerArray(Node inliningTarget, MemoryBlock memory, PointerArray
602609
}
603610

604611
@Specialization
605-
static long doMemoryView(MemoryBlock memory, MemoryViewStorage storage, int offset) {
606-
// TODO
607-
throw CompilerDirectives.shouldNotReachHere("Memoryview not implemented");
612+
static long doMemoryView(Node inliningTarget, MemoryBlock memory, MemoryViewStorage storage, int offset,
613+
@CachedLibrary(limit = "1") InteropLibrary ilib,
614+
@Cached(inline = false) SequenceStorageNodes.StorageToNativeNode storageToNativeNode) {
615+
PMemoryView mv = storage.memoryView;
616+
Object ptr = null;
617+
if (mv.getBufferPointer() != null) {
618+
ptr = mv.getBufferPointer();
619+
} else if (mv.getBuffer() instanceof PBytesLike bytes) {
620+
if (bytes.getSequenceStorage() instanceof NativeSequenceStorage nativeSequenceStorage) {
621+
ptr = nativeSequenceStorage.getPtr();
622+
}
623+
if (bytes.getSequenceStorage() instanceof ByteSequenceStorage byteSequenceStorage) {
624+
NativeSequenceStorage nativeStorage = storageToNativeNode.execute(byteSequenceStorage.getInternalByteArray(), byteSequenceStorage.length());
625+
bytes.setSequenceStorage(nativeStorage);
626+
ptr = nativeStorage.getPtr();
627+
}
628+
}
629+
if (ptr != null && ilib.isPointer(ptr)) {
630+
try {
631+
long nativePointer = ilib.asPointer(ptr);
632+
memory.storage = new LongPointerStorage(nativePointer);
633+
return nativePointer + offset;
634+
} catch (UnsupportedMessageException e) {
635+
throw CompilerDirectives.shouldNotReachHere(e);
636+
}
637+
}
638+
throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.MEMORYVIEW_CANNOT_BE_CONVERTED_TO_NATIVE_MEMORY);
608639
}
609640
}
610641

@@ -619,9 +650,9 @@ public final Object execute(Node inliningTarget, Pointer ptr) {
619650
protected abstract Object execute(Node inliningTarget, MemoryBlock memory, Storage storage, int offset);
620651

621652
@Specialization
622-
static Object doNFIPointer(@SuppressWarnings("unused") MemoryBlock memory, NFIPointerStorage storage, int offset) {
653+
static Object doNFIPointer(Node inliningTarget, @SuppressWarnings("unused") MemoryBlock memory, NFIPointerStorage storage, int offset) {
623654
if (offset != 0) {
624-
throw CompilerDirectives.shouldNotReachHere("Invalid offset for a pointer");
655+
throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_APPLY_OFFSET_TO_AN_OBJECT_POINTER);
625656
}
626657
return storage.pointer;
627658
}
@@ -638,8 +669,8 @@ public final long execute(Node inliningTarget, Pointer ptr) {
638669

639670
@Specialization
640671
@SuppressWarnings("unused")
641-
static long doNFIPointer(MemoryBlock memory, NFIPointerStorage storage, int offset) {
642-
throw CompilerDirectives.shouldNotReachHere("Cannot convert Object pointer to native");
672+
static long doNFIPointer(Node inliningTarget, MemoryBlock memory, NFIPointerStorage storage, int offset) {
673+
throw PRaiseNode.raiseUncached(inliningTarget, NotImplementedError, ErrorMessages.CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE);
643674
}
644675
}
645676

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,9 @@ public abstract class ErrorMessages {
11881188

11891189
// ctypes
11901190
public static final TruffleString PASSING_STRUCTS_BY_VALUE_NOT_SUPPORTED = tsLiteral("Passing structs by value is not supported on NFI backend");
1191+
public static final TruffleString MEMORYVIEW_CANNOT_BE_CONVERTED_TO_NATIVE_MEMORY = tsLiteral("Memoryview cannot be converted to native memory");
1192+
public static final TruffleString CANNOT_CONVERT_OBJECT_POINTER_TO_NATIVE = tsLiteral("Cannot convert Object pointer to native");
1193+
public static final TruffleString CANNOT_APPLY_OFFSET_TO_AN_OBJECT_POINTER = tsLiteral("Cannot apply offset to an object pointer");
11911194
public static final TruffleString S_SYMBOL_IS_MISSING = tsLiteral("%s symbol is missing");
11921195
public static final TruffleString PACK_MUST_BE_A_NON_NEGATIVE_INTEGER = tsLiteral("_pack_ must be a non-negative integer");
11931196
public static final TruffleString FIELDS_MUST_BE_A_SEQUENCE_OF_PAIRS = tsLiteral("'_fields_' must be a sequence of pairs");
@@ -1197,7 +1200,6 @@ public abstract class ErrorMessages {
11971200
public static final TruffleString NUMBER_OF_BITS_INVALID_FOR_BIT_FIELD = tsLiteral("number of bits invalid for bit field");
11981201
public static final TruffleString STRUCTURE_OR_UNION_CANNOT_CONTAIN_ITSELF = tsLiteral("Structure or union cannot contain itself");
11991202
public static final TruffleString FIELDS_MUST_BE_A_SEQUENCE_OF_NAME_C_TYPE_PAIRS = tsLiteral("'_fields_' must be a sequence of (name, C type) pairs");
1200-
public static final TruffleString INTEGER_EXPECTED = tsLiteral("integer expected");
12011203
public static final TruffleString UNDERLYING_BUFFER_IS_NOT_WRITABLE = tsLiteral("underlying buffer is not writable");
12021204
public static final TruffleString UNDERLYING_BUFFER_IS_NOT_C_CONTIGUOUS = tsLiteral("underlying buffer is not C contiguous");
12031205
public static final TruffleString OFFSET_CANNOT_BE_NEGATIVE = tsLiteral("offset cannot be negative");

0 commit comments

Comments
 (0)