bpo-43693: Un-revert commits 2c1e258 and b2bf2bc. (gh-26577)

These were reverted in gh-26530 (commit 17c4edc) 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:
Eric Snow 2021-06-07 12:22:26 -06:00 committed by GitHub
parent 001eb520b5
commit 2ab27c4af4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 6044 additions and 5710 deletions

View file

@ -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
}