Skip to content

Instantly share code, notes, and snippets.

@isidentical
Created March 1, 2019 20:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isidentical/02a7842380bbc8472d0fc8b87322e940 to your computer and use it in GitHub Desktop.
Save isidentical/02a7842380bbc8472d0fc8b87322e940 to your computer and use it in GitHub Desktop.
PyObject *
custom_PyFunction_FastCallKeywords(PyObject *func, PyObject *const *stack,
Py_ssize_t nargs, PyObject *kwnames)
{
__asm__("NOP");
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
PyObject *kwdefs, *closure, *name, *qualname;
PyObject **d;
Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
Py_ssize_t nd;
PyObject *w, *args, *instance, *catlizor, *tracked, *hooks;
int i, n, pre = 0, on_call = 0, post = 0;
assert(PyFunction_Check(func));
assert(nargs >= 0);
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
assert((nargs == 0 && nkwargs == 0) || stack != NULL);
kwdefs = PyFunction_GET_KW_DEFAULTS(func);
closure = PyFunction_GET_CLOSURE(func);
name = ((PyFunctionObject *)func) -> func_name;
qualname = ((PyFunctionObject *)func) -> func_qualname;
if (argdefs != NULL) {
d = &PyTuple_GET_ITEM(argdefs, 0);
nd = PyTuple_GET_SIZE(argdefs);
}
else {
d = NULL;
nd = 0;
}
if (nargs > co->co_argcount) {
n = co->co_argcount;
}
else {
n = nargs;
}
args = PyList_New(n);
for (i = 0; i < n; i++) {
w = stack[i];
Py_INCREF(w);
PyList_SetItem(args, i, w);
}
instance = PyList_GetItem(args, 1);
if (PyObject_HasAttrString(instance, CATLIZED_SIGN)){
catlizor = PyObject_GetAttrString(instance, CATLIZED_SIGN);
tracked = PyObject_CallMethod(catlizor, "tracked", Py_True);
if (PySet_Size(tracked) > 0){
pre = PySet_Contains(tracked, PyLong_FromLong(0));
on_call = PySet_Contains(tracked, PyLong_FromLong(1));
post = PySet_Contains(tracked, PyLong_FromLong(2));
}
}
if (pre)
PyObject_CallMethod(catlizor, CAPI_METHOD, "(iO)", 0, func);
PyObject *result = _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
stack, nargs,
nkwargs ? &PyTuple_GET_ITEM(kwnames, 0) : NULL,
stack + nargs,
nkwargs, 1,
d, (int)nd, kwdefs,
closure, name, qualname);
if (on_call)
PyObject_CallMethod(catlizor, CAPI_METHOD, "(iOO)", 1, func, result);
if (post)
PyObject_CallMethod(catlizor, CAPI_METHOD, "(iO)", 2, func);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment