Skip to content

Commit 44a4ed1

Browse files
committed
[GR-22248] Avoid helper objects in C API call functions.
PullRequest: graalpython/1675
2 parents 79dba74 + 5a9f73f commit 44a4ed1

File tree

3 files changed

+238
-92
lines changed

3 files changed

+238
-92
lines changed

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

Lines changed: 35 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -199,129 +199,92 @@ PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwar
199199
return _Py_CheckFunctionResult(callable, result, NULL);
200200
}
201201

202+
#define IS_SINGLE_ARG(_fmt) ((_fmt[0]) != '\0' && (_fmt[1]) == '\0')
203+
204+
typedef PyObject *(*call_fun_t)(PyObject *, PyObject *, PyObject *, int32_t);
205+
UPCALL_TYPED_ID(PyObject_Call, call_fun_t);
202206
PyObject* PyObject_Call(PyObject* callable, PyObject* args, PyObject* kwargs) {
203-
return polyglot_invoke(PY_TRUFFLE_CEXT, "PyObject_Call", native_to_java(callable), native_to_java(args), native_to_java(kwargs));
207+
return _jls_PyObject_Call(native_to_java(callable), native_to_java(args), native_to_java(kwargs), 0);
204208
}
205209

206210
PyObject* PyObject_CallObject(PyObject* callable, PyObject* args) {
207-
return PyObject_Call(callable, args, PyDict_New());
211+
return _jls_PyObject_Call(native_to_java(callable), native_to_java(args), NULL, 0);
208212
}
209213

210-
NO_INLINE
211214
PyObject* PyObject_CallFunction(PyObject* callable, const char* fmt, ...) {
212215
if (fmt == NULL || fmt[0] == '\0') {
213-
return PyObject_CallObject(callable, NULL);
216+
return _jls_PyObject_Call(native_to_java(callable), NULL, NULL, 0);
214217
}
215-
216218
va_list va;
217219
va_start(va, fmt);
218220
PyObject* args = Py_VaBuildValue(fmt, va);
219221
va_end(va);
220-
221-
if (strlen(fmt) < 2) {
222-
PyObject* singleArg = args;
223-
args = PyTuple_New(strlen(fmt));
224-
if (strlen(fmt) == 1) {
225-
Py_XINCREF(singleArg);
226-
PyTuple_SetItem(args, 0, singleArg);
227-
}
228-
}
229-
return PyObject_CallObject(callable, args);
222+
return _jls_PyObject_Call(native_to_java(callable), native_to_java(args), NULL, IS_SINGLE_ARG(fmt));
230223
}
231224

232-
NO_INLINE
233225
PyObject* _PyObject_CallFunction_SizeT(PyObject* callable, const char* fmt, ...) {
234226
if (fmt == NULL || fmt[0] == '\0') {
235-
return PyObject_CallObject(callable, NULL);
227+
return _jls_PyObject_Call(native_to_java(callable), NULL, NULL, 0);
236228
}
237-
238229
va_list va;
239230
va_start(va, fmt);
240231
PyObject* args = Py_VaBuildValue(fmt, va);
241232
va_end(va);
242-
243-
if (strlen(fmt) < 2) {
244-
PyObject* singleArg = args;
245-
args = PyTuple_New(strlen(fmt));
246-
if (strlen(fmt) == 1) {
247-
Py_XINCREF(singleArg);
248-
PyTuple_SetItem(args, 0, singleArg);
249-
}
250-
}
251-
return PyObject_CallObject(callable, args);
233+
return _jls_PyObject_Call(native_to_java(callable), native_to_java(args), NULL, IS_SINGLE_ARG(fmt));
252234
}
253235

254-
NO_INLINE
236+
typedef PyObject *(*call_fun_obj_args_t)(PyObject *, void *);
237+
UPCALL_TYPED_ID(PyObject_CallFunctionObjArgs, call_fun_obj_args_t);
255238
PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...) {
256239
va_list vargs;
257240
va_start(vargs, callable);
258241
// the arguments are given as a variable list followed by NULL
259-
int nargs = polyglot_get_array_size(vargs) - 1;
260-
PyObject* args = PyTuple_New(nargs);
261-
for (int i = 0; i < nargs; i++) {
262-
PyObject* arg = (PyObject*) va_arg(vargs, PyObject *);
263-
Py_INCREF(arg);
264-
PyTuple_SetItem(args, i, arg);
265-
}
242+
PyObject *result = _jls_PyObject_CallFunctionObjArgs(native_to_java(callable), &vargs);
266243
va_end(vargs);
267-
return PyObject_CallObject(callable, args);
244+
return result;
268245
}
269246

