#include <stdbool.h>
#include <stddef.h>
+/* Starting in CPython 3.11, CPython separates the frame state between the
+ * full frame objects exposed by the Python and C runtime state introspection
+ * APIs, and internal lighter weight interpreter frames, which are simple C
+ * structures owned by either the interpreter eval loop (while executing
+ * ordinary functions), by a generator or coroutine object (for frames that
+ * are able to be suspended), or by their corresponding full frame object (if
+ * a state instrospection API has been invoked and the full frame object has
+ * taken responsibility for the lifecycle of the interpreter frame).
+ *
+ * This split storage eliminates a lot of allocation and deallocation of full
+ * Python objects during code execution, providing a significant speed gain
+ * over the previous approach of using full Python objects for both
+ * introspection and code execution.
+ *
+ * Struct names:
+ *
+ * * PyFrameObject: the full Python frame object
+ * * _PyInterpreterFrame: the lightweight frame struct used by the eval loop
+ * * _PyCFrame: a struct that lives on the C stack and allows Python level
+ * recursive evaluation to be decoupled from recursive C level invocation
+ * of the bytecode eval loop
+ * * See pystate.h for more details on this struct
+ *
+ * Field naming conventions:
+ *
+ * * full frame object fields have an "f_*" (or "_f_*") prefix
+ * * new interpreter frame fields have no prefix
+ * * Several interpreter frame fields have the "f_*" prefix as a result of
+ * trying to keep diffs as small as was feasible when splitting the original
+ * frame struct definition in two. The following are all interpreter frame
+ * fields, NOT full frame object fields:
+ * * f_func
+ * * f_globals
+ * * f_builtins
+ * * f_locals
+ * * f_code
+ * * f_lasti
+ * * f_state
+ * * Renaming those fields was considered but ultimately deemed too disruptive
+ * to key third party projects that were trying to keep up with the Python
+ * 3.11 code evaluation changes during the alpha release cycle
+ * (see bpo-44800 for details)
+ *
+ * Naming conventions for local variables, function parameters and fields in other structs:
+ *
+ * * "frame" and "f" may refer to either full frame objects or interpreter frames
+ * * the context of use or the field naming conventions usually make the
+ * type being referenced unambiguous in code reviews
+ * * the following alternative names are used when more clarity is needed:
+ * * full frame objects: "frame_obj" (and variants like "frameobj" or "fobj")
+ * * interpreter frame structs: "frame_data" or "iframe"
+ * * "current frame" should NOT be abbreviated as "cframe", as the latter now
+ * typically refers to _PyCFrame structs
+ *
+ * Function/macro parameter types:
+ *
+ * * "PyFrame_*" functions and other public C API functions that relate to
+ * frames accept full frame object pointers
+ * * "_PyFrame_*" functions and other private C API functions that relate to
+ * frames accept either full frame object or interpreter frame pointers.
+ * Check the specific function signatures for details.
+ *
+ * Function return types:
+ *
+ * * Public C API functions will only ever return full frame object pointers
+ * * Private C API functions with an underscore prefix may return interpreter
+ * frame pointers instead. Check the specific function signatures for details.
+ */
+
struct _frame {
PyObject_HEAD
PyFrameObject *f_back; /* previous frame, or NULL */