Skip to content

Commit 3016860

Browse files
committed
Implement arg parse specifiers 'L' and 'K' and fix KW arg parsing bug.
1 parent 170b742 commit 3016860

File tree

4 files changed

+48
-33
lines changed

4 files changed

+48
-33
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ extern PyObject* to_sulong(void *o);
8686
extern PyObject* explicit_cast(PyObject* cobj);
8787
#define as_char_pointer(obj) polyglot_invoke(PY_TRUFFLE_CEXT, "to_char_pointer", to_java(obj))
8888
#define as_long(obj) ((long)polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "to_long", to_java(obj))))
89+
#define as_long_long(obj) ((long long)polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 1, sizeof(long long), polyglot_from_string("long long", "utf-8"))))
90+
#define as_unsigned_long_long(obj) ((unsigned long long)polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 0, sizeof(unsigned long long), polyglot_from_string("unsigned long long", "utf-8"))))
8991
#define as_int(obj) ((int)as_long(obj))
9092
#define as_short(obj) ((short)as_long(obj))
9193
#define as_uchar(obj) ((unsigned char)as_long(obj))

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,46 +38,59 @@
3838
*/
3939
#include "capi.h"
4040

41-
#include <stdbool.h>
4241
#include <stddef.h>
4342

4443
PyTypeObject PyLong_Type = PY_TRUFFLE_TYPE("int", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, offsetof(PyLongObject, ob_digit));
4544

4645
long PyLong_AsLong(PyObject *obj) {
47-
return truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), true, sizeof(long), truffle_read_string("long"));
46+
return truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 1, sizeof(long), truffle_read_string("long"));
4847
}
4948

5049
long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow) {
5150
if (obj == NULL) {
5251
PyErr_BadInternalCall();
5352
return -1;
5453
}
55-
long result = truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), true, sizeof(long), truffle_read_string("long"));
54+
long result = truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 1, sizeof(long), truffle_read_string("long"));
5655
*overflow = result == -1L && PyErr_Occurred() != NULL;
5756
return result;
5857
}
5958

59+
long long PyLong_AsLonglong(PyObject *obj) {
60+
return as_long_long(obj);
61+
}
62+
63+
long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow) {
64+
long long result = PyLong_AsLongLong(obj);
65+
*overflow = result == -1L && PyErr_Occurred() != NULL;
66+
return result;
67+
}
68+
69+
unsigned long long PyLong_AsUnsignedLonglong(PyObject *obj) {
70+
return as_unsigned_long_long(obj);
71+
}
72+
6073
unsigned long PyLong_AsUnsignedLong(PyObject *obj) {
6174
if (obj == NULL) {
6275
PyErr_BadInternalCall();
6376
return (unsigned long)-1;
6477
}
65-
return (unsigned long) truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), false, sizeof(unsigned long), truffle_read_string("unsigned long"));
78+
return (unsigned long) truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 0, sizeof(unsigned long), truffle_read_string("unsigned long"));
6679
}
6780
PyObject * PyLong_FromSsize_t(Py_ssize_t n) {
6881
return PyLong_FromLongLong(n);
6982
}
7083

7184
PyObject * PyLong_FromDouble(double n) {
72-
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, true);
85+
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, 1);
7386
if (result == ERROR_MARKER) {
7487
return NULL;
7588
}
7689
return to_sulong(result);
7790
}
7891

7992
Py_ssize_t PyLong_AsSsize_t(PyObject *obj) {
80-
return truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), true, sizeof(Py_ssize_t), truffle_read_string("ssize_t"));
93+
return truffle_invoke_l(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 1, sizeof(Py_ssize_t), truffle_read_string("ssize_t"));
8194
}
8295

8396
PyObject * PyLong_FromVoidPtr(void *p) {
@@ -96,15 +109,15 @@ void * PyLong_AsVoidPtr(PyObject *obj){
96109
}
97110

98111
PyObject * PyLong_FromLong(long n) {
99-
void *result = polyglot_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, true);
112+
void *result = polyglot_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, 1);
100113
if (result == ERROR_MARKER) {
101114
return NULL;
102115
}
103116
return to_sulong(result);
104117
}
105118

106119
PyObject * PyLong_FromLongLong(long long n) {
107-
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, true);
120+
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, 1);
108121
if (result == ERROR_MARKER) {
109122
return NULL;
110123
}
@@ -116,7 +129,7 @@ PyObject * PyLong_FromUnsignedLong(unsigned long n) {
116129
}
117130

118131
PyObject * PyLong_FromUnsignedLongLong(unsigned long long n) {
119-
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, false);
132+
PyObject *result = truffle_invoke(PY_TRUFFLE_CEXT, "PyLong_FromLongLong", n, 0);
120133
if (result == ERROR_MARKER) {
121134
return NULL;
122135
}

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ PyObject* PyTruffle_GetArg(positional_argstack* p, PyObject* kwds, char** kwdnam
5353
if (p->argnum < l) {
5454
out = PyTuple_GetItem(p->argv, p->argnum);
5555
}
56-
} else if (out == NULL && p->prev == NULL && kwdnames != NULL) { // only the bottom argstack can have keyword names
56+
}
57+
if (out == NULL && p->prev == NULL && kwdnames != NULL) { // only the bottom argstack can have keyword names
5758
const char* kwdname = kwdnames[p->argnum];
5859
if (kwdname != NULL) {
59-
out = PyDict_GetItem(kwds, to_sulong(truffle_read_string(kwdname)));
60+
PyObject *nameobj = to_sulong(truffle_read_string(kwdname));
61+
out = PyDict_GetItem(kwds, nameobj);
6062
}
6163
}
62-
p->argnum++;
64+
(p->argnum)++;
6365
return out;
6466
}
6567

