Skip to content

Commit d20ae24

Browse files
committed
[GR-9943] [GR-9715] Refactorings and fixes for Numpy/Multiarray.
PullRequest: graalpython/57
2 parents 49d0455 + 23cb5eb commit d20ae24

File tree

20 files changed

+560
-282
lines changed

20 files changed

+560
-282
lines changed

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

Lines changed: 196 additions & 66 deletions
Large diffs are not rendered by default.

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

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ void initialize_exceptions();
9494
// defined in 'pyhash.c'
9595
void initialize_hashes();
9696

97+
// prototype of C landing function
98+
PyObject *wrap_direct(PyCFunction fun, ...);
99+
PyObject *wrap_varargs(PyCFunction fun, PyObject *module, PyObject *varargs);
100+
PyObject *wrap_keywords(PyCFunctionWithKeywords fun, PyObject *module, PyObject *varargs, PyObject *kwargs);
101+
PyObject *wrap_noargs(PyCFunction fun, PyObject *module, PyObject *pnone);
102+
PyObject *wrap_fastcall(_PyCFunctionFast fun, PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames);
103+
PyObject *wrap_unsupported(void *fun, ...);
104+
97105
#define write_struct_field(object, struct, fieldname, value) \
98106
truffle_write(to_java(object), \
99107
#fieldname , \
@@ -119,6 +127,21 @@ void initialize_hashes();
119127
truffle_read(PY_TRUFFLE_CEXT, "METH_FASTCALL") : \
120128
truffle_read(PY_TRUFFLE_CEXT, "METH_UNSUPPORTED")))))))
121129

130+
#define get_method_flags_cwrapper(flags) \
131+
(void*)((((flags) < 0) ? \
132+
wrap_direct : \
133+
(((flags) & METH_KEYWORDS) ? \
134+
wrap_keywords : \
135+
(((flags) & METH_VARARGS) ? \
136+
wrap_varargs : \
137+
(((flags) & METH_NOARGS) ? \
138+
wrap_noargs : \
139+
(((flags) & METH_O) ? \
140+
wrap_direct : \
141+
(((flags) & METH_FASTCALL) ? \
142+
wrap_fastcall : \
143+
wrap_unsupported)))))))
144+
122145

123146
#define PY_TRUFFLE_TYPE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__) {\
124147
PyVarObject_HEAD_INIT((__SUPER_TYPE__), 0)\
@@ -167,43 +190,43 @@ void initialize_hashes();
167190
int PyTruffle_Debug(void *arg);
168191
PyTypeObject* PyObjectHandle_ForJavaType(void* jobj);
169192

170-
extern short ReadShortMember(PyObject* object, int offset);
171-
extern int ReadIntMember(PyObject* object, int offset);
172-
extern long ReadLongMember(PyObject* object, int offset);
173-
extern float ReadFloatMember(PyObject* object, int offset);
174-
extern double ReadDoubleMember(PyObject* object, int offset);
175-
extern void* ReadStringMember(PyObject* object, int offset);
176-
extern PyObject* ReadObjectMember(PyObject* object, int offset);
177-
extern char ReadCharMember(PyObject* object, int offset);
178-
extern char ReadByteMember(PyObject* object, int offset);
179-
extern unsigned char ReadUByteMember(PyObject* object, int offset);
180-
extern unsigned short ReadUShortMember(PyObject* object, int offset);
181-
extern unsigned int ReadUIntMember(PyObject* object, int offset);
182-
extern unsigned long ReadULongMember(PyObject* object, int offset);
183-
extern char ReadBoolMember(PyObject* object, int offset);
184-
extern PyObject* ReadObjectExMember(PyObject* object, int offset);
185-
extern long long ReadLongLongMember(PyObject* object, int offset);
186-
extern unsigned long long ReadULongLongMember(PyObject* object, int offset);
187-
extern Py_ssize_t ReadPySSizeT(PyObject* object, int offset);
188-
189-
extern void WriteShortMember(PyObject* object, int offset, short value);
190-
extern void WriteIntMember(PyObject* object, int offset, int value);
191-
extern void WriteLongMember(PyObject* object, int offset, long value);
192-
extern void WriteFloatMember(PyObject* object, int offset, float value);
193-
extern void WriteDoubleMember(PyObject* object, int offset, double value);
194-
extern void WriteStringMember(PyObject* object, int offset, PyObject* value);
195-
extern void WriteObjectMember(PyObject* object, int offset, PyObject* value);
196-
extern void WriteCharMember(PyObject* object, int offset, PyObject* value);
197-
extern void WriteByteMember(PyObject* object, int offset, PyObject* value);
198-
extern void WriteUByteMember(PyObject* object, int offset, PyObject* value);
199-
extern void WriteUShortMember(PyObject* object, int offset, unsigned short value);
200-
extern void WriteUIntMember(PyObject* object, int offset, unsigned int value);
201-
extern void WriteULongMember(PyObject* object, int offset, unsigned long value);
202-
extern void WriteBoolMember(PyObject* object, int offset, PyObject* value);
203-
extern void WriteObjectExMember(PyObject* object, int offset, PyObject* value);
204-
extern void WriteLongLongMember(PyObject* object, int offset, long long value);
205-
extern void WriteULongLongMember(PyObject* object, int offset, unsigned long long value);
206-
extern void WritePySSizeT(PyObject* object, int offset, Py_ssize_t value);
193+
extern PyObject* ReadShortMember(PyObject* object, PyObject* offset);
194+
extern PyObject* ReadIntMember(PyObject* object, PyObject* offset);
195+
extern PyObject* ReadLongMember(PyObject* object, PyObject* offset);
196+
extern PyObject* ReadFloatMember(PyObject* object, PyObject* offset);
197+
extern PyObject* ReadDoubleMember(PyObject* object, PyObject* offset);
198+
extern PyObject* ReadStringMember(PyObject* object, PyObject* offset);
199+
extern PyObject* ReadObjectMember(PyObject* object, PyObject* offset);
200+
extern PyObject* ReadCharMember(PyObject* object, PyObject* offset);
201+
extern PyObject* ReadByteMember(PyObject* object, PyObject* offset);
202+
extern PyObject* ReadUByteMember(PyObject* object, PyObject* offset);
203+
extern PyObject* ReadUShortMember(PyObject* object, PyObject* offset);
204+
extern PyObject* ReadUIntMember(PyObject* object, PyObject* offset);
205+
extern PyObject* ReadULongMember(PyObject* object, PyObject* offset);
206+
extern PyObject* ReadBoolMember(PyObject* object, PyObject* offset);
207+
extern PyObject* ReadObjectExMember(PyObject* object, PyObject* offset);
208+
extern PyObject* ReadLongLongMember(PyObject* object, PyObject* offset);
209+
extern PyObject* ReadULongLongMember(PyObject* object, PyObject* offset);
210+
extern PyObject* ReadPySSizeT(PyObject* object, PyObject* offset);
211+
212+
extern PyObject* WriteShortMember(PyObject* object, PyObject* offset, PyObject* value);
213+
extern PyObject* WriteIntMember(PyObject* object, PyObject* offset, PyObject* value);
214+
extern PyObject* WriteLongMember(PyObject* object, PyObject* offset, PyObject* value);
215+
extern PyObject* WriteFloatMember(PyObject* object, PyObject* offset, PyObject* value);
216+
extern PyObject* WriteDoubleMember(PyObject* object, PyObject* offset, PyObject* value);
217+
extern PyObject* WriteStringMember(PyObject* object, PyObject* offset, PyObject* value);
218+
extern PyObject* WriteObjectMember(PyObject* object, PyObject* offset, PyObject* value);
219+
extern PyObject* WriteCharMember(PyObject* object, PyObject* offset, PyObject* value);
220+
extern PyObject* WriteByteMember(PyObject* object, PyObject* offset, PyObject* value);
221+
extern PyObject* WriteUByteMember(PyObject* object, PyObject* offset, PyObject* value);
222+
extern PyObject* WriteUShortMember(PyObject* object, PyObject* offset, PyObject* value);
223+
extern PyObject* WriteUIntMember(PyObject* object, PyObject* offset, PyObject* value);
224+
extern PyObject* WriteULongMember(PyObject* object, PyObject* offset, PyObject* value);
225+
extern PyObject* WriteBoolMember(PyObject* object, PyObject* offset, PyObject* value);
226+
extern PyObject* WriteObjectExMember(PyObject* object, PyObject* offset, PyObject* value);
227+
extern PyObject* WriteLongLongMember(PyObject* object, PyObject* offset, PyObject* value);
228+
extern PyObject* WriteULongLongMember(PyObject* object, PyObject* offset, PyObject* value);
229+
extern PyObject* WritePySSizeT(PyObject* object, PyObject* offset, PyObject* value);
207230

208231
extern PyObject marker_struct;
209232
#define ERROR_MARKER &marker_struct

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ int PyModule_AddFunctions(PyObject* mod, PyMethodDef* methods) {
5454
mod_w,
5555
truffle_read_string((const char*)(def.ml_name)),
5656
truffle_address_to_function(def.ml_meth),
57+
truffle_address_to_function(get_method_flags_cwrapper(def.ml_flags)),
5758
get_method_flags_wrapper(def.ml_flags),
5859
truffle_read_string((const char*)(def.ml_doc ? def.ml_doc : "")));
5960
def = methods[++idx];

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,18 @@ int PyType_Ready(PyTypeObject* cls) {
175175
#define ADD_IF_MISSING(attr, def) if (!(attr)) { attr = def; }
176176
#define ADD_METHOD(m) ADD_METHOD_OR_SLOT(m.ml_name, m.ml_meth, m.ml_flags, m.ml_doc)
177177
#define ADD_SLOT(name, meth, flags) ADD_METHOD_OR_SLOT(name, meth, flags, name)
178-
#define ADD_METHOD_OR_SLOT(name, meth, flags, doc) \
179-
if (meth) { \
180-
truffle_invoke(PY_TRUFFLE_CEXT, \
181-
"AddFunction", \
182-
javacls, \
183-
truffle_read_string(name), \
184-
truffle_address_to_function(meth), \
185-
get_method_flags_wrapper(flags), \
186-
truffle_read_string(doc), \
187-
(flags) > 0 && ((flags) & METH_CLASS) != 0, \
188-
(flags) > 0 && ((flags) & METH_STATIC) != 0); \
178+
#define ADD_METHOD_OR_SLOT(name, meth, flags, doc) \
179+
if (meth) { \
180+
truffle_invoke(PY_TRUFFLE_CEXT, \
181+
"AddFunction", \
182+
javacls, \
183+
truffle_read_string(name), \
184+
truffle_address_to_function(meth), \
185+
truffle_address_to_function(get_method_flags_cwrapper(flags)), \
186+
get_method_flags_wrapper(flags), \
187+
truffle_read_string(doc), \
188+
(flags) > 0 && ((flags) & METH_CLASS) != 0, \
189+
(flags) > 0 && ((flags) & METH_STATIC) != 0); \
189190
}
190191

191192
// https://docs.python.org/3/c-api/typeobj.html#Py_TPFLAGS_READY
@@ -392,7 +393,7 @@ int PyType_Ready(PyTypeObject* cls) {
392393
if (mappings) {
393394
ADD_SLOT("__len__", mappings->mp_length, -1);
394395
ADD_SLOT("__getitem__", mappings->mp_subscript, -2);
395-
ADD_SLOT("__setitem__", mappings->mp_subscript, -3);
396+
ADD_SLOT("__setitem__", mappings->mp_ass_subscript, -3);
396397
}
397398

398399
PyAsyncMethods* async = cls->tp_as_async;

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

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,26 @@
3636
# SOFTWARE.
3737

3838
import sys
39-
#from _ast import arguments
4039
os = sys.modules.get("posix", sys.modules.get("nt", None))
4140
if os is None:
4241
raise ImportError("posix or nt module is required in builtin modules")
4342
__dir__ = __file__.rpartition("/")[0]
4443

45-
4644
GRAALPYTHON = sys.implementation.name == "graalpython"
4745

46+
4847
def unhandled_error_compare(x, y):
49-
if (isinstance(x,BaseException) and isinstance(y,BaseException)):
48+
if (isinstance(x, BaseException) and isinstance(y, BaseException)):
5049
return type(x) == type(y)
5150
else:
5251
return x == y
5352

53+
5454
class CPyExtTestCase():
55+
5556
def setUp(self):
5657
for typ in type(self).mro():
57-
for k,v in typ.__dict__.items():
58+
for k, v in typ.__dict__.items():
5859
if k.startswith("test_"):
5960
modname = k.replace("test_", "")
6061
if k.startswith("test_graalpython_"):
@@ -67,15 +68,15 @@ def setUp(self):
6768

6869
def ccompile(self, name):
6970
from distutils.core import setup, Extension
70-
module = Extension(name, sources = ['%s/%s.c' % (__dir__, name)])
71+
module = Extension(name, sources=['%s/%s.c' % (__dir__, name)])
7172
args = ['--quiet', 'build', 'install_lib', '-f', '--install-dir=%s' % __dir__]
7273
setup(
73-
script_name = 'setup',
74-
script_args = args,
75-
name = name,
76-
version = '1.0',
77-
description = '',
78-
ext_modules = [module]
74+
script_name='setup',
75+
script_args=args,
76+
name=name,
77+
version='1.0',
78+
description='',
79+
ext_modules=[module]
7980
)
8081

8182

@@ -185,7 +186,7 @@ def ccompile(self, name):
185186
PyObject* ___arg;
186187
{argumentdeclarations};
187188
{resultvardeclarations}
188-
void* res;
189+
{resulttype} res;
189190
190191
if (!PyArg_ParseTuple(args, "O", &___arg)) {{
191192
return NULL;
@@ -202,7 +203,7 @@ def ccompile(self, name):
202203
}}
203204
#endif
204205
205-
res = (void *){callfunction}({argumentnames}{resultvarlocations});
206+
res = {callfunction}({argumentnames}{resultvarlocations});
206207
207208
return Py_BuildValue("{resultspec}", res {resultvarnames});
208209
}}
@@ -228,15 +229,17 @@ def ccompile(self, name):
228229
}}
229230
"""
230231

232+
231233
class CPyExtFunction():
234+
232235
def __init__(self, pfunc, parameters, template=c_template, cmpfunc=None, **kwargs):
233236
self.template = template
234237
self.pfunc = pfunc
235238
self.parameters = parameters
236239
kwargs["name"] = kwargs["name"] if "name" in kwargs else None
237240
self.name = kwargs["name"]
238241
if "code" in kwargs:
239-
kwargs["customcode"] = kwargs["code"]
242+
kwargs["customcode"] = kwargs["code"]
240243
del kwargs["code"]
241244
else:
242245
kwargs["customcode"] = ""
@@ -286,7 +289,7 @@ def _insert(self, d, name, default_value):
286289

287290
def __repr__(self):
288291
return "<CPyExtFunction %s>" % self.name
289-
292+
290293
def test(self):
291294
sys.path.insert(0, __dir__)
292295
try:
@@ -327,10 +330,11 @@ class CPyExtFunctionOutVars(CPyExtFunction):
327330
This class supports this.
328331
Set 'resultvars' to declare the output vars.
329332
'''
333+
330334
def __init__(self, pfunc, parameters, template=c_template_multi_res, **kwargs):
331335
super(CPyExtFunctionOutVars, self).__init__(pfunc, parameters, **kwargs)
332336
self.template = template
333-
337+
334338
def create_module(self, name=None):
335339
fargs = self.formatargs
336340
if "resultvars" not in fargs:
@@ -348,26 +352,28 @@ def create_module(self, name=None):
348352
fargs["resultvarnames"] = ""
349353
if len(fargs["resultvarnames"]) and not fargs["resultvarnames"].startswith(","):
350354
fargs["resultvarnames"] = ", " + fargs["resultvarnames"]
351-
355+
352356
if "resultvarlocations" not in fargs:
353357
fargs["resultvarlocations"] = ", ".join("&" + arg.rpartition(" ")[2] for arg in fargs["resultvars"])
358+
if "resulttype" not in fargs:
359+
fargs["resulttype"] = "void*"
354360
if len(fargs["resultvarlocations"]):
355361
fargs["resultvarlocations"] = ", " + fargs["resultvarlocations"]
356362
self._insert(fargs, "customcode", "")
357363
super(CPyExtFunctionOutVars, self).create_module(name)
358364

359365

360366
class CPyExtFunctionVoid(CPyExtFunction):
367+
361368
def __init__(self, pfunc, parameters, template=c_template_void, **kwargs):
362369
super(CPyExtFunctionVoid, self).__init__(pfunc, parameters, **kwargs)
363370
self.template = template
364-
371+
365372
def create_module(self, name=None):
366373
fargs = self.formatargs
367374
if "resultval" not in fargs:
368375
fargs["resultval"] = "Py_None"
369376
super(CPyExtFunctionVoid, self).create_module(name)
370377

371378

372-
373379
CPyExtTestCase.compile_module = ccompile

graalpython/com.oracle.graal.python.test/src/tests/cpyext/noddy2.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,23 @@
4141
#include <Python.h>
4242
#include "structmember.h"
4343

44+
#include <stddef.h>
45+
4446
typedef struct {
4547
PyObject_HEAD
4648
PyObject *first; /* first name */
4749
PyObject *last; /* last name */
4850
int number;
51+
short n_short;
52+
long n_long;
53+
float n_float;
54+
double n_double;
55+
char c;
56+
int8_t n_byte;
57+
uint8_t n_ubyte;
58+
unsigned short n_ushort;
59+
unsigned int n_unumber;
60+
unsigned long n_ulong;
4961
} Noddy;
5062

5163
static void
@@ -76,6 +88,16 @@ Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
7688
}
7789

7890
self->number = 0;
91+
self->n_short = 0;
92+
self->n_long = 0;
93+
self->n_float = 0;
94+
self->n_double = 0;
95+
self->c = 0;
96+
self->n_byte = 0;
97+
self->n_ubyte = 0;
98+
self->n_ushort = 0;
99+
self->n_unumber = 0;
100+
self->n_ulong = 0;
79101
}
80102

81103
return (PyObject *)self;
@@ -118,6 +140,26 @@ static PyMemberDef Noddy_members[] = {
118140
"last name"},
119141
{"number", T_INT, offsetof(Noddy, number), 0,
120142
"noddy number"},
143+
{"n_short", T_SHORT, offsetof(Noddy, n_short), 0,
144+
"noddy short"},
145+
{"n_long", T_LONG, offsetof(Noddy, n_long), 0,
146+
"noddy long"},
147+
{"n_float", T_FLOAT, offsetof(Noddy, n_float), 0,
148+
"noddy float"},
149+
{"n_double", T_DOUBLE, offsetof(Noddy, n_double), 0,
150+
"noddy double"},
151+
{"c", T_CHAR, offsetof(Noddy, c), 0,
152+
"noddy char"},
153+
{"n_byte", T_BYTE, offsetof(Noddy, n_byte), 0,
154+
"noddy byte"},
155+
{"n_ubyte", T_UBYTE, offsetof(Noddy, n_ubyte), 0,
156+
"noddy ubyte"},
157+
{"n_ushort", T_USHORT, offsetof(Noddy, n_ushort), 0,
158+
"noddy ushort"},
159+
{"n_unumber", T_UINT, offsetof(Noddy, n_unumber), 0,
160+
"noddy uint"},
161+
{"n_ulong", T_ULONG, offsetof(Noddy, n_ulong), 0,
162+
"noddy ulong"},
121163
{NULL} /* Sentinel */
122164
};
123165

0 commit comments

Comments
 (0)