mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	bpo-43693: Turn localspluskinds into an object (GH-26749)
Managing it as a bare pointer to malloc'ed bytes is just too awkward in a few places.
This commit is contained in:
		
							parent
							
								
									c5d700f0e2
								
							
						
					
					
						commit
						355f5dd36a
					
				
					 14 changed files with 5455 additions and 5395 deletions
				
			
		|  | @ -26,9 +26,6 @@ typedef uint16_t _Py_CODEUNIT; | ||||||
| typedef struct _PyOpcache _PyOpcache; | typedef struct _PyOpcache _PyOpcache; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| typedef unsigned char _PyLocalsPlusKind; |  | ||||||
| typedef _PyLocalsPlusKind *_PyLocalsPlusKinds; |  | ||||||
| 
 |  | ||||||
| /* Bytecode object */ | /* Bytecode object */ | ||||||
| struct PyCodeObject { | struct PyCodeObject { | ||||||
|     PyObject_HEAD |     PyObject_HEAD | ||||||
|  | @ -75,7 +72,7 @@ struct PyCodeObject { | ||||||
|     int co_firstlineno;         /* first source line number */ |     int co_firstlineno;         /* first source line number */ | ||||||
|     PyObject *co_code;          /* instruction opcodes */ |     PyObject *co_code;          /* instruction opcodes */ | ||||||
|     PyObject *co_localsplusnames;  /* tuple mapping offsets to names */ |     PyObject *co_localsplusnames;  /* tuple mapping offsets to names */ | ||||||
|     _PyLocalsPlusKinds co_localspluskinds; /* array mapping to local kinds */ |     PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte per variable) */ | ||||||
|     PyObject *co_filename;      /* unicode (where it was loaded from) */ |     PyObject *co_filename;      /* unicode (where it was loaded from) */ | ||||||
|     PyObject *co_name;          /* unicode (name, for reference) */ |     PyObject *co_name;          /* unicode (name, for reference) */ | ||||||
|     PyObject *co_linetable;     /* string (encoding addr<->lineno mapping) See
 |     PyObject *co_linetable;     /* string (encoding addr<->lineno mapping) See
 | ||||||
|  | @ -222,4 +219,3 @@ void PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int | ||||||
| int PyLineTable_NextAddressRange(PyCodeAddressRange *range); | int PyLineTable_NextAddressRange(PyCodeAddressRange *range); | ||||||
| int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); | int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -180,39 +180,34 @@ extern Py_ssize_t _Py_QuickenedCount; | ||||||
|  * "free" kind is mutually exclusive with both. |  * "free" kind is mutually exclusive with both. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| // For now _PyLocalsPlusKind and _PyLocalsPlusKinds are defined
 | // Note that these all fit within a byte, as do combinations.
 | ||||||
| // in Include/cpython/code.h.
 |  | ||||||
| /* Note that these all fit within _PyLocalsPlusKind, as do combinations. */ |  | ||||||
| // Later, we will use the smaller numbers to differentiate the different
 | // Later, we will use the smaller numbers to differentiate the different
 | ||||||
| // kinds of locals (e.g. pos-only arg, varkwargs, local-only).
 | // kinds of locals (e.g. pos-only arg, varkwargs, local-only).
 | ||||||
| #define CO_FAST_LOCAL   0x20 | #define CO_FAST_LOCAL   0x20 | ||||||
| #define CO_FAST_CELL    0x40 | #define CO_FAST_CELL    0x40 | ||||||
| #define CO_FAST_FREE    0x80 | #define CO_FAST_FREE    0x80 | ||||||
| 
 | 
 | ||||||
| static inline int | typedef unsigned char _PyLocals_Kind; | ||||||
| _PyCode_InitLocalsPlusKinds(int num, _PyLocalsPlusKinds *pkinds) | 
 | ||||||
|  | static inline _PyLocals_Kind | ||||||
|  | _PyLocals_GetKind(PyObject *kinds, int i) | ||||||
| { | { | ||||||
|     if (num == 0) { |     assert(PyBytes_Check(kinds)); | ||||||
|         *pkinds = NULL; |     assert(0 <= i && i < PyBytes_GET_SIZE(kinds)); | ||||||
|         return 0; |     char *ptr = PyBytes_AS_STRING(kinds); | ||||||
|     } |     return (_PyLocals_Kind)(ptr[i]); | ||||||
|     _PyLocalsPlusKinds kinds = PyMem_NEW(_PyLocalsPlusKind, num); |  | ||||||
|     if (kinds == NULL) { |  | ||||||
|         PyErr_NoMemory(); |  | ||||||
|         return -1; |  | ||||||
|     } |  | ||||||
|     *pkinds = kinds; |  | ||||||
|     return 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void | static inline void | ||||||
| _PyCode_ClearLocalsPlusKinds(_PyLocalsPlusKinds kinds) | _PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind) | ||||||
| { | { | ||||||
|     if (kinds != NULL) { |     assert(PyBytes_Check(kinds)); | ||||||
|         PyMem_Free(kinds); |     assert(0 <= i && i < PyBytes_GET_SIZE(kinds)); | ||||||
|     } |     char *ptr = PyBytes_AS_STRING(kinds); | ||||||
|  |     ptr[i] = (char) kind; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| struct _PyCodeConstructor { | struct _PyCodeConstructor { | ||||||
|     /* metadata */ |     /* metadata */ | ||||||
|     PyObject *filename; |     PyObject *filename; | ||||||
|  | @ -229,8 +224,8 @@ struct _PyCodeConstructor { | ||||||
|     PyObject *names; |     PyObject *names; | ||||||
| 
 | 
 | ||||||
|     /* mapping frame offsets to information */ |     /* mapping frame offsets to information */ | ||||||
|     PyObject *localsplusnames; |     PyObject *localsplusnames;  // Tuple of strings
 | ||||||
|     _PyLocalsPlusKinds localspluskinds; |     PyObject *localspluskinds;  // Bytes object, one byte per variable
 | ||||||
| 
 | 
 | ||||||
|     /* args (within varnames) */ |     /* args (within varnames) */ | ||||||
|     int argcount; |     int argcount; | ||||||
|  |  | ||||||
|  | @ -80,9 +80,9 @@ class struct_frozen(Structure): | ||||||
|                 continue |                 continue | ||||||
|             items.append((entry.name.decode("ascii"), entry.size)) |             items.append((entry.name.decode("ascii"), entry.size)) | ||||||
| 
 | 
 | ||||||
|         expected = [("__hello__", 128), |         expected = [("__hello__", 133), | ||||||
|                     ("__phello__", -128), |                     ("__phello__", -133), | ||||||
|                     ("__phello__.spam", 128), |                     ("__phello__.spam", 133), | ||||||
|                     ] |                     ] | ||||||
|         self.assertEqual(items, expected, "PyImport_FrozenModules example " |         self.assertEqual(items, expected, "PyImport_FrozenModules example " | ||||||
|             "in Doc/library/ctypes.rst may be out of date") |             "in Doc/library/ctypes.rst may be out of date") | ||||||
|  |  | ||||||
|  | @ -359,6 +359,7 @@ def _write_atomic(path, data, mode=0o666): | ||||||
| #     Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693) | #     Python 3.11a1 3454 (compute cell offsets relative to locals bpo-43693) | ||||||
| #     Python 3.11a1 3455 (add MAKE_CELL bpo-43693) | #     Python 3.11a1 3455 (add MAKE_CELL bpo-43693) | ||||||
| #     Python 3.11a1 3456 (interleave cell args bpo-43693) | #     Python 3.11a1 3456 (interleave cell args bpo-43693) | ||||||
|  | #     Python 3.11a1 3457 (Change localsplus to a bytes object bpo-43693) | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
| # MAGIC must change whenever the bytecode emitted by the compiler may no | # MAGIC must change whenever the bytecode emitted by the compiler may no | ||||||
|  | @ -368,7 +369,7 @@ def _write_atomic(path, data, mode=0o666): | ||||||
| # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array | # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array | ||||||
| # in PC/launcher.c must also be updated. | # in PC/launcher.c must also be updated. | ||||||
| 
 | 
 | ||||||
| MAGIC_NUMBER = (3456).to_bytes(2, 'little') + b'\r\n' | MAGIC_NUMBER = (3457).to_bytes(2, 'little') + b'\r\n' | ||||||
| _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c | _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c | ||||||
| 
 | 
 | ||||||
| _PYCACHE = '__pycache__' | _PYCACHE = '__pycache__' | ||||||
|  |  | ||||||
|  | @ -156,16 +156,16 @@ validate_and_copy_tuple(PyObject *tup) | ||||||
| 
 | 
 | ||||||
| // This is also used in compile.c.
 | // This is also used in compile.c.
 | ||||||
| void | void | ||||||
| _Py_set_localsplus_info(int offset, PyObject *name, _PyLocalsPlusKind kind, | _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind, | ||||||
|                        PyObject *names, _PyLocalsPlusKinds kinds) |                         PyObject *names, PyObject *kinds) | ||||||
| { | { | ||||||
|     Py_INCREF(name); |     Py_INCREF(name); | ||||||
|     PyTuple_SET_ITEM(names, offset, name); |     PyTuple_SET_ITEM(names, offset, name); | ||||||
|     kinds[offset] = kind; |     _PyLocals_SetKind(kinds, offset, kind); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds, | get_localsplus_counts(PyObject *names, PyObject *kinds, | ||||||
|                       int *pnlocals, int *pnplaincellvars, int *pncellvars, |                       int *pnlocals, int *pnplaincellvars, int *pncellvars, | ||||||
|                       int *pnfreevars) |                       int *pnfreevars) | ||||||
| { | { | ||||||
|  | @ -175,17 +175,18 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds, | ||||||
|     int nfreevars = 0; |     int nfreevars = 0; | ||||||
|     Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names); |     Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names); | ||||||
|     for (int i = 0; i < nlocalsplus; i++) { |     for (int i = 0; i < nlocalsplus; i++) { | ||||||
|         if (kinds[i] & CO_FAST_LOCAL) { |         _PyLocals_Kind kind = _PyLocals_GetKind(kinds, i); | ||||||
|  |         if (kind & CO_FAST_LOCAL) { | ||||||
|             nlocals += 1; |             nlocals += 1; | ||||||
|             if (kinds[i] & CO_FAST_CELL) { |             if (kind & CO_FAST_CELL) { | ||||||
|                 ncellvars += 1; |                 ncellvars += 1; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (kinds[i] & CO_FAST_CELL) { |         else if (kind & CO_FAST_CELL) { | ||||||
|             ncellvars += 1; |             ncellvars += 1; | ||||||
|             nplaincellvars += 1; |             nplaincellvars += 1; | ||||||
|         } |         } | ||||||
|         else if (kinds[i] & CO_FAST_FREE) { |         else if (kind & CO_FAST_FREE) { | ||||||
|             nfreevars += 1; |             nfreevars += 1; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -204,7 +205,7 @@ get_localsplus_counts(PyObject *names, _PyLocalsPlusKinds kinds, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static PyObject * | static PyObject * | ||||||
| get_localsplus_names(PyCodeObject *co, _PyLocalsPlusKind kind, int num) | get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num) | ||||||
| { | { | ||||||
|     PyObject *names = PyTuple_New(num); |     PyObject *names = PyTuple_New(num); | ||||||
|     if (names == NULL) { |     if (names == NULL) { | ||||||
|  | @ -212,7 +213,8 @@ get_localsplus_names(PyCodeObject *co, _PyLocalsPlusKind kind, int num) | ||||||
|     } |     } | ||||||
|     int index = 0; |     int index = 0; | ||||||
|     for (int offset = 0; offset < co->co_nlocalsplus; offset++) { |     for (int offset = 0; offset < co->co_nlocalsplus; offset++) { | ||||||
|         if ((co->co_localspluskinds[offset] & kind) == 0) { |         _PyLocals_Kind k = _PyLocals_GetKind(co->co_localspluskinds, offset); | ||||||
|  |         if ((k & kind) == 0) { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         assert(index < num); |         assert(index < num); | ||||||
|  | @ -236,8 +238,9 @@ _PyCode_Validate(struct _PyCodeConstructor *con) | ||||||
|         con->consts == NULL || !PyTuple_Check(con->consts) || |         con->consts == NULL || !PyTuple_Check(con->consts) || | ||||||
|         con->names == NULL || !PyTuple_Check(con->names) || |         con->names == NULL || !PyTuple_Check(con->names) || | ||||||
|         con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) || |         con->localsplusnames == NULL || !PyTuple_Check(con->localsplusnames) || | ||||||
|         (PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds == NULL) || |         con->localspluskinds == NULL || !PyBytes_Check(con->localspluskinds) || | ||||||
|         (!PyTuple_GET_SIZE(con->localsplusnames) && con->localspluskinds != NULL) || |         PyTuple_GET_SIZE(con->localsplusnames) | ||||||
|  |             != PyBytes_GET_SIZE(con->localspluskinds) || | ||||||
|         con->name == NULL || !PyUnicode_Check(con->name) || |         con->name == NULL || !PyUnicode_Check(con->name) || | ||||||
|         con->filename == NULL || !PyUnicode_Check(con->filename) || |         con->filename == NULL || !PyUnicode_Check(con->filename) || | ||||||
|         con->linetable == NULL || !PyBytes_Check(con->linetable) || |         con->linetable == NULL || !PyBytes_Check(con->linetable) || | ||||||
|  | @ -309,7 +312,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) | ||||||
| 
 | 
 | ||||||
|     Py_INCREF(con->localsplusnames); |     Py_INCREF(con->localsplusnames); | ||||||
|     co->co_localsplusnames = con->localsplusnames; |     co->co_localsplusnames = con->localsplusnames; | ||||||
|     // We take ownership of the kinds array.
 |     Py_INCREF(con->localspluskinds); | ||||||
|     co->co_localspluskinds = con->localspluskinds; |     co->co_localspluskinds = con->localspluskinds; | ||||||
| 
 | 
 | ||||||
|     co->co_argcount = con->argcount; |     co->co_argcount = con->argcount; | ||||||
|  | @ -394,7 +397,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, | ||||||
| { | { | ||||||
|     PyCodeObject *co = NULL; |     PyCodeObject *co = NULL; | ||||||
|     PyObject *localsplusnames = NULL; |     PyObject *localsplusnames = NULL; | ||||||
|     _PyLocalsPlusKinds localspluskinds = NULL; |     PyObject *localspluskinds = NULL; | ||||||
| 
 | 
 | ||||||
|     if (varnames == NULL || !PyTuple_Check(varnames) || |     if (varnames == NULL || !PyTuple_Check(varnames) || | ||||||
|         cellvars == NULL || !PyTuple_Check(cellvars) || |         cellvars == NULL || !PyTuple_Check(cellvars) || | ||||||
|  | @ -413,7 +416,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, | ||||||
|     if (localsplusnames == NULL) { |     if (localsplusnames == NULL) { | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) { |     localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus); | ||||||
|  |     if (localspluskinds == NULL) { | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     int  offset = 0; |     int  offset = 0; | ||||||
|  | @ -438,7 +442,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, | ||||||
|             // Merge the localsplus indices.
 |             // Merge the localsplus indices.
 | ||||||
|             nlocalsplus -= 1; |             nlocalsplus -= 1; | ||||||
|             offset -= 1; |             offset -= 1; | ||||||
|             localspluskinds[argoffset] |= CO_FAST_CELL; |             _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, argoffset); | ||||||
|  |             _PyLocals_SetKind(localspluskinds, argoffset, kind | CO_FAST_CELL); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         _Py_set_localsplus_info(offset, name, CO_FAST_CELL, |         _Py_set_localsplus_info(offset, name, CO_FAST_CELL, | ||||||
|  | @ -495,7 +500,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     localspluskinds = NULL;  // This keeps it from getting freed below.
 |  | ||||||
|     Py_INCREF(varnames); |     Py_INCREF(varnames); | ||||||
|     co->co_varnames = varnames; |     co->co_varnames = varnames; | ||||||
|     Py_INCREF(cellvars); |     Py_INCREF(cellvars); | ||||||
|  | @ -505,7 +509,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, | ||||||
| 
 | 
 | ||||||
| error: | error: | ||||||
|     Py_XDECREF(localsplusnames); |     Py_XDECREF(localsplusnames); | ||||||
|     _PyCode_ClearLocalsPlusKinds(localspluskinds); |     Py_XDECREF(localspluskinds); | ||||||
|     return co; |     return co; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -558,6 +562,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) | ||||||
|         .consts = nulltuple, |         .consts = nulltuple, | ||||||
|         .names = nulltuple, |         .names = nulltuple, | ||||||
|         .localsplusnames = nulltuple, |         .localsplusnames = nulltuple, | ||||||
|  |         .localspluskinds = emptystring, | ||||||
|         .exceptiontable = emptystring, |         .exceptiontable = emptystring, | ||||||
|     }; |     }; | ||||||
|     result = _PyCode_New(&con); |     result = _PyCode_New(&con); | ||||||
|  | @ -1142,7 +1147,7 @@ code_dealloc(PyCodeObject *co) | ||||||
|     Py_XDECREF(co->co_consts); |     Py_XDECREF(co->co_consts); | ||||||
|     Py_XDECREF(co->co_names); |     Py_XDECREF(co->co_names); | ||||||
|     Py_XDECREF(co->co_localsplusnames); |     Py_XDECREF(co->co_localsplusnames); | ||||||
|     _PyCode_ClearLocalsPlusKinds(co->co_localspluskinds); |     Py_XDECREF(co->co_localspluskinds); | ||||||
|     Py_XDECREF(co->co_varnames); |     Py_XDECREF(co->co_varnames); | ||||||
|     Py_XDECREF(co->co_freevars); |     Py_XDECREF(co->co_freevars); | ||||||
|     Py_XDECREF(co->co_cellvars); |     Py_XDECREF(co->co_cellvars); | ||||||
|  |  | ||||||
|  | @ -958,7 +958,7 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f) | ||||||
|     co = _PyFrame_GetCode(f); |     co = _PyFrame_GetCode(f); | ||||||
|     fast = f->f_localsptr; |     fast = f->f_localsptr; | ||||||
|     for (int i = 0; i < co->co_nlocalsplus; i++) { |     for (int i = 0; i < co->co_nlocalsplus; i++) { | ||||||
|         _PyLocalsPlusKind kind = co->co_localspluskinds[i]; |         _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); | ||||||
| 
 | 
 | ||||||
|         /* If the namespace is unoptimized, then one of the
 |         /* If the namespace is unoptimized, then one of the
 | ||||||
|            following cases applies: |            following cases applies: | ||||||
|  | @ -1052,7 +1052,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) | ||||||
| 
 | 
 | ||||||
|     PyErr_Fetch(&error_type, &error_value, &error_traceback); |     PyErr_Fetch(&error_type, &error_value, &error_traceback); | ||||||
|     for (int i = 0; i < co->co_nlocalsplus; i++) { |     for (int i = 0; i < co->co_nlocalsplus; i++) { | ||||||
|         _PyLocalsPlusKind kind = co->co_localspluskinds[i]; |         _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); | ||||||
| 
 | 
 | ||||||
|         /* Same test as in PyFrame_FastToLocals() above. */ |         /* Same test as in PyFrame_FastToLocals() above. */ | ||||||
|         if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { |         if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { | ||||||
|  |  | ||||||
|  | @ -8864,7 +8864,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co, | ||||||
| 
 | 
 | ||||||
|     PyObject *firstarg = f->f_localsptr[0]; |     PyObject *firstarg = f->f_localsptr[0]; | ||||||
|     // The first argument might be a cell.
 |     // The first argument might be a cell.
 | ||||||
|     if (firstarg != NULL && (co->co_localspluskinds[0] & CO_FAST_CELL)) { |     if (firstarg != NULL && (_PyLocals_GetKind(co->co_localspluskinds, 0) & CO_FAST_CELL)) { | ||||||
|         // "firstarg" is a cell here unless (very unlikely) super()
 |         // "firstarg" is a cell here unless (very unlikely) super()
 | ||||||
|         // was called from the C-API before the first MAKE_CELL op.
 |         // was called from the C-API before the first MAKE_CELL op.
 | ||||||
|         if (f->f_lasti >= 0) { |         if (f->f_lasti >= 0) { | ||||||
|  | @ -8883,7 +8883,7 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co, | ||||||
|     PyTypeObject *type = NULL; |     PyTypeObject *type = NULL; | ||||||
|     int i = co->co_nlocals + co->co_nplaincellvars; |     int i = co->co_nlocals + co->co_nplaincellvars; | ||||||
|     for (; i < co->co_nlocalsplus; i++) { |     for (; i < co->co_nlocalsplus; i++) { | ||||||
|         assert((co->co_localspluskinds[i] & CO_FAST_FREE) != 0); |         assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0); | ||||||
|         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); |         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); | ||||||
|         assert(PyUnicode_Check(name)); |         assert(PyUnicode_Check(name)); | ||||||
|         if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) { |         if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) { | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								Programs/test_frozenmain.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								Programs/test_frozenmain.h
									
										
									
										generated
									
									
									
								
							|  | @ -19,9 +19,9 @@ unsigned char M_test_frozenmain[] = { | ||||||
|     121,115,90,17,95,116,101,115,116,105,110,116,101,114,110,97, |     121,115,90,17,95,116,101,115,116,105,110,116,101,114,110,97, | ||||||
|     108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114, |     108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114, | ||||||
|     103,118,90,11,103,101,116,95,99,111,110,102,105,103,115,114, |     103,118,90,11,103,101,116,95,99,111,110,102,105,103,115,114, | ||||||
|     2,0,0,0,218,3,107,101,121,169,0,250,18,116,101,115, |     2,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0, | ||||||
|     116,95,102,114,111,122,101,110,109,97,105,110,46,112,121,218, |     250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105, | ||||||
|     8,60,109,111,100,117,108,101,62,1,0,0,0,115,16,0, |     110,46,112,121,218,8,60,109,111,100,117,108,101,62,1,0, | ||||||
|     0,0,8,3,8,1,8,2,12,1,12,1,8,1,26,7, |     0,0,115,16,0,0,0,8,3,8,1,8,2,12,1,12, | ||||||
|     4,249,243,0,0,0,0, |     1,8,1,26,7,4,249,114,9,0,0,0, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -7187,15 +7187,13 @@ merge_const_one(struct compiler *c, PyObject **obj) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // This is in codeobject.c.
 | // This is in codeobject.c.
 | ||||||
| extern void _Py_set_localsplus_info(int, PyObject *, _PyLocalsPlusKind, | extern void _Py_set_localsplus_info(int, PyObject *, unsigned char, | ||||||
|                                    PyObject *, _PyLocalsPlusKinds); |                                    PyObject *, PyObject *); | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| compute_localsplus_info(struct compiler *c, int nlocalsplus, | compute_localsplus_info(struct compiler *c, int nlocalsplus, | ||||||
|                         PyObject *names, _PyLocalsPlusKinds kinds) |                         PyObject *names, PyObject *kinds) | ||||||
| { | { | ||||||
|     assert(PyTuple_GET_SIZE(names) == nlocalsplus); |  | ||||||
| 
 |  | ||||||
|     PyObject *k, *v; |     PyObject *k, *v; | ||||||
|     Py_ssize_t pos = 0; |     Py_ssize_t pos = 0; | ||||||
|     while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) { |     while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) { | ||||||
|  | @ -7203,7 +7201,7 @@ compute_localsplus_info(struct compiler *c, int nlocalsplus, | ||||||
|         assert(offset >= 0); |         assert(offset >= 0); | ||||||
|         assert(offset < nlocalsplus); |         assert(offset < nlocalsplus); | ||||||
|         // For now we do not distinguish arg kinds.
 |         // For now we do not distinguish arg kinds.
 | ||||||
|         _PyLocalsPlusKind kind = CO_FAST_LOCAL; |         _PyLocals_Kind kind = CO_FAST_LOCAL; | ||||||
|         if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) { |         if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) { | ||||||
|             kind |= CO_FAST_CELL; |             kind |= CO_FAST_CELL; | ||||||
|         } |         } | ||||||
|  | @ -7245,7 +7243,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, | ||||||
|     PyObject *names = NULL; |     PyObject *names = NULL; | ||||||
|     PyObject *consts = NULL; |     PyObject *consts = NULL; | ||||||
|     PyObject *localsplusnames = NULL; |     PyObject *localsplusnames = NULL; | ||||||
|     _PyLocalsPlusKinds localspluskinds = NULL; |     PyObject *localspluskinds = NULL; | ||||||
|     PyObject *name = NULL; |     PyObject *name = NULL; | ||||||
| 
 | 
 | ||||||
|     names = dict_keys_inorder(c->u->u_names, 0); |     names = dict_keys_inorder(c->u->u_names, 0); | ||||||
|  | @ -7281,7 +7279,8 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, | ||||||
|     if (localsplusnames == NULL) { |     if (localsplusnames == NULL) { | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     if (_PyCode_InitLocalsPlusKinds(nlocalsplus, &localspluskinds) < 0) { |     localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus); | ||||||
|  |     if (localspluskinds == NULL) { | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds); |     compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds); | ||||||
|  | @ -7315,7 +7314,6 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!merge_const_one(c, &localsplusnames)) { |     if (!merge_const_one(c, &localsplusnames)) { | ||||||
|         _PyCode_ClearLocalsPlusKinds(con.localspluskinds); |  | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
|     con.localsplusnames = localsplusnames; |     con.localsplusnames = localsplusnames; | ||||||
|  | @ -7325,13 +7323,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, | ||||||
|         goto error; |         goto error; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     localspluskinds = NULL;  // This keeps it from getting freed below.
 |  | ||||||
| 
 |  | ||||||
|  error: |  error: | ||||||
|     Py_XDECREF(names); |     Py_XDECREF(names); | ||||||
|     Py_XDECREF(consts); |     Py_XDECREF(consts); | ||||||
|     Py_XDECREF(localsplusnames); |     Py_XDECREF(localsplusnames); | ||||||
|     _PyCode_ClearLocalsPlusKinds(localspluskinds); |     Py_XDECREF(localspluskinds); | ||||||
|     Py_XDECREF(name); |     Py_XDECREF(name); | ||||||
|     return co; |     return co; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,7 +5,8 @@ const unsigned char _Py_M__hello[] = { | ||||||
|     100,1,131,1,1,0,100,2,83,0,41,3,84,122,12,72, |     100,1,131,1,1,0,100,2,83,0,41,3,84,122,12,72, | ||||||
|     101,108,108,111,32,119,111,114,108,100,33,78,41,2,90,11, |     101,108,108,111,32,119,111,114,108,100,33,78,41,2,90,11, | ||||||
|     105,110,105,116,105,97,108,105,122,101,100,218,5,112,114,105, |     105,110,105,116,105,97,108,105,122,101,100,218,5,112,114,105, | ||||||
|     110,116,169,0,122,14,60,102,114,111,122,101,110,32,104,101, |     110,116,169,0,243,0,0,0,0,122,14,60,102,114,111,122, | ||||||
|     108,108,111,62,218,8,60,109,111,100,117,108,101,62,1,0, |     101,110,32,104,101,108,108,111,62,218,8,60,109,111,100,117, | ||||||
|     0,0,115,4,0,0,0,4,0,12,1,243,0,0,0,0, |     108,101,62,1,0,0,0,115,4,0,0,0,4,0,12,1, | ||||||
|  |     114,2,0,0,0, | ||||||
| }; | }; | ||||||
|  |  | ||||||
							
								
								
									
										3525
									
								
								Python/importlib.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										3525
									
								
								Python/importlib.h
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										5135
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										5135
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -519,7 +519,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) | ||||||
|         w_object(co->co_consts, p); |         w_object(co->co_consts, p); | ||||||
|         w_object(co->co_names, p); |         w_object(co->co_names, p); | ||||||
|         w_object(co->co_localsplusnames, p); |         w_object(co->co_localsplusnames, p); | ||||||
|         w_string(co->co_localspluskinds, co->co_nlocalsplus, p); |         w_object(co->co_localspluskinds, p); | ||||||
|         w_object(co->co_filename, p); |         w_object(co->co_filename, p); | ||||||
|         w_object(co->co_name, p); |         w_object(co->co_name, p); | ||||||
|         w_long(co->co_firstlineno, p); |         w_long(co->co_firstlineno, p); | ||||||
|  | @ -1306,7 +1306,7 @@ r_object(RFILE *p) | ||||||
|             PyObject *consts = NULL; |             PyObject *consts = NULL; | ||||||
|             PyObject *names = NULL; |             PyObject *names = NULL; | ||||||
|             PyObject *localsplusnames = NULL; |             PyObject *localsplusnames = NULL; | ||||||
|             _PyLocalsPlusKinds localspluskinds = NULL; |             PyObject *localspluskinds = NULL; | ||||||
|             PyObject *filename = NULL; |             PyObject *filename = NULL; | ||||||
|             PyObject *name = NULL; |             PyObject *name = NULL; | ||||||
|             int firstlineno; |             int firstlineno; | ||||||
|  | @ -1348,19 +1348,9 @@ r_object(RFILE *p) | ||||||
|             localsplusnames = r_object(p); |             localsplusnames = r_object(p); | ||||||
|             if (localsplusnames == NULL) |             if (localsplusnames == NULL) | ||||||
|                 goto code_error; |                 goto code_error; | ||||||
| 
 |             localspluskinds = r_object(p); | ||||||
|             assert(PyTuple_GET_SIZE(localsplusnames) < INT_MAX); |             if (localspluskinds == NULL) | ||||||
|             int nlocalsplus = (int)PyTuple_GET_SIZE(localsplusnames); |                 goto code_error; | ||||||
|             if (nlocalsplus) { |  | ||||||
|                 if (_PyCode_InitLocalsPlusKinds(nlocalsplus, |  | ||||||
|                                                &localspluskinds) < 0) { |  | ||||||
|                     goto code_error; |  | ||||||
|                 } |  | ||||||
|                 for (int i = 0; i < nlocalsplus; i++) { |  | ||||||
|                     localspluskinds[i] = r_byte(p); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             filename = r_object(p); |             filename = r_object(p); | ||||||
|             if (filename == NULL) |             if (filename == NULL) | ||||||
|                 goto code_error; |                 goto code_error; | ||||||
|  | @ -1377,6 +1367,7 @@ r_object(RFILE *p) | ||||||
|             if (exceptiontable == NULL) |             if (exceptiontable == NULL) | ||||||
|                 goto code_error; |                 goto code_error; | ||||||
| 
 | 
 | ||||||
|  |             Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(localsplusnames); | ||||||
|             if (PySys_Audit("code.__new__", "OOOiiiiii", |             if (PySys_Audit("code.__new__", "OOOiiiiii", | ||||||
|                             code, filename, name, argcount, posonlyargcount, |                             code, filename, name, argcount, posonlyargcount, | ||||||
|                             kwonlyargcount, nlocalsplus, stacksize, |                             kwonlyargcount, nlocalsplus, stacksize, | ||||||
|  | @ -1417,8 +1408,6 @@ r_object(RFILE *p) | ||||||
|                 goto code_error; |                 goto code_error; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             localspluskinds = NULL;  // This keeps it from getting freed below.
 |  | ||||||
| 
 |  | ||||||
|             v = r_ref_insert(v, idx, flag, p); |             v = r_ref_insert(v, idx, flag, p); | ||||||
| 
 | 
 | ||||||
|           code_error: |           code_error: | ||||||
|  | @ -1426,7 +1415,7 @@ r_object(RFILE *p) | ||||||
|             Py_XDECREF(consts); |             Py_XDECREF(consts); | ||||||
|             Py_XDECREF(names); |             Py_XDECREF(names); | ||||||
|             Py_XDECREF(localsplusnames); |             Py_XDECREF(localsplusnames); | ||||||
|             _PyCode_ClearLocalsPlusKinds(localspluskinds); |             Py_XDECREF(localspluskinds); | ||||||
|             Py_XDECREF(filename); |             Py_XDECREF(filename); | ||||||
|             Py_XDECREF(name); |             Py_XDECREF(name); | ||||||
|             Py_XDECREF(linetable); |             Py_XDECREF(linetable); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum