mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
These were reverted in gh-26530 (commit17c4edc
) due to refleaks. *2c1e258
- Compute deref offsets in compiler (gh-25152) *b2bf2bc
- Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388) This change fixes the refleaks. https://bugs.python.org/issue43693
This commit is contained in:
parent
001eb520b5
commit
2ab27c4af4
23 changed files with 6044 additions and 5710 deletions
|
@ -150,6 +150,58 @@ int _Py_Quicken(PyCodeObject *code);
|
|||
|
||||
extern Py_ssize_t _Py_QuickenedCount;
|
||||
|
||||
|
||||
/* "Locals plus" for a code object is the set of locals + cell vars +
|
||||
* free vars. This relates to variable names as well as offsets into
|
||||
* the "fast locals" storage array of execution frames. The compiler
|
||||
* builds the list of names, their offsets, and the corresponding
|
||||
* kind of local.
|
||||
*
|
||||
* Those kinds represent the source of the initial value and the
|
||||
* variable's scope (as related to closures). A "local" is an
|
||||
* argument or other variable defined in the current scope. A "free"
|
||||
* variable is one that is defined in an outer scope and comes from
|
||||
* the function's closure. A "cell" variable is a local that escapes
|
||||
* into an inner function as part of a closure, and thus must be
|
||||
* wrapped in a cell. Any "local" can also be a "cell", but the
|
||||
* "free" kind is mutually exclusive with both.
|
||||
*/
|
||||
|
||||
// We would use an enum if C let us specify the storage type.
|
||||
typedef unsigned char _PyLocalsPlusKind;
|
||||
/* Note that these all fit within _PyLocalsPlusKind, as do combinations. */
|
||||
// Later, we will use the smaller numbers to differentiate the different
|
||||
// kinds of locals (e.g. pos-only arg, varkwargs, local-only).
|
||||
#define CO_FAST_LOCAL 0x20
|
||||
#define CO_FAST_CELL 0x40
|
||||
#define CO_FAST_FREE 0x80
|
||||
|
||||
typedef _PyLocalsPlusKind *_PyLocalsPlusKinds;
|
||||
|
||||
static inline int
|
||||
_PyCode_InitLocalsPlusKinds(int num, _PyLocalsPlusKinds *pkinds)
|
||||
{
|
||||
if (num == 0) {
|
||||
*pkinds = NULL;
|
||||
return 0;
|
||||
}
|
||||
_PyLocalsPlusKinds kinds = PyMem_NEW(_PyLocalsPlusKind, num);
|
||||
if (kinds == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
*pkinds = kinds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_PyCode_ClearLocalsPlusKinds(_PyLocalsPlusKinds kinds)
|
||||
{
|
||||
if (kinds != NULL) {
|
||||
PyMem_Free(kinds);
|
||||
}
|
||||
}
|
||||
|
||||
struct _PyCodeConstructor {
|
||||
/* metadata */
|
||||
PyObject *filename;
|
||||
|
@ -166,13 +218,13 @@ struct _PyCodeConstructor {
|
|||
PyObject *names;
|
||||
|
||||
/* mapping frame offsets to information */
|
||||
PyObject *varnames;
|
||||
PyObject *cellvars;
|
||||
PyObject *freevars;
|
||||
PyObject *localsplusnames;
|
||||
_PyLocalsPlusKinds localspluskinds;
|
||||
|
||||
/* args (within varnames) */
|
||||
int argcount;
|
||||
int posonlyargcount;
|
||||
// XXX Replace argcount with posorkwargcount (argcount - posonlyargcount).
|
||||
int kwonlyargcount;
|
||||
|
||||
/* needed to create the frame */
|
||||
|
@ -199,6 +251,11 @@ PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);
|
|||
|
||||
int _PyCode_InitOpcache(PyCodeObject *co);
|
||||
|
||||
/* Getters for internal PyCodeObject data. */
|
||||
PyAPI_FUNC(PyObject *) _PyCode_GetVarnames(PyCodeObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyCode_GetCellvars(PyCodeObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyCode_GetFreevars(PyCodeObject *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue