Skip to content

Commit 9593c44

Browse files
fangerertimfel
authored andcommitted
Implement PyObject_CallMethodObjArgs
1 parent 0c7b588 commit 9593c44

File tree

1 file changed

+49
-6
lines changed

1 file changed

+49
-6
lines changed

graalpython/com.oracle.graal.python.jni/src/capi_native.c

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,13 +482,19 @@ static PyObject* callBuffer[1024];
482482
PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, ...) {
483483
va_list myargs;
484484
va_start(myargs, callable);
485+
PyObject *arg;
485486
int count = 0;
486487
while (count <= 1024) {
487-
PyObject *o = va_arg(myargs, PyObject *);
488-
if (o == NULL) {
488+
arg = va_arg(myargs, PyObject *);
489+
if (arg == NULL) {
489490
break;
490491
}
491-
callBuffer[count++] = o;
492+
callBuffer[count++] = arg;
493+
}
494+
// test if buffer was too small
495+
if (arg != NULL) {
496+
fprintf(stderr, "argument buffer for 'PyObject_CallFunctionObjArgs' is too small");
497+
exit(-1);
492498
}
493499
PyObject* args = PyTuple_New(count);
494500
for (int i = 0; i < count; i++) {
@@ -502,9 +508,46 @@ PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, ...) {
502508
return result;
503509
}
504510

505-
PyObject * PyObject_CallMethodObjArgs(PyObject *a, PyObject *b, ...) {
506-
printf("PyObject_CallMethodObjArgs not implemented in capi_native - exiting\n");
507-
exit(-1);
511+
PyObject * PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) {
512+
if ((obj == NULL || name == NULL) && !PyErr_Occurred()) {
513+
PyErr_SetString(PyExc_SystemError,
514+
"null argument to internal routine");
515+
return NULL;
516+
}
517+
518+
PyObject *callable = NULL;
519+
int is_method = _PyObject_GetMethod(obj, name, &callable);
520+
if (callable == NULL) {
521+
return NULL;
522+
}
523+
obj = is_method ? obj : NULL;
524+
525+
va_list myargs;
526+
va_start(myargs, name);
527+
PyObject *arg;
528+
int count = 0;
529+
while (count <= 1024) {
530+
arg = va_arg(myargs, PyObject *);
531+
if (arg == NULL) {
532+
break;
533+
}
534+
callBuffer[count++] = arg;
535+
}
536+
// test if buffer was too small
537+
if (arg != NULL) {
538+
fprintf(stderr, "argument buffer for 'PyObject_CallMethodObjArgs' is too small");
539+
exit(-1);
540+
}
541+
PyObject* args = PyTuple_New(count);
542+
for (int i = 0; i < count; i++) {
543+
Py_INCREF(callBuffer[i]);
544+
PyTuple_SetItem(args, i, callBuffer[i]);
545+
}
546+
va_end(myargs);
547+
548+
PyObject* result = PyObject_CallObject(callable, args);
549+
Py_DECREF(args);
550+
return result;
508551
}
509552

510553
PyObject * _PyObject_CallMethodIdObjArgs(PyObject *object, struct _Py_Identifier *name, ...) {

0 commit comments

Comments
 (0)