@@ -239,11 +241,15 @@ int PyTruffle_Arg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const ch
239241
PyTruffle_WriteOut(output_idx, unsigned long, as_long(arg));
240242
break;
241243
case 'L':
242-
PyErr_Format(PyExc_TypeError, "long long argument parsing not yet supported");
243-
return 0;
244+
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
245+
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
246+
PyTruffle_WriteOut(output_idx, long long, as_long_long(arg));
247+
break;
244248
case 'K':
245-
PyErr_Format(PyExc_TypeError, "long long argument parsing not yet supported");
246-
return 0;
249+
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
250+
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
251+
PyTruffle_WriteOut(output_idx, unsigned long long, as_unsigned_long_long(arg));
252+
break;
247253
case 'n':
248254
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
249255
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
@@ -253,11 +259,11 @@ int PyTruffle_Arg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const ch
253259
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
254260
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
255261
if (!(PyBytes_Check(arg) || PyByteArray_Check(arg))) {
256-
PyErr_Format(PyExc_TypeError, "expted bytes or bytearray, got %R", Py_TYPE(arg));
262+
PyErr_Format(PyExc_TypeError, "expected bytes or bytearray, got %R", Py_TYPE(arg));
257263
return 0;
258264
}
259265
if (Py_SIZE(arg) != 1) {
260-
PyErr_Format(PyExc_TypeError, "expted bytes or bytearray of length 1, was length %d", Py_SIZE(arg));
266+
PyErr_Format(PyExc_TypeError, "expected bytes or bytearray of length 1, was length %d", Py_SIZE(arg));
261267
return 0;
262268
}
263269
PyTruffle_WriteOut(output_idx, char, as_char(polyglot_invoke(to_java(arg), "__getitem__", 0)));
@@ -266,11 +272,11 @@ int PyTruffle_Arg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const ch
266272
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
267273
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
268274
if (!PyUnicode_Check(arg)) {
269-
PyErr_Format(PyExc_TypeError, "expted bytes or bytearray, got %R", Py_TYPE(arg));
275+
PyErr_Format(PyExc_TypeError, "expected bytes or bytearray, got %R", Py_TYPE(arg));
270276
return 0;
271277
}
272278
if (Py_SIZE(arg) != 1) {
273-
PyErr_Format(PyExc_TypeError, "expted str of length 1, was length %d", Py_SIZE(arg));
279+
PyErr_Format(PyExc_TypeError, "expected str of length 1, was length %d", Py_SIZE(arg));
274280
return 0;
275281
}
276282
PyTruffle_WriteOut(output_idx, int, as_int(polyglot_invoke(to_java(arg), "__getitem__", 0)));
@@ -292,9 +298,9 @@ int PyTruffle_Arg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const ch
292298
arg = PyTruffle_GetArg(v, kwds, kwdnames, rest_keywords_only);
293299
if (format[format_idx + 1] == '!') {
294300
format_idx++;
301+
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
295302
PyTypeObject* typeobject = (PyTypeObject*)PyTruffle_ArgN(output_idx);
296303
output_idx++;
297-
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
298304
if (!PyType_IsSubtype(Py_TYPE(arg), typeobject)) {
299305
PyErr_Format(PyExc_TypeError, "expected object of type %R, got %R", typeobject, Py_TYPE(arg));
300306
return 0;
@@ -304,9 +310,9 @@ int PyTruffle_Arg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const ch
304310
format_idx++;
305311
void* (*converter)(PyObject*,void*) = PyTruffle_ArgN(output_idx);
306312
output_idx++;
313+
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
307314
void* output = PyTruffle_ArgN(output_idx);
308315
output_idx++;
309-
PyTruffle_SkipOptionalArg(output_idx, arg, rest_optional);
310316
int status = converter(arg, output);
311317
if (!status) {
312318
if (!PyErr_Occurred()) {

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -720,18 +720,18 @@ Object doPInt(int obj, int signed, long targetTypeSize, @SuppressWarnings("unuse
720720
return obj & 0xFFFFFFFFL;
721721
}
722722
} else {
723-
throw raise(PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
723+
return raiseNative(-1, PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
724724
}
725725
}
726726

727727
@Specialization
728728
Object doPInt(long obj, @SuppressWarnings("unused") int signed, long targetTypeSize, String targetTypeName) {
729729
if (targetTypeSize == 4) {
730-
throw raise(PythonErrorType.OverflowError, "Python int too large to convert to C %s", targetTypeName);
730+
return raiseNative(-1, PythonErrorType.OverflowError, "Python int too large to convert to C %s", targetTypeName);
731731
} else if (targetTypeSize == 8) {
732732
return obj;
733733
} else {
734-
throw raise(PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
734+
return raiseNative(-1, PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
735735
}
736736
}
737737

@@ -755,17 +755,11 @@ Object doPInt(PInt obj, int signed, long targetTypeSize, String targetTypeName)
755755
throw new ArithmeticException();
756756
}
757757
} else {
758-
throw raise(PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
758+
return raiseNative(-1, PythonErrorType.SystemError, "Unsupported target size: %d", targetTypeSize);
759759
}
760760

761761
} catch (ArithmeticException e) {
762-
try {
763-
throw raise(PythonErrorType.OverflowError, "Python int too large to convert to C %s", targetTypeName);
764-
} catch (PException p) {
765-
p.getExceptionObject().reifyException();
766-
getContext().setCurrentException(p);
767-
return -1;
768-
}
762+
return raiseNative(-1, PythonErrorType.OverflowError, "Python int too large to convert to C %s", targetTypeName);
769763
}
770764
}
771765

0 commit comments

Comments
 (0)