270-
UPCALL_ID(PyObject_CallMethod);
271-
NO_INLINE
247+
typedef PyObject *(*call_method_t)(PyObject *, void *, void *, int32_t);
248+
UPCALL_TYPED_ID(PyObject_CallMethod, call_method_t);
272249
PyObject* PyObject_CallMethod(PyObject* object, const char* method, const char* fmt, ...) {
273250
PyObject* args;
274251
if (fmt == NULL || fmt[0] == '\0') {
275-
args = Py_None;
276-
} else {
277-
va_list va;
278-
va_start(va, fmt);
279-
args = Py_VaBuildValue(fmt, va);
280-
va_end(va);
252+
return _jls_PyObject_CallMethod(native_to_java(object), polyglot_from_string(method, SRC_CS), NULL, 0);
281253
}
282-
return UPCALL_CEXT_O(_jls_PyObject_CallMethod, native_to_java(object), polyglot_from_string(method, SRC_CS), native_to_java(args));
254+
va_list va;
255+
va_start(va, fmt);
256+
args = Py_VaBuildValue(fmt, va);
257+
va_end(va);
258+
return _jls_PyObject_CallMethod(native_to_java(object), polyglot_from_string(method, SRC_CS), native_to_java(args), IS_SINGLE_ARG(fmt));
283259
}
284260

285-
NO_INLINE
261+
typedef PyObject *(*call_meth_obj_args_t)(PyObject *, void *, void *);
262+
UPCALL_TYPED_ID(PyObject_CallMethodObjArgs, call_meth_obj_args_t);
286263
PyObject* PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) {
287264
va_list vargs;
288265
va_start(vargs, name);
289266
// the arguments are given as a variable list followed by NULL
290-
int argc = polyglot_get_array_size(vargs) - 1;
291-
PyObject* args = PyTuple_New(argc);
292-
for (int i = 0; i < argc; i++) {
293-
PyObject *arg = va_arg(vargs, PyObject*);
294-
Py_INCREF(arg);
295-
PyTuple_SetItem(args, i, arg);
296-
}
267+
PyObject *result = _jls_PyObject_CallMethodObjArgs(native_to_java(callable), native_to_java(name), &vargs);
297268
va_end(vargs);
298-
return UPCALL_CEXT_O(_jls_PyObject_CallMethod, native_to_java(callable), native_to_java(name), native_to_java(args));
269+
return result;
299270
}
300271

301-
NO_INLINE
302272
PyObject* _PyObject_CallMethod_SizeT(PyObject* object, const char* method, const char* fmt, ...) {
303273
PyObject* args;
304274
if (fmt == NULL || fmt[0] == '\0') {
305-
args = Py_None;
306-
} else {
307-
va_list va;
308-
va_start(va, fmt);
309-
args = Py_VaBuildValue(fmt, va);
310-
va_end(va);
275+
return _jls_PyObject_CallMethod(native_to_java(object), polyglot_from_string(method, SRC_CS), NULL, 0);
311276
}
312-
return UPCALL_CEXT_O(_jls_PyObject_CallMethod, native_to_java(object), polyglot_from_string(method, SRC_CS), native_to_java(args));
277+
va_list va;
278+
va_start(va, fmt);
279+
args = Py_VaBuildValue(fmt, va);
280+
va_end(va);
281+
return _jls_PyObject_CallMethod(native_to_java(object), polyglot_from_string(method, SRC_CS), native_to_java(args), IS_SINGLE_ARG(fmt));
313282
}
314283

284+
typedef PyObject *(*fast_call_dict_fun_t)(PyObject *, void *, PyObject *);
285+
UPCALL_TYPED_ID(PyObject_FastCallDict, fast_call_dict_fun_t);
315286
PyObject * _PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t nargs, PyObject *kwargs) {
316-
PyObject* targs = PyTuple_New(nargs);
317-
Py_ssize_t i;
318-
PyObject* arg;
319-
for(i=0; i < nargs; i++) {
320-
arg = args[i];
321-
Py_XINCREF(arg);
322-
PyTuple_SetItem(targs, i, arg);
323-
}
324-
return polyglot_invoke(PY_TRUFFLE_CEXT, "PyObject_Call", native_to_java(func), native_to_java(targs), native_to_java(kwargs));
287+
return _jls_PyObject_FastCallDict(native_to_java(func), polyglot_from_PyObjectPtr_array(args, nargs), native_to_java(kwargs));
325288
}
326289

327290
PyObject* PyObject_Type(PyObject* obj) {

0 commit comments

Comments
 (0)