Skip to content

Commit 335e58b

Browse files
committed
update Py_BuildValue to support most formats
1 parent e329f82 commit 335e58b

File tree

1 file changed

+77
-15
lines changed

1 file changed

+77
-15
lines changed

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

Lines changed: 77 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
250250
# define ARG truffle_get_arg(value_idx)
251251
# define APPEND_VALUE(list, value) PyList_Append(list, value); value_idx++
252252

253+
PyObject* (*converter)(void*) = NULL;
253254
unsigned int value_idx = 1;
254255
unsigned int format_idx = 0;
255256
build_stack *v = (build_stack*)calloc(1, sizeof(build_stack));
@@ -261,41 +262,102 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
261262
PyObject* list = v->list;
262263

263264
switch(c) {
264-
case 'n':
265-
APPEND_VALUE(list, (Py_ssize_t)ARG);
266-
break;
267-
case 'i':
268-
APPEND_VALUE(list, (int)ARG);
269-
break;
270265
case 's':
271-
if (ARG == NULL) {
272-
APPEND_VALUE(list, Py_None);
266+
case 'z':
267+
case 'U':
268+
if (format[format_idx + 1] == '#') {
269+
int size = (int)truffle_get_arg(value_idx + 1);
270+
if (ARG == NULL) {
271+
APPEND_VALUE(list, Py_None);
272+
} else {
273+
APPEND_VALUE(list, polyglot_from_string_n((char*)ARG, size, "utf-8"));
274+
}
275+
value_idx++; // skip length argument
276+
format_idx++;
273277
} else {
274-
APPEND_VALUE(list, polyglot_from_string((char*)ARG, "utf-8"));
278+
if (ARG == NULL) {
279+
APPEND_VALUE(list, Py_None);
280+
} else {
281+
APPEND_VALUE(list, polyglot_from_string((char*)ARG, "utf-8"));
282+
}
275283
}
276284
break;
277-
case 'd':
278-
APPEND_VALUE(list, PyFloat_FromDouble((double)(unsigned long long)ARG));
285+
case 'y':
286+
if (format[format_idx + 1] == '#') {
287+
int size = (int)truffle_get_arg(value_idx + 1);
288+
if (ARG == NULL) {
289+
APPEND_VALUE(list, Py_None);
290+
} else {
291+
APPEND_VALUE(list, PyBytes_FromStringAndSize((char*)ARG, size));
292+
}
293+
value_idx++; // skip length argument
294+
format_idx++;
295+
} else {
296+
if (ARG == NULL) {
297+
APPEND_VALUE(list, Py_None);
298+
} else {
299+
APPEND_VALUE(list, PyBytes_FromString((char*)ARG));
300+
}
301+
}
302+
break;
303+
case 'u':
304+
fprintf(stderr, "error: unsupported format 'u'\n");
305+
break;
306+
case 'i':
307+
case 'b':
308+
case 'h':
309+
APPEND_VALUE(list, (int)ARG);
279310
break;
280311
case 'l':
281312
APPEND_VALUE(list, (long)ARG);
282313
break;
283-
case 'L':
284-
APPEND_VALUE(list, (long long)ARG);
314+
case 'B':
315+
case 'H':
316+
case 'I':
317+
APPEND_VALUE(list, (unsigned int)ARG);
285318
break;
286319
case 'k':
287320
APPEND_VALUE(list, (unsigned long)ARG);
288321
break;
322+
case 'L':
323+
APPEND_VALUE(list, (long long)ARG);
324+
break;
289325
case 'K':
290326
APPEND_VALUE(list, (unsigned long long)ARG);
291327
break;
292-
case 'N':
293-
case 'S':
328+
case 'n':
329+
APPEND_VALUE(list, (Py_ssize_t)ARG);
330+
break;
331+
case 'c':
332+
c = (char)ARG;
333+
APPEND_VALUE(list, PyBytes_FromStringAndSize(&c, 1));
334+
break;
335+
case 'C':
336+
c = (char)ARG;
337+
APPEND_VALUE(list, polyglot_from_string_n(&c, 1, "utf-8"));
338+
break;
339+
case 'd':
340+
case 'f':
341+
APPEND_VALUE(list, PyFloat_FromDouble((double)(unsigned long long)ARG));
342+
break;
343+
case 'D':
344+
fprintf(stderr, "error: unsupported format 'D'\n");
345+
break;
294346
case 'O':
347+
if (format[format_idx + 1] == '&') {
348+
converter = truffle_get_arg(value_idx + 1);
349+
}
350+
case 'S':
351+
case 'N':
295352
if (ARG == NULL && !PyErr_Occurred()) {
296353
/* If a NULL was passed because a call that should have constructed a value failed, that's OK,
297354
* and we pass the error on; but if no error occurred it's not clear that the caller knew what she was doing. */
298355
PyErr_SetString(PyExc_SystemError, "NULL object passed to Py_BuildValue");
356+
} else if (converter != NULL) {
357+
APPEND_VALUE(list, converter(ARG));
358+
converter = NULL;
359+
value_idx++; // skip converter argument
360+
format_idx++;
299361
} else {
300362
APPEND_VALUE(list, ARG);
301363
}

0 commit comments

Comments
 (0)