Skip to content

Commit 4bf85af

Browse files
committed
Add array support to memoryview
1 parent 50ac5ad commit 4bf85af

File tree

6 files changed

+132
-62
lines changed

6 files changed

+132
-62
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__SLOTS__;
7878
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__WEAKREF__;
7979
import static com.oracle.graal.python.nodes.SpecialMethodNames.DECODE;
80+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__BYTES__;
8081
import static com.oracle.graal.python.nodes.SpecialMethodNames.__COMPLEX__;
8182
import static com.oracle.graal.python.nodes.SpecialMethodNames.__EQ__;
8283
import static com.oracle.graal.python.nodes.SpecialMethodNames.__FLOAT__;
@@ -86,6 +87,7 @@
8687
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INT__;
8788
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEW__;
8889
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
90+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REVERSED__;
8991
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
9092
import static com.oracle.graal.python.nodes.SpecialMethodNames.__TRUNC__;
9193
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
@@ -111,6 +113,7 @@
111113
import com.oracle.graal.python.builtins.objects.PEllipsis;
112114
import com.oracle.graal.python.builtins.objects.PNone;
113115
import com.oracle.graal.python.builtins.objects.PNotImplemented;
116+
import com.oracle.graal.python.builtins.objects.array.PArray;
114117
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
115118
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
116119
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
@@ -189,8 +192,6 @@
189192
import com.oracle.graal.python.nodes.PGuards;
190193
import com.oracle.graal.python.nodes.SpecialAttributeNames;
191194
import com.oracle.graal.python.nodes.SpecialMethodNames;
192-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__BYTES__;
193-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REVERSED__;
194195
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
195196
import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetAnyAttributeNode;
196197
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
@@ -3371,8 +3372,6 @@ public final PMemoryView execute(VirtualFrame frame, Object object) {
33713372
return execute(frame, PythonBuiltinClassType.PMemoryView, object);
33723373
}
33733374

