PyObject *func_module; /* The __module__ attribute, can be anything */
PyObject *func_annotations; /* Annotations, a dict or NULL */
vectorcallfunc vectorcall;
+ /* Version number for use by specializer.
+ * Can set to non-zero when we want to specialize.
+ * Will be set to zero if any of these change:
+ * defaults
+ * kwdefaults (only if the object changes, not the contents of the dict)
+ * code
+ * annotations */
+ uint32_t func_version;
/* Invariant:
* func_closure contains the bindings for func_code->co_freevars, so
PyObject *const *stack,
size_t nargsf,
PyObject *kwnames);
+
+uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
#endif
/* Macros for direct access to these values. Type checks are *not*
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "structmember.h" // PyMemberDef
+static uint32_t next_func_version = 1;
+
PyObject *
PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
{
op->func_module = module;
op->func_annotations = NULL;
op->vectorcall = _PyFunction_Vectorcall;
-
+ op->func_version = 0;
_PyObject_GC_TRACK(op);
return (PyObject *)op;
return NULL;
}
+uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func)
+{
+ if (func->func_version != 0) {
+ return func->func_version;
+ }
+ if (next_func_version == 0) {
+ return 0;
+ }
+ uint32_t v = next_func_version++;
+ func->func_version = v;
+ return v;
+}
+
PyObject *
PyFunction_New(PyObject *code, PyObject *globals)
{
PyErr_SetString(PyExc_SystemError, "non-tuple default args");
return -1;
}
+ ((PyFunctionObject *)op)->func_version = 0;
Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults);
return 0;
}
"non-dict keyword only default args");
return -1;
}
+ ((PyFunctionObject *)op)->func_version = 0;
Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults);
return 0;
}
Py_TYPE(closure)->tp_name);
return -1;
}
+ ((PyFunctionObject *)op)->func_version = 0;
Py_XSETREF(((PyFunctionObject *)op)->func_closure, closure);
return 0;
}
"non-dict annotations");
return -1;
}
+ ((PyFunctionObject *)op)->func_version = 0;
Py_XSETREF(((PyFunctionObject *)op)->func_annotations, annotations);
return 0;
}
nclosure, nfree);
return -1;
}
+ op->func_version = 0;
Py_INCREF(value);
Py_XSETREF(op->func_code, value);
return 0;
return -1;
}
+ op->func_version = 0;
Py_XINCREF(value);
Py_XSETREF(op->func_defaults, value);
return 0;
return -1;
}
+ op->func_version = 0;
Py_XINCREF(value);
Py_XSETREF(op->func_kwdefaults, value);
return 0;
"__annotations__ must be set to a dict object");
return -1;
}
+ op->func_version = 0;
Py_XINCREF(value);
Py_XSETREF(op->func_annotations, value);
return 0;
static int
func_clear(PyFunctionObject *op)
{
+ op->func_version = 0;
Py_CLEAR(op->func_code);
Py_CLEAR(op->func_globals);
Py_CLEAR(op->func_builtins);