bpo-46008: Make runtime-global object/type lifecycle functions and state consistent. (gh-29998)

This change is strictly renames and moving code around.  It helps in the following ways:

* ensures type-related init functions focus strictly on one of the three aspects (state, objects, types)
* passes in PyInterpreterState * to all those functions, simplifying work on moving types/objects/state to the interpreter
* consistent naming conventions help make what's going on more clear
* keeping API related to a type in the corresponding header file makes it more obvious where to look for it

https://bugs.python.org/issue46008
This commit is contained in:
Eric Snow 2021-12-09 12:59:26 -07:00 committed by GitHub
parent d8a464ef03
commit c8749b5783
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 818 additions and 361 deletions

View file

@ -0,0 +1,30 @@
#ifndef Py_INTERNAL_BYTESOBJECT_H
#define Py_INTERNAL_BYTESOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern PyStatus _PyBytes_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyBytes_InitTypes(PyInterpreterState *);
extern void _PyBytes_Fini(PyInterpreterState *);
/* other API */
struct _Py_bytes_state {
PyObject *empty_string;
PyBytesObject *characters[256];
};
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_BYTESOBJECT_H */

View file

@ -7,6 +7,32 @@
#include "pycore_hamt.h" /* PyHamtObject */
/* runtime lifecycle */
PyStatus _PyContext_InitTypes(PyInterpreterState *);
void _PyContext_Fini(PyInterpreterState *);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
# define PyContext_MAXFREELIST 0
#endif
#ifndef PyContext_MAXFREELIST
# define PyContext_MAXFREELIST 255
#endif
struct _Py_context_state {
#if PyContext_MAXFREELIST > 0
// List of free PyContext objects
PyContext *freelist;
int numfree;
#endif
};
struct _pycontextobject {
PyObject_HEAD
PyContext *ctx_prev;
@ -36,7 +62,4 @@ struct _pycontexttokenobject {
};
int _PyContext_Init(void);
void _PyContext_Fini(PyInterpreterState *interp);
#endif /* !Py_INTERNAL_CONTEXT_H */

View file

@ -10,6 +10,32 @@ extern "C" {
#endif
/* runtime lifecycle */
extern void _PyDict_Fini(PyInterpreterState *interp);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
# define PyDict_MAXFREELIST 0
#endif
#ifndef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 80
#endif
struct _Py_dict_state {
#if PyDict_MAXFREELIST > 0
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
int numfree;
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int keys_numfree;
#endif
};
typedef struct {
/* Cached hash code of me_key. */
Py_hash_t me_hash;

View file

@ -0,0 +1,37 @@
#ifndef Py_INTERNAL_EXCEPTIONS_H
#define Py_INTERNAL_EXCEPTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern PyStatus _PyExc_InitState(PyInterpreterState *);
extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyExc_InitTypes(PyInterpreterState *);
extern void _PyExc_Fini(PyInterpreterState *);
/* other API */
struct _Py_exc_state {
// The dict mapping from errno codes to OSError subclasses
PyObject *errnomap;
PyBaseExceptionObject *memerrors_freelist;
int memerrors_numfree;
// The ExceptionGroup type
PyObject *PyExc_ExceptionGroup;
};
extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_EXCEPTIONS_H */

View file

@ -8,6 +8,35 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern void _PyFloat_InitState(PyInterpreterState *);
extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
extern void _PyFloat_Fini(PyInterpreterState *);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
# define PyFloat_MAXFREELIST 0
#endif
#ifndef PyFloat_MAXFREELIST
# define PyFloat_MAXFREELIST 100
#endif
struct _Py_float_state {
#if PyFloat_MAXFREELIST > 0
/* Special free list
free_list is a singly-linked list of available PyFloatObjects,
linked via abuse of their ob_type members. */
int numfree;
PyFloatObject *free_list;
#endif
};
/* _PyFloat_{Pack,Unpack}{4,8}
*
* The struct and pickle (at least) modules need an efficient platform-

View file

@ -4,6 +4,14 @@
extern "C" {
#endif
/* runtime lifecycle */
extern void _PyFrame_Fini(PyInterpreterState *interp);
/* other API */
/* These values are chosen so that the inline functions below all
* compare f_state to zero.
*/

View file

@ -0,0 +1,46 @@
#ifndef Py_INTERNAL_GENOBJECT_H
#define Py_INTERNAL_GENOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern void _PyAsyncGen_Fini(PyInterpreterState *);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
# define _PyAsyncGen_MAXFREELIST 0
#endif
#ifndef _PyAsyncGen_MAXFREELIST
# define _PyAsyncGen_MAXFREELIST 80
#endif
struct _Py_async_gen_state {
#if _PyAsyncGen_MAXFREELIST > 0
/* Freelists boost performance 6-10%; they also reduce memory
fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
are short-living objects that are instantiated for every
__anext__() call. */
struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
int value_numfree;
struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
int asend_numfree;
#endif
};
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_GENOBJECT_H */

View file

@ -8,6 +8,14 @@
#define _Py_HAMT_MAX_TREE_DEPTH 7
/* runtime lifecycle */
PyStatus _PyHamt_InitTypes(PyInterpreterState *);
void _PyHamt_Fini(PyInterpreterState *);
/* other API */
#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type)
@ -110,7 +118,4 @@ PyObject * _PyHamt_NewIterValues(PyHamtObject *o);
/* Return a Items iterator over "o". */
PyObject * _PyHamt_NewIterItems(PyHamtObject *o);
int _PyHamt_Init(void);
void _PyHamt_Fini(void);
#endif /* !Py_INTERNAL_HAMT_H */

View file

@ -10,8 +10,18 @@ extern "C" {
#include "pycore_atomic.h" // _Py_atomic_address
#include "pycore_ast_state.h" // struct ast_state
#include "pycore_bytesobject.h" // struct _Py_bytes_state
#include "pycore_context.h" // struct _Py_context_state
#include "pycore_dict.h" // struct _Py_dict_state
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_gil.h" // struct _gil_runtime_state
#include "pycore_gc.h" // struct _gc_runtime_state
#include "pycore_list.h" // struct _Py_list_state
#include "pycore_tuple.h" // struct _Py_tuple_state
#include "pycore_typeobject.h" // struct type_cache
#include "pycore_unicodeobject.h" // struct _Py_unicode_state
#include "pycore_warnings.h" // struct _warnings_runtime_state
struct _pending_calls {
@ -44,158 +54,6 @@ struct _ceval_state {
#endif
};
/* fs_codec.encoding is initialized to NULL.
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
struct _Py_unicode_fs_codec {
char *encoding; // Filesystem encoding (encoded to UTF-8)
int utf8; // encoding=="utf-8"?
char *errors; // Filesystem errors (encoded to UTF-8)
_Py_error_handler error_handler;
};
struct _Py_bytes_state {
PyObject *empty_string;
PyBytesObject *characters[256];
};
struct _Py_unicode_ids {
Py_ssize_t size;
PyObject **array;
};
struct _Py_unicode_state {
// The empty Unicode object is a singleton to improve performance.
PyObject *empty_string;
/* Single character Unicode strings in the Latin-1 range are being
shared as well. */
PyObject *latin1[256];
struct _Py_unicode_fs_codec fs_codec;
/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
When the interned string reaches a refcnt of 0 the string deallocation
function will delete the reference from this dictionary.
Another way to look at this is that to say that the actual reference
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
*/
PyObject *interned;
// Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
struct _Py_unicode_ids ids;
};
#ifndef WITH_FREELISTS
// without freelists
# define PyFloat_MAXFREELIST 0
// for tuples only store empty tuple singleton
# define PyTuple_MAXSAVESIZE 1
# define PyTuple_MAXFREELIST 1
# define PyList_MAXFREELIST 0
# define PyDict_MAXFREELIST 0
# define _PyAsyncGen_MAXFREELIST 0
# define PyContext_MAXFREELIST 0
#endif
#ifndef PyFloat_MAXFREELIST
# define PyFloat_MAXFREELIST 100
#endif
struct _Py_float_state {
#if PyFloat_MAXFREELIST > 0
/* Special free list
free_list is a singly-linked list of available PyFloatObjects,
linked via abuse of their ob_type members. */
int numfree;
PyFloatObject *free_list;
#endif
};
/* Speed optimization to avoid frequent malloc/free of small tuples */
#ifndef PyTuple_MAXSAVESIZE
// Largest tuple to save on free list
# define PyTuple_MAXSAVESIZE 20
#endif
#ifndef PyTuple_MAXFREELIST
// Maximum number of tuples of each size to save
# define PyTuple_MAXFREELIST 2000
#endif
struct _Py_tuple_state {
#if PyTuple_MAXSAVESIZE > 0
/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
entry 0 is the empty tuple () of which at most one instance
will be allocated. */
PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
int numfree[PyTuple_MAXSAVESIZE];
#endif
};
/* Empty list reuse scheme to save calls to malloc and free */
#ifndef PyList_MAXFREELIST
# define PyList_MAXFREELIST 80
#endif
struct _Py_list_state {
#if PyList_MAXFREELIST > 0
PyListObject *free_list[PyList_MAXFREELIST];
int numfree;
#endif
};
#ifndef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 80
#endif
struct _Py_dict_state {
#if PyDict_MAXFREELIST > 0
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
int numfree;
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int keys_numfree;
#endif
};
#ifndef _PyAsyncGen_MAXFREELIST
# define _PyAsyncGen_MAXFREELIST 80
#endif
struct _Py_async_gen_state {
#if _PyAsyncGen_MAXFREELIST > 0
/* Freelists boost performance 6-10%; they also reduce memory
fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
are short-living objects that are instantiated for every
__anext__() call. */
struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
int value_numfree;
struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
int asend_numfree;
#endif
};
#ifndef PyContext_MAXFREELIST
# define PyContext_MAXFREELIST 255
#endif
struct _Py_context_state {
#if PyContext_MAXFREELIST > 0
// List of free PyContext objects
PyContext *freelist;
int numfree;
#endif
};
struct _Py_exc_state {
// The dict mapping from errno codes to OSError subclasses
PyObject *errnomap;
PyBaseExceptionObject *memerrors_freelist;
int memerrors_numfree;
// The ExceptionGroup type
PyObject *PyExc_ExceptionGroup;
};
// atexit state
typedef struct {
@ -211,27 +69,6 @@ struct atexit_state {
};
// Type attribute lookup cache: speed up attribute and method lookups,
// see _PyType_Lookup().
struct type_cache_entry {
unsigned int version; // initialized from type->tp_version_tag
PyObject *name; // reference to exactly a str or None
PyObject *value; // borrowed reference or NULL
};
#define MCACHE_SIZE_EXP 12
#define MCACHE_STATS 0
struct type_cache {
struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
#if MCACHE_STATS
size_t hits;
size_t misses;
size_t collisions;
#endif
};
/* interpreter state */
// The PyInterpreterState typedef is in Include/pystate.h.

View file

@ -11,6 +11,30 @@ extern "C" {
#include "listobject.h" // _PyList_CAST()
/* runtime lifecycle */
extern void _PyList_Fini(PyInterpreterState *);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
# define PyList_MAXFREELIST 0
#endif
/* Empty list reuse scheme to save calls to malloc and free */
#ifndef PyList_MAXFREELIST
# define PyList_MAXFREELIST 80
#endif
struct _Py_list_state {
#if PyList_MAXFREELIST > 0
PyListObject *free_list[PyList_MAXFREELIST];
int numfree;
#endif
};
#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item)

View file

@ -8,18 +8,28 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
#include "pycore_interp.h" // PyInterpreterState.small_ints
#include "pycore_long_state.h" // _PyLong_SMALL_INTS
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_runtime.h" // _PyRuntime
/* runtime lifecycle */
extern void _PyLong_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
/* other API */
// Return a borrowed reference to the zero singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetZero(void)
{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS]; }
{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
// Return a borrowed reference to the one singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetOne(void)
{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS+1]; }
{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);

View file

@ -0,0 +1,33 @@
#ifndef Py_INTERNAL_LONG_STATE_H
#define Py_INTERNAL_LONG_STATE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
#define _PY_NSMALLPOSINTS 257
#define _PY_NSMALLNEGINTS 5
// _PyLong_GetZero() and _PyLong_GetOne() must always be available
#if _PY_NSMALLPOSINTS < 2
# error "_PY_NSMALLPOSINTS must be greater than 1"
#endif
struct _Py_long_state {
/* Small integers are preallocated in this array so that they
* can be shared.
* The integers that are preallocated are those in the range
*-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
*/
PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
};
#define _PyLong_SMALL_INTS _PyRuntime.int_state.small_ints
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_LONG_STATE_H */

View file

@ -8,6 +8,14 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern PyStatus _PyErr_InitTypes(PyInterpreterState *);
/* other API */
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
{
assert(tstate != NULL);

View file

@ -49,13 +49,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */
extern PyStatus _PyUnicode_Init(PyInterpreterState *interp);
extern PyStatus _PyUnicode_InitTypes(void);
extern PyStatus _PyBytes_Init(PyInterpreterState *interp);
extern int _PyStructSequence_Init(void);
extern void _PyLong_Init(PyInterpreterState *interp);
extern int _PyLong_InitTypes(void);
extern PyStatus _PyTuple_Init(PyInterpreterState *interp);
extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable);
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
@ -65,15 +58,9 @@ extern PyStatus _PySys_Create(
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
extern int _PySys_UpdateConfig(PyThreadState *tstate);
extern PyStatus _PyExc_Init(PyInterpreterState *interp);
extern PyStatus _PyErr_InitTypes(void);
extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
extern void _PyFloat_Init(void);
extern int _PyFloat_InitTypes(void);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
extern PyStatus _PyTypes_Init(void);
extern PyStatus _PyTypes_InitSlotDefs(void);
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
@ -81,28 +68,13 @@ extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
/* Various internal finalizers */
extern void _PyFrame_Fini(PyInterpreterState *interp);
extern void _PyDict_Fini(PyInterpreterState *interp);
extern void _PyTuple_Fini(PyInterpreterState *interp);
extern void _PyList_Fini(PyInterpreterState *interp);
extern void _PyBytes_Fini(PyInterpreterState *interp);
extern void _PyFloat_Fini(PyInterpreterState *interp);
extern void _PySlice_Fini(PyInterpreterState *interp);
extern void _PyAsyncGen_Fini(PyInterpreterState *interp);
extern int _PySignal_Init(int install_signal_handlers);
extern void _PySignal_Fini(void);
extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *interp);
extern void _PyExc_Fini(PyInterpreterState *interp);
extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);
extern void _PyGC_Fini(PyInterpreterState *interp);
extern void _PyType_Fini(PyInterpreterState *interp);
extern void _Py_HashRandomization_Fini(void);
extern void _PyUnicode_Fini(PyInterpreterState *interp);
extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
extern void _PyLong_Fini(PyInterpreterState *interp);
extern void _PyFaulthandler_Fini(void);
extern void _PyHash_Fini(void);
extern void _PyTraceMalloc_Fini(void);

View file

@ -10,14 +10,8 @@ extern "C" {
#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_gil.h" // struct _gil_runtime_state
#define _PY_NSMALLPOSINTS 257
#define _PY_NSMALLNEGINTS 5
// _PyLong_GetZero() and _PyLong_GetOne() must always be available
#if _PY_NSMALLPOSINTS < 2
# error "_PY_NSMALLPOSINTS must be greater than 1"
#endif
#include "pycore_long_state.h" // struct _Py_long_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
/* ceval state */
@ -57,13 +51,6 @@ typedef struct _Py_AuditHookEntry {
void *userData;
} _Py_AuditHookEntry;
struct _Py_unicode_runtime_ids {
PyThread_type_lock lock;
// next_index value must be preserved when Py_Initialize()/Py_Finalize()
// is called multiple times: see _PyUnicode_FromId() implementation.
Py_ssize_t next_index;
};
/* Full Python runtime state */
typedef struct pyruntimestate {
@ -114,12 +101,7 @@ typedef struct pyruntimestate {
unsigned long main_thread;
/* Small integers are preallocated in this array so that they
* can be shared.
* The integers that are preallocated are those in the range
*-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
*/
PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
struct _Py_long_state int_state;
#define NEXITFUNCS 32
void (*exitfuncs[NEXITFUNCS])(void);

View file

@ -0,0 +1,20 @@
#ifndef Py_INTERNAL_SLICEOBJECT_H
#define Py_INTERNAL_SLICEOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern void _PySlice_Fini(PyInterpreterState *);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_SLICEOBJECT_H */

View file

@ -9,6 +9,13 @@ extern "C" {
#endif
/* runtime lifecycle */
extern PyStatus _PyStructSequence_InitState(PyInterpreterState *);
/* other API */
PyAPI_FUNC(int) _PyStructSequence_InitType(
PyTypeObject *type,
PyStructSequence_Desc *desc,

View file

@ -10,6 +10,43 @@ extern "C" {
#include "tupleobject.h" /* _PyTuple_CAST() */
/* runtime lifecycle */
extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyTuple_InitTypes(PyInterpreterState *);
extern void _PyTuple_Fini(PyInterpreterState *);
/* other API */
#ifndef WITH_FREELISTS
// without freelists
// for tuples only store empty tuple singleton
# define PyTuple_MAXSAVESIZE 1
# define PyTuple_MAXFREELIST 1
#endif
/* Speed optimization to avoid frequent malloc/free of small tuples */
#ifndef PyTuple_MAXSAVESIZE
// Largest tuple to save on free list
# define PyTuple_MAXSAVESIZE 20
#endif
#ifndef PyTuple_MAXFREELIST
// Maximum number of tuples of each size to save
# define PyTuple_MAXFREELIST 2000
#endif
struct _Py_tuple_state {
#if PyTuple_MAXSAVESIZE > 0
/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
entry 0 is the empty tuple () of which at most one instance
will be allocated. */
PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
int numfree[PyTuple_MAXSAVESIZE];
#endif
};
#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item)
extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t);

View file

@ -0,0 +1,47 @@
#ifndef Py_INTERNAL_TYPEOBJECT_H
#define Py_INTERNAL_TYPEOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern PyStatus _PyTypes_InitState(PyInterpreterState *);
extern PyStatus _PyTypes_InitTypes(PyInterpreterState *);
extern void _PyTypes_Fini(PyInterpreterState *);
/* other API */
// Type attribute lookup cache: speed up attribute and method lookups,
// see _PyType_Lookup().
struct type_cache_entry {
unsigned int version; // initialized from type->tp_version_tag
PyObject *name; // reference to exactly a str or None
PyObject *value; // borrowed reference or NULL
};
#define MCACHE_SIZE_EXP 12
#define MCACHE_STATS 0
struct type_cache {
struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
#if MCACHE_STATS
size_t hits;
size_t misses;
size_t collisions;
#endif
};
extern PyStatus _PyTypes_InitSlotDefs(void);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_TYPEOBJECT_H */

View file

@ -0,0 +1,71 @@
#ifndef Py_INTERNAL_UNICODEOBJECT_H
#define Py_INTERNAL_UNICODEOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
/* runtime lifecycle */
extern void _PyUnicode_InitState(PyInterpreterState *);
extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
extern void _PyUnicode_Fini(PyInterpreterState *);
/* other API */
struct _Py_unicode_runtime_ids {
PyThread_type_lock lock;
// next_index value must be preserved when Py_Initialize()/Py_Finalize()
// is called multiple times: see _PyUnicode_FromId() implementation.
Py_ssize_t next_index;
};
/* fs_codec.encoding is initialized to NULL.
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
struct _Py_unicode_fs_codec {
char *encoding; // Filesystem encoding (encoded to UTF-8)
int utf8; // encoding=="utf-8"?
char *errors; // Filesystem errors (encoded to UTF-8)
_Py_error_handler error_handler;
};
struct _Py_unicode_ids {
Py_ssize_t size;
PyObject **array;
};
struct _Py_unicode_state {
// The empty Unicode object is a singleton to improve performance.
PyObject *empty_string;
/* Single character Unicode strings in the Latin-1 range are being
shared as well. */
PyObject *latin1[256];
struct _Py_unicode_fs_codec fs_codec;
/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
When the interned string reaches a refcnt of 0 the string deallocation
function will delete the reference from this dictionary.
Another way to look at this is that to say that the actual reference
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
*/
PyObject *interned;
// Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
struct _Py_unicode_ids ids;
};
extern void _PyUnicode_ClearInterned(PyInterpreterState *);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_UNICODEOBJECT_H */

View file

@ -1576,6 +1576,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_atomic_funcs.h \
$(srcdir)/Include/internal/pycore_bitutils.h \
$(srcdir)/Include/internal/pycore_bytes_methods.h \
$(srcdir)/Include/internal/pycore_bytesobject.h \
$(srcdir)/Include/internal/pycore_call.h \
$(srcdir)/Include/internal/pycore_ceval.h \
$(srcdir)/Include/internal/pycore_code.h \
@ -1584,10 +1585,12 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_context.h \
$(srcdir)/Include/internal/pycore_dict.h \
$(srcdir)/Include/internal/pycore_dtoa.h \
$(srcdir)/Include/internal/pycore_exceptions.h \
$(srcdir)/Include/internal/pycore_fileutils.h \
$(srcdir)/Include/internal/pycore_floatobject.h \
$(srcdir)/Include/internal/pycore_format.h \
$(srcdir)/Include/internal/pycore_function.h \
$(srcdir)/Include/internal/pycore_genobject.h \
$(srcdir)/Include/internal/pycore_getopt.h \
$(srcdir)/Include/internal/pycore_gil.h \
$(srcdir)/Include/internal/pycore_hamt.h \
@ -1598,6 +1601,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_interpreteridobject.h \
$(srcdir)/Include/internal/pycore_list.h \
$(srcdir)/Include/internal/pycore_long.h \
$(srcdir)/Include/internal/pycore_long_state.h \
$(srcdir)/Include/internal/pycore_moduleobject.h \
$(srcdir)/Include/internal/pycore_namespace.h \
$(srcdir)/Include/internal/pycore_object.h \
@ -1609,14 +1613,17 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_pymem.h \
$(srcdir)/Include/internal/pycore_pystate.h \
$(srcdir)/Include/internal/pycore_runtime.h \
$(srcdir)/Include/internal/pycore_sliceobject.h \
$(srcdir)/Include/internal/pycore_strhex.h \
$(srcdir)/Include/internal/pycore_structseq.h \
$(srcdir)/Include/internal/pycore_symtable.h \
$(srcdir)/Include/internal/pycore_sysmodule.h \
$(srcdir)/Include/internal/pycore_traceback.h \
$(srcdir)/Include/internal/pycore_tuple.h \
$(srcdir)/Include/internal/pycore_typeobject.h \
$(srcdir)/Include/internal/pycore_ucnhash.h \
$(srcdir)/Include/internal/pycore_unionobject.h \
$(srcdir)/Include/internal/pycore_unicodeobject.h \
$(srcdir)/Include/internal/pycore_warnings.h \
$(DTRACE_HEADERS) \
\

View file

@ -5,6 +5,7 @@
#include "Python.h"
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_bytes_methods.h" // _Py_bytes_startswith()
#include "pycore_bytesobject.h" // struct _Py_bytes_state
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_format.h" // F_LJUST
#include "pycore_initconfig.h" // _PyStatus_OK()
@ -3086,7 +3087,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
PyStatus
_PyBytes_Init(PyInterpreterState *interp)
_PyBytes_InitGlobalObjects(PyInterpreterState *interp)
{
struct _Py_bytes_state *state = &interp->bytes;
if (bytes_create_empty_string_singleton(state) < 0) {
@ -3096,6 +3097,25 @@ _PyBytes_Init(PyInterpreterState *interp)
}
PyStatus
_PyBytes_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (PyType_Ready(&PyBytes_Type) < 0) {
return _PyStatus_ERR("Can't initialize bytes type");
}
if (PyType_Ready(&PyBytesIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize bytes iterator type");
}
return _PyStatus_OK();
}
void
_PyBytes_Fini(PyInterpreterState *interp)
{

View file

@ -7,6 +7,7 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stdbool.h>
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_initconfig.h"
#include "pycore_object.h"
#include "structmember.h" // PyMemberDef
@ -3189,10 +3190,8 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
#endif /* MS_WINDOWS */
PyStatus
_PyExc_Init(PyInterpreterState *interp)
_PyExc_InitTypes(PyInterpreterState *interp)
{
struct _Py_exc_state *state = &interp->exc_state;
#define PRE_INIT(TYPE) \
if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
@ -3201,17 +3200,6 @@ _PyExc_Init(PyInterpreterState *interp)
Py_INCREF(PyExc_ ## TYPE); \
}
#define ADD_ERRNO(TYPE, CODE) \
do { \
PyObject *_code = PyLong_FromLong(CODE); \
assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
Py_XDECREF(_code); \
return _PyStatus_ERR("errmap insertion problem."); \
} \
Py_DECREF(_code); \
} while (0)
PRE_INIT(BaseException);
PRE_INIT(BaseExceptionGroup);
PRE_INIT(Exception);
@ -3282,10 +3270,37 @@ _PyExc_Init(PyInterpreterState *interp)
PRE_INIT(ProcessLookupError);
PRE_INIT(TimeoutError);
return _PyStatus_OK();
#undef PRE_INIT
}
PyStatus
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
{
if (preallocate_memerrors() < 0) {
return _PyStatus_NO_MEMORY();
}
return _PyStatus_OK();
}
PyStatus
_PyExc_InitState(PyInterpreterState *interp)
{
struct _Py_exc_state *state = &interp->exc_state;
#define ADD_ERRNO(TYPE, CODE) \
do { \
PyObject *_code = PyLong_FromLong(CODE); \
assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) { \
Py_XDECREF(_code); \
return _PyStatus_ERR("errmap insertion problem."); \
} \
Py_DECREF(_code); \
} while (0)
/* Add exceptions to errnomap */
assert(state->errnomap == NULL);
state->errnomap = PyDict_New();
@ -3317,7 +3332,6 @@ _PyExc_Init(PyInterpreterState *interp)
return _PyStatus_OK();
#undef PRE_INIT
#undef ADD_ERRNO
}

View file

@ -6,6 +6,7 @@
#include "Python.h"
#include "pycore_dtoa.h" // _Py_dg_dtoa()
#include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_interp.h" // _PyInterpreterState.float_state
#include "pycore_long.h" // _PyLong_GetOne()
#include "pycore_object.h" // _PyObject_Init()
@ -1981,8 +1982,12 @@ PyTypeObject PyFloat_Type = {
};
void
_PyFloat_Init(void)
_PyFloat_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
/* We attempt to determine if this machine is using IEEE
floating point formats by peering at the bits of some
carefully chosen values. If it looks like we are on an
@ -2030,16 +2035,25 @@ _PyFloat_Init(void)
float_format = detected_float_format;
}
int
_PyFloat_InitTypes(void)
PyStatus
_PyFloat_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (PyType_Ready(&PyFloat_Type) < 0) {
return _PyStatus_ERR("Can't initialize float type");
}
/* Init float info */
if (FloatInfoType.tp_name == NULL) {
if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) {
return -1;
return _PyStatus_ERR("can't init float info type");
}
}
return 0;
return _PyStatus_OK();
}
void

View file

@ -3,6 +3,7 @@
#include "Python.h"
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_EvalFrame()
#include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
#include "pycore_pystate.h" // _PyThreadState_GET()

View file

@ -3,6 +3,7 @@
#include "Python.h"
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_interp.h" // PyInterpreterState.list
#include "pycore_list.h" // struct _Py_list_state
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_tuple.h" // _PyTuple_FromArray()
#include <stddef.h>

View file

@ -4,10 +4,11 @@
#include "Python.h"
#include "pycore_bitutils.h" // _Py_popcount32()
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_long.h" // _Py_SmallInts
#include "pycore_object.h" // _PyObject_InitVar()
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
#include <ctype.h>
#include <float.h>
@ -48,7 +49,7 @@ static PyObject *
get_small_int(sdigit ival)
{
assert(IS_SMALL_INT(ival));
PyObject *v = (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS + ival];
PyObject *v = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival];
Py_INCREF(v);
return v;
}
@ -5828,31 +5829,51 @@ PyLong_GetInfo(void)
return int_info;
}
/* runtime lifecycle */
void
_PyLong_Init(PyInterpreterState *interp)
_PyLong_InitGlobalObjects(PyInterpreterState *interp)
{
if (_PyRuntime.small_ints[0].ob_base.ob_base.ob_refcnt == 0) {
for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) {
sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS;
int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
_PyRuntime.small_ints[i].ob_base.ob_base.ob_refcnt = 1;
_PyRuntime.small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type;
_PyRuntime.small_ints[i].ob_base.ob_size = size;
_PyRuntime.small_ints[i].ob_digit[0] = (digit)abs(ival);
}
if (!_Py_IsMainInterpreter(interp)) {
return;
}
PyLongObject *small_ints = _PyLong_SMALL_INTS;
if (small_ints[0].ob_base.ob_base.ob_refcnt != 0) {
// Py_Initialize() must be running a second time.
return;
}
for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) {
sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS;
int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
small_ints[i].ob_base.ob_base.ob_refcnt = 1;
small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type;
small_ints[i].ob_base.ob_size = size;
small_ints[i].ob_digit[0] = (digit)abs(ival);
}
}
int
_PyLong_InitTypes(void)
PyStatus
_PyLong_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (PyType_Ready(&PyLong_Type) < 0) {
return _PyStatus_ERR("Can't initialize int type");
}
/* initialize int_info */
if (Int_InfoType.tp_name == NULL) {
if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
return -1;
return _PyStatus_ERR("can't init int info type");
}
}
return 0;
return _PyStatus_OK();
}
void

View file

@ -10,10 +10,10 @@
#include "pycore_namespace.h" // _PyNamespace_Type
#include "pycore_object.h" // _PyType_CheckConsistency()
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pylifecycle.h" // _PyTypes_InitSlotDefs()
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_symtable.h" // PySTEntry_Type
#include "pycore_typeobject.h" // _PyTypes_InitSlotDefs()
#include "pycore_unionobject.h" // _PyUnion_Type
#include "frameobject.h" // PyFrame_Type
#include "pycore_interpreteridobject.h" // _PyInterpreterID_Type
@ -1823,13 +1823,27 @@ PyObject _Py_NotImplementedStruct = {
};
PyStatus
_PyTypes_Init(void)
_PyTypes_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
PyStatus status = _PyTypes_InitSlotDefs();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
return _PyStatus_OK();
}
PyStatus
_PyTypes_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
#define INIT_TYPE(TYPE) \
do { \
if (PyType_Ready(&(TYPE)) < 0) { \
@ -1843,13 +1857,11 @@ _PyTypes_Init(void)
assert(PyBaseObject_Type.tp_base == NULL);
assert(PyType_Type.tp_base == &PyBaseObject_Type);
// All other static types
// All other static types (unless initialized elsewhere)
INIT_TYPE(PyAsyncGen_Type);
INIT_TYPE(PyBool_Type);
INIT_TYPE(PyByteArrayIter_Type);
INIT_TYPE(PyByteArray_Type);
INIT_TYPE(PyBytesIter_Type);
INIT_TYPE(PyBytes_Type);
INIT_TYPE(PyCFunction_Type);
INIT_TYPE(PyCMethod_Type);
INIT_TYPE(PyCallIter_Type);
@ -1873,7 +1885,6 @@ _PyTypes_Init(void)
INIT_TYPE(PyDict_Type);
INIT_TYPE(PyEllipsis_Type);
INIT_TYPE(PyEnum_Type);
INIT_TYPE(PyFloat_Type);
INIT_TYPE(PyFrame_Type);
INIT_TYPE(PyFrozenSet_Type);
INIT_TYPE(PyFunction_Type);
@ -1884,7 +1895,6 @@ _PyTypes_Init(void)
INIT_TYPE(PyListRevIter_Type);
INIT_TYPE(PyList_Type);
INIT_TYPE(PyLongRangeIter_Type);
INIT_TYPE(PyLong_Type);
INIT_TYPE(PyMemberDescr_Type);
INIT_TYPE(PyMemoryView_Type);
INIT_TYPE(PyMethodDescr_Type);
@ -1910,10 +1920,6 @@ _PyTypes_Init(void)
INIT_TYPE(PyStdPrinter_Type);
INIT_TYPE(PySuper_Type);
INIT_TYPE(PyTraceBack_Type);
INIT_TYPE(PyTupleIter_Type);
INIT_TYPE(PyTuple_Type);
INIT_TYPE(PyUnicodeIter_Type);
INIT_TYPE(PyUnicode_Type);
INIT_TYPE(PyWrapperDescr_Type);
INIT_TYPE(Py_GenericAliasType);
INIT_TYPE(_PyAnextAwaitable_Type);

View file

@ -12,6 +12,7 @@
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "structmember.h" // PyMemberDef
#include "pycore_structseq.h" // PyStructSequence_InitType()
#include "pycore_initconfig.h" // _PyStatus_OK()
static const char visible_length_key[] = "n_sequence_fields";
static const char real_length_key[] = "n_fields";
@ -583,13 +584,20 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc)
return type;
}
int _PyStructSequence_Init(void)
/* runtime lifecycle */
PyStatus _PyStructSequence_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL
|| _PyUnicode_FromId(&PyId_n_fields) == NULL
|| _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL)
{
return -1;
return _PyStatus_ERR("can't initialize structseq state");
}
return 0;
return _PyStatus_OK();
}