3374-
// TODO arrays should support buffer protocol too, but their implementation would be
3375-
// complex, because they don't have an underlying byte array
33763375
@Specialization
33773376
PMemoryView fromBytes(@SuppressWarnings("unused") Object cls, PBytes object,
33783377
@Shared("getQueue") @Cached MemoryViewNodes.GetBufferReferences getQueue,
@@ -3391,6 +3390,13 @@ PMemoryView fromByteArray(@SuppressWarnings("unused") Object cls, PByteArray obj
33913390
return fromManaged(object, 1, lenNode.execute(storage), false, "B", true, getQueue.execute());
33923391
}
33933392

3393+
@Specialization
3394+
PMemoryView fromArray(@SuppressWarnings("unused") Object cls, PArray object,
3395+
@Shared("getQueue") @Cached MemoryViewNodes.GetBufferReferences getQueue) {
3396+
int itemsize = object.getFormat().bytesize;
3397+
return fromManaged(object, itemsize, object.getLength(), false, object.getFormatStr(), true, getQueue.execute());
3398+
}
3399+
33943400
@Specialization
33953401
PMemoryView fromMemoryView(@SuppressWarnings("unused") Object cls, PMemoryView object,
33963402
@Shared("getQueue") @Cached MemoryViewNodes.GetBufferReferences getQueue) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyMemoryViewBufferWrapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static Object getBufManaged(PMemoryView object, @SuppressWarnings("unused") Stri
164164
@Cached SequenceNodes.SetSequenceStorageNode setStorage,
165165
@Shared("pointerAdd") @Cached CExtNodes.PointerAddNode pointerAddNode,
166166
@Cached PySequenceArrayWrapper.ToNativeStorageNode toNativeStorageNode) {
167+
// TODO GR-21120: Add support for PArray
167168
PSequence owner = (PSequence) object.getOwner();
168169
NativeSequenceStorage nativeStorage = toNativeStorageNode.execute(getStorage.execute(owner));
169170
if (nativeStorage == null) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
4646

4747
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
48+
import com.oracle.graal.python.builtins.objects.array.PArray;
4849
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
50+
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
4951
import com.oracle.graal.python.builtins.objects.ints.PInt;
5052
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
5153
import com.oracle.graal.python.builtins.objects.str.PString;
@@ -62,6 +64,7 @@
6264
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6365
import com.oracle.truffle.api.dsl.Cached;
6466
import com.oracle.truffle.api.dsl.Cached.Shared;
67+
import com.oracle.truffle.api.dsl.GenerateUncached;
6568
import com.oracle.truffle.api.dsl.ImportStatic;
6669
import com.oracle.truffle.api.dsl.Specialization;
6770
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -312,4 +315,54 @@ private PException raise(PythonBuiltinClassType type) {
312315
}
313316
}
314317

318+
@GenerateUncached
319+
public abstract static class GetByteLenght extends Node {
320+
public abstract int execute(Object buffer);
321+
322+
@Specialization
323+
static int doBytes(PBytesLike bytes,
324+
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
325+
@Cached SequenceStorageNodes.LenNode lenNode) {
326+
return lenNode.execute(getSequenceStorageNode.execute(bytes));
327+
}
328+
329+
@Specialization
330+
static int doArray(PArray array) {
331+
return array.getLength() * array.getFormat().bytesize;
332+
}
333+
}
334+
335+
@GenerateUncached
336+
public abstract static class CopyBytesFromBuffer extends Node {
337+
public abstract void execute(Object buffer, int srcPos, byte[] dest, int destPos, int lenght);
338+
339+
@Specialization
340+
static void doBytes(PBytesLike src, int srcPos, byte[] dest, int destPos, int lenght,
341+
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
342+
@Cached SequenceStorageNodes.CopyBytesFromByteStorage copyFrom) {
343+
copyFrom.execute(getSequenceStorageNode.execute(src), srcPos, dest, destPos, lenght);
344+
}
345+
346+
@Specialization
347+
static void doArray(PArray src, int srcPos, byte[] dest, int destPos, int lenght) {
348+
PythonUtils.arraycopy(src.getBuffer(), srcPos, dest, destPos, lenght);
349+
}
350+
}
351+
352+
@GenerateUncached
353+
public abstract static class CopyBytesToBuffer extends Node {
354+
public abstract void execute(byte[] src, int srcPos, Object dest, int destPos, int lenght);
355+
356+
@Specialization
357+
static void doBytes(byte[] src, int srcPos, PBytesLike dest, int destPos, int lenght,
358+
@Cached SequenceNodes.GetSequenceStorageNode getSequenceStorageNode,
359+
@Cached SequenceStorageNodes.CopyBytesToByteStorage copyTo) {
360+
copyTo.execute(src, srcPos, getSequenceStorageNode.execute(dest), destPos, lenght);
361+
}
362+
363+
@Specialization
364+
static void doArray(byte[] src, int srcPos, PArray dest, int destPos, int lenght) {
365+
PythonUtils.arraycopy(src, srcPos, dest.getBuffer(), destPos, lenght);
366+
}
367+
}
315368
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,48 @@ protected static int len(LenNode lenNode, SequenceStorage s) {
21652165
}
21662166
}
21672167

2168+
@GenerateUncached
2169+
@ImportStatic(SequenceStorageBaseNode.class)
2170+
public abstract static class CopyBytesFromByteStorage extends PNodeWithContext {
2171+
2172+
public abstract void execute(SequenceStorage src, int srcPos, byte[] dest, int destPos, int lenght);
2173+
2174+
@Specialization
2175+
static void doByteSequenceStorage(ByteSequenceStorage src, int srcPos, byte[] dest, int destPos, int lenght) {
2176+
PythonUtils.arraycopy(src.getInternalByteArray(), srcPos, dest, destPos, lenght);
2177+
}
2178+
2179+
@Specialization(guards = "isByteStorage(src)")
2180+
static void doNativeByte(NativeSequenceStorage src, int srcPos, byte[] dest, int destPos, int lenght,
2181+
@Cached GetItemScalarNode getItemNode) {
2182+
for (int i = 0; i < lenght; i++) {
2183+
int elem = getItemNode.executeInt(src, srcPos + i);
2184+
assert elem >= 0 && elem < 256;
2185+
dest[destPos + i] = (byte) elem;
2186+
}
2187+
}
2188+
}
2189+
2190+
@GenerateUncached
2191+
@ImportStatic(SequenceStorageBaseNode.class)
2192+
public abstract static class CopyBytesToByteStorage extends PNodeWithContext {
2193+
2194+
public abstract void execute(byte[] src, int srcPos, SequenceStorage dest, int destPos, int lenght);
2195+
2196+
@Specialization
2197+
static void doByteSequenceStorage(byte[] src, int srcPos, ByteSequenceStorage dest, int destPos, int lenght) {
2198+
PythonUtils.arraycopy(src, srcPos, dest.getInternalByteArray(), destPos, lenght);
2199+
}
2200+
2201+
@Specialization(guards = "isByteStorage(dest)")
2202+
static void doNativeByte(byte[] src, int srcPos, NativeSequenceStorage dest, int destPos, int lenght,
2203+
@Cached SetItemScalarNode setItemNode) {
2204+
for (int i = 0; i < lenght; i++) {
2205+
setItemNode.execute(dest, destPos + i, src[srcPos + i]);
2206+
}
2207+
}
2208+
}
2209+
21682210
@GenerateUncached
21692211
public abstract static class ToByteArrayNode extends Node {
21702212

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewBuiltins.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import com.oracle.graal.python.builtins.objects.PEllipsis;
6868
import com.oracle.graal.python.builtins.objects.PNone;
6969
import com.oracle.graal.python.builtins.objects.PNotImplemented;
70+
import com.oracle.graal.python.builtins.objects.array.PArray;
7071
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins.ExpectIntNode;
7172
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins.SepExpectByteNode;
7273
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
@@ -77,7 +78,6 @@
7778
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
7879
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
7980
import com.oracle.graal.python.builtins.objects.list.PList;
80-
import com.oracle.graal.python.util.BufferFormat;
8181
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
8282
import com.oracle.graal.python.builtins.objects.slice.PSlice;
8383
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -97,6 +97,7 @@
9797
import com.oracle.graal.python.runtime.exception.PException;
9898
import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage;
9999
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
100+
import com.oracle.graal.python.util.BufferFormat;
100101
import com.oracle.graal.python.util.PythonUtils;
101102
import com.oracle.truffle.api.CompilerDirectives;
102103
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -110,6 +111,7 @@
110111
import com.oracle.truffle.api.library.CachedLibrary;
111112
import com.oracle.truffle.api.object.HiddenKey;
112113
import com.oracle.truffle.api.profiles.ConditionProfile;
114+
import com.oracle.truffle.api.profiles.ValueProfile;
113115

114116
@CoreFunctions(extendClasses = PythonBuiltinClassType.PMemoryView)
115117
public class MemoryViewBuiltins extends PythonBuiltins {
@@ -176,7 +178,7 @@ public void postInitialize(PythonCore core) {
176178
// It's a weakref, it may go away and in that case we don't have to do
177179
// anything
178180
if (owner != null) {
179-
releaseBufferOfManagedObject(owner, ConditionProfile.getUncached());
181+
releaseBufferOfManagedObject(owner);
180182
}
181183
return null;
182184
}
@@ -763,10 +765,10 @@ Object releaseSimple(PMemoryView self) {
763765

764766
@Specialization(guards = {"self.getReference() != null", "!self.getManagedBuffer().isForNative()"})
765767
Object releaseManaged(PMemoryView self,
766-
@Cached ConditionProfile isByteArrayProfile) {
768+
@Cached("createClassProfile()") ValueProfile bufferClassProfile) {
767769
checkExports(self);
768770
if (checkShouldReleaseBuffer(self)) {
769-
releaseBufferOfManagedObject(self.getOwner(), isByteArrayProfile);
771+
releaseBufferOfManagedObject(bufferClassProfile.profile(self.getOwner()));
770772
}
771773
self.setReleased();
772774
return PNone.NONE;
@@ -949,8 +951,10 @@ boolean get(PMemoryView self) {
949951
}
950952
}
951953

952-
private static void releaseBufferOfManagedObject(Object object, ConditionProfile isByteArrayProfile) {
953-
if (isByteArrayProfile.profile(object instanceof PByteArray)) {
954+
private static void releaseBufferOfManagedObject(Object object) {
955+
if (object instanceof PByteArray) {
956+
// TODO GR-26945
957+
} else if (object instanceof PArray) {
954958
// TODO GR-26945
955959
}
956960
}

0 commit comments

Comments
 (0)