Skip to content

Commit 3ffe6d0

Browse files
committed
Support writing to buffer decorator.
1 parent 267cb99 commit 3ffe6d0

File tree

8 files changed

+56
-19
lines changed

8 files changed

+56
-19
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef struct {
6868

6969
typedef struct {
7070
PyObject_VAR_HEAD
71+
int readonly;
7172
void *buf_delegate;
7273
} PyBufferDecorator;
7374

graalpython/com.oracle.graal.python.cext/src/memoryobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@ PyTypeObject PyMemoryView_Type = PY_TRUFFLE_TYPE("memoryview", &PyType_Type, Py_
4444
PyTypeObject PyBuffer_Type = PY_TRUFFLE_TYPE("buffer", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyBufferDecorator));
4545

4646
int bufferdecorator_getbuffer(PyBufferDecorator *self, Py_buffer *view, int flags) {
47-
return PyBuffer_FillInfo(view, (PyObject*)self, polyglot_get_member(self, "buf_delegate"), PyObject_Size((PyObject *)self), 1, flags);
47+
return PyBuffer_FillInfo(view, (PyObject*)self, polyglot_get_member(self, "buf_delegate"), PyObject_Size((PyObject *)self), self->readonly, flags);
4848
}

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import static com.oracle.graal.python.nodes.BuiltinNames.ZIP;
4848
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FILE__;
4949
import static com.oracle.graal.python.nodes.SpecialMethodNames.DECODE;
50+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
5051
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
5152
import static com.oracle.graal.python.runtime.exception.PythonErrorType.OverflowError;
5253
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
@@ -340,9 +341,6 @@ public PDict dictEmpty(PythonClass cls, Object[] args, PKeyword[] keywordArgs) {
340341
@Builtin(name = ENUMERATE, fixedNumOfArguments = 2, keywordArguments = {"start"}, constructsClass = PEnumerate.class)
341342
@GenerateNodeFactory
342343
public abstract static class EnumerateNode extends PythonBuiltinNode {
343-
/**
344-
* TODO enumerate can take a keyword argument start, and currently that's not supported.
345-
*/
346344

347345
@Specialization
348346
public PEnumerate enumerate(PythonClass cls, Object iterable, @SuppressWarnings("unused") PNone keywordArg,
@@ -1678,19 +1676,32 @@ Object slice(PythonClass cls, Object start, Object stop, Object step,
16781676
}
16791677

16801678
// buffer([iterable])
1681-
@Builtin(name = "buffer", fixedNumOfArguments = 2, constructsClass = PBuffer.class)
1679+
@Builtin(name = "buffer", minNumOfArguments = 2, maxNumOfArguments = 3, constructsClass = PBuffer.class)
16821680
@GenerateNodeFactory
16831681
public abstract static class BufferNode extends PythonBuiltinNode {
1682+
@Child private LookupInheritedAttributeNode getSetItemNode;
1683+
1684+
@Specialization(guards = "isNoValue(readOnly)")
1685+
protected PBuffer construct(PythonClass cls, Object delegate, @SuppressWarnings("unused") PNone readOnly) {
1686+
return factory().createBuffer(cls, delegate, !hasSetItem(delegate));
1687+
}
16841688

16851689
@Specialization
1686-
protected PBuffer construct(PythonClass cls, Object value) {
1687-
return factory().createBuffer(cls, value);
1690+
protected PBuffer construct(PythonClass cls, Object delegate, boolean readOnly) {
1691+
return factory().createBuffer(cls, delegate, readOnly);
16881692
}
16891693

16901694
@Fallback
1691-
public PBuffer listObject(@SuppressWarnings("unused") Object cls, Object arg) {
1692-
CompilerAsserts.neverPartOfCompilation();
1693-
throw new RuntimeException("buffer does not support iterable object " + arg);
1695+
public PBuffer doGeneric(@SuppressWarnings("unused") Object cls, Object delegate, @SuppressWarnings("unused") Object readOnly) {
1696+
throw raise(TypeError, "cannot create buffer for object %s", delegate);
1697+
}
1698+
1699+
public boolean hasSetItem(Object object) {
1700+
if (getSetItemNode == null) {
1701+
CompilerDirectives.transferToInterpreterAndInvalidate();
1702+
getSetItemNode = LookupInheritedAttributeNode.create(__SETITEM__);
1703+
}
1704+
return getSetItemNode.execute(object) != PNone.NO_VALUE;
16941705
}
16951706
}
16961707

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public final class NativeMemberNames {
9191
public static final String MD_DEF = "md_def";
9292
public static final String MD_DICT = "md_dict";
9393
public static final String BUF_DELEGATE = "buf_delegate";
94+
public static final String BUF_READONLY = "readonly";
9495
public static final String NB_ADD = "nb_add";
9596
public static final String NB_INDEX = "nb_index";
9697
public static final String NB_POW = "nb_power";

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.cext;
4242

43+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
44+
4345
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
4446
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
4547
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
@@ -57,6 +59,7 @@
5759
import com.oracle.graal.python.nodes.PBaseNode;
5860
import com.oracle.graal.python.nodes.SpecialMethodNames;
5961
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
62+
import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode;
6063
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
6164
import com.oracle.graal.python.nodes.truffle.PythonTypes;
6265
import com.oracle.truffle.api.CompilerDirectives;
@@ -227,29 +230,40 @@ Object doTuple(PTuple tuple, long idx, Object value) {
227230
}
228231

229232
@Specialization
230-
Object doTuple(PList list, long idx, Object value,
233+
Object doList(PList list, long idx, Object value,
231234
@Cached("createListSetItem()") ListBuiltins.SetItemNode setItemNode) {
232235
return setItemNode.execute(list, idx, getToJavaNode().execute(value));
233236
}
234237

235238
@Specialization
236-
Object doTuple(PBytes tuple, long idx, byte value) {
239+
Object doBytes(PBytes tuple, long idx, byte value) {
237240
// TODO(fa) do proper index conversion
238241
tuple.getInternalByteArray()[(int) idx] = value;
239242
return value;
240243
}
241244

242245
@Specialization
243-
Object doTuple(PByteArray tuple, long idx, byte value) {
246+
Object doByteArray(PByteArray tuple, long idx, byte value) {
244247
// TODO(fa) do proper index conversion
245248
tuple.getInternalByteArray()[(int) idx] = value;
246249
return value;
247250
}
248251

252+
@Specialization
253+
Object doGeneric(Object tuple, Object idx, Object value,
254+
@Cached("createSetItem()") LookupAndCallTernaryNode setItemNode) {
255+
setItemNode.execute(tuple, idx, value);
256+
return value;
257+
}
258+
249259
protected static ListBuiltins.SetItemNode createListSetItem() {
250260
return ListBuiltinsFactory.SetItemNodeFactory.create();
251261
}
252262

263+
protected static LookupAndCallTernaryNode createSetItem() {
264+
return LookupAndCallTernaryNode.create(__SETITEM__);
265+
}
266+
253267
private CExtNodes.ToJavaNode getToJavaNode() {
254268
if (toJavaNode == null) {
255269
CompilerDirectives.transferToInterpreterAndInvalidate();

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,10 +409,15 @@ Object doMdDef(PythonObject object, @SuppressWarnings("unused") String key) {
409409
}
410410

411411
@Specialization(guards = "eq(BUF_DELEGATE, key)")
412-
Object doObSval(PBuffer object, @SuppressWarnings("unused") String key) {
412+
Object doBufDelegate(PBuffer object, @SuppressWarnings("unused") String key) {
413413
return new PySequenceArrayWrapper(object.getDelegate(), 1);
414414
}
415415

416+
@Specialization(guards = "eq(BUF_READONLY, key)")
417+
int doBufReadonly(PBuffer object, @SuppressWarnings("unused") String key) {
418+
return object.isReadOnly() ? 1 : 0;
419+
}
420+
416421
@Specialization(guards = "eq(START, key)")
417422
int doStart(PSlice object, @SuppressWarnings("unused") String key) {
418423
return object.getStart();

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@
4646
public class PBuffer extends PythonBuiltinObject {
4747

4848
private final Object delegate;
49+
private final boolean readOnly;
4950

50-
public PBuffer(PythonClass cls, Object iterable) {
51+
public PBuffer(PythonClass cls, Object iterable, boolean readOnly) {
5152
super(cls);
5253
this.delegate = iterable;
54+
this.readOnly = readOnly;
5355
}
5456

5557
public Object getDelegate() {
5658
return delegate;
5759
}
5860

61+
public boolean isReadOnly() {
62+
return readOnly;
63+
}
5964
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -695,12 +695,12 @@ public PForeignArrayIterator createForeignArrayIterator(TruffleObject iterable,
695695
return trace(new PForeignArrayIterator(lookupClass(PythonBuiltinClassType.PForeignArrayIterator), iterable, size));
696696
}
697697

698-
public PBuffer createBuffer(PythonClass cls, Object iterable) {
699-
return trace(new PBuffer(cls, iterable));
698+
public PBuffer createBuffer(PythonClass cls, Object iterable, boolean readonly) {
699+
return trace(new PBuffer(cls, iterable, readonly));
700700
}
701701

702-
public PBuffer createBuffer(Object iterable) {
703-
return trace(new PBuffer(lookupClass(PythonBuiltinClassType.PBuffer), iterable));
702+
public PBuffer createBuffer(Object iterable, boolean readonly) {
703+
return trace(new PBuffer(lookupClass(PythonBuiltinClassType.PBuffer), iterable, readonly));
704704
}
705705

706706
public PCode createCode(RootNode result) {

0 commit comments

Comments
 (0)