View file

@ -7,6 +7,7 @@
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_pyerrors.h" // _Py_FatalRefcountError()
#include "pycore_tuple.h" // struct _Py_tuple_state()
/*[clinic input]
class tuple "PyTupleObject *" "&PyTuple_Type"
@ -1066,7 +1067,7 @@ _PyTuple_ClearFreeList(PyInterpreterState *interp)
PyStatus
_PyTuple_Init(PyInterpreterState *interp)
_PyTuple_InitGlobalObjects(PyInterpreterState *interp)
{
struct _Py_tuple_state *state = &interp->tuple;
if (tuple_create_empty_tuple_singleton(state) < 0) {
@ -1076,6 +1077,24 @@ _PyTuple_Init(PyInterpreterState *interp)
}
PyStatus
_PyTuple_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (PyType_Ready(&PyTuple_Type) < 0) {
return _PyStatus_ERR("Can't initialize tuple type");
}
if (PyType_Ready(&PyTupleIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize tuple iterator type");
}
return _PyStatus_OK();
}
void
_PyTuple_Fini(PyInterpreterState *interp)
{

View file

@ -9,6 +9,7 @@
#include "pycore_object.h" // _PyType_HasFeature()
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_typeobject.h" // struct type_cache
#include "pycore_unionobject.h" // _Py_union_type_or
#include "frameobject.h" // PyFrameObject
#include "pycore_frame.h" // InterpreterFrame
@ -294,7 +295,7 @@ PyType_ClearCache(void)
void
_PyType_Fini(PyInterpreterState *interp)
_PyTypes_Fini(PyInterpreterState *interp)
{
struct type_cache *cache = &interp->type_cache;
type_cache_clear(cache, NULL);

View file

@ -53,6 +53,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "pycore_pylifecycle.h" // _Py_SetFileSystemEncoding()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI
#include "pycore_unicodeobject.h" // struct _Py_unicode_state
#include "stringlib/eq.h" // unicode_eq()
#ifdef MS_WINDOWS
@ -15504,41 +15505,56 @@ PyTypeObject PyUnicode_Type = {
/* Initialize the Unicode implementation */
void
_PyUnicode_InitState(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}
/* initialize the linebreak bloom filter */
const Py_UCS2 linebreak[] = {
0x000A, /* LINE FEED */
0x000D, /* CARRIAGE RETURN */
0x001C, /* FILE SEPARATOR */
0x001D, /* GROUP SEPARATOR */
0x001E, /* RECORD SEPARATOR */
0x0085, /* NEXT LINE */
0x2028, /* LINE SEPARATOR */
0x2029, /* PARAGRAPH SEPARATOR */
};
bloom_linebreak = make_bloom_mask(
PyUnicode_2BYTE_KIND, linebreak,
Py_ARRAY_LENGTH(linebreak));
}
PyStatus
_PyUnicode_Init(PyInterpreterState *interp)
_PyUnicode_InitGlobalObjects(PyInterpreterState *interp)
{
struct _Py_unicode_state *state = &interp->unicode;
if (unicode_create_empty_string_singleton(state) < 0) {
return _PyStatus_NO_MEMORY();
}
if (_Py_IsMainInterpreter(interp)) {
/* initialize the linebreak bloom filter */
const Py_UCS2 linebreak[] = {
0x000A, /* LINE FEED */
0x000D, /* CARRIAGE RETURN */
0x001C, /* FILE SEPARATOR */
0x001D, /* GROUP SEPARATOR */
0x001E, /* RECORD SEPARATOR */
0x0085, /* NEXT LINE */
0x2028, /* LINE SEPARATOR */
0x2029, /* PARAGRAPH SEPARATOR */
};
bloom_linebreak = make_bloom_mask(
PyUnicode_2BYTE_KIND, linebreak,
Py_ARRAY_LENGTH(linebreak));
}
return _PyStatus_OK();
}
PyStatus
_PyUnicode_InitTypes(void)
_PyUnicode_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (PyType_Ready(&PyUnicode_Type) < 0) {
return _PyStatus_ERR("Can't initialize unicode type");
}
if (PyType_Ready(&PyUnicodeIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize unicode iterator type");
}
if (PyType_Ready(&EncodingMapType) < 0) {
return _PyStatus_ERR("Can't initialize encoding map type");
}

View file

@ -196,6 +196,7 @@
<ClInclude Include="..\Include\internal\pycore_atomic_funcs.h" />
<ClInclude Include="..\Include\internal\pycore_bitutils.h" />
<ClInclude Include="..\Include\internal\pycore_bytes_methods.h" />
<ClInclude Include="..\Include\internal\pycore_bytesobject.h" />
<ClInclude Include="..\Include\internal\pycore_call.h" />
<ClInclude Include="..\Include\internal\pycore_ceval.h" />
<ClInclude Include="..\Include\internal\pycore_code.h" />
@ -203,11 +204,13 @@
<ClInclude Include="..\Include\internal\pycore_condvar.h" />
<ClInclude Include="..\Include\internal\pycore_context.h" />
<ClInclude Include="..\Include\internal\pycore_dtoa.h" />
<ClInclude Include="..\Include\internal\pycore_exceptions.h" />
<ClInclude Include="..\Include\internal\pycore_fileutils.h" />
<ClInclude Include="..\Include\internal\pycore_floatobject.h" />
<ClInclude Include="..\Include\internal\pycore_format.h" />
<ClInclude Include="..\Include\internal\pycore_function.h" />
<ClInclude Include="..\Include\internal\pycore_gc.h" />
<ClInclude Include="..\Include\internal\pycore_genobject.h" />
<ClInclude Include="..\Include\internal\pycore_getopt.h" />
<ClInclude Include="..\Include\internal\pycore_gil.h" />
<ClInclude Include="..\Include\internal\pycore_hamt.h" />
@ -218,6 +221,7 @@
<ClInclude Include="..\Include\internal\pycore_interpreteridobject.h" />
<ClInclude Include="..\Include\internal\pycore_list.h" />
<ClInclude Include="..\Include\internal\pycore_long.h" />
<ClInclude Include="..\Include\internal\pycore_long_state.h" />
<ClInclude Include="..\Include\internal\pycore_moduleobject.h" />
<ClInclude Include="..\Include\internal\pycore_namespace.h" />
<ClInclude Include="..\Include\internal\pycore_object.h" />
@ -229,14 +233,17 @@
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
<ClInclude Include="..\Include\internal\pycore_runtime.h" />
<ClInclude Include="..\Include\internal\pycore_sliceobject.h" />
<ClInclude Include="..\Include\internal\pycore_strhex.h" />
<ClInclude Include="..\Include\internal\pycore_structseq.h" />
<ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
<ClInclude Include="..\Include\internal\pycore_symtable.h" />
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
<ClInclude Include="..\Include\internal\pycore_tuple.h" />
<ClInclude Include="..\Include\internal\pycore_typeobject.h" />
<ClInclude Include="..\Include\internal\pycore_ucnhash.h" />
<ClInclude Include="..\Include\internal\pycore_unionobject.h" />
<ClInclude Include="..\Include\internal\pycore_unicodeobject.h" />
<ClInclude Include="..\Include\internal\pycore_warnings.h" />
<ClInclude Include="..\Include\intrcheck.h" />
<ClInclude Include="..\Include\iterobject.h" />

View file

@ -468,6 +468,9 @@
<ClInclude Include="..\Include\cpython\initconfig.h">
<Filter>Include\cpython</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_unicodeobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_warnings.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -498,6 +501,9 @@
<ClInclude Include="..\Include\internal\pycore_bytes_methods.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_bytesobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_call.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -519,6 +525,9 @@
<ClInclude Include="..\Include\internal\pycore_dtoa.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_exceptions.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_fileutils.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -531,6 +540,9 @@
<ClInclude Include="..\Include\internal\pycore_gc.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_genobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_getopt.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -561,6 +573,9 @@
<ClInclude Include="..\Include\internal\pycore_long.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_long_state.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_moduleobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -594,6 +609,9 @@
<ClInclude Include="..\Include\internal\pycore_runtime.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_sliceobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_strhex.h">
<Filter>Include\internal</Filter>
</ClInclude>
@ -609,6 +627,9 @@
<ClInclude Include="..\Include\internal\pycore_tuple.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_typeobject.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_ucnhash.h">
<Filter>Include\internal</Filter>
</ClInclude>

View file

@ -3,6 +3,7 @@
#include "pycore_context.h"
#include "pycore_gc.h" // _PyObject_GC_MAY_BE_TRACKED()
#include "pycore_hamt.h"
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h" // _PyThreadState_GET()
@ -1317,15 +1318,20 @@ _PyContext_Fini(PyInterpreterState *interp)
struct _Py_context_state *state = &interp->context;
state->numfree = -1;
#endif
_PyHamt_Fini();
_PyHamt_Fini(interp);
}
int
_PyContext_Init(void)
PyStatus
_PyContext_InitTypes(PyInterpreterState *interp)
{
if (!_PyHamt_Init()) {
return 0;
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
PyStatus status = _PyHamt_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if ((PyType_Ready(&PyContext_Type) < 0) ||
@ -1333,7 +1339,7 @@ _PyContext_Init(void)
(PyType_Ready(&PyContextToken_Type) < 0) ||
(PyType_Ready(&PyContextTokenMissing_Type) < 0))
{
return 0;
return _PyStatus_ERR("can't init context types");
}
PyObject *missing = get_token_missing();
@ -1341,9 +1347,9 @@ _PyContext_Init(void)
PyContextToken_Type.tp_dict, "MISSING", missing))
{
Py_DECREF(missing);
return 0;
return _PyStatus_ERR("can't init context types");
}
Py_DECREF(missing);
return 1;
return _PyStatus_OK();
}

