Skip to content

Commit 8d1261a

Browse files
committed
Add missing exception transformation to memoryview upcalls
1 parent f6fb2df commit 8d1261a

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_memoryview.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,38 @@ def compile_module(self, name):
108108
cmpfunc=unhandled_error_compare_with_message,
109109
)
110110

111+
test_memoryview_fromobject = CPyExtFunction(
112+
lambda args: args[2],
113+
lambda: (
114+
(b'123', 2, ord('3')),
115+
(bytearray(b'123'), 2, ord('3')),
116+
(memoryview(bytearray(b'123')), 2, ord('3')),
117+
([1, 2, 3], 0, TypeError("memoryview: a bytes-like object is required, not 'list'")),
118+
# This tests that exceptions are properly converted on C boundary
119+
(None, 0, None),
120+
),
121+
code='''
122+
static PyObject* test_fromobject(PyObject *object, PyObject *key, PyObject* expected) {
123+
PyObject *mv = PyMemoryView_FromObject(object);
124+
if (!mv) {
125+
if (object == Py_None) {
126+
PyErr_Clear();
127+
Py_RETURN_NONE;
128+
}
129+
return NULL;
130+
}
131+
PyObject *item = PyObject_GetItem(mv, key);
132+
Py_DECREF(mv);
133+
return item;
134+
}
135+
''',
136+
resultspec='O',
137+
argspec='OOO',
138+
arguments=["PyObject* object", "PyObject* key", "PyObject* expected"],
139+
callfunction="test_fromobject",
140+
cmpfunc=unhandled_error_compare_with_message,
141+
)
142+
111143
test_memoryview_tolist = CPyExtFunction(
112144
lambda args: args[0],
113145
lambda: [

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

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,33 +1550,40 @@ Object doPythonObject(PythonManagedClass obj, Object getBufferProc, Object relea
15501550
@GenerateNodeFactory
15511551
abstract static class PyTruffle_MemoryViewFromObject extends NativeBuiltin {
15521552
@Specialization
1553-
static Object wrap(Object object,
1554-
@Cached AsPythonObjectNode asPythonObjectNode,
1553+
Object wrap(VirtualFrame frame, Object object,
15551554
@Cached BuiltinConstructors.MemoryViewNode memoryViewNode,
1556-
@Cached ToNewRefNode toNewRefNode) {
1557-
return toNewRefNode.execute(memoryViewNode.create(asPythonObjectNode.execute(object)));
1555+
@Cached GetNativeNullNode getNativeNullNode) {
1556+
try {
1557+
return memoryViewNode.create(object);
1558+
} catch (PException e) {
1559+
transformToNative(frame, e);
1560+
return getNativeNullNode.execute();
1561+
}
15581562
}
15591563
}
15601564

1565+
// Called without landing node
15611566
@Builtin(name = NativeCAPISymbols.FUN_PY_TRUFFLE_MEMORYVIEW_FROM_BUFFER, minNumOfPositionalArgs = 12)
15621567
@GenerateNodeFactory
15631568
abstract static class PyTruffle_MemoryViewFromBuffer extends NativeBuiltin {
15641569

15651570
@Specialization
1566-
static Object wrap(Object bufferStructPointer, Object ownerObj, Object releasefn, Object lenObj, Object readonlyObj, Object itemsizeObj, Object formatObj,
1571+
Object wrap(VirtualFrame frame, Object bufferStructPointer, Object ownerObj, Object releasefn, Object lenObj,
1572+
Object readonlyObj, Object itemsizeObj, Object formatObj,
15671573
Object ndimObj, Object bufPointer, Object shapePointer, Object stridesPointer, Object suboffsetsPointer,
15681574
@Cached MemoryViewNodes.InitFlagsNode initFlagsNode,
15691575
@CachedLibrary(limit = "1") InteropLibrary lib,
15701576
@Cached CastToJavaIntExactNode castToIntNode,
15711577
@Cached AsPythonObjectNode asPythonObjectNode,
1572-
@Cached ToNewRefNode toNewRefNode) {
1573-
int ndim = castToIntNode.execute(ndimObj);
1574-
int itemsize = castToIntNode.execute(itemsizeObj);
1575-
int len = castToIntNode.execute(lenObj);
1576-
boolean readonly = castToIntNode.execute(readonlyObj) != 0;
1577-
String format = (String) asPythonObjectNode.execute(formatObj);
1578-
Object owner = lib.isNull(ownerObj) ? null : asPythonObjectNode.execute(ownerObj);
1578+
@Cached ToNewRefNode toNewRefNode,
1579+
@Cached GetNativeNullNode getNativeNullNode) {
15791580
try {
1581+
int ndim = castToIntNode.execute(ndimObj);
1582+
int itemsize = castToIntNode.execute(itemsizeObj);
1583+
int len = castToIntNode.execute(lenObj);
1584+
boolean readonly = castToIntNode.execute(readonlyObj) != 0;
1585+
String format = (String) asPythonObjectNode.execute(formatObj);
1586+
Object owner = lib.isNull(ownerObj) ? null : asPythonObjectNode.execute(ownerObj);
15801587
int[] shape = null;
15811588
int[] strides = null;
15821589
int[] suboffsets = null;
@@ -1617,6 +1624,9 @@ static Object wrap(Object bufferStructPointer, Object ownerObj, Object releasefn
16171624
PythonBuiltinClassType.PMemoryView.getInstanceShape(),
16181625
managedBuffer, owner, len, readonly, itemsize, format, ndim, bufPointer, 0, shape, strides, suboffsets, flags);
16191626
return toNewRefNode.execute(memoryview);
1627+
} catch (PException e) {
1628+
transformToNative(frame, e);
1629+
return toNewRefNode.execute(getNativeNullNode.execute());
16201630
} catch (UnsupportedMessageException | InvalidArrayIndexException e) {
16211631
throw CompilerDirectives.shouldNotReachHere(e);
16221632
}

0 commit comments

Comments
 (0)