Skip to content

Commit 1fccf3a

Browse files
committed
add Py_VaBuildValue and redefine the dependant functions
1 parent b4a502f commit 1fccf3a

File tree

2 files changed

+63
-47
lines changed

2 files changed

+63
-47
lines changed

graalpython/com.oracle.graal.python.cext/include/Python.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,6 @@
127127
#undef Py_INCREF
128128
#define Py_INCREF(o) 0
129129

130-
// TODO: (tfel) Is this necessary?
131-
#ifndef Py_BuildValue
132-
#define Py_BuildValue _Py_BuildValue_SizeT
133-
#endif
134-
135130
/*
136131
* #define Py_INCREF(op) ( \
137132
* _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \

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

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,21 @@ typedef struct _build_stack {
468468
struct _build_stack* prev;
469469
} build_stack;
470470

471-
PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
472-
# define ARG polyglot_get_arg(value_idx)
473-
# define APPEND_VALUE(list, value) PyList_Append(list, value); value_idx++
471+
PyObject* Py_VaBuildValue(const char *format, va_list va) {
472+
return _Py_VaBuildValue_SizeT(format, va);
473+
}
474474

475+
PyObject* _Py_VaBuildValue_SizeT(const char *format, va_list va) {
475476
PyObject* (*converter)(void*) = NULL;
476477
char argchar[2] = {'\0'};
477-
unsigned int value_idx = 1;
478478
unsigned int format_idx = 0;
479479
build_stack *v = (build_stack*)calloc(1, sizeof(build_stack));
480480
build_stack *next;
481481
v->list = PyList_New(0);
482482

483+
char *char_arg;
484+
void *void_arg;
485+
483486
char c = format[format_idx];
484487
while (c != '\0') {
485488
PyObject* list = v->list;
@@ -488,38 +491,38 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
488491
case 's':
489492
case 'z':
490493
case 'U':
494+
char_arg = va_arg(va, char*);
491495
if (format[format_idx + 1] == '#') {
492-
int size = (int)polyglot_get_arg(value_idx + 1);
493-
if (ARG == NULL) {
494-
APPEND_VALUE(list, Py_None);
496+
int size = va_arg(va, int);
497+
if (char_arg == NULL) {
498+
PyList_Append(list, Py_None);
495499
} else {
496-
APPEND_VALUE(list, PyUnicode_FromStringAndSize((char*)ARG, size));
500+
PyList_Append(list, PyUnicode_FromStringAndSize(char_arg, size));
497501
}
498-
value_idx++; // skip length argument
499502
format_idx++;
500503
} else {
501-
if (ARG == NULL) {
502-
APPEND_VALUE(list, Py_None);
504+
if (char_arg == NULL) {
505+
PyList_Append(list, Py_None);
503506
} else {
504-
APPEND_VALUE(list, PyUnicode_FromString((char*)ARG));
507+
PyList_Append(list, PyUnicode_FromString(char_arg));
505508
}
506509
}
507510
break;
508511
case 'y':
512+
char_arg = va_arg(va, char*);
509513
if (format[format_idx + 1] == '#') {
510-
int size = (int)polyglot_get_arg(value_idx + 1);
511-
if (ARG == NULL) {
512-
APPEND_VALUE(list, Py_None);
514+
int size = va_arg(va, int);
515+
if (char_arg == NULL) {
516+
PyList_Append(list, Py_None);
513517
} else {
514-
APPEND_VALUE(list, PyBytes_FromStringAndSize((char*)ARG, size));
518+
PyList_Append(list, PyBytes_FromStringAndSize(char_arg, size));
515519
}
516-
value_idx++; // skip length argument
517520
format_idx++;
518521
} else {
519-
if (ARG == NULL) {
520-
APPEND_VALUE(list, Py_None);
522+
if (char_arg == NULL) {
523+
PyList_Append(list, Py_None);
521524
} else {
522-
APPEND_VALUE(list, PyBytes_FromString((char*)ARG));
525+
PyList_Append(list, PyBytes_FromString(char_arg));
523526
}
524527
}
525528
break;
@@ -529,63 +532,68 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
529532
case 'i':
530533
case 'b':
531534
case 'h':
532-
APPEND_VALUE(list, PyLong_FromLong((int)ARG));
535+
PyList_Append(list, PyLong_FromLong(va_arg(va, int)));
533536
break;
534537
case 'l':
535-
APPEND_VALUE(list, PyLong_FromLong((long)ARG));
538+
PyList_Append(list, PyLong_FromLong(va_arg(va, long)));
536539
break;
537540
case 'B':
538541
case 'H':
539542
case 'I':
540-
APPEND_VALUE(list, PyLong_FromUnsignedLong((unsigned int)ARG));
543+
PyList_Append(list, PyLong_FromUnsignedLong(va_arg(va, unsigned int)));
541544
break;
542545
case 'k':
543-
APPEND_VALUE(list, PyLong_FromUnsignedLong((unsigned long)ARG));
546+
PyList_Append(list, PyLong_FromUnsignedLong(va_arg(va, unsigned long)));
544547
break;
545548
case 'L':
546-
APPEND_VALUE(list, PyLong_FromLongLong((long long)ARG));
549+
PyList_Append(list, PyLong_FromLongLong(va_arg(va, long long)));
547550
break;
548551
case 'K':
549-
APPEND_VALUE(list, PyLong_FromLongLong((unsigned long long)ARG));
552+
PyList_Append(list, PyLong_FromLongLong(va_arg(va, unsigned long long)));
550553
break;
551554
case 'n':
552-
APPEND_VALUE(list, PyLong_FromSsize_t((Py_ssize_t)ARG));
555+
PyList_Append(list, PyLong_FromSsize_t(va_arg(va, Py_ssize_t)));
553556
break;
554557
case 'c':
555-
argchar[0] = (char)ARG;
556-
APPEND_VALUE(list, PyBytes_FromStringAndSize(argchar, 1));
558+
// note: a vararg char is promoted to int according to the C standard
559+
argchar[0] = va_arg(va, int);
560+
PyList_Append(list, PyBytes_FromStringAndSize(argchar, 1));
557561
break;
558562
case 'C':
559-
argchar[0] = (char)ARG;
560-
APPEND_VALUE(list, polyglot_from_string(argchar, "ascii"));
563+
// note: a vararg char is promoted to int according to the C standard
564+
argchar[0] = va_arg(va, int);
565+
PyList_Append(list, polyglot_from_string(argchar, "ascii"));
561566
break;
562567
case 'd':
563568
case 'f':
564-
APPEND_VALUE(list, PyFloat_FromDouble((double)(unsigned long long)ARG));
569+
PyList_Append(list, PyFloat_FromDouble(va_arg(va, double)));
565570
break;
566571
case 'D':
567572
fprintf(stderr, "error: unsupported format 'D'\n");
568573
break;
569574
case 'O':
570-
if (format[format_idx + 1] == '&') {
571-
converter = polyglot_get_arg(value_idx + 1);
572-
}
573575
case 'S':
574576
case 'N':
575-
if (ARG == NULL) {
577+
void_arg = va_arg(va, void*);
578+
if (c == 'O') {
579+
if (format[format_idx + 1] == '&') {
580+
converter = va_arg(va, void*);
581+
}
582+
}
583+
584+
if (void_arg == NULL) {
576585
if (!PyErr_Occurred()) {
577586
/* If a NULL was passed because a call that should have constructed a value failed, that's OK,
578587
* and we pass the error on; but if no error occurred it's not clear that the caller knew what she was doing. */
579588
PyErr_SetString(PyExc_SystemError, "NULL object passed to Py_BuildValue");
580589
}
581590
return NULL;
582591
} else if (converter != NULL) {
583-
APPEND_VALUE(list, converter(ARG));
592+
PyList_Append(list, converter(void_arg));
584593
converter = NULL;
585-
value_idx++; // skip converter argument
586594
format_idx++;
587595
} else {
588-
APPEND_VALUE(list, ARG);
596+
PyList_Append(list, (PyObject*)void_arg);
589597
}
590598
break;
591599
case '(':
@@ -648,9 +656,6 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
648656
c = format[++format_idx];
649657
}
650658

651-
# undef APPEND_VALUE
652-
# undef ARG
653-
654659
if (v->prev != NULL) {
655660
PyErr_SetString(PyExc_SystemError, "dangling group in Py_BuildValue");
656661
return NULL;
@@ -667,6 +672,22 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
667672
}
668673
}
669674

675+
PyObject* Py_BuildValue(const char *format, ...) {
676+
va_list va;
677+
va_start(va, format);
678+
PyObject *result = Py_VaBuildValue(format, va);
679+
va_end(va);
680+
return result;
681+
}
682+
683+
PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
684+
va_list va;
685+
va_start(va, format);
686+
PyObject *result = _Py_VaBuildValue_SizeT(format, va);
687+
va_end(va);
688+
return result;
689+
}
690+
670691
// taken from CPython "Python/modsupport.c"
671692
int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) {
672693
PyObject *o = PyUnicode_FromString(value);

0 commit comments

Comments
 (0)