View file

@ -1241,8 +1241,12 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = {
PyStatus
_PyErr_InitTypes(void)
_PyErr_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if (UnraisableHookArgsType.tp_name == NULL) {
if (PyStructSequence_InitType2(&UnraisableHookArgsType,
&UnraisableHookArgs_desc) < 0) {

View file

@ -2,6 +2,7 @@
#include "pycore_bitutils.h" // _Py_popcount32
#include "pycore_hamt.h"
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include <stddef.h> // offsetof()
@ -2952,9 +2953,13 @@ PyTypeObject _PyHamt_CollisionNode_Type = {
};
int
_PyHamt_Init(void)
PyStatus
_PyHamt_InitTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return _PyStatus_OK();
}
if ((PyType_Ready(&_PyHamt_Type) < 0) ||
(PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) ||
(PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) ||
@ -2963,14 +2968,14 @@ _PyHamt_Init(void)
(PyType_Ready(&_PyHamtValues_Type) < 0) ||
(PyType_Ready(&_PyHamtItems_Type) < 0))
{
return 0;
return _PyStatus_ERR("can't init hamt types");
}
return 1;
return _PyStatus_OK();
}
void
_PyHamt_Fini(void)
_PyHamt_Fini(PyInterpreterState *interp)
{
Py_CLEAR(_empty_hamt);
Py_CLEAR(_empty_bitmap_node);

View file

@ -2,18 +2,31 @@
#include "Python.h"
#include "pycore_bytesobject.h" // _PyBytes_InitTypes()
#include "pycore_ceval.h" // _PyEval_FiniGIL()
#include "pycore_context.h" // _PyContext_Init()
#include "pycore_exceptions.h" // _PyExc_InitTypes()
#include "pycore_dict.h" // _PyDict_Fini()
#include "pycore_fileutils.h" // _Py_ResetForceASCII()
#include "pycore_floatobject.h" // _PyFloat_InitTypes()
#include "pycore_frame.h" // _PyFrame_Fini()
#include "pycore_genobject.h" // _PyAsyncGen_Fini()
#include "pycore_import.h" // _PyImport_BootstrapImp()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_list.h" // _PyList_Fini()
#include "pycore_long.h" // _PyLong_InitTypes()
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
#include "pycore_pathconfig.h" // _PyConfig_WritePathConfig()
#include "pycore_pyerrors.h" // _PyErr_Occurred()
#include "pycore_pylifecycle.h" // _PyErr_Print()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_sliceobject.h" // _PySlice_Fini()
#include "pycore_structseq.h" // _PyStructSequence_InitState()
#include "pycore_sysmodule.h" // _PySys_ClearAuditHooks()
#include "pycore_traceback.h" // _Py_DumpTracebackThreads()
#include "pycore_tuple.h" // _PyTuple_InitTypes()
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
#include <locale.h> // setlocale()
#include <stdlib.h> // getenv()
@ -659,27 +672,27 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
static PyStatus
pycore_init_singletons(PyInterpreterState *interp)
pycore_init_global_objects(PyInterpreterState *interp)
{
PyStatus status;
_PyLong_Init(interp);
_PyLong_InitGlobalObjects(interp);
if (_Py_IsMainInterpreter(interp)) {
_PyFloat_Init();
}
_PyFloat_InitState(interp);
status = _PyBytes_Init(interp);
status = _PyBytes_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyUnicode_Init(interp);
status = _PyUnicode_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyTuple_Init(interp);
_PyUnicode_InitState(interp);
status = _PyTuple_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
@ -692,48 +705,70 @@ static PyStatus
pycore_init_types(PyInterpreterState *interp)
{
PyStatus status;
int is_main_interp = _Py_IsMainInterpreter(interp);
if (is_main_interp) {
if (_PyStructSequence_Init() < 0) {
return _PyStatus_ERR("can't initialize structseq");
}
status = _PyTypes_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if (_PyLong_InitTypes() < 0) {
return _PyStatus_ERR("can't init int type");
}
status = _PyUnicode_InitTypes();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
}
if (is_main_interp) {
if (_PyFloat_InitTypes() < 0) {
return _PyStatus_ERR("can't init float");
}
}
status = _PyExc_Init(interp);
status = _PyStructSequence_InitState(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyErr_InitTypes();
status = _PyTypes_InitState(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if (is_main_interp) {
if (!_PyContext_Init()) {
return _PyStatus_ERR("can't init context");
}
status = _PyTypes_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyBytes_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyLong_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyUnicode_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyFloat_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyTuple_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyExc_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyExc_InitGlobalObjects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyExc_InitState(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyErr_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyContext_InitTypes(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
return _PyStatus_OK();
@ -799,7 +834,7 @@ pycore_interp_init(PyThreadState *tstate)
// Create singletons before the first PyType_Ready() call, since
// PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
// and the empty tuple singletons (tp_bases).
status = pycore_init_singletons(interp);
status = pycore_init_global_objects(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
@ -1641,7 +1676,7 @@ finalize_interp_types(PyInterpreterState *interp)
_PyFrame_Fini(interp);
_PyAsyncGen_Fini(interp);
_PyContext_Fini(interp);
_PyType_Fini(interp);
_PyTypes_Fini(interp);
// Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses
// a dict internally.
_PyUnicode_ClearInterned(interp);
@ -1655,7 +1690,6 @@ finalize_interp_types(PyInterpreterState *interp)
_PyBytes_Fini(interp);
_PyUnicode_Fini(interp);
_PyFloat_Fini(interp);
_PyLong_Fini(interp);
}