SlotConnectorBase::SlotConnectorBase(PyObject* slot, int n_sig_args) { function = 0; klass = 0; PyObject* instance = 0; cfunction = 0; if (PyMethod_Check(slot)) { instance = PyMethod_GET_SELF(slot); klass = PyMethod_GET_CLASS(slot); function = PyMethod_GET_FUNCTION(slot); Py_INCREF(klass); Py_INCREF(function); PyObject* func_code = PyObject_GetAttrString(function, "func_code"); PyObject* co_argcount = PyObject_GetAttrString(func_code, "co_argcount"); n_slot_args = PyInt_AsLong(co_argcount)-1; if (n_slot_args == -1) { PyErr_SetString(PyExc_TypeError, "Slot method should at least have a 'self' argument"); return; } core = ((Wt::WObject*)(((PyCPPClassInstance*)instance)->proxy->getCoreAsVoid())); Py_DECREF(func_code); Py_DECREF(co_argcount); } else if PyCFunction_Check(slot) { instance = PyCFunction_GET_SELF(slot); cfunction = PyCFunction_GET_FUNCTION(slot); flags = PyCFunction_GET_FLAGS(slot); n_slot_args = PyCFunction_GET_NARGS(slot); core = ((Wt::WObject*)(((PyCPPClassInstance*)instance)->proxy->getCoreAsVoid())); } else {
/* A custom, fast, inlinable version of PyCFunction_Call() */ static PyObject * call_cfunc(DispatcherObject *self, PyObject *cfunc, PyObject *args, PyObject *kws, PyObject *locals) { PyCFunctionWithKeywords fn; PyThreadState *tstate; assert(PyCFunction_Check(cfunc)); assert(PyCFunction_GET_FLAGS(cfunc) == METH_VARARGS | METH_KEYWORDS); fn = (PyCFunctionWithKeywords) PyCFunction_GET_FUNCTION(cfunc); tstate = PyThreadState_GET(); if (tstate->use_tracing && tstate->c_profilefunc) { /* * The following code requires some explaining: * * We want the jit-compiled function to be visible to the profiler, so we * need to synthesize a frame for it. * The PyFrame_New() constructor doesn't do anything with the 'locals' value if the 'code's * 'CO_NEWLOCALS' flag is set (which is always the case nowadays). * So, to get local variables into the frame, we have to manually set the 'f_locals' * member, then call `PyFrame_LocalsToFast`, where a subsequent call to the `frame.f_locals` * property (by virtue of the `frame_getlocals` function in frameobject.c) will find them. */ PyCodeObject *code = (PyCodeObject*)PyObject_GetAttrString((PyObject*)self, "__code__"); PyObject *globals = PyDict_New(); PyObject *builtins = PyEval_GetBuiltins(); PyFrameObject *frame = NULL; PyObject *result = NULL; if (!code) { PyErr_Format(PyExc_RuntimeError, "No __code__ attribute found."); goto error; } /* Populate builtins, which is required by some JITted functions */ if (PyDict_SetItemString(globals, "__builtins__", builtins)) { goto error; } frame = PyFrame_New(tstate, code, globals, NULL); if (frame == NULL) { goto error; } /* Populate the 'fast locals' in `frame` */ Py_XDECREF(frame->f_locals); frame->f_locals = locals; Py_XINCREF(frame->f_locals); PyFrame_LocalsToFast(frame, 0); tstate->frame = frame; C_TRACE(result, fn(PyCFunction_GET_SELF(cfunc), args, kws)); tstate->frame = frame->f_back; error: Py_XDECREF(frame); Py_XDECREF(globals); Py_XDECREF(code); return result; } else return fn(PyCFunction_GET_SELF(cfunc), args, kws); }
PyObject * PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); Py_ssize_t size; switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { case METH_VARARGS: if (kw == NULL || PyDict_Size(kw) == 0) return (*meth)(self, arg); break; case METH_VARARGS | METH_KEYWORDS: case METH_OLDARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 0) return (*meth)(self, NULL); PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", f->m_ml->ml_name, size); return NULL; } break; case METH_O: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 1) return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", f->m_ml->ml_name, size); return NULL; } break; case METH_OLDARGS: /* the really old style */ if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 1) arg = PyTuple_GET_ITEM(arg, 0); else if (size == 0) arg = NULL; return (*meth)(self, arg); } break; default: PyErr_BadInternalCall(); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; }
int PyCFunction_GetFlags(PyObject *op) { if (!PyCFunction_Check(op)) { PyErr_BadInternalCall(); return -1; } return PyCFunction_GET_FLAGS(op); }
PyObject * PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); Py_ssize_t size; switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { case METH_VARARGS: if (kw == NULL || PyDict_Size(kw) == 0) return (*meth)(self, arg); break; case METH_VARARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 0) return (*meth)(self, NULL); PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", f->m_ml->ml_name, size); return NULL; } break; case METH_O: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 1) return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", f->m_ml->ml_name, size); return NULL; } break; default: PyErr_SetString(PyExc_SystemError, "Bad call flags in " "PyCFunction_Call. METH_OLDARGS is no " "longer supported!"); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; }
PyObject* signalCall(PyObject* self, PyObject* args, PyObject* kw) { PySideSignal* signal = reinterpret_cast<PySideSignal*>(self); if (!signal->homonymousMethod) { PyErr_SetString(PyExc_TypeError, "native Qt signal is not callable"); return 0; } descrgetfunc getDescriptor = signal->homonymousMethod->ob_type->tp_descr_get; Shiboken::AutoDecRef homonymousMethod(getDescriptor(signal->homonymousMethod, 0, 0)); if (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC) return PyCFunction_Call(homonymousMethod, args, kw); ternaryfunc callFunc = signal->homonymousMethod->ob_type->tp_call; return callFunc(homonymousMethod, args, kw); }
static PyObject * call_function(PyObject ***pp_stack, int oparg) { int na = oparg & 0xff; int nk = (oparg>>8) & 0xff; int n = na + 2 * nk; PyObject **pfunc = (*pp_stack) - n - 1; PyObject *func = *pfunc; PyObject *x, *w; /* Always dispatch PyCFunction first, because these are presumed to be the most frequent callable object. */ if (PyCFunction_Check(func) && nk == 0) { int flags = PyCFunction_GET_FLAGS(func); if (flags & (METH_NOARGS | METH_O)) { PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); if (flags & METH_NOARGS && na == 0) x = (*meth)(self, NULL); else if (flags & METH_O && na == 1) { PyObject *arg = EXT_POP(*pp_stack); x = (*meth)(self, arg); Py_DECREF(arg); } else { err_args(func, flags, na); x = NULL; } } else { PyObject *callargs; callargs = load_args(pp_stack, na); x = PyCFunction_Call(func, callargs, NULL); Py_XDECREF(callargs); } } else { if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) { /* optimize access to bound methods */ PyObject *self = PyMethod_GET_SELF(func); Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); Py_INCREF(func); Py_DECREF(*pfunc); *pfunc = self; na++; n++; } else Py_INCREF(func); if (PyFunction_Check(func)) x = fast_function(func, pp_stack, n, na, nk); else x = do_call(func, pp_stack, na, nk); Py_DECREF(func); } /* What does this do? */ while ((*pp_stack) > pfunc) { w = EXT_POP(*pp_stack); Py_DECREF(w); } return x; }
PyObject * PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); Py_ssize_t size; switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { case METH_VARARGS: if (kw == NULL || PyDict_Size(kw) == 0) return (*meth)(self, arg); break; case METH_VARARGS | METH_KEYWORDS: case METH_OLDARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_ARG_RANGE: { if (kw == NULL || PyDict_Size(kw) == 0) { PyObject *args[PY_MAX_ARITY] = {NULL}; int min_arity = PyCFunction_GET_MIN_ARITY(func); int max_arity = PyCFunction_GET_MAX_ARITY(func); size = PyTuple_GET_SIZE(arg); switch (size) { default: PyErr_BadInternalCall(); return NULL; case 3: args[2] = PyTuple_GET_ITEM(arg, 2); case 2: args[1] = PyTuple_GET_ITEM(arg, 1); case 1: args[0] = PyTuple_GET_ITEM(arg, 0); case 0: break; } /* But wait, you ask, what about {un,bin}ary functions? Aren't we passing more arguments than it expects? Yes, but C allows this. Go C. */ if (min_arity <= size && size <= max_arity) return (*(PyCFunctionThreeArgs)meth) (self, args[0], args[1], args[2]); if (max_arity == min_arity) PyErr_Format(PyExc_TypeError, "%.200s() takes exactly %d argument(s)" " (%zd given)", f->m_ml->ml_name, max_arity, size); else PyErr_Format(PyExc_TypeError, "%.200s() takes %d-%d arguments" " (%zd given)", f->m_ml->ml_name, min_arity, max_arity, size); return NULL; } break; } case METH_OLDARGS: /* the really old style */ if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 1) arg = PyTuple_GET_ITEM(arg, 0); else if (size == 0) arg = NULL; return (*meth)(self, arg); } break; /* METH_O is deprecated; PyCFunction_NewEx is supposed to convert it to METH_ARG_RANGE and set ml_{min,max}_arity correctly. */ case METH_O: default: PyErr_BadInternalCall(); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; }
PyObject * PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); PyObject *arg, *res; Py_ssize_t size; int flags; /* PyCFunction_Call() must not be called with an exception set, because it may clear it (directly or indirectly) and so the caller loses its exception */ assert(!PyErr_Occurred()); flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST); if (flags == (METH_VARARGS | METH_KEYWORDS)) { res = (*(PyCFunctionWithKeywords)meth)(self, args, kwds); } else { if (kwds != NULL && PyDict_Size(kwds) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; } switch (flags) { case METH_VARARGS: res = (*meth)(self, args); break; case METH_NOARGS: size = PyTuple_GET_SIZE(args); if (size != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", f->m_ml->ml_name, size); return NULL; } res = (*meth)(self, NULL); break; case METH_O: size = PyTuple_GET_SIZE(args); if (size != 1) { PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", f->m_ml->ml_name, size); return NULL; } arg = PyTuple_GET_ITEM(args, 0); res = (*meth)(self, arg); break; default: PyErr_SetString(PyExc_SystemError, "Bad call flags in PyCFunction_Call. " "METH_OLDARGS is no longer supported!"); return NULL; } } return _Py_CheckFunctionResult(func, res, NULL); }
PyObject * PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { STACKLESS_GETARG(); PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); Py_ssize_t size; #ifdef STACKLESS switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS)) { #else switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { #endif case METH_VARARGS: if (kw == NULL || PyDict_Size(kw) == 0) WRAP_RETURN( (*meth)(self, arg) ) break; case METH_VARARGS | METH_KEYWORDS: WRAP_RETURN( (*(PyCFunctionWithKeywords)meth)(self, arg, kw) ) case METH_NOARGS: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 0) WRAP_RETURN( (*meth)(self, NULL) ) PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", f->m_ml->ml_name, size); return NULL; } break; case METH_O: if (kw == NULL || PyDict_Size(kw) == 0) { size = PyTuple_GET_SIZE(arg); if (size == 1) WRAP_RETURN( (*meth)(self, PyTuple_GET_ITEM(arg, 0)) ) PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", f->m_ml->ml_name, size); return NULL; } break; default: PyErr_SetString(PyExc_SystemError, "Bad call flags in " "PyCFunction_Call. METH_OLDARGS is no " "longer supported!"); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; } /* Methods (the standard built-in methods, that is) */ static void meth_dealloc(PyCFunctionObject *m) { _PyObject_GC_UNTRACK(m); Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); if (numfree < PyCFunction_MAXFREELIST) { m->m_self = (PyObject *)free_list; free_list = m; numfree++; } else { PyObject_GC_Del(m); } }