Add pre-build wheels to support python 3.10/3.12 cuda 12.1
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
#ifndef Py_PYTHON_H
|
||||
#define Py_PYTHON_H
|
||||
/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
|
||||
|
||||
/* Include nearly all Python header files */
|
||||
|
||||
#include "patchlevel.h"
|
||||
#include "pyconfig.h"
|
||||
#include "pymacconfig.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
#error "Something's broken. UCHAR_MAX should be defined in limits.h."
|
||||
#endif
|
||||
|
||||
#if UCHAR_MAX != 255
|
||||
#error "Python's source code assumes C's unsigned char is an 8-bit type."
|
||||
#endif
|
||||
|
||||
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
|
||||
#define _SGI_MP_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifndef NULL
|
||||
# error "Python.h requires that stdio.h define NULL."
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#ifndef MS_WINDOWS
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* For size_t? */
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
/* CAUTION: Build setups should ensure that NDEBUG is defined on the
|
||||
* compiler command line when building Python in release mode; else
|
||||
* assert() calls won't be removed.
|
||||
*/
|
||||
#include <assert.h>
|
||||
|
||||
#include "pyport.h"
|
||||
#include "pymacro.h"
|
||||
|
||||
/* A convenient way for code to know if sanitizers are enabled. */
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(memory_sanitizer)
|
||||
# if !defined(_Py_MEMORY_SANITIZER)
|
||||
# define _Py_MEMORY_SANITIZER
|
||||
# endif
|
||||
# endif
|
||||
# if __has_feature(address_sanitizer)
|
||||
# if !defined(_Py_ADDRESS_SANITIZER)
|
||||
# define _Py_ADDRESS_SANITIZER
|
||||
# endif
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if defined(__SANITIZE_ADDRESS__)
|
||||
# define _Py_ADDRESS_SANITIZER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "pymath.h"
|
||||
#include "pymem.h"
|
||||
|
||||
#include "object.h"
|
||||
#include "objimpl.h"
|
||||
#include "typeslots.h"
|
||||
#include "pyhash.h"
|
||||
|
||||
#include "cpython/pydebug.h"
|
||||
|
||||
#include "bytearrayobject.h"
|
||||
#include "bytesobject.h"
|
||||
#include "unicodeobject.h"
|
||||
#include "longobject.h"
|
||||
#include "longintrepr.h"
|
||||
#include "boolobject.h"
|
||||
#include "floatobject.h"
|
||||
#include "complexobject.h"
|
||||
#include "rangeobject.h"
|
||||
#include "memoryobject.h"
|
||||
#include "tupleobject.h"
|
||||
#include "listobject.h"
|
||||
#include "dictobject.h"
|
||||
#include "cpython/odictobject.h"
|
||||
#include "enumobject.h"
|
||||
#include "setobject.h"
|
||||
#include "methodobject.h"
|
||||
#include "moduleobject.h"
|
||||
#include "funcobject.h"
|
||||
#include "classobject.h"
|
||||
#include "fileobject.h"
|
||||
#include "pycapsule.h"
|
||||
#include "code.h"
|
||||
#include "pyframe.h"
|
||||
#include "traceback.h"
|
||||
#include "sliceobject.h"
|
||||
#include "cellobject.h"
|
||||
#include "iterobject.h"
|
||||
#include "cpython/initconfig.h"
|
||||
#include "genobject.h"
|
||||
#include "descrobject.h"
|
||||
#include "genericaliasobject.h"
|
||||
#include "warnings.h"
|
||||
#include "weakrefobject.h"
|
||||
#include "structseq.h"
|
||||
#include "namespaceobject.h"
|
||||
#include "cpython/picklebufobject.h"
|
||||
#include "cpython/pytime.h"
|
||||
|
||||
#include "codecs.h"
|
||||
#include "pyerrors.h"
|
||||
#include "pythread.h"
|
||||
#include "pystate.h"
|
||||
#include "context.h"
|
||||
|
||||
#include "modsupport.h"
|
||||
#include "compile.h"
|
||||
#include "pythonrun.h"
|
||||
#include "pylifecycle.h"
|
||||
#include "ceval.h"
|
||||
#include "sysmodule.h"
|
||||
#include "osmodule.h"
|
||||
#include "intrcheck.h"
|
||||
#include "import.h"
|
||||
|
||||
#include "abstract.h"
|
||||
#include "bltinmodule.h"
|
||||
|
||||
#include "eval.h"
|
||||
|
||||
#include "cpython/pyctype.h"
|
||||
#include "pystrtod.h"
|
||||
#include "pystrcmp.h"
|
||||
#include "fileutils.h"
|
||||
#include "cpython/pyfpe.h"
|
||||
#include "tracemalloc.h"
|
||||
|
||||
#endif /* !Py_PYTHON_H */
|
||||
@@ -0,0 +1,12 @@
|
||||
The Python C API
|
||||
================
|
||||
|
||||
The C API is divided into three sections:
|
||||
|
||||
1. ``Include/``: Limited API
|
||||
2. ``Include/cpython/``: CPython implementation details
|
||||
3. ``Include/internal/``: The internal API
|
||||
|
||||
Information on changing the C API is available `in the developer guide`_
|
||||
|
||||
.. _in the developer guide: https://devguide.python.org/c-api/
|
||||
@@ -0,0 +1,873 @@
|
||||
/* Abstract Object Interface (many thanks to Jim Fulton) */
|
||||
|
||||
#ifndef Py_ABSTRACTOBJECT_H
|
||||
#define Py_ABSTRACTOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* === Object Protocol ================================================== */
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_Print(PyObject *o, FILE *fp, int flags);
|
||||
|
||||
Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument
|
||||
is used to enable certain printing options. The only option currently
|
||||
supported is Py_Print_RAW.
|
||||
|
||||
(What should be said about Py_Print_RAW?). */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_HasAttrString(PyObject *o, const char *attr_name);
|
||||
|
||||
Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise.
|
||||
|
||||
This is equivalent to the Python expression: hasattr(o,attr_name).
|
||||
|
||||
This function always succeeds. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name);
|
||||
|
||||
Retrieve an attributed named attr_name form object o.
|
||||
Returns the attribute value on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o.attr_name. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_HasAttr(PyObject *o, PyObject *attr_name);
|
||||
|
||||
Returns 1 if o has the attribute attr_name, and 0 otherwise.
|
||||
|
||||
This is equivalent to the Python expression: hasattr(o,attr_name).
|
||||
|
||||
This function always succeeds. */
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name);
|
||||
|
||||
Retrieve an attributed named 'attr_name' form object 'o'.
|
||||
Returns the attribute value on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o.attr_name. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v);
|
||||
|
||||
Set the value of the attribute named attr_name, for object 'o',
|
||||
to the value 'v'. Raise an exception and return -1 on failure; return 0 on
|
||||
success.
|
||||
|
||||
This is the equivalent of the Python statement o.attr_name=v. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
|
||||
|
||||
Set the value of the attribute named attr_name, for object 'o', to the value
|
||||
'v'. an exception and return -1 on failure; return 0 on success.
|
||||
|
||||
This is the equivalent of the Python statement o.attr_name=v. */
|
||||
|
||||
/* Implemented as a macro:
|
||||
|
||||
int PyObject_DelAttrString(PyObject *o, const char *attr_name);
|
||||
|
||||
Delete attribute named attr_name, for object o. Returns
|
||||
-1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: del o.attr_name. */
|
||||
#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL)
|
||||
|
||||
|
||||
/* Implemented as a macro:
|
||||
|
||||
int PyObject_DelAttr(PyObject *o, PyObject *attr_name);
|
||||
|
||||
Delete attribute named attr_name, for object o. Returns -1
|
||||
on failure. This is the equivalent of the Python
|
||||
statement: del o.attr_name. */
|
||||
#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL)
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
PyObject *PyObject_Repr(PyObject *o);
|
||||
|
||||
Compute the string representation of object 'o'. Returns the
|
||||
string representation on success, NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: repr(o).
|
||||
|
||||
Called by the repr() built-in function. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
PyObject *PyObject_Str(PyObject *o);
|
||||
|
||||
Compute the string representation of object, o. Returns the
|
||||
string representation on success, NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: str(o).
|
||||
|
||||
Called by the str() and print() built-in functions. */
|
||||
|
||||
|
||||
/* Declared elsewhere
|
||||
|
||||
PyAPI_FUNC(int) PyCallable_Check(PyObject *o);
|
||||
|
||||
Determine if the object, o, is callable. Return 1 if the object is callable
|
||||
and 0 otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
|
||||
|
||||
#ifdef PY_SSIZE_T_CLEAN
|
||||
# define PyObject_CallFunction _PyObject_CallFunction_SizeT
|
||||
# define PyObject_CallMethod _PyObject_CallMethod_SizeT
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
|
||||
/* Call a callable Python object without any arguments */
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func);
|
||||
#endif
|
||||
|
||||
|
||||
/* Call a callable Python object 'callable' with arguments given by the
|
||||
tuple 'args' and keywords arguments given by the dictionary 'kwargs'.
|
||||
|
||||
'args' must not be NULL, use an empty tuple if no arguments are
|
||||
needed. If no named arguments are needed, 'kwargs' can be NULL.
|
||||
|
||||
This is the equivalent of the Python expression:
|
||||
callable(*args, **kwargs). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable,
|
||||
PyObject *args, PyObject *kwargs);
|
||||
|
||||
|
||||
/* Call a callable Python object 'callable', with arguments given by the
|
||||
tuple 'args'. If no arguments are needed, then 'args' can be NULL.
|
||||
|
||||
Returns the result of the call on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression:
|
||||
callable(*args). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable,
|
||||
PyObject *args);
|
||||
|
||||
/* Call a callable Python object, callable, with a variable number of C
|
||||
arguments. The C arguments are described using a mkvalue-style format
|
||||
string.
|
||||
|
||||
The format may be NULL, indicating that no arguments are provided.
|
||||
|
||||
Returns the result of the call on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression:
|
||||
callable(arg1, arg2, ...). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable,
|
||||
const char *format, ...);
|
||||
|
||||
/* Call the method named 'name' of object 'obj' with a variable number of
|
||||
C arguments. The C arguments are described by a mkvalue format string.
|
||||
|
||||
The format can be NULL, indicating that no arguments are provided.
|
||||
|
||||
Returns the result of the call on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression:
|
||||
obj.name(arg1, arg2, ...). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj,
|
||||
const char *name,
|
||||
const char *format, ...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
/* Call a callable Python object 'callable' with a variable number of C
|
||||
arguments. The C arguments are provided as PyObject* values, terminated
|
||||
by a NULL.
|
||||
|
||||
Returns the result of the call on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression:
|
||||
callable(arg1, arg2, ...). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable,
|
||||
...);
|
||||
|
||||
/* Call the method named 'name' of object 'obj' with a variable number of
|
||||
C arguments. The C arguments are provided as PyObject* values, terminated
|
||||
by NULL.
|
||||
|
||||
Returns the result of the call on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: obj.name(*args). */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(
|
||||
PyObject *obj,
|
||||
PyObject *name,
|
||||
...);
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
Py_hash_t PyObject_Hash(PyObject *o);
|
||||
|
||||
Compute and return the hash, hash_value, of an object, o. On
|
||||
failure, return -1.
|
||||
|
||||
This is the equivalent of the Python expression: hash(o). */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_IsTrue(PyObject *o);
|
||||
|
||||
Returns 1 if the object, o, is considered to be true, 0 if o is
|
||||
considered to be false and -1 on failure.
|
||||
|
||||
This is equivalent to the Python expression: not not o. */
|
||||
|
||||
|
||||
/* Implemented elsewhere:
|
||||
|
||||
int PyObject_Not(PyObject *o);
|
||||
|
||||
Returns 0 if the object, o, is considered to be true, 1 if o is
|
||||
considered to be false and -1 on failure.
|
||||
|
||||
This is equivalent to the Python expression: not o. */
|
||||
|
||||
|
||||
/* Get the type of an object.
|
||||
|
||||
On success, returns a type object corresponding to the object type of object
|
||||
'o'. On failure, returns NULL.
|
||||
|
||||
This is equivalent to the Python expression: type(o) */
|
||||
PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o);
|
||||
|
||||
|
||||
/* Return the size of object 'o'. If the object 'o' provides both sequence and
|
||||
mapping protocols, the sequence size is returned.
|
||||
|
||||
On error, -1 is returned.
|
||||
|
||||
This is the equivalent to the Python expression: len(o) */
|
||||
PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o);
|
||||
|
||||
|
||||
/* For DLL compatibility */
|
||||
#undef PyObject_Length
|
||||
PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
|
||||
#define PyObject_Length PyObject_Size
|
||||
|
||||
/* Return element of 'o' corresponding to the object 'key'. Return NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o[key] */
|
||||
PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
|
||||
|
||||
|
||||
/* Map the object 'key' to the value 'v' into 'o'.
|
||||
|
||||
Raise an exception and return -1 on failure; return 0 on success.
|
||||
|
||||
This is the equivalent of the Python statement: o[key]=v. */
|
||||
PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
|
||||
|
||||
/* Remove the mapping for the string 'key' from the object 'o'.
|
||||
Returns -1 on failure.
|
||||
|
||||
This is equivalent to the Python statement: del o[key]. */
|
||||
PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
|
||||
|
||||
/* Delete the mapping for the object 'key' from the object 'o'.
|
||||
Returns -1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: del o[key]. */
|
||||
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
||||
|
||||
|
||||
/* === Old Buffer API ============================================ */
|
||||
|
||||
/* FIXME: usage of these should all be replaced in Python itself
|
||||
but for backwards compatibility we will implement them.
|
||||
Their usage without a corresponding "unlock" mechanism
|
||||
may create issues (but they would already be there). */
|
||||
|
||||
/* Takes an arbitrary object which must support the (character, single segment)
|
||||
buffer interface and returns a pointer to a read-only memory location
|
||||
usable as character based input for subsequent processing.
|
||||
|
||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||
occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
|
||||
const char **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
/* Checks whether an arbitrary object supports the (character, single segment)
|
||||
buffer interface.
|
||||
|
||||
Returns 1 on success, 0 on failure. */
|
||||
Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj);
|
||||
|
||||
/* Same as PyObject_AsCharBuffer() except that this API expects (readable,
|
||||
single segment) buffer interface and returns a pointer to a read-only memory
|
||||
location which can contain arbitrary data.
|
||||
|
||||
0 is returned on success. buffer and buffer_len are only set in case no
|
||||
error occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj,
|
||||
const void **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
/* Takes an arbitrary object which must support the (writable, single segment)
|
||||
buffer interface and returns a pointer to a writable memory location in
|
||||
buffer of size 'buffer_len'.
|
||||
|
||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
||||
occurs. Otherwise, -1 is returned and an exception set. */
|
||||
Py_DEPRECATED(3.0)
|
||||
PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
|
||||
void **buffer,
|
||||
Py_ssize_t *buffer_len);
|
||||
|
||||
|
||||
/* === New Buffer API ============================================ */
|
||||
|
||||
/* Takes an arbitrary object and returns the result of calling
|
||||
obj.__format__(format_spec). */
|
||||
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
|
||||
PyObject *format_spec);
|
||||
|
||||
|
||||
/* ==== Iterators ================================================ */
|
||||
|
||||
/* Takes an object and returns an iterator for it.
|
||||
This is typically a new iterator but if the argument is an iterator, this
|
||||
returns itself. */
|
||||
PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
|
||||
|
||||
/* Takes an AsyncIterable object and returns an AsyncIterator for it.
|
||||
This is typically a new iterator but if the argument is an AsyncIterator,
|
||||
this returns itself. */
|
||||
PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *);
|
||||
|
||||
/* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyIter_Check(PyObject *);
|
||||
|
||||
/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyAIter_Check(PyObject *);
|
||||
|
||||
/* Takes an iterator object and calls its tp_iternext slot,
|
||||
returning the next value.
|
||||
|
||||
If the iterator is exhausted, this returns NULL without setting an
|
||||
exception.
|
||||
|
||||
NULL with an exception means an error occurred. */
|
||||
PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
||||
|
||||
/* Takes generator, coroutine or iterator object and sends the value into it.
|
||||
Returns:
|
||||
- PYGEN_RETURN (0) if generator has returned.
|
||||
'result' parameter is filled with return value
|
||||
- PYGEN_ERROR (-1) if exception was raised.
|
||||
'result' parameter is NULL
|
||||
- PYGEN_NEXT (1) if generator has yielded.
|
||||
'result' parameter is filled with yielded value. */
|
||||
PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **);
|
||||
#endif
|
||||
|
||||
|
||||
/* === Number Protocol ================================================== */
|
||||
|
||||
/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyNumber_Check(PyObject *o);
|
||||
|
||||
/* Returns the result of adding o1 and o2, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 + o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of subtracting o2 from o1, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 - o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of multiplying o1 and o2, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 * o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2);
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
||||
/* This is the equivalent of the Python expression: o1 @ o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2);
|
||||
#endif
|
||||
|
||||
/* Returns the result of dividing o1 by o2 giving an integral result,
|
||||
or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 // o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of dividing o1 by o2 giving a float result, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 / o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the remainder of dividing o1 by o2, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 % o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* See the built-in function divmod.
|
||||
|
||||
Returns NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: divmod(o1, o2). */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* See the built-in function pow. Returns NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: pow(o1, o2, o3),
|
||||
where o3 is optional. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2,
|
||||
PyObject *o3);
|
||||
|
||||
/* Returns the negation of o on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: -o. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o);
|
||||
|
||||
/* Returns the positive of o on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: +o. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o);
|
||||
|
||||
/* Returns the absolute value of 'o', or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: abs(o). */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o);
|
||||
|
||||
/* Returns the bitwise negation of 'o' on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: ~o. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o);
|
||||
|
||||
/* Returns the result of left shifting o1 by o2 on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 << o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of right shifting o1 by o2 on success, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 >> o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of bitwise and of o1 and o2 on success, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 & o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 ^ o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of bitwise or on o1 and o2 on success, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 | o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns 1 if obj is an index integer (has the nb_index slot of the
|
||||
tp_as_number structure filled in), and 0 otherwise. */
|
||||
PyAPI_FUNC(int) PyIndex_Check(PyObject *);
|
||||
|
||||
/* Returns the object 'o' converted to a Python int, or NULL with an exception
|
||||
raised on failure. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o);
|
||||
|
||||
/* Returns the object 'o' converted to Py_ssize_t by going through
|
||||
PyNumber_Index() first.
|
||||
|
||||
If an overflow error occurs while converting the int to Py_ssize_t, then the
|
||||
second argument 'exc' is the error-type to return. If it is NULL, then the
|
||||
overflow error is cleared and the value is clipped. */
|
||||
PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc);
|
||||
|
||||
/* Returns the object 'o' converted to an integer object on success, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: int(o). */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o);
|
||||
|
||||
/* Returns the object 'o' converted to a float object on success, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: float(o). */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o);
|
||||
|
||||
|
||||
/* --- In-place variants of (some of) the above number protocol functions -- */
|
||||
|
||||
/* Returns the result of adding o2 to o1, possibly in-place, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 += o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of subtracting o2 from o1, possibly in-place or
|
||||
NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 -= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 *= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2);
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
||||
/* This is the equivalent of the Python expression: o1 @= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2);
|
||||
#endif
|
||||
|
||||
/* Returns the result of dividing o1 by o2 giving an integral result, possibly
|
||||
in-place, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 /= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1,
|
||||
PyObject *o2);
|
||||
|
||||
/* Returns the result of dividing o1 by o2 giving a float result, possibly
|
||||
in-place, or null on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 /= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1,
|
||||
PyObject *o2);
|
||||
|
||||
/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on
|
||||
failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 %= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of raising o1 to the power of o2, possibly in-place,
|
||||
or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 **= o2,
|
||||
or o1 = pow(o1, o2, o3) if o3 is present. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2,
|
||||
PyObject *o3);
|
||||
|
||||
/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 <<= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of right shifting o1 by o2, possibly in-place or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 >>= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 &= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL
|
||||
on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 ^= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the result of bitwise or of o1 and o2, possibly in-place,
|
||||
or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 |= o2. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Returns the integer n converted to a string with a base, with a base
|
||||
marker of 0b, 0o or 0x prefixed if applicable.
|
||||
|
||||
If n is not an int object, it is converted with PyNumber_Index first. */
|
||||
PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base);
|
||||
|
||||
|
||||
/* === Sequence protocol ================================================ */
|
||||
|
||||
/* Return 1 if the object provides sequence protocol, and zero
|
||||
otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PySequence_Check(PyObject *o);
|
||||
|
||||
/* Return the size of sequence object o, or -1 on failure. */
|
||||
PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o);
|
||||
|
||||
/* For DLL compatibility */
|
||||
#undef PySequence_Length
|
||||
PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o);
|
||||
#define PySequence_Length PySequence_Size
|
||||
|
||||
|
||||
/* Return the concatenation of o1 and o2 on success, and NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 + o2. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Return the result of repeating sequence object 'o' 'count' times,
|
||||
or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o * count. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count);
|
||||
|
||||
/* Return the ith element of o, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o[i]. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i);
|
||||
|
||||
/* Return the slice of sequence object o between i1 and i2, or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o[i1:i2]. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
||||
|
||||
/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception
|
||||
and return -1 on failure; return 0 on success.
|
||||
|
||||
This is the equivalent of the Python statement o[i] = v. */
|
||||
PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
|
||||
|
||||
/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: del o[i]. */
|
||||
PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
|
||||
|
||||
/* Assign the sequence object 'v' to the slice in sequence object 'o',
|
||||
from 'i1' to 'i2'. Returns -1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: o[i1:i2] = v. */
|
||||
PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2,
|
||||
PyObject *v);
|
||||
|
||||
/* Delete the slice in sequence object 'o' from 'i1' to 'i2'.
|
||||
Returns -1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: del o[i1:i2]. */
|
||||
PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
||||
|
||||
/* Returns the sequence 'o' as a tuple on success, and NULL on failure.
|
||||
|
||||
This is equivalent to the Python expression: tuple(o). */
|
||||
PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o);
|
||||
|
||||
/* Returns the sequence 'o' as a list on success, and NULL on failure.
|
||||
This is equivalent to the Python expression: list(o) */
|
||||
PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o);
|
||||
|
||||
/* Return the sequence 'o' as a list, unless it's already a tuple or list.
|
||||
|
||||
Use PySequence_Fast_GET_ITEM to access the members of this list, and
|
||||
PySequence_Fast_GET_SIZE to get its length.
|
||||
|
||||
Returns NULL on failure. If the object does not support iteration, raises a
|
||||
TypeError exception with 'm' as the message text. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
|
||||
|
||||
/* Return the size of the sequence 'o', assuming that 'o' was returned by
|
||||
PySequence_Fast and is not NULL. */
|
||||
#define PySequence_Fast_GET_SIZE(o) \
|
||||
(PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
|
||||
|
||||
/* Return the 'i'-th element of the sequence 'o', assuming that o was returned
|
||||
by PySequence_Fast, and that i is within bounds. */
|
||||
#define PySequence_Fast_GET_ITEM(o, i)\
|
||||
(PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))
|
||||
|
||||
/* Return a pointer to the underlying item array for
|
||||
an object returned by PySequence_Fast */
|
||||
#define PySequence_Fast_ITEMS(sf) \
|
||||
(PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \
|
||||
: ((PyTupleObject *)(sf))->ob_item)
|
||||
|
||||
/* Return the number of occurrences on value on 'o', that is, return
|
||||
the number of keys for which o[key] == value.
|
||||
|
||||
On failure, return -1. This is equivalent to the Python expression:
|
||||
o.count(value). */
|
||||
PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value);
|
||||
|
||||
/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence
|
||||
'seq'; -1 on error.
|
||||
|
||||
Use __contains__ if possible, else _PySequence_IterSearch(). */
|
||||
PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);
|
||||
|
||||
/* For DLL-level backwards compatibility */
|
||||
#undef PySequence_In
|
||||
/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal
|
||||
to 'value', return 1, otherwise return 0. On error, return -1.
|
||||
|
||||
This is equivalent to the Python expression: value in o. */
|
||||
PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value);
|
||||
|
||||
/* For source-level backwards compatibility */
|
||||
#define PySequence_In PySequence_Contains
|
||||
|
||||
|
||||
/* Return the first index for which o[i] == value.
|
||||
On error, return -1.
|
||||
|
||||
This is equivalent to the Python expression: o.index(value). */
|
||||
PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value);
|
||||
|
||||
|
||||
/* --- In-place versions of some of the above Sequence functions --- */
|
||||
|
||||
/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the
|
||||
resulting object, which could be 'o1', or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 += o2. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2);
|
||||
|
||||
/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting
|
||||
object, which could be 'o', or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o1 *= count. */
|
||||
PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count);
|
||||
|
||||
|
||||
/* === Mapping protocol ================================================= */
|
||||
|
||||
/* Return 1 if the object provides mapping protocol, and 0 otherwise.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyMapping_Check(PyObject *o);
|
||||
|
||||
/* Returns the number of keys in mapping object 'o' on success, and -1 on
|
||||
failure. This is equivalent to the Python expression: len(o). */
|
||||
PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o);
|
||||
|
||||
/* For DLL compatibility */
|
||||
#undef PyMapping_Length
|
||||
PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o);
|
||||
#define PyMapping_Length PyMapping_Size
|
||||
|
||||
|
||||
/* Implemented as a macro:
|
||||
|
||||
int PyMapping_DelItemString(PyObject *o, const char *key);
|
||||
|
||||
Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on
|
||||
failure.
|
||||
|
||||
This is equivalent to the Python statement: del o[key]. */
|
||||
#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K))
|
||||
|
||||
/* Implemented as a macro:
|
||||
|
||||
int PyMapping_DelItem(PyObject *o, PyObject *key);
|
||||
|
||||
Remove the mapping for the object 'key' from the mapping object 'o'.
|
||||
Returns -1 on failure.
|
||||
|
||||
This is equivalent to the Python statement: del o[key]. */
|
||||
#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K))
|
||||
|
||||
/* On success, return 1 if the mapping object 'o' has the key 'key',
|
||||
and 0 otherwise.
|
||||
|
||||
This is equivalent to the Python expression: key in o.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key);
|
||||
|
||||
/* Return 1 if the mapping object has the key 'key', and 0 otherwise.
|
||||
|
||||
This is equivalent to the Python expression: key in o.
|
||||
|
||||
This function always succeeds. */
|
||||
PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key);
|
||||
|
||||
/* On success, return a list or tuple of the keys in mapping object 'o'.
|
||||
On failure, return NULL. */
|
||||
PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o);
|
||||
|
||||
/* On success, return a list or tuple of the values in mapping object 'o'.
|
||||
On failure, return NULL. */
|
||||
PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o);
|
||||
|
||||
/* On success, return a list or tuple of the items in mapping object 'o',
|
||||
where each item is a tuple containing a key-value pair. On failure, return
|
||||
NULL. */
|
||||
PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o);
|
||||
|
||||
/* Return element of 'o' corresponding to the string 'key' or NULL on failure.
|
||||
|
||||
This is the equivalent of the Python expression: o[key]. */
|
||||
PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
|
||||
const char *key);
|
||||
|
||||
/* Map the string 'key' to the value 'v' in the mapping 'o'.
|
||||
Returns -1 on failure.
|
||||
|
||||
This is the equivalent of the Python statement: o[key]=v. */
|
||||
PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key,
|
||||
PyObject *value);
|
||||
|
||||
/* isinstance(object, typeorclass) */
|
||||
PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
|
||||
|
||||
/* issubclass(object, typeorclass) */
|
||||
PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_ABSTRACTOBJECT_H
|
||||
# include "cpython/abstract.h"
|
||||
# undef Py_CPYTHON_ABSTRACTOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* Py_ABSTRACTOBJECT_H */
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef Py_BLTINMODULE_H
|
||||
#define Py_BLTINMODULE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyFilter_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyMap_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyZip_Type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_BLTINMODULE_H */
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Boolean object interface */
|
||||
|
||||
#ifndef Py_BOOLOBJECT_H
|
||||
#define Py_BOOLOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyBool_Type;
|
||||
|
||||
#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type)
|
||||
|
||||
/* Py_False and Py_True are the only two bools in existence.
|
||||
Don't forget to apply Py_INCREF() when returning either!!! */
|
||||
|
||||
/* Don't use these directly */
|
||||
PyAPI_DATA(struct _longobject) _Py_FalseStruct;
|
||||
PyAPI_DATA(struct _longobject) _Py_TrueStruct;
|
||||
|
||||
/* Use these macros */
|
||||
#define Py_False ((PyObject *) &_Py_FalseStruct)
|
||||
#define Py_True ((PyObject *) &_Py_TrueStruct)
|
||||
|
||||
// Test if an object is the True singleton, the same as "x is True" in Python.
|
||||
PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
|
||||
#define Py_IsTrue(x) Py_Is((x), Py_True)
|
||||
|
||||
// Test if an object is the False singleton, the same as "x is False" in Python.
|
||||
PyAPI_FUNC(int) Py_IsFalse(PyObject *x);
|
||||
#define Py_IsFalse(x) Py_Is((x), Py_False)
|
||||
|
||||
/* Macros for returning Py_True or Py_False, respectively */
|
||||
#define Py_RETURN_TRUE return Py_NewRef(Py_True)
|
||||
#define Py_RETURN_FALSE return Py_NewRef(Py_False)
|
||||
|
||||
/* Function to return a bool from a C long */
|
||||
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_BOOLOBJECT_H */
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ByteArray object interface */
|
||||
|
||||
#ifndef Py_BYTEARRAYOBJECT_H
|
||||
#define Py_BYTEARRAYOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Type PyByteArrayObject represents a mutable array of bytes.
|
||||
* The Python API is that of a sequence;
|
||||
* the bytes are mapped to ints in [0, 256).
|
||||
* Bytes are not characters; they may be used to encode characters.
|
||||
* The only way to go between bytes and str/unicode is via encoding
|
||||
* and decoding.
|
||||
* For the convenience of C programmers, the bytes type is considered
|
||||
* to contain a char pointer, not an unsigned char pointer.
|
||||
*/
|
||||
|
||||
/* Type object */
|
||||
PyAPI_DATA(PyTypeObject) PyByteArray_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type;
|
||||
|
||||
/* Type check macros */
|
||||
#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type)
|
||||
#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type)
|
||||
|
||||
/* Direct API functions */
|
||||
PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t);
|
||||
PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *);
|
||||
PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *);
|
||||
PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_BYTEARRAYOBJECT_H
|
||||
# include "cpython/bytearrayobject.h"
|
||||
# undef Py_CPYTHON_BYTEARRAYOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_BYTEARRAYOBJECT_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
/* Bytes object interface */
|
||||
|
||||
#ifndef Py_BYTESOBJECT_H
|
||||
#define Py_BYTESOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
Type PyBytesObject represents a byte string. An extra zero byte is
|
||||
reserved at the end to ensure it is zero-terminated, but a size is
|
||||
present so strings with null bytes in them can be represented. This
|
||||
is an immutable object type.
|
||||
|
||||
There are functions to create new bytes objects, to test
|
||||
an object for bytes-ness, and to get the
|
||||
byte string value. The latter function returns a null pointer
|
||||
if the object is not of the proper type.
|
||||
There is a variant that takes an explicit size as well as a
|
||||
variant that assumes a zero-terminated string. Note that none of the
|
||||
functions should be applied to NULL pointer.
|
||||
*/
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyBytes_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyBytesIter_Type;
|
||||
|
||||
#define PyBytes_Check(op) \
|
||||
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
|
||||
#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t);
|
||||
PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *);
|
||||
PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list)
|
||||
Py_GCC_ATTRIBUTE((format(printf, 1, 0)));
|
||||
PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...)
|
||||
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
||||
PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *);
|
||||
PyAPI_FUNC(char *) PyBytes_AsString(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int);
|
||||
PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *);
|
||||
PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t,
|
||||
const char *, Py_ssize_t,
|
||||
const char *);
|
||||
|
||||
/* Provides access to the internal data buffer and size of a bytes object.
|
||||
Passing NULL as len parameter will force the string buffer to be
|
||||
0-terminated (passing a string with embedded NUL characters will
|
||||
cause an exception). */
|
||||
PyAPI_FUNC(int) PyBytes_AsStringAndSize(
|
||||
PyObject *obj, /* bytes object */
|
||||
char **s, /* pointer to buffer variable */
|
||||
Py_ssize_t *len /* pointer to length variable or NULL */
|
||||
);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_BYTESOBJECT_H
|
||||
# include "cpython/bytesobject.h"
|
||||
# undef Py_CPYTHON_BYTESOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_BYTESOBJECT_H */
|
||||
@@ -0,0 +1,29 @@
|
||||
/* Cell object interface */
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_CELLOBJECT_H
|
||||
#define Py_CELLOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *ob_ref; /* Content of the cell or NULL when empty */
|
||||
} PyCellObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyCell_Type;
|
||||
|
||||
#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);
|
||||
PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *);
|
||||
|
||||
#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref)
|
||||
#define PyCell_SET(op, v) ((void)(((PyCellObject *)(op))->ob_ref = v))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_TUPLEOBJECT_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,158 @@
|
||||
#ifndef Py_CEVAL_H
|
||||
#define Py_CEVAL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Interface to random parts in ceval.c */
|
||||
|
||||
/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction
|
||||
* and PyEval_CallMethod are deprecated. Since they are officially part of the
|
||||
* stable ABI (PEP 384), they must be kept for backward compatibility.
|
||||
* PyObject_Call(), PyObject_CallFunction() and PyObject_CallMethod() are
|
||||
* recommended to call a callable object.
|
||||
*/
|
||||
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords(
|
||||
PyObject *callable,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
/* Deprecated since PyEval_CallObjectWithKeywords is deprecated */
|
||||
#define PyEval_CallObject(callable, arg) \
|
||||
PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL)
|
||||
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction(
|
||||
PyObject *callable, const char *format, ...);
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallMethod(
|
||||
PyObject *obj, const char *name, const char *format, ...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void);
|
||||
PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
|
||||
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
|
||||
PyAPI_FUNC(PyFrameObject *) PyEval_GetFrame(void);
|
||||
|
||||
PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
|
||||
PyAPI_FUNC(int) Py_MakePendingCalls(void);
|
||||
|
||||
/* Protection against deeply nested recursive calls
|
||||
|
||||
In Python 3.0, this protection has two levels:
|
||||
* normal anti-recursion protection is triggered when the recursion level
|
||||
exceeds the current recursion limit. It raises a RecursionError, and sets
|
||||
the "overflowed" flag in the thread state structure. This flag
|
||||
temporarily *disables* the normal protection; this allows cleanup code
|
||||
to potentially outgrow the recursion limit while processing the
|
||||
RecursionError.
|
||||
* "last chance" anti-recursion protection is triggered when the recursion
|
||||
level exceeds "current recursion limit + 50". By construction, this
|
||||
protection can only be triggered when the "overflowed" flag is set. It
|
||||
means the cleanup code has itself gone into an infinite loop, or the
|
||||
RecursionError has been mistakingly ignored. When this protection is
|
||||
triggered, the interpreter aborts with a Fatal Error.
|
||||
|
||||
In addition, the "overflowed" flag is automatically reset when the
|
||||
recursion level drops below "current recursion limit - 50". This heuristic
|
||||
is meant to ensure that the normal anti-recursion protection doesn't get
|
||||
disabled too long.
|
||||
|
||||
Please note: this scheme has its own limitations. See:
|
||||
http://mail.python.org/pipermail/python-dev/2008-August/082106.html
|
||||
for some observations.
|
||||
*/
|
||||
PyAPI_FUNC(void) Py_SetRecursionLimit(int);
|
||||
PyAPI_FUNC(int) Py_GetRecursionLimit(void);
|
||||
|
||||
PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where);
|
||||
PyAPI_FUNC(void) Py_LeaveRecursiveCall(void);
|
||||
|
||||
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
|
||||
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(PyFrameObject *);
|
||||
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
|
||||
|
||||
/* Interface for threads.
|
||||
|
||||
A module that plans to do a blocking system call (or something else
|
||||
that lasts a long time and doesn't touch Python data) can allow other
|
||||
threads to run as follows:
|
||||
|
||||
...preparations here...
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
...blocking system call here...
|
||||
Py_END_ALLOW_THREADS
|
||||
...interpret result here...
|
||||
|
||||
The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a
|
||||
{}-surrounded block.
|
||||
To leave the block in the middle (e.g., with return), you must insert
|
||||
a line containing Py_BLOCK_THREADS before the return, e.g.
|
||||
|
||||
if (...premature_exit...) {
|
||||
Py_BLOCK_THREADS
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
An alternative is:
|
||||
|
||||
Py_BLOCK_THREADS
|
||||
if (...premature_exit...) {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return NULL;
|
||||
}
|
||||
Py_UNBLOCK_THREADS
|
||||
|
||||
For convenience, that the value of 'errno' is restored across
|
||||
Py_END_ALLOW_THREADS and Py_BLOCK_THREADS.
|
||||
|
||||
WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
|
||||
Py_END_ALLOW_THREADS!!!
|
||||
|
||||
Note that not yet all candidates have been converted to use this
|
||||
mechanism!
|
||||
*/
|
||||
|
||||
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
|
||||
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
||||
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
||||
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
|
||||
/* PyEval_AcquireLock() and PyEval_ReleaseLock() are part of stable ABI.
|
||||
* They will be removed from this header file in the future version.
|
||||
* But they will be remained in ABI until Python 4.0.
|
||||
*/
|
||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void);
|
||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
||||
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
|
||||
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
|
||||
|
||||
#define Py_BEGIN_ALLOW_THREADS { \
|
||||
PyThreadState *_save; \
|
||||
_save = PyEval_SaveThread();
|
||||
#define Py_BLOCK_THREADS PyEval_RestoreThread(_save);
|
||||
#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread();
|
||||
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
|
||||
}
|
||||
|
||||
/* Masks and values used by FORMAT_VALUE opcode. */
|
||||
#define FVC_MASK 0x3
|
||||
#define FVC_NONE 0x0
|
||||
#define FVC_STR 0x1
|
||||
#define FVC_REPR 0x2
|
||||
#define FVC_ASCII 0x3
|
||||
#define FVS_MASK 0x4
|
||||
#define FVS_HAVE_SPEC 0x4
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_CEVAL_H
|
||||
# include "cpython/ceval.h"
|
||||
# undef Py_CPYTHON_CEVAL_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CEVAL_H */
|
||||
@@ -0,0 +1,57 @@
|
||||
/* Former class object interface -- now only bound methods are here */
|
||||
|
||||
/* Revealing some structures (not for general use) */
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_CLASSOBJECT_H
|
||||
#define Py_CLASSOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *im_func; /* The callable object implementing the method */
|
||||
PyObject *im_self; /* The instance it is bound to */
|
||||
PyObject *im_weakreflist; /* List of weak references */
|
||||
vectorcallfunc vectorcall;
|
||||
} PyMethodObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyMethod_Type;
|
||||
|
||||
#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
|
||||
|
||||
/* Macros for direct access to these values. Type checks are *not*
|
||||
done, so use with care. */
|
||||
#define PyMethod_GET_FUNCTION(meth) \
|
||||
(((PyMethodObject *)meth) -> im_func)
|
||||
#define PyMethod_GET_SELF(meth) \
|
||||
(((PyMethodObject *)meth) -> im_self)
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *func;
|
||||
} PyInstanceMethodObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type;
|
||||
|
||||
#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *);
|
||||
|
||||
/* Macros for direct access to these values. Type checks are *not*
|
||||
done, so use with care. */
|
||||
#define PyInstanceMethod_GET_FUNCTION(meth) \
|
||||
(((PyInstanceMethodObject *)meth) -> func)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CLASSOBJECT_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Definitions for bytecode */
|
||||
|
||||
#ifndef Py_CODE_H
|
||||
#define Py_CODE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct PyCodeObject PyCodeObject;
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_CODE_H
|
||||
# include "cpython/code.h"
|
||||
# undef Py_CPYTHON_CODE_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CODE_H */
|
||||
@@ -0,0 +1,248 @@
|
||||
#ifndef Py_CODECREGISTRY_H
|
||||
#define Py_CODECREGISTRY_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
|
||||
Python Codec Registry and support functions
|
||||
|
||||
|
||||
Written by Marc-Andre Lemburg (mal@lemburg.com).
|
||||
|
||||
Copyright (c) Corporation for National Research Initiatives.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
/* Register a new codec search function.
|
||||
|
||||
As side effect, this tries to load the encodings package, if not
|
||||
yet done, to make sure that it is always first in the list of
|
||||
search functions.
|
||||
|
||||
The search_function's refcount is incremented by this function. */
|
||||
|
||||
PyAPI_FUNC(int) PyCodec_Register(
|
||||
PyObject *search_function
|
||||
);
|
||||
|
||||
/* Unregister a codec search function and clear the registry's cache.
|
||||
If the search function is not registered, do nothing.
|
||||
Return 0 on success. Raise an exception and return -1 on error. */
|
||||
|
||||
PyAPI_FUNC(int) PyCodec_Unregister(
|
||||
PyObject *search_function
|
||||
);
|
||||
|
||||
/* Codec registry lookup API.
|
||||
|
||||
Looks up the given encoding and returns a CodecInfo object with
|
||||
function attributes which implement the different aspects of
|
||||
processing the encoding.
|
||||
|
||||
The encoding string is looked up converted to all lower-case
|
||||
characters. This makes encodings looked up through this mechanism
|
||||
effectively case-insensitive.
|
||||
|
||||
If no codec is found, a KeyError is set and NULL returned.
|
||||
|
||||
As side effect, this tries to load the encodings package, if not
|
||||
yet done. This is part of the lazy load strategy for the encodings
|
||||
package.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
|
||||
const char *encoding
|
||||
);
|
||||
|
||||
PyAPI_FUNC(int) _PyCodec_Forget(
|
||||
const char *encoding
|
||||
);
|
||||
#endif
|
||||
|
||||
/* Codec registry encoding check API.
|
||||
|
||||
Returns 1/0 depending on whether there is a registered codec for
|
||||
the given encoding.
|
||||
|
||||
*/
|
||||
|
||||
PyAPI_FUNC(int) PyCodec_KnownEncoding(
|
||||
const char *encoding
|
||||
);
|
||||
|
||||
/* Generic codec based encoding API.
|
||||
|
||||
object is passed through the encoder function found for the given
|
||||
encoding using the error handling method defined by errors. errors
|
||||
may be NULL to use the default method defined for the codec.
|
||||
|
||||
Raises a LookupError in case no encoder can be found.
|
||||
|
||||
*/
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_Encode(
|
||||
PyObject *object,
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* Generic codec based decoding API.
|
||||
|
||||
object is passed through the decoder function found for the given
|
||||
encoding using the error handling method defined by errors. errors
|
||||
may be NULL to use the default method defined for the codec.
|
||||
|
||||
Raises a LookupError in case no encoder can be found.
|
||||
|
||||
*/
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_Decode(
|
||||
PyObject *object,
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
/* Text codec specific encoding and decoding API.
|
||||
|
||||
Checks the encoding against a list of codecs which do not
|
||||
implement a str<->bytes encoding before attempting the
|
||||
operation.
|
||||
|
||||
Please note that these APIs are internal and should not
|
||||
be used in Python C extensions.
|
||||
|
||||
XXX (ncoghlan): should we make these, or something like them, public
|
||||
in Python 3.5+?
|
||||
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding(
|
||||
const char *encoding,
|
||||
const char *alternate_command
|
||||
);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyCodec_EncodeText(
|
||||
PyObject *object,
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyCodec_DecodeText(
|
||||
PyObject *object,
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* These two aren't actually text encoding specific, but _io.TextIOWrapper
|
||||
* is the only current API consumer.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder(
|
||||
PyObject *codec_info,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder(
|
||||
PyObject *codec_info,
|
||||
const char *errors
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* --- Codec Lookup APIs --------------------------------------------------
|
||||
|
||||
All APIs return a codec object with incremented refcount and are
|
||||
based on _PyCodec_Lookup(). The same comments w/r to the encoding
|
||||
name also apply to these APIs.
|
||||
|
||||
*/
|
||||
|
||||
/* Get an encoder function for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_Encoder(
|
||||
const char *encoding
|
||||
);
|
||||
|
||||
/* Get a decoder function for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_Decoder(
|
||||
const char *encoding
|
||||
);
|
||||
|
||||
/* Get an IncrementalEncoder object for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* Get an IncrementalDecoder object function for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
|
||||
const char *encoding,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* Get a StreamReader factory function for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
|
||||
const char *encoding,
|
||||
PyObject *stream,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* Get a StreamWriter factory function for the given encoding. */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyCodec_StreamWriter(
|
||||
const char *encoding,
|
||||
PyObject *stream,
|
||||
const char *errors
|
||||
);
|
||||
|
||||
/* Unicode encoding error handling callback registry API */
|
||||
|
||||
/* Register the error handling callback function error under the given
|
||||
name. This function will be called by the codec when it encounters
|
||||
unencodable characters/undecodable bytes and doesn't know the
|
||||
callback name, when name is specified as the error parameter
|
||||
in the call to the encode/decode function.
|
||||
Return 0 on success, -1 on error */
|
||||
PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error);
|
||||
|
||||
/* Lookup the error handling callback function registered under the given
|
||||
name. As a special case NULL can be passed, in which case
|
||||
the error handling callback for "strict" will be returned. */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name);
|
||||
|
||||
/* raise exc as an exception */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc);
|
||||
|
||||
/* ignore the unicode error, skipping the faulty input */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc);
|
||||
|
||||
/* replace the unicode encode error with ? or U+FFFD */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc);
|
||||
|
||||
/* replace the unicode encode error with XML character references */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc);
|
||||
|
||||
/* replace the unicode encode error with backslash escapes (\x, \u and \U) */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc);
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
||||
/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */
|
||||
PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc);
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_DATA(const char *) Py_hexdigits;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CODECREGISTRY_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef Py_COMPILE_H
|
||||
#define Py_COMPILE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* These definitions must match corresponding definitions in graminit.h. */
|
||||
#define Py_single_input 256
|
||||
#define Py_file_input 257
|
||||
#define Py_eval_input 258
|
||||
#define Py_func_type_input 345
|
||||
|
||||
/* This doesn't need to match anything */
|
||||
#define Py_fstring_input 800
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_COMPILE_H
|
||||
# include "cpython/compile.h"
|
||||
# undef Py_CPYTHON_COMPILE_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_COMPILE_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Complex number structure */
|
||||
|
||||
#ifndef Py_COMPLEXOBJECT_H
|
||||
#define Py_COMPLEXOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef struct {
|
||||
double real;
|
||||
double imag;
|
||||
} Py_complex;
|
||||
|
||||
/* Operations on complex numbers from complexmodule.c */
|
||||
|
||||
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
|
||||
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
|
||||
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
|
||||
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
|
||||
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
|
||||
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
|
||||
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
|
||||
#endif
|
||||
|
||||
/* Complex object interface */
|
||||
|
||||
/*
|
||||
PyComplexObject represents a complex number with double-precision
|
||||
real and imaginary parts.
|
||||
*/
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
Py_complex cval;
|
||||
} PyComplexObject;
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyComplex_Type;
|
||||
|
||||
#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
|
||||
#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type)
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
|
||||
#endif
|
||||
PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
|
||||
|
||||
PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
|
||||
PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
|
||||
#endif
|
||||
|
||||
/* Format the object based on the format_spec, as defined in PEP 3101
|
||||
(Advanced String Formatting). */
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(int) _PyComplex_FormatAdvancedWriter(
|
||||
_PyUnicodeWriter *writer,
|
||||
PyObject *obj,
|
||||
PyObject *format_spec,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t end);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_COMPLEXOBJECT_H */
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef Py_CONTEXT_H
|
||||
#define Py_CONTEXT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyContext_Type;
|
||||
typedef struct _pycontextobject PyContext;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyContextVar_Type;
|
||||
typedef struct _pycontextvarobject PyContextVar;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyContextToken_Type;
|
||||
typedef struct _pycontexttokenobject PyContextToken;
|
||||
|
||||
|
||||
#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type)
|
||||
#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type)
|
||||
#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type)
|
||||
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyContext_New(void);
|
||||
PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void);
|
||||
|
||||
PyAPI_FUNC(int) PyContext_Enter(PyObject *);
|
||||
PyAPI_FUNC(int) PyContext_Exit(PyObject *);
|
||||
|
||||
|
||||
/* Create a new context variable.
|
||||
|
||||
default_value can be NULL.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) PyContextVar_New(
|
||||
const char *name, PyObject *default_value);
|
||||
|
||||
|
||||
/* Get a value for the variable.
|
||||
|
||||
Returns -1 if an error occurred during lookup.
|
||||
|
||||
Returns 0 if value either was or was not found.
|
||||
|
||||
If value was found, *value will point to it.
|
||||
If not, it will point to:
|
||||
|
||||
- default_value, if not NULL;
|
||||
- the default value of "var", if not NULL;
|
||||
- NULL.
|
||||
|
||||
'*value' will be a new ref, if not NULL.
|
||||
*/
|
||||
PyAPI_FUNC(int) PyContextVar_Get(
|
||||
PyObject *var, PyObject *default_value, PyObject **value);
|
||||
|
||||
|
||||
/* Set a new value for the variable.
|
||||
Returns NULL if an error occurs.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value);
|
||||
|
||||
|
||||
/* Reset a variable to its previous value.
|
||||
Returns 0 on success, -1 on error.
|
||||
*/
|
||||
PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token);
|
||||
|
||||
|
||||
/* This method is exposed only for CPython tests. Don not use it. */
|
||||
PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void);
|
||||
|
||||
|
||||
#endif /* !Py_LIMITED_API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_CONTEXT_H */
|
||||
@@ -0,0 +1,373 @@
|
||||
#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* === Object Protocol ================================================== */
|
||||
|
||||
#ifdef PY_SSIZE_T_CLEAN
|
||||
# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
|
||||
#endif
|
||||
|
||||
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
|
||||
format to a Python dictionary ("kwargs" dict).
|
||||
|
||||
The type of kwnames keys is not checked. The final function getting
|
||||
arguments is responsible to check if all keys are strings, for example using
|
||||
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
|
||||
|
||||
Duplicate keys are merged using the last value. If duplicate keys must raise
|
||||
an exception, the caller is responsible to implement an explicit keys on
|
||||
kwnames. */
|
||||
PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
||||
PyObject *const *values,
|
||||
PyObject *kwnames);
|
||||
|
||||
/* Suggested size (number of positional arguments) for arrays of PyObject*
|
||||
allocated on a C stack to avoid allocating memory on the heap memory. Such
|
||||
array is used to pass positional arguments to call functions of the
|
||||
PyObject_Vectorcall() family.
|
||||
|
||||
The size is chosen to not abuse the C stack and so limit the risk of stack
|
||||
overflow. The size is also chosen to allow using the small stack for most
|
||||
function calls of the Python standard library. On 64-bit CPU, it allocates
|
||||
40 bytes on the stack. */
|
||||
#define _PY_FASTCALL_SMALL_STACK 5
|
||||
|
||||
PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *result,
|
||||
const char *where);
|
||||
|
||||
/* === Vectorcall protocol (PEP 590) ============================= */
|
||||
|
||||
/* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
|
||||
or PyObject_FastCallDict() (both forms are supported),
|
||||
except that nargs is plainly the number of arguments without flags. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *const *args, Py_ssize_t nargs,
|
||||
PyObject *keywords);
|
||||
|
||||
#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1))
|
||||
|
||||
static inline Py_ssize_t
|
||||
PyVectorcall_NARGS(size_t n)
|
||||
{
|
||||
return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
}
|
||||
|
||||
static inline vectorcallfunc
|
||||
PyVectorcall_Function(PyObject *callable)
|
||||
{
|
||||
PyTypeObject *tp;
|
||||
Py_ssize_t offset;
|
||||
vectorcallfunc ptr;
|
||||
|
||||
assert(callable != NULL);
|
||||
tp = Py_TYPE(callable);
|
||||
if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
|
||||
return NULL;
|
||||
}
|
||||
assert(PyCallable_Check(callable));
|
||||
offset = tp->tp_vectorcall_offset;
|
||||
assert(offset > 0);
|
||||
memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Call the callable object 'callable' with the "vectorcall" calling
|
||||
convention.
|
||||
|
||||
args is a C array for positional arguments.
|
||||
|
||||
nargsf is the number of positional arguments plus optionally the flag
|
||||
PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
|
||||
modify args[-1].
|
||||
|
||||
kwnames is a tuple of keyword names. The values of the keyword arguments
|
||||
are stored in "args" after the positional arguments (note that the number
|
||||
of keyword arguments does not change nargsf). kwnames can also be NULL if
|
||||
there are no keyword arguments.
|
||||
|
||||
keywords must only contain strings and all keys must be unique.
|
||||
|
||||
Return the result on success. Raise an exception and return NULL on
|
||||
error. */
|
||||
static inline PyObject *
|
||||
_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
|
||||
PyObject *const *args, size_t nargsf,
|
||||
PyObject *kwnames)
|
||||
{
|
||||
vectorcallfunc func;
|
||||
PyObject *res;
|
||||
|
||||
assert(kwnames == NULL || PyTuple_Check(kwnames));
|
||||
assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
|
||||
|
||||
func = PyVectorcall_Function(callable);
|
||||
if (func == NULL) {
|
||||
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
||||
return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
|
||||
}
|
||||
res = func(callable, args, nargsf, kwnames);
|
||||
return _Py_CheckFunctionResult(tstate, callable, res, NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
PyObject_Vectorcall(PyObject *callable, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
return _PyObject_VectorcallTstate(tstate, callable,
|
||||
args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
// Backwards compatibility aliases for API that was provisional in Python 3.8
|
||||
#define _PyObject_Vectorcall PyObject_Vectorcall
|
||||
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
|
||||
#define _PyObject_FastCallDict PyObject_VectorcallDict
|
||||
#define _PyVectorcall_Function PyVectorcall_Function
|
||||
#define _PyObject_CallOneArg PyObject_CallOneArg
|
||||
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
|
||||
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
|
||||
|
||||
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
|
||||
dict, which may be NULL if there are no keyword arguments. */
|
||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
|
||||
PyObject *callable,
|
||||
PyObject *const *args,
|
||||
size_t nargsf,
|
||||
PyObject *kwargs);
|
||||
|
||||
/* Call "callable" (which must support vectorcall) with positional arguments
|
||||
"tuple" and keyword arguments "dict". "dict" may also be NULL */
|
||||
PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
|
||||
}
|
||||
|
||||
/* Same as PyObject_Vectorcall except without keyword arguments */
|
||||
static inline PyObject *
|
||||
_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
return _PyObject_FastCallTstate(tstate, func, args, nargs);
|
||||
}
|
||||
|
||||
/* Call a callable without any arguments
|
||||
Private static inline function variant of public function
|
||||
PyObject_CallNoArgs(). */
|
||||
static inline PyObject *
|
||||
_PyObject_CallNoArg(PyObject *func) {
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
PyObject_CallOneArg(PyObject *func, PyObject *arg)
|
||||
{
|
||||
PyObject *_args[2];
|
||||
PyObject **args;
|
||||
PyThreadState *tstate;
|
||||
size_t nargsf;
|
||||
|
||||
assert(arg != NULL);
|
||||
args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET
|
||||
args[0] = arg;
|
||||
tstate = PyThreadState_Get();
|
||||
nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL);
|
||||
}
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
|
||||
PyObject *name, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames);
|
||||
|
||||
static inline PyObject *
|
||||
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
|
||||
{
|
||||
return PyObject_VectorcallMethod(name, &self,
|
||||
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
||||
{
|
||||
PyObject *args[2] = {self, arg};
|
||||
|
||||
assert(arg != NULL);
|
||||
return PyObject_VectorcallMethod(name, args,
|
||||
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
||||
}
|
||||
|
||||
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
|
||||
as the method name. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
const char *format, ...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
|
||||
PyObject *obj,
|
||||
struct _Py_Identifier *name,
|
||||
...);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_VectorcallMethodId(
|
||||
_Py_Identifier *name, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
|
||||
if (!oname) {
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
|
||||
{
|
||||
return _PyObject_VectorcallMethodId(name, &self,
|
||||
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
|
||||
{
|
||||
PyObject *args[2] = {self, arg};
|
||||
|
||||
assert(arg != NULL);
|
||||
return _PyObject_VectorcallMethodId(name, args,
|
||||
2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
||||
}
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
|
||||
|
||||
/* Guess the size of object 'o' using len(o) or o.__length_hint__().
|
||||
If neither of those return a non-negative value, then return the default
|
||||
value. If one of the calls fails, this function returns -1. */
|
||||
PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
|
||||
|
||||
/* === New Buffer API ============================================ */
|
||||
|
||||
/* Return 1 if the getbuffer function is available, otherwise return 0. */
|
||||
PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj);
|
||||
|
||||
/* This is a C-API version of the getbuffer function call. It checks
|
||||
to make sure object has the required function pointer and issues the
|
||||
call.
|
||||
|
||||
Returns -1 and raises an error on failure and returns 0 on success. */
|
||||
PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
|
||||
int flags);
|
||||
|
||||
/* Get the memory area pointed to by the indices for the buffer given.
|
||||
Note that view->ndim is the assumed size of indices. */
|
||||
PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices);
|
||||
|
||||
/* Return the implied itemsize of the data-format area from a
|
||||
struct-style description. */
|
||||
PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format);
|
||||
|
||||
/* Implementation in memoryobject.c */
|
||||
PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view,
|
||||
Py_ssize_t len, char order);
|
||||
|
||||
PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf,
|
||||
Py_ssize_t len, char order);
|
||||
|
||||
/* Copy len bytes of data from the contiguous chunk of memory
|
||||
pointed to by buf into the buffer exported by obj. Return
|
||||
0 on success and return -1 and raise a PyBuffer_Error on
|
||||
error (i.e. the object does not have a buffer interface or
|
||||
it is not working).
|
||||
|
||||
If fort is 'F', then if the object is multi-dimensional,
|
||||
then the data will be copied into the array in
|
||||
Fortran-style (first dimension varies the fastest). If
|
||||
fort is 'C', then the data will be copied into the array
|
||||
in C-style (last dimension varies the fastest). If fort
|
||||
is 'A', then it does not matter and the copy will be made
|
||||
in whatever way is more efficient. */
|
||||
PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src);
|
||||
|
||||
/* Copy the data from the src buffer to the buffer of destination. */
|
||||
PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort);
|
||||
|
||||
/*Fill the strides array with byte-strides of a contiguous
|
||||
(Fortran-style if fort is 'F' or C-style otherwise)
|
||||
array of the given shape with the given number of bytes
|
||||
per element. */
|
||||
PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims,
|
||||
Py_ssize_t *shape,
|
||||
Py_ssize_t *strides,
|
||||
int itemsize,
|
||||
char fort);
|
||||
|
||||
/* Fills in a buffer-info structure correctly for an exporter
|
||||
that can only share a contiguous chunk of memory of
|
||||
"unsigned bytes" of the given length.
|
||||
|
||||
Returns 0 on success and -1 (with raising an error) on error. */
|
||||
PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf,
|
||||
Py_ssize_t len, int readonly,
|
||||
int flags);
|
||||
|
||||
/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */
|
||||
PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view);
|
||||
|
||||
/* === Sequence protocol ================================================ */
|
||||
|
||||
/* Assume tp_as_sequence and sq_item exist and that 'i' does not
|
||||
need to be corrected for a negative index. */
|
||||
#define PySequence_ITEM(o, i)\
|
||||
( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
|
||||
|
||||
#define PY_ITERSEARCH_COUNT 1
|
||||
#define PY_ITERSEARCH_INDEX 2
|
||||
#define PY_ITERSEARCH_CONTAINS 3
|
||||
|
||||
/* Iterate over seq.
|
||||
|
||||
Result depends on the operation:
|
||||
|
||||
PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if
|
||||
error.
|
||||
PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of
|
||||
obj in seq; set ValueError and return -1 if none found;
|
||||
also return -1 on error.
|
||||
PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on
|
||||
error. */
|
||||
PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
|
||||
PyObject *obj, int operation);
|
||||
|
||||
/* === Mapping protocol ================================================= */
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
|
||||
|
||||
PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
|
||||
|
||||
PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
|
||||
|
||||
/* For internal use by buffer API functions */
|
||||
PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
|
||||
const Py_ssize_t *shape);
|
||||
PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
|
||||
const Py_ssize_t *shape);
|
||||
|
||||
/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
|
||||
PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
|
||||
|
||||
/* Same as PyNumber_Index but can return an instance of a subclass of int. */
|
||||
PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* Object layout */
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */
|
||||
char *ob_bytes; /* Physical backing buffer */
|
||||
char *ob_start; /* Logical start inside ob_bytes */
|
||||
Py_ssize_t ob_exports; /* How many buffer exports */
|
||||
} PyByteArrayObject;
|
||||
|
||||
/* Macros, trading safety for speed */
|
||||
#define PyByteArray_AS_STRING(self) \
|
||||
(assert(PyByteArray_Check(self)), \
|
||||
Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string)
|
||||
#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self))
|
||||
|
||||
PyAPI_DATA(char) _PyByteArray_empty_string[];
|
||||
@@ -0,0 +1,118 @@
|
||||
#ifndef Py_CPYTHON_BYTESOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
Py_hash_t ob_shash;
|
||||
char ob_sval[1];
|
||||
|
||||
/* Invariants:
|
||||
* ob_sval contains space for 'ob_size+1' elements.
|
||||
* ob_sval[ob_size] == 0.
|
||||
* ob_shash is the hash of the byte string or -1 if not computed yet.
|
||||
*/
|
||||
} PyBytesObject;
|
||||
|
||||
PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t);
|
||||
PyAPI_FUNC(PyObject*) _PyBytes_FormatEx(
|
||||
const char *format,
|
||||
Py_ssize_t format_len,
|
||||
PyObject *args,
|
||||
int use_bytearray);
|
||||
PyAPI_FUNC(PyObject*) _PyBytes_FromHex(
|
||||
PyObject *string,
|
||||
int use_bytearray);
|
||||
|
||||
/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */
|
||||
PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
|
||||
const char *, const char **);
|
||||
|
||||
/* Macro, trading safety for speed */
|
||||
#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \
|
||||
(((PyBytesObject *)(op))->ob_sval))
|
||||
#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op))
|
||||
|
||||
/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*,
|
||||
x must be an iterable object. */
|
||||
PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x);
|
||||
|
||||
|
||||
/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer".
|
||||
A _PyBytesWriter variable must be declared at the end of variables in a
|
||||
function to optimize the memory allocation on the stack. */
|
||||
typedef struct {
|
||||
/* bytes, bytearray or NULL (when the small buffer is used) */
|
||||
PyObject *buffer;
|
||||
|
||||
/* Number of allocated size. */
|
||||
Py_ssize_t allocated;
|
||||
|
||||
/* Minimum number of allocated bytes,
|
||||
incremented by _PyBytesWriter_Prepare() */
|
||||
Py_ssize_t min_size;
|
||||
|
||||
/* If non-zero, use a bytearray instead of a bytes object for buffer. */
|
||||
int use_bytearray;
|
||||
|
||||
/* If non-zero, overallocate the buffer (default: 0).
|
||||
This flag must be zero if use_bytearray is non-zero. */
|
||||
int overallocate;
|
||||
|
||||
/* Stack buffer */
|
||||
int use_small_buffer;
|
||||
char small_buffer[512];
|
||||
} _PyBytesWriter;
|
||||
|
||||
/* Initialize a bytes writer
|
||||
|
||||
By default, the overallocation is disabled. Set the overallocate attribute
|
||||
to control the allocation of the buffer. */
|
||||
PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer);
|
||||
|
||||
/* Get the buffer content and reset the writer.
|
||||
Return a bytes object, or a bytearray object if use_bytearray is non-zero.
|
||||
Raise an exception and return NULL on error. */
|
||||
PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer,
|
||||
void *str);
|
||||
|
||||
/* Deallocate memory of a writer (clear its internal buffer). */
|
||||
PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer);
|
||||
|
||||
/* Allocate the buffer to write size bytes.
|
||||
Return the pointer to the beginning of buffer data.
|
||||
Raise an exception and return NULL on error. */
|
||||
PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer,
|
||||
Py_ssize_t size);
|
||||
|
||||
/* Ensure that the buffer is large enough to write *size* bytes.
|
||||
Add size to the writer minimum size (min_size attribute).
|
||||
|
||||
str is the current pointer inside the buffer.
|
||||
Return the updated current pointer inside the buffer.
|
||||
Raise an exception and return NULL on error. */
|
||||
PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer,
|
||||
void *str,
|
||||
Py_ssize_t size);
|
||||
|
||||
/* Resize the buffer to make it larger.
|
||||
The new buffer may be larger than size bytes because of overallocation.
|
||||
Return the updated current pointer inside the buffer.
|
||||
Raise an exception and return NULL on error.
|
||||
|
||||
Note: size must be greater than the number of allocated bytes in the writer.
|
||||
|
||||
This function doesn't use the writer minimum size (min_size attribute).
|
||||
|
||||
See also _PyBytesWriter_Prepare().
|
||||
*/
|
||||
PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer,
|
||||
void *str,
|
||||
Py_ssize_t size);
|
||||
|
||||
/* Write bytes.
|
||||
Raise an exception and return NULL on error. */
|
||||
PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,
|
||||
void *str,
|
||||
const void *bytes,
|
||||
Py_ssize_t size);
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef Py_CPYTHON_CEVAL_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
|
||||
PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
|
||||
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
|
||||
PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
|
||||
PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void);
|
||||
PyAPI_FUNC(int) _PyEval_SetAsyncGenFirstiter(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void);
|
||||
PyAPI_FUNC(int) _PyEval_SetAsyncGenFinalizer(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void);
|
||||
|
||||
/* Helper to look up a builtin object */
|
||||
PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *);
|
||||
/* Look at the current frame's (if any) code's co_flags, and turn on
|
||||
the corresponding compiler flags in cf->cf_flags. Return 1 if any
|
||||
flag was set, else return 0. */
|
||||
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int exc);
|
||||
|
||||
PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
|
||||
PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
|
||||
|
||||
PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
|
||||
|
||||
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
||||
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
||||
@@ -0,0 +1,184 @@
|
||||
#ifndef Py_CPYTHON_CODE_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef uint16_t _Py_CODEUNIT;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define _Py_OPCODE(word) ((word) >> 8)
|
||||
# define _Py_OPARG(word) ((word) & 255)
|
||||
#else
|
||||
# define _Py_OPCODE(word) ((word) & 255)
|
||||
# define _Py_OPARG(word) ((word) >> 8)
|
||||
#endif
|
||||
|
||||
typedef struct _PyOpcache _PyOpcache;
|
||||
|
||||
/* Bytecode object */
|
||||
struct PyCodeObject {
|
||||
PyObject_HEAD
|
||||
int co_argcount; /* #arguments, except *args */
|
||||
int co_posonlyargcount; /* #positional only arguments */
|
||||
int co_kwonlyargcount; /* #keyword only arguments */
|
||||
int co_nlocals; /* #local variables */
|
||||
int co_stacksize; /* #entries needed for evaluation stack */
|
||||
int co_flags; /* CO_..., see below */
|
||||
int co_firstlineno; /* first source line number */
|
||||
PyObject *co_code; /* instruction opcodes */
|
||||
PyObject *co_consts; /* list (constants used) */
|
||||
PyObject *co_names; /* list of strings (names used) */
|
||||
PyObject *co_varnames; /* tuple of strings (local variable names) */
|
||||
PyObject *co_freevars; /* tuple of strings (free variable names) */
|
||||
PyObject *co_cellvars; /* tuple of strings (cell variable names) */
|
||||
/* The rest aren't used in either hash or comparisons, except for co_name,
|
||||
used in both. This is done to preserve the name and line number
|
||||
for tracebacks and debuggers; otherwise, constant de-duplication
|
||||
would collapse identical functions/lambdas defined on different lines.
|
||||
*/
|
||||
Py_ssize_t *co_cell2arg; /* Maps cell vars which are arguments. */
|
||||
PyObject *co_filename; /* unicode (where it was loaded from) */
|
||||
PyObject *co_name; /* unicode (name, for reference) */
|
||||
PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See
|
||||
Objects/lnotab_notes.txt for details. */
|
||||
void *co_zombieframe; /* for optimization only (see frameobject.c) */
|
||||
PyObject *co_weakreflist; /* to support weakrefs to code objects */
|
||||
/* Scratch space for extra data relating to the code object.
|
||||
Type is a void* to keep the format private in codeobject.c to force
|
||||
people to go through the proper APIs. */
|
||||
void *co_extra;
|
||||
|
||||
/* Per opcodes just-in-time cache
|
||||
*
|
||||
* To reduce cache size, we use indirect mapping from opcode index to
|
||||
* cache object:
|
||||
* cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1]
|
||||
*/
|
||||
|
||||
// co_opcache_map is indexed by (next_instr - first_instr).
|
||||
// * 0 means there is no cache for this opcode.
|
||||
// * n > 0 means there is cache in co_opcache[n-1].
|
||||
unsigned char *co_opcache_map;
|
||||
_PyOpcache *co_opcache;
|
||||
int co_opcache_flag; // used to determine when create a cache.
|
||||
unsigned char co_opcache_size; // length of co_opcache.
|
||||
};
|
||||
|
||||
/* Masks for co_flags above */
|
||||
#define CO_OPTIMIZED 0x0001
|
||||
#define CO_NEWLOCALS 0x0002
|
||||
#define CO_VARARGS 0x0004
|
||||
#define CO_VARKEYWORDS 0x0008
|
||||
#define CO_NESTED 0x0010
|
||||
#define CO_GENERATOR 0x0020
|
||||
/* The CO_NOFREE flag is set if there are no free or cell variables.
|
||||
This information is redundant, but it allows a single flag test
|
||||
to determine whether there is any extra work to be done when the
|
||||
call frame it setup.
|
||||
*/
|
||||
#define CO_NOFREE 0x0040
|
||||
|
||||
/* The CO_COROUTINE flag is set for coroutine functions (defined with
|
||||
``async def`` keywords) */
|
||||
#define CO_COROUTINE 0x0080
|
||||
#define CO_ITERABLE_COROUTINE 0x0100
|
||||
#define CO_ASYNC_GENERATOR 0x0200
|
||||
|
||||
/* bpo-39562: These constant values are changed in Python 3.9
|
||||
to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
|
||||
constants must be kept unique. PyCF_ constants can use bits from
|
||||
0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
|
||||
#define CO_FUTURE_DIVISION 0x20000
|
||||
#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */
|
||||
#define CO_FUTURE_WITH_STATEMENT 0x80000
|
||||
#define CO_FUTURE_PRINT_FUNCTION 0x100000
|
||||
#define CO_FUTURE_UNICODE_LITERALS 0x200000
|
||||
|
||||
#define CO_FUTURE_BARRY_AS_BDFL 0x400000
|
||||
#define CO_FUTURE_GENERATOR_STOP 0x800000
|
||||
#define CO_FUTURE_ANNOTATIONS 0x1000000
|
||||
|
||||
/* This value is found in the co_cell2arg array when the associated cell
|
||||
variable does not correspond to an argument. */
|
||||
#define CO_CELL_NOT_AN_ARG (-1)
|
||||
|
||||
/* This should be defined if a future statement modifies the syntax.
|
||||
For example, when a keyword is added.
|
||||
*/
|
||||
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
|
||||
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyCode_Type;
|
||||
|
||||
#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type)
|
||||
#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars))
|
||||
|
||||
/* Public interface */
|
||||
PyAPI_FUNC(PyCodeObject *) PyCode_New(
|
||||
int, int, int, int, int, PyObject *, PyObject *,
|
||||
PyObject *, PyObject *, PyObject *, PyObject *,
|
||||
PyObject *, PyObject *, int, PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs(
|
||||
int, int, int, int, int, int, PyObject *, PyObject *,
|
||||
PyObject *, PyObject *, PyObject *, PyObject *,
|
||||
PyObject *, PyObject *, int, PyObject *);
|
||||
/* same as struct above */
|
||||
|
||||
/* Creates a new empty code object with the specified source location. */
|
||||
PyAPI_FUNC(PyCodeObject *)
|
||||
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
|
||||
|
||||
/* Return the line number associated with the specified bytecode index
|
||||
in this code object. If you just need the line number of a frame,
|
||||
use PyFrame_GetLineNumber() instead. */
|
||||
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
|
||||
|
||||
/* for internal use only */
|
||||
struct _opaque {
|
||||
int computed_line;
|
||||
const char *lo_next;
|
||||
const char *limit;
|
||||
};
|
||||
|
||||
typedef struct _line_offsets {
|
||||
int ar_start;
|
||||
int ar_end;
|
||||
int ar_line;
|
||||
struct _opaque opaque;
|
||||
} PyCodeAddressRange;
|
||||
|
||||
/* Update *bounds to describe the first and one-past-the-last instructions in the
|
||||
same line as lasti. Return the number of that line.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds);
|
||||
|
||||
/* Create a comparable key used to compare constants taking in account the
|
||||
* object type. It is used to make sure types are not coerced (e.g., float and
|
||||
* complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
|
||||
*
|
||||
* Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
|
||||
* depending on the type and the value. The type is the first item to not
|
||||
* compare bytes and str which can raise a BytesWarning exception. */
|
||||
PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
|
||||
|
||||
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
|
||||
PyObject *names, PyObject *lnotab);
|
||||
|
||||
|
||||
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index,
|
||||
void **extra);
|
||||
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index,
|
||||
void *extra);
|
||||
|
||||
/** API for initializing the line number table. */
|
||||
int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds);
|
||||
|
||||
/** Out of process API for initializing the line number table. */
|
||||
void PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range);
|
||||
|
||||
/** API for traversing the line number table. */
|
||||
int PyLineTable_NextAddressRange(PyCodeAddressRange *range);
|
||||
int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef Py_CPYTHON_COMPILE_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* Public interface */
|
||||
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
|
||||
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
|
||||
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
|
||||
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
|
||||
#define PyCF_MASK_OBSOLETE (CO_NESTED)
|
||||
|
||||
/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique.
|
||||
PyCF_ constants can use bits from 0x0100 to 0x10000.
|
||||
CO_FUTURE_ constants use bits starting at 0x20000. */
|
||||
#define PyCF_SOURCE_IS_UTF8 0x0100
|
||||
#define PyCF_DONT_IMPLY_DEDENT 0x0200
|
||||
#define PyCF_ONLY_AST 0x0400
|
||||
#define PyCF_IGNORE_COOKIE 0x0800
|
||||
#define PyCF_TYPE_COMMENTS 0x1000
|
||||
#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
|
||||
#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000
|
||||
#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
|
||||
PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \
|
||||
PyCF_ALLOW_INCOMPLETE_INPUT)
|
||||
|
||||
typedef struct {
|
||||
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
|
||||
int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */
|
||||
} PyCompilerFlags;
|
||||
|
||||
#define _PyCompilerFlags_INIT \
|
||||
(PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}
|
||||
|
||||
/* Future feature support */
|
||||
|
||||
typedef struct {
|
||||
int ff_features; /* flags set by future statements */
|
||||
int ff_lineno; /* line number of last future statement */
|
||||
} PyFutureFeatures;
|
||||
|
||||
#define FUTURE_NESTED_SCOPES "nested_scopes"
|
||||
#define FUTURE_GENERATORS "generators"
|
||||
#define FUTURE_DIVISION "division"
|
||||
#define FUTURE_ABSOLUTE_IMPORT "absolute_import"
|
||||
#define FUTURE_WITH_STATEMENT "with_statement"
|
||||
#define FUTURE_PRINT_FUNCTION "print_function"
|
||||
#define FUTURE_UNICODE_LITERALS "unicode_literals"
|
||||
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
|
||||
#define FUTURE_GENERATOR_STOP "generator_stop"
|
||||
#define FUTURE_ANNOTATIONS "annotations"
|
||||
|
||||
#define PY_INVALID_STACK_EFFECT INT_MAX
|
||||
PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg);
|
||||
PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump);
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef Py_CPYTHON_DICTOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef struct _dictkeysobject PyDictKeysObject;
|
||||
|
||||
/* The ma_values pointer is NULL for a combined table
|
||||
* or points to an array of PyObject* for a split table
|
||||
*/
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
/* Number of items in the dictionary */
|
||||
Py_ssize_t ma_used;
|
||||
|
||||
/* Dictionary version: globally unique, value change each time
|
||||
the dictionary is modified */
|
||||
uint64_t ma_version_tag;
|
||||
|
||||
PyDictKeysObject *ma_keys;
|
||||
|
||||
/* If ma_values is NULL, the table is "combined": keys and values
|
||||
are stored in ma_keys.
|
||||
|
||||
If ma_values is not NULL, the table is split:
|
||||
keys are stored in ma_keys and values are stored in ma_values */
|
||||
PyObject **ma_values;
|
||||
} PyDictObject;
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
|
||||
Py_hash_t hash);
|
||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
|
||||
struct _Py_Identifier *key);
|
||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
|
||||
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
|
||||
PyObject *mp, PyObject *key, PyObject *defaultobj);
|
||||
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
|
||||
PyObject *item, Py_hash_t hash);
|
||||
PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
|
||||
Py_hash_t hash);
|
||||
PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
|
||||
int (*predicate)(PyObject *value));
|
||||
PyDictKeysObject *_PyDict_NewKeysForClass(void);
|
||||
PyAPI_FUNC(int) _PyDict_Next(
|
||||
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
|
||||
|
||||
/* Get the number of items of a dictionary. */
|
||||
#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
|
||||
PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t);
|
||||
PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, struct _Py_Identifier *);
|
||||
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
|
||||
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
|
||||
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
|
||||
Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
|
||||
PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
|
||||
PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
|
||||
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
|
||||
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
|
||||
|
||||
/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
|
||||
the first occurrence of a key wins, if override is 1, the last occurrence
|
||||
of a key wins, if override is 2, a KeyError with conflicting key as
|
||||
argument is raised.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
|
||||
PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item);
|
||||
|
||||
PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key);
|
||||
PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
|
||||
|
||||
int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
|
||||
PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
|
||||
Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **);
|
||||
|
||||
/* _PyDictView */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyDictObject *dv_dict;
|
||||
} _PyDictViewObject;
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef Py_CPYTHON_FILEOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
|
||||
|
||||
/* The std printer acts as a preliminary sys.stderr until the new io
|
||||
infrastructure is in place. */
|
||||
PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
|
||||
PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
|
||||
|
||||
typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path);
|
||||
PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path);
|
||||
PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData);
|
||||
|
||||
PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *);
|
||||
@@ -0,0 +1,172 @@
|
||||
#ifndef Py_CPYTHON_FILEUTILS_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
_Py_ERROR_UNKNOWN=0,
|
||||
_Py_ERROR_STRICT,
|
||||
_Py_ERROR_SURROGATEESCAPE,
|
||||
_Py_ERROR_REPLACE,
|
||||
_Py_ERROR_IGNORE,
|
||||
_Py_ERROR_BACKSLASHREPLACE,
|
||||
_Py_ERROR_SURROGATEPASS,
|
||||
_Py_ERROR_XMLCHARREFREPLACE,
|
||||
_Py_ERROR_OTHER
|
||||
} _Py_error_handler;
|
||||
|
||||
PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors);
|
||||
|
||||
PyAPI_FUNC(int) _Py_DecodeLocaleEx(
|
||||
const char *arg,
|
||||
wchar_t **wstr,
|
||||
size_t *wlen,
|
||||
const char **reason,
|
||||
int current_locale,
|
||||
_Py_error_handler errors);
|
||||
|
||||
PyAPI_FUNC(int) _Py_EncodeLocaleEx(
|
||||
const wchar_t *text,
|
||||
char **str,
|
||||
size_t *error_pos,
|
||||
const char **reason,
|
||||
int current_locale,
|
||||
_Py_error_handler errors);
|
||||
|
||||
PyAPI_FUNC(char*) _Py_EncodeLocaleRaw(
|
||||
const wchar_t *text,
|
||||
size_t *error_pos);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _Py_device_encoding(int);
|
||||
|
||||
#if defined(MS_WINDOWS) || defined(__APPLE__)
|
||||
/* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
|
||||
On macOS 10.13, read() and write() with more than INT_MAX bytes
|
||||
fail with EINVAL (bpo-24658). */
|
||||
# define _PY_READ_MAX INT_MAX
|
||||
# define _PY_WRITE_MAX INT_MAX
|
||||
#else
|
||||
/* write() should truncate the input to PY_SSIZE_T_MAX bytes,
|
||||
but it's safer to do it ourself to have a portable behaviour */
|
||||
# define _PY_READ_MAX PY_SSIZE_T_MAX
|
||||
# define _PY_WRITE_MAX PY_SSIZE_T_MAX
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
struct _Py_stat_struct {
|
||||
unsigned long st_dev;
|
||||
uint64_t st_ino;
|
||||
unsigned short st_mode;
|
||||
int st_nlink;
|
||||
int st_uid;
|
||||
int st_gid;
|
||||
unsigned long st_rdev;
|
||||
__int64 st_size;
|
||||
time_t st_atime;
|
||||
int st_atime_nsec;
|
||||
time_t st_mtime;
|
||||
int st_mtime_nsec;
|
||||
time_t st_ctime;
|
||||
int st_ctime_nsec;
|
||||
unsigned long st_file_attributes;
|
||||
unsigned long st_reparse_tag;
|
||||
};
|
||||
#else
|
||||
# define _Py_stat_struct stat
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(int) _Py_fstat(
|
||||
int fd,
|
||||
struct _Py_stat_struct *status);
|
||||
|
||||
PyAPI_FUNC(int) _Py_fstat_noraise(
|
||||
int fd,
|
||||
struct _Py_stat_struct *status);
|
||||
|
||||
PyAPI_FUNC(int) _Py_stat(
|
||||
PyObject *path,
|
||||
struct stat *status);
|
||||
|
||||
PyAPI_FUNC(int) _Py_open(
|
||||
const char *pathname,
|
||||
int flags);
|
||||
|
||||
PyAPI_FUNC(int) _Py_open_noraise(
|
||||
const char *pathname,
|
||||
int flags);
|
||||
|
||||
PyAPI_FUNC(FILE *) _Py_wfopen(
|
||||
const wchar_t *path,
|
||||
const wchar_t *mode);
|
||||
|
||||
PyAPI_FUNC(FILE*) _Py_fopen_obj(
|
||||
PyObject *path,
|
||||
const char *mode);
|
||||
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_read(
|
||||
int fd,
|
||||
void *buf,
|
||||
size_t count);
|
||||
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_write(
|
||||
int fd,
|
||||
const void *buf,
|
||||
size_t count);
|
||||
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
|
||||
int fd,
|
||||
const void *buf,
|
||||
size_t count);
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
PyAPI_FUNC(int) _Py_wreadlink(
|
||||
const wchar_t *path,
|
||||
wchar_t *buf,
|
||||
/* Number of characters of 'buf' buffer
|
||||
including the trailing NUL character */
|
||||
size_t buflen);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REALPATH
|
||||
PyAPI_FUNC(wchar_t*) _Py_wrealpath(
|
||||
const wchar_t *path,
|
||||
wchar_t *resolved_path,
|
||||
/* Number of characters of 'resolved_path' buffer
|
||||
including the trailing NUL character */
|
||||
size_t resolved_path_len);
|
||||
#endif
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
PyAPI_FUNC(int) _Py_isabs(const wchar_t *path);
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p);
|
||||
|
||||
PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
|
||||
wchar_t *buf,
|
||||
/* Number of characters of 'buf' buffer
|
||||
including the trailing NUL character */
|
||||
size_t buflen);
|
||||
|
||||
PyAPI_FUNC(int) _Py_get_inheritable(int fd);
|
||||
|
||||
PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
|
||||
int *atomic_flag_works);
|
||||
|
||||
PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
|
||||
int *atomic_flag_works);
|
||||
|
||||
PyAPI_FUNC(int) _Py_dup(int fd);
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
PyAPI_FUNC(int) _Py_get_blocking(int fd);
|
||||
|
||||
PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
|
||||
#else /* MS_WINDOWS */
|
||||
PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);
|
||||
|
||||
PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);
|
||||
|
||||
PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags);
|
||||
|
||||
PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
|
||||
#endif /* MS_WINDOWS */
|
||||
@@ -0,0 +1,94 @@
|
||||
/* Frame object interface */
|
||||
|
||||
#ifndef Py_CPYTHON_FRAMEOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* These values are chosen so that the inline functions below all
|
||||
* compare f_state to zero.
|
||||
*/
|
||||
enum _framestate {
|
||||
FRAME_CREATED = -2,
|
||||
FRAME_SUSPENDED = -1,
|
||||
FRAME_EXECUTING = 0,
|
||||
FRAME_RETURNED = 1,
|
||||
FRAME_UNWINDING = 2,
|
||||
FRAME_RAISED = 3,
|
||||
FRAME_CLEARED = 4
|
||||
};
|
||||
|
||||
typedef signed char PyFrameState;
|
||||
|
||||
typedef struct {
|
||||
int b_type; /* what kind of block this is */
|
||||
int b_handler; /* where to jump to find handler */
|
||||
int b_level; /* value stack level to pop to */
|
||||
} PyTryBlock;
|
||||
|
||||
struct _frame {
|
||||
PyObject_VAR_HEAD
|
||||
struct _frame *f_back; /* previous frame, or NULL */
|
||||
PyCodeObject *f_code; /* code segment */
|
||||
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
|
||||
PyObject *f_globals; /* global symbol table (PyDictObject) */
|
||||
PyObject *f_locals; /* local symbol table (any mapping) */
|
||||
PyObject **f_valuestack; /* points after the last local */
|
||||
PyObject *f_trace; /* Trace function */
|
||||
int f_stackdepth; /* Depth of value stack */
|
||||
char f_trace_lines; /* Emit per-line trace events? */
|
||||
char f_trace_opcodes; /* Emit per-opcode trace events? */
|
||||
|
||||
/* Borrowed reference to a generator, or NULL */
|
||||
PyObject *f_gen;
|
||||
|
||||
int f_lasti; /* Last instruction if called */
|
||||
int f_lineno; /* Current line number. Only valid if non-zero */
|
||||
int f_iblock; /* index in f_blockstack */
|
||||
PyFrameState f_state; /* What state the frame is in */
|
||||
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
|
||||
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
|
||||
};
|
||||
|
||||
static inline int _PyFrame_IsRunnable(struct _frame *f) {
|
||||
return f->f_state < FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
static inline int _PyFrame_IsExecuting(struct _frame *f) {
|
||||
return f->f_state == FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
static inline int _PyFrameHasCompleted(struct _frame *f) {
|
||||
return f->f_state > FRAME_EXECUTING;
|
||||
}
|
||||
|
||||
/* Standard object interface */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyFrame_Type;
|
||||
|
||||
#define PyFrame_Check(op) Py_IS_TYPE(op, &PyFrame_Type)
|
||||
|
||||
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
|
||||
PyObject *, PyObject *);
|
||||
|
||||
/* only internal use */
|
||||
PyFrameObject*
|
||||
_PyFrame_New_NoTrack(PyThreadState *, PyFrameConstructor *, PyObject *);
|
||||
|
||||
|
||||
/* The rest of the interface is specific for frame objects */
|
||||
|
||||
/* Block management functions */
|
||||
|
||||
PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int);
|
||||
PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *);
|
||||
|
||||
/* Conversions between "fast locals" and locals in dictionary */
|
||||
|
||||
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
|
||||
|
||||
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
|
||||
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
|
||||
|
||||
PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out);
|
||||
|
||||
PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame);
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef Py_CPYTHON_IMPORT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyMODINIT_FUNC PyInit__imp(void);
|
||||
|
||||
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name);
|
||||
PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module);
|
||||
PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module);
|
||||
|
||||
PyAPI_FUNC(void) _PyImport_AcquireLock(void);
|
||||
PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
|
||||
|
||||
/* Obsolete since 3.5, will be removed in 3.11. */
|
||||
Py_DEPRECATED(3.10) PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *);
|
||||
|
||||
PyAPI_FUNC(int) _PyImport_FixupBuiltin(
|
||||
PyObject *mod,
|
||||
const char *name, /* UTF-8 encoded string */
|
||||
PyObject *modules
|
||||
);
|
||||
PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *,
|
||||
PyObject *, PyObject *);
|
||||
|
||||
struct _inittab {
|
||||
const char *name; /* ASCII encoded string */
|
||||
PyObject* (*initfunc)(void);
|
||||
};
|
||||
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
|
||||
PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
||||
|
||||
struct _frozen {
|
||||
const char *name; /* ASCII encoded string */
|
||||
const unsigned char *code;
|
||||
int size;
|
||||
};
|
||||
|
||||
/* Embedding apps may change this pointer to point to their favorite
|
||||
collection of frozen modules: */
|
||||
|
||||
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
|
||||
|
||||
PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *);
|
||||
PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *);
|
||||
@@ -0,0 +1,249 @@
|
||||
#ifndef Py_PYCORECONFIG_H
|
||||
#define Py_PYCORECONFIG_H
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --- PyStatus ----------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
_PyStatus_TYPE_OK=0,
|
||||
_PyStatus_TYPE_ERROR=1,
|
||||
_PyStatus_TYPE_EXIT=2
|
||||
} _type;
|
||||
const char *func;
|
||||
const char *err_msg;
|
||||
int exitcode;
|
||||
} PyStatus;
|
||||
|
||||
PyAPI_FUNC(PyStatus) PyStatus_Ok(void);
|
||||
PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg);
|
||||
PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void);
|
||||
PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
|
||||
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
|
||||
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
|
||||
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
|
||||
|
||||
/* --- PyWideStringList ------------------------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
/* If length is greater than zero, items must be non-NULL
|
||||
and all items strings must be non-NULL */
|
||||
Py_ssize_t length;
|
||||
wchar_t **items;
|
||||
} PyWideStringList;
|
||||
|
||||
PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
|
||||
const wchar_t *item);
|
||||
PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list,
|
||||
Py_ssize_t index,
|
||||
const wchar_t *item);
|
||||
|
||||
|
||||
/* --- PyPreConfig ----------------------------------------------- */
|
||||
|
||||
typedef struct PyPreConfig {
|
||||
int _config_init; /* _PyConfigInitEnum value */
|
||||
|
||||
/* Parse Py_PreInitializeFromBytesArgs() arguments?
|
||||
See PyConfig.parse_argv */
|
||||
int parse_argv;
|
||||
|
||||
/* If greater than 0, enable isolated mode: sys.path contains
|
||||
neither the script's directory nor the user's site-packages directory.
|
||||
|
||||
Set to 1 by the -I command line option. If set to -1 (default), inherit
|
||||
Py_IsolatedFlag value. */
|
||||
int isolated;
|
||||
|
||||
/* If greater than 0: use environment variables.
|
||||
Set to 0 by -E command line option. If set to -1 (default), it is
|
||||
set to !Py_IgnoreEnvironmentFlag. */
|
||||
int use_environment;
|
||||
|
||||
/* Set the LC_CTYPE locale to the user preferred locale? If equals to 0,
|
||||
set coerce_c_locale and coerce_c_locale_warn to 0. */
|
||||
int configure_locale;
|
||||
|
||||
/* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538)
|
||||
|
||||
Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1.
|
||||
Set to 2 if the user preferred LC_CTYPE locale is "C".
|
||||
|
||||
If it is equal to 1, LC_CTYPE locale is read to decide if it should be
|
||||
coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2
|
||||
if the LC_CTYPE locale must be coerced.
|
||||
|
||||
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
||||
should be enabled or not. */
|
||||
int coerce_c_locale;
|
||||
|
||||
/* Emit a warning if the LC_CTYPE locale is coerced?
|
||||
|
||||
Set to 1 by PYTHONCOERCECLOCALE=warn.
|
||||
|
||||
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
||||
should be enabled or not. */
|
||||
int coerce_c_locale_warn;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* If greater than 1, use the "mbcs" encoding instead of the UTF-8
|
||||
encoding for the filesystem encoding.
|
||||
|
||||
Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is
|
||||
set to a non-empty string. If set to -1 (default), inherit
|
||||
Py_LegacyWindowsFSEncodingFlag value.
|
||||
|
||||
See PEP 529 for more details. */
|
||||
int legacy_windows_fs_encoding;
|
||||
#endif
|
||||
|
||||
/* Enable UTF-8 mode? (PEP 540)
|
||||
|
||||
Disabled by default (equals to 0).
|
||||
|
||||
Set to 1 by "-X utf8" and "-X utf8=1" command line options.
|
||||
Set to 1 by PYTHONUTF8=1 environment variable.
|
||||
|
||||
Set to 0 by "-X utf8=0" and PYTHONUTF8=0.
|
||||
|
||||
If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or
|
||||
"POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */
|
||||
int utf8_mode;
|
||||
|
||||
/* If non-zero, enable the Python Development Mode.
|
||||
|
||||
Set to 1 by the -X dev command line option. Set by the PYTHONDEVMODE
|
||||
environment variable. */
|
||||
int dev_mode;
|
||||
|
||||
/* Memory allocator: PYTHONMALLOC env var.
|
||||
See PyMemAllocatorName for valid values. */
|
||||
int allocator;
|
||||
} PyPreConfig;
|
||||
|
||||
PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config);
|
||||
PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);
|
||||
|
||||
|
||||
/* --- PyConfig ---------------------------------------------- */
|
||||
|
||||
/* This structure is best documented in the Doc/c-api/init_config.rst file. */
|
||||
typedef struct PyConfig {
|
||||
int _config_init; /* _PyConfigInitEnum value */
|
||||
|
||||
int isolated;
|
||||
int use_environment;
|
||||
int dev_mode;
|
||||
int install_signal_handlers;
|
||||
int use_hash_seed;
|
||||
unsigned long hash_seed;
|
||||
int faulthandler;
|
||||
int tracemalloc;
|
||||
int import_time;
|
||||
int show_ref_count;
|
||||
int dump_refs;
|
||||
int malloc_stats;
|
||||
wchar_t *filesystem_encoding;
|
||||
wchar_t *filesystem_errors;
|
||||
wchar_t *pycache_prefix;
|
||||
int parse_argv;
|
||||
PyWideStringList orig_argv;
|
||||
PyWideStringList argv;
|
||||
PyWideStringList xoptions;
|
||||
PyWideStringList warnoptions;
|
||||
int site_import;
|
||||
int bytes_warning;
|
||||
int warn_default_encoding;
|
||||
int inspect;
|
||||
int interactive;
|
||||
int optimization_level;
|
||||
int parser_debug;
|
||||
int write_bytecode;
|
||||
int verbose;
|
||||
int quiet;
|
||||
int user_site_directory;
|
||||
int configure_c_stdio;
|
||||
int buffered_stdio;
|
||||
wchar_t *stdio_encoding;
|
||||
wchar_t *stdio_errors;
|
||||
#ifdef MS_WINDOWS
|
||||
int legacy_windows_stdio;
|
||||
#endif
|
||||
wchar_t *check_hash_pycs_mode;
|
||||
|
||||
/* --- Path configuration inputs ------------ */
|
||||
int pathconfig_warnings;
|
||||
wchar_t *program_name;
|
||||
wchar_t *pythonpath_env;
|
||||
wchar_t *home;
|
||||
wchar_t *platlibdir;
|
||||
|
||||
/* --- Path configuration outputs ----------- */
|
||||
int module_search_paths_set;
|
||||
PyWideStringList module_search_paths;
|
||||
wchar_t *executable;
|
||||
wchar_t *base_executable;
|
||||
wchar_t *prefix;
|
||||
wchar_t *base_prefix;
|
||||
wchar_t *exec_prefix;
|
||||
wchar_t *base_exec_prefix;
|
||||
|
||||
/* --- Parameter only used by Py_Main() ---------- */
|
||||
int skip_source_first_line;
|
||||
wchar_t *run_command;
|
||||
wchar_t *run_module;
|
||||
wchar_t *run_filename;
|
||||
|
||||
/* --- Private fields ---------------------------- */
|
||||
|
||||
// Install importlib? If equals to 0, importlib is not initialized at all.
|
||||
// Needed by freeze_importlib.
|
||||
int _install_importlib;
|
||||
|
||||
// If equal to 0, stop Python initialization before the "main" phase.
|
||||
int _init_main;
|
||||
|
||||
// If non-zero, disallow threads, subprocesses, and fork.
|
||||
// Default: 0.
|
||||
int _isolated_interpreter;
|
||||
} PyConfig;
|
||||
|
||||
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);
|
||||
PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config);
|
||||
PyAPI_FUNC(void) PyConfig_Clear(PyConfig *);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_SetString(
|
||||
PyConfig *config,
|
||||
wchar_t **config_str,
|
||||
const wchar_t *str);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_SetBytesString(
|
||||
PyConfig *config,
|
||||
wchar_t **config_str,
|
||||
const char *str);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
|
||||
PyConfig *config,
|
||||
Py_ssize_t argc,
|
||||
char * const *argv);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
|
||||
Py_ssize_t argc,
|
||||
wchar_t * const *argv);
|
||||
PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
|
||||
PyWideStringList *list,
|
||||
Py_ssize_t length, wchar_t **items);
|
||||
|
||||
|
||||
/* --- Helper functions --------------------------------------- */
|
||||
|
||||
/* Get the original command line arguments, before Python modified them.
|
||||
|
||||
See also PyConfig.orig_argv. */
|
||||
PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_LIMITED_API */
|
||||
#endif /* !Py_PYCORECONFIG_H */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef Py_CPYTHON_INTERPRETERIDOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* Interpreter ID Object */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type;
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t);
|
||||
PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *);
|
||||
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *);
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef Py_CPYTHON_LISTOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
|
||||
PyObject **ob_item;
|
||||
|
||||
/* ob_item contains space for 'allocated' elements. The number
|
||||
* currently in use is ob_size.
|
||||
* Invariants:
|
||||
* 0 <= ob_size <= allocated
|
||||
* len(list) == ob_size
|
||||
* ob_item == NULL implies ob_size == allocated == 0
|
||||
* list.sort() temporarily sets allocated to -1 to detect mutations.
|
||||
*
|
||||
* Items must normally not be NULL, except during construction when
|
||||
* the list is not yet visible outside the function that builds it.
|
||||
*/
|
||||
Py_ssize_t allocated;
|
||||
} PyListObject;
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
|
||||
PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out);
|
||||
|
||||
/* Macro, trading safety for speed */
|
||||
|
||||
/* Cast argument to PyListObject* type. */
|
||||
#define _PyList_CAST(op) (assert(PyList_Check(op)), (PyListObject *)(op))
|
||||
|
||||
#define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i])
|
||||
#define PyList_SET_ITEM(op, i, v) ((void)(_PyList_CAST(op)->ob_item[i] = (v)))
|
||||
#define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op))
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef Py_CPYTHON_METHODOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyCMethod_Type;
|
||||
|
||||
#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type)
|
||||
#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type)
|
||||
|
||||
/* Macros for direct access to these values. Type checks are *not*
|
||||
done, so use with care. */
|
||||
#define PyCFunction_GET_FUNCTION(func) \
|
||||
(((PyCFunctionObject *)func) -> m_ml -> ml_meth)
|
||||
#define PyCFunction_GET_SELF(func) \
|
||||
(((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \
|
||||
NULL : ((PyCFunctionObject *)func) -> m_self)
|
||||
#define PyCFunction_GET_FLAGS(func) \
|
||||
(((PyCFunctionObject *)func) -> m_ml -> ml_flags)
|
||||
#define PyCFunction_GET_CLASS(func) \
|
||||
(((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_METHOD ? \
|
||||
((PyCMethodObject *)func) -> mm_class : NULL)
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyMethodDef *m_ml; /* Description of the C function to call */
|
||||
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
|
||||
PyObject *m_module; /* The __module__ attribute, can be anything */
|
||||
PyObject *m_weakreflist; /* List of weak references */
|
||||
vectorcallfunc vectorcall;
|
||||
} PyCFunctionObject;
|
||||
|
||||
typedef struct {
|
||||
PyCFunctionObject func;
|
||||
PyTypeObject *mm_class; /* Class that defines this method */
|
||||
} PyCMethodObject;
|
||||
@@ -0,0 +1,552 @@
|
||||
#ifndef Py_CPYTHON_OBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
/* Py_TRACE_REFS is such major surgery that we call external routines. */
|
||||
PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
|
||||
#endif
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
|
||||
#endif
|
||||
|
||||
|
||||
/********************* String Literals ****************************************/
|
||||
/* This structure helps managing static strings. The basic usage goes like this:
|
||||
Instead of doing
|
||||
|
||||
r = PyObject_CallMethod(o, "foo", "args", ...);
|
||||
|
||||
do
|
||||
|
||||
_Py_IDENTIFIER(foo);
|
||||
...
|
||||
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
|
||||
|
||||
PyId_foo is a static variable, either on block level or file level. On first
|
||||
usage, the string "foo" is interned, and the structures are linked. On interpreter
|
||||
shutdown, all strings are released.
|
||||
|
||||
Alternatively, _Py_static_string allows choosing the variable name.
|
||||
_PyUnicode_FromId returns a borrowed reference to the interned string.
|
||||
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
|
||||
*/
|
||||
typedef struct _Py_Identifier {
|
||||
const char* string;
|
||||
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
|
||||
// unique and must be initialized to -1.
|
||||
Py_ssize_t index;
|
||||
} _Py_Identifier;
|
||||
|
||||
#define _Py_static_string_init(value) { .string = value, .index = -1 }
|
||||
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
|
||||
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
|
||||
|
||||
/* buffer interface */
|
||||
typedef struct bufferinfo {
|
||||
void *buf;
|
||||
PyObject *obj; /* owned reference */
|
||||
Py_ssize_t len;
|
||||
Py_ssize_t itemsize; /* This is Py_ssize_t so it can be
|
||||
pointed to by strides in simple case.*/
|
||||
int readonly;
|
||||
int ndim;
|
||||
char *format;
|
||||
Py_ssize_t *shape;
|
||||
Py_ssize_t *strides;
|
||||
Py_ssize_t *suboffsets;
|
||||
void *internal;
|
||||
} Py_buffer;
|
||||
|
||||
typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
|
||||
typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
|
||||
|
||||
typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames);
|
||||
|
||||
/* Maximum number of dimensions */
|
||||
#define PyBUF_MAX_NDIM 64
|
||||
|
||||
/* Flags for getting buffers */
|
||||
#define PyBUF_SIMPLE 0
|
||||
#define PyBUF_WRITABLE 0x0001
|
||||
/* we used to include an E, backwards compatible alias */
|
||||
#define PyBUF_WRITEABLE PyBUF_WRITABLE
|
||||
#define PyBUF_FORMAT 0x0004
|
||||
#define PyBUF_ND 0x0008
|
||||
#define PyBUF_STRIDES (0x0010 | PyBUF_ND)
|
||||
#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
|
||||
#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
|
||||
#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
|
||||
#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
|
||||
|
||||
#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE)
|
||||
#define PyBUF_CONTIG_RO (PyBUF_ND)
|
||||
|
||||
#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE)
|
||||
#define PyBUF_STRIDED_RO (PyBUF_STRIDES)
|
||||
|
||||
#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT)
|
||||
#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT)
|
||||
|
||||
#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT)
|
||||
#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT)
|
||||
|
||||
|
||||
#define PyBUF_READ 0x100
|
||||
#define PyBUF_WRITE 0x200
|
||||
/* End buffer interface */
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Number implementations must check *both*
|
||||
arguments for proper type and implement the necessary conversions
|
||||
in the slot functions themselves. */
|
||||
|
||||
binaryfunc nb_add;
|
||||
binaryfunc nb_subtract;
|
||||
binaryfunc nb_multiply;
|
||||
binaryfunc nb_remainder;
|
||||
binaryfunc nb_divmod;
|
||||
ternaryfunc nb_power;
|
||||
unaryfunc nb_negative;
|
||||
unaryfunc nb_positive;
|
||||
unaryfunc nb_absolute;
|
||||
inquiry nb_bool;
|
||||
unaryfunc nb_invert;
|
||||
binaryfunc nb_lshift;
|
||||
binaryfunc nb_rshift;
|
||||
binaryfunc nb_and;
|
||||
binaryfunc nb_xor;
|
||||
binaryfunc nb_or;
|
||||
unaryfunc nb_int;
|
||||
void *nb_reserved; /* the slot formerly known as nb_long */
|
||||
unaryfunc nb_float;
|
||||
|
||||
binaryfunc nb_inplace_add;
|
||||
binaryfunc nb_inplace_subtract;
|
||||
binaryfunc nb_inplace_multiply;
|
||||
binaryfunc nb_inplace_remainder;
|
||||
ternaryfunc nb_inplace_power;
|
||||
binaryfunc nb_inplace_lshift;
|
||||
binaryfunc nb_inplace_rshift;
|
||||
binaryfunc nb_inplace_and;
|
||||
binaryfunc nb_inplace_xor;
|
||||
binaryfunc nb_inplace_or;
|
||||
|
||||
binaryfunc nb_floor_divide;
|
||||
binaryfunc nb_true_divide;
|
||||
binaryfunc nb_inplace_floor_divide;
|
||||
binaryfunc nb_inplace_true_divide;
|
||||
|
||||
unaryfunc nb_index;
|
||||
|
||||
binaryfunc nb_matrix_multiply;
|
||||
binaryfunc nb_inplace_matrix_multiply;
|
||||
} PyNumberMethods;
|
||||
|
||||
typedef struct {
|
||||
lenfunc sq_length;
|
||||
binaryfunc sq_concat;
|
||||
ssizeargfunc sq_repeat;
|
||||
ssizeargfunc sq_item;
|
||||
void *was_sq_slice;
|
||||
ssizeobjargproc sq_ass_item;
|
||||
void *was_sq_ass_slice;
|
||||
objobjproc sq_contains;
|
||||
|
||||
binaryfunc sq_inplace_concat;
|
||||
ssizeargfunc sq_inplace_repeat;
|
||||
} PySequenceMethods;
|
||||
|
||||
typedef struct {
|
||||
lenfunc mp_length;
|
||||
binaryfunc mp_subscript;
|
||||
objobjargproc mp_ass_subscript;
|
||||
} PyMappingMethods;
|
||||
|
||||
typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result);
|
||||
|
||||
typedef struct {
|
||||
unaryfunc am_await;
|
||||
unaryfunc am_aiter;
|
||||
unaryfunc am_anext;
|
||||
sendfunc am_send;
|
||||
} PyAsyncMethods;
|
||||
|
||||
typedef struct {
|
||||
getbufferproc bf_getbuffer;
|
||||
releasebufferproc bf_releasebuffer;
|
||||
} PyBufferProcs;
|
||||
|
||||
/* Allow printfunc in the tp_vectorcall_offset slot for
|
||||
* backwards-compatibility */
|
||||
typedef Py_ssize_t printfunc;
|
||||
|
||||
// If this structure is modified, Doc/includes/typestruct.h should be updated
|
||||
// as well.
|
||||
struct _typeobject {
|
||||
PyObject_VAR_HEAD
|
||||
const char *tp_name; /* For printing, in format "<module>.<name>" */
|
||||
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
|
||||
|
||||
/* Methods to implement standard operations */
|
||||
|
||||
destructor tp_dealloc;
|
||||
Py_ssize_t tp_vectorcall_offset;
|
||||
getattrfunc tp_getattr;
|
||||
setattrfunc tp_setattr;
|
||||
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
|
||||
or tp_reserved (Python 3) */
|
||||
reprfunc tp_repr;
|
||||
|
||||
/* Method suites for standard classes */
|
||||
|
||||
PyNumberMethods *tp_as_number;
|
||||
PySequenceMethods *tp_as_sequence;
|
||||
PyMappingMethods *tp_as_mapping;
|
||||
|
||||
/* More standard operations (here for binary compatibility) */
|
||||
|
||||
hashfunc tp_hash;
|
||||
ternaryfunc tp_call;
|
||||
reprfunc tp_str;
|
||||
getattrofunc tp_getattro;
|
||||
setattrofunc tp_setattro;
|
||||
|
||||
/* Functions to access object as input/output buffer */
|
||||
PyBufferProcs *tp_as_buffer;
|
||||
|
||||
/* Flags to define presence of optional/expanded features */
|
||||
unsigned long tp_flags;
|
||||
|
||||
const char *tp_doc; /* Documentation string */
|
||||
|
||||
/* Assigned meaning in release 2.0 */
|
||||
/* call function for all accessible objects */
|
||||
traverseproc tp_traverse;
|
||||
|
||||
/* delete references to contained objects */
|
||||
inquiry tp_clear;
|
||||
|
||||
/* Assigned meaning in release 2.1 */
|
||||
/* rich comparisons */
|
||||
richcmpfunc tp_richcompare;
|
||||
|
||||
/* weak reference enabler */
|
||||
Py_ssize_t tp_weaklistoffset;
|
||||
|
||||
/* Iterators */
|
||||
getiterfunc tp_iter;
|
||||
iternextfunc tp_iternext;
|
||||
|
||||
/* Attribute descriptor and subclassing stuff */
|
||||
struct PyMethodDef *tp_methods;
|
||||
struct PyMemberDef *tp_members;
|
||||
struct PyGetSetDef *tp_getset;
|
||||
// Strong reference on a heap type, borrowed reference on a static type
|
||||
struct _typeobject *tp_base;
|
||||
PyObject *tp_dict;
|
||||
descrgetfunc tp_descr_get;
|
||||
descrsetfunc tp_descr_set;
|
||||
Py_ssize_t tp_dictoffset;
|
||||
initproc tp_init;
|
||||
allocfunc tp_alloc;
|
||||
newfunc tp_new;
|
||||
freefunc tp_free; /* Low-level free-memory routine */
|
||||
inquiry tp_is_gc; /* For PyObject_IS_GC */
|
||||
PyObject *tp_bases;
|
||||
PyObject *tp_mro; /* method resolution order */
|
||||
PyObject *tp_cache;
|
||||
PyObject *tp_subclasses;
|
||||
PyObject *tp_weaklist;
|
||||
destructor tp_del;
|
||||
|
||||
/* Type attribute cache version tag. Added in version 2.6 */
|
||||
unsigned int tp_version_tag;
|
||||
|
||||
destructor tp_finalize;
|
||||
vectorcallfunc tp_vectorcall;
|
||||
};
|
||||
|
||||
/* The *real* layout of a type object when allocated on the heap */
|
||||
typedef struct _heaptypeobject {
|
||||
/* Note: there's a dependency on the order of these members
|
||||
in slotptr() in typeobject.c . */
|
||||
PyTypeObject ht_type;
|
||||
PyAsyncMethods as_async;
|
||||
PyNumberMethods as_number;
|
||||
PyMappingMethods as_mapping;
|
||||
PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
|
||||
so that the mapping wins when both
|
||||
the mapping and the sequence define
|
||||
a given operator (e.g. __getitem__).
|
||||
see add_operators() in typeobject.c . */
|
||||
PyBufferProcs as_buffer;
|
||||
PyObject *ht_name, *ht_slots, *ht_qualname;
|
||||
struct _dictkeysobject *ht_cached_keys;
|
||||
PyObject *ht_module;
|
||||
/* here are optional user slots, followed by the members. */
|
||||
} PyHeapTypeObject;
|
||||
|
||||
/* access macro to the members which are floating "behind" the object */
|
||||
#define PyHeapType_GET_MEMBERS(etype) \
|
||||
((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize))
|
||||
|
||||
PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
|
||||
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *);
|
||||
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
|
||||
PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
|
||||
struct PyModuleDef;
|
||||
PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef(PyTypeObject *, struct PyModuleDef *);
|
||||
|
||||
struct _Py_Identifier;
|
||||
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
|
||||
PyAPI_FUNC(void) _Py_BreakPoint(void);
|
||||
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
|
||||
PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *);
|
||||
PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *);
|
||||
/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
|
||||
don't raise AttributeError.
|
||||
|
||||
Return 1 and set *result != NULL if an attribute is found.
|
||||
Return 0 and set *result == NULL if an attribute is not found;
|
||||
an AttributeError is silenced.
|
||||
Return -1 and set *result == NULL if an error other than AttributeError
|
||||
is raised.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **);
|
||||
PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **);
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
|
||||
|
||||
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
|
||||
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
|
||||
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
|
||||
|
||||
/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes
|
||||
dict as the last parameter. */
|
||||
PyAPI_FUNC(PyObject *)
|
||||
_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int);
|
||||
PyAPI_FUNC(int)
|
||||
_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
||||
PyObject *, PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
|
||||
|
||||
/* Safely decref `op` and set `op` to `op2`.
|
||||
*
|
||||
* As in case of Py_CLEAR "the obvious" code can be deadly:
|
||||
*
|
||||
* Py_DECREF(op);
|
||||
* op = op2;
|
||||
*
|
||||
* The safe way is:
|
||||
*
|
||||
* Py_SETREF(op, op2);
|
||||
*
|
||||
* That arranges to set `op` to `op2` _before_ decref'ing, so that any code
|
||||
* triggered as a side-effect of `op` getting torn down no longer believes
|
||||
* `op` points to a valid object.
|
||||
*
|
||||
* Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of
|
||||
* Py_DECREF.
|
||||
*/
|
||||
|
||||
#define Py_SETREF(op, op2) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
(op) = (op2); \
|
||||
Py_DECREF(_py_tmp); \
|
||||
} while (0)
|
||||
|
||||
#define Py_XSETREF(op, op2) \
|
||||
do { \
|
||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
||||
(op) = (op2); \
|
||||
Py_XDECREF(_py_tmp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
PyAPI_DATA(PyTypeObject) _PyNone_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
|
||||
|
||||
/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
|
||||
* Defined in object.c.
|
||||
*/
|
||||
PyAPI_DATA(int) _Py_SwappedOp[];
|
||||
|
||||
PyAPI_FUNC(void)
|
||||
_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
|
||||
size_t sizeof_block);
|
||||
PyAPI_FUNC(void)
|
||||
_PyObject_DebugTypeStats(FILE *out);
|
||||
|
||||
/* Define a pair of assertion macros:
|
||||
_PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
|
||||
|
||||
These work like the regular C assert(), in that they will abort the
|
||||
process with a message on stderr if the given condition fails to hold,
|
||||
but compile away to nothing if NDEBUG is defined.
|
||||
|
||||
However, before aborting, Python will also try to call _PyObject_Dump() on
|
||||
the given object. This may be of use when investigating bugs in which a
|
||||
particular object is corrupt (e.g. buggy a tp_visit method in an extension
|
||||
module breaking the garbage collector), to help locate the broken objects.
|
||||
|
||||
The WITH_MSG variant allows you to supply an additional message that Python
|
||||
will attempt to print to stderr, after the object dump. */
|
||||
#ifdef NDEBUG
|
||||
/* No debugging: compile away the assertions: */
|
||||
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
||||
((void)0)
|
||||
#else
|
||||
/* With debugging: generate checks: */
|
||||
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
||||
((expr) \
|
||||
? (void)(0) \
|
||||
: _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \
|
||||
(msg), (filename), (lineno), (func)))
|
||||
#endif
|
||||
|
||||
#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
|
||||
_PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__)
|
||||
#define _PyObject_ASSERT(obj, expr) \
|
||||
_PyObject_ASSERT_WITH_MSG(obj, expr, NULL)
|
||||
|
||||
#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \
|
||||
_PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__)
|
||||
|
||||
/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined,
|
||||
to avoid causing compiler/linker errors when building extensions without
|
||||
NDEBUG against a Python built with NDEBUG defined.
|
||||
|
||||
msg, expr and function can be NULL. */
|
||||
PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed(
|
||||
PyObject *obj,
|
||||
const char *expr,
|
||||
const char *msg,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *function);
|
||||
|
||||
/* Check if an object is consistent. For example, ensure that the reference
|
||||
counter is greater than or equal to 1, and ensure that ob_type is not NULL.
|
||||
|
||||
Call _PyObject_AssertFailed() if the object is inconsistent.
|
||||
|
||||
If check_content is zero, only check header fields: reduce the overhead.
|
||||
|
||||
The function always return 1. The return value is just here to be able to
|
||||
write:
|
||||
|
||||
assert(_PyObject_CheckConsistency(obj, 1)); */
|
||||
PyAPI_FUNC(int) _PyObject_CheckConsistency(
|
||||
PyObject *op,
|
||||
int check_content);
|
||||
|
||||
|
||||
/* Trashcan mechanism, thanks to Christian Tismer.
|
||||
|
||||
When deallocating a container object, it's possible to trigger an unbounded
|
||||
chain of deallocations, as each Py_DECREF in turn drops the refcount on "the
|
||||
next" object in the chain to 0. This can easily lead to stack overflows,
|
||||
especially in threads (which typically have less stack space to work with).
|
||||
|
||||
A container object can avoid this by bracketing the body of its tp_dealloc
|
||||
function with a pair of macros:
|
||||
|
||||
static void
|
||||
mytype_dealloc(mytype *p)
|
||||
{
|
||||
... declarations go here ...
|
||||
|
||||
PyObject_GC_UnTrack(p); // must untrack first
|
||||
Py_TRASHCAN_BEGIN(p, mytype_dealloc)
|
||||
... The body of the deallocator goes here, including all calls ...
|
||||
... to Py_DECREF on contained objects. ...
|
||||
Py_TRASHCAN_END // there should be no code after this
|
||||
}
|
||||
|
||||
CAUTION: Never return from the middle of the body! If the body needs to
|
||||
"get out early", put a label immediately before the Py_TRASHCAN_END
|
||||
call, and goto it. Else the call-depth counter (see below) will stay
|
||||
above 0 forever, and the trashcan will never get emptied.
|
||||
|
||||
How it works: The BEGIN macro increments a call-depth counter. So long
|
||||
as this counter is small, the body of the deallocator is run directly without
|
||||
further ado. But if the counter gets large, it instead adds p to a list of
|
||||
objects to be deallocated later, skips the body of the deallocator, and
|
||||
resumes execution after the END macro. The tp_dealloc routine then returns
|
||||
without deallocating anything (and so unbounded call-stack depth is avoided).
|
||||
|
||||
When the call stack finishes unwinding again, code generated by the END macro
|
||||
notices this, and calls another routine to deallocate all the objects that
|
||||
may have been added to the list of deferred deallocations. In effect, a
|
||||
chain of N deallocations is broken into (N-1)/(PyTrash_UNWIND_LEVEL-1) pieces,
|
||||
with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL.
|
||||
|
||||
Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
|
||||
class, we need to ensure that the trashcan is only triggered on the tp_dealloc
|
||||
of the actual class being deallocated. Otherwise we might end up with a
|
||||
partially-deallocated object. To check this, the tp_dealloc function must be
|
||||
passed as second argument to Py_TRASHCAN_BEGIN().
|
||||
*/
|
||||
|
||||
/* This is the old private API, invoked by the macros before 3.2.4.
|
||||
Kept for binary compatibility of extensions using the stable ABI. */
|
||||
PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*);
|
||||
PyAPI_FUNC(void) _PyTrash_destroy_chain(void);
|
||||
|
||||
/* This is the old private API, invoked by the macros before 3.9.
|
||||
Kept for binary compatibility of extensions using the stable ABI. */
|
||||
PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyObject*);
|
||||
PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void);
|
||||
|
||||
/* Forward declarations for PyThreadState */
|
||||
struct _ts;
|
||||
|
||||
/* Python 3.9 private API, invoked by the macros below. */
|
||||
PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op);
|
||||
PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate);
|
||||
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
|
||||
PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc);
|
||||
|
||||
#define PyTrash_UNWIND_LEVEL 50
|
||||
|
||||
#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
|
||||
do { \
|
||||
PyThreadState *_tstate = NULL; \
|
||||
/* If "cond" is false, then _tstate remains NULL and the deallocator \
|
||||
* is run normally without involving the trashcan */ \
|
||||
if (cond) { \
|
||||
_tstate = PyThreadState_Get(); \
|
||||
if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
/* The body of the deallocator is here. */
|
||||
#define Py_TRASHCAN_END \
|
||||
if (_tstate) { \
|
||||
_PyTrash_end(_tstate); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define Py_TRASHCAN_BEGIN(op, dealloc) \
|
||||
Py_TRASHCAN_BEGIN_CONDITION(op, \
|
||||
_PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc))
|
||||
|
||||
/* For backwards compatibility, these macros enable the trashcan
|
||||
* unconditionally */
|
||||
#define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1)
|
||||
#define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END
|
||||
@@ -0,0 +1,100 @@
|
||||
#ifndef Py_CPYTHON_OBJIMPL_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
|
||||
|
||||
/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
|
||||
vrbl-size object with nitems items, exclusive of gc overhead (if any). The
|
||||
value is rounded up to the closest multiple of sizeof(void *), in order to
|
||||
ensure that pointer fields at the end of the object are correctly aligned
|
||||
for the platform (this is of special importance for subclasses of, e.g.,
|
||||
str or int, so that pointers can be stored after the embedded data).
|
||||
|
||||
Note that there's no memory wastage in doing this, as malloc has to
|
||||
return (at worst) pointer-aligned memory anyway.
|
||||
*/
|
||||
#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
|
||||
# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
|
||||
#endif
|
||||
|
||||
#define _PyObject_VAR_SIZE(typeobj, nitems) \
|
||||
_Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
|
||||
(nitems)*(typeobj)->tp_itemsize, \
|
||||
SIZEOF_VOID_P)
|
||||
|
||||
|
||||
/* This example code implements an object constructor with a custom
|
||||
allocator, where PyObject_New is inlined, and shows the important
|
||||
distinction between two steps (at least):
|
||||
1) the actual allocation of the object storage;
|
||||
2) the initialization of the Python specific fields
|
||||
in this storage with PyObject_{Init, InitVar}.
|
||||
|
||||
PyObject *
|
||||
YourObject_New(...)
|
||||
{
|
||||
PyObject *op;
|
||||
|
||||
op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
|
||||
if (op == NULL) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
|
||||
PyObject_Init(op, &YourTypeStruct);
|
||||
|
||||
op->ob_field = value;
|
||||
...
|
||||
return op;
|
||||
}
|
||||
|
||||
Note that in C++, the use of the new operator usually implies that
|
||||
the 1st step is performed automatically for you, so in a C++ class
|
||||
constructor you would start directly with PyObject_Init/InitVar. */
|
||||
|
||||
/* This function returns the number of allocated memory blocks, regardless of size */
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
|
||||
|
||||
/* Macros */
|
||||
#ifdef WITH_PYMALLOC
|
||||
PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* user context passed as the first argument to the 2 functions */
|
||||
void *ctx;
|
||||
|
||||
/* allocate an arena of size bytes */
|
||||
void* (*alloc) (void *ctx, size_t size);
|
||||
|
||||
/* free an arena */
|
||||
void (*free) (void *ctx, void *ptr, size_t size);
|
||||
} PyObjectArenaAllocator;
|
||||
|
||||
/* Get the arena allocator. */
|
||||
PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
|
||||
|
||||
/* Set the arena allocator. */
|
||||
PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
|
||||
|
||||
|
||||
/* Test if an object implements the garbage collector protocol */
|
||||
PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);
|
||||
|
||||
|
||||
/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which
|
||||
defines a different _PyGC_FINALIZED() macro. */
|
||||
#ifndef Py_BUILD_CORE
|
||||
// Kept for backward compatibility with Python 3.8
|
||||
# define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o)
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);
|
||||
PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
|
||||
|
||||
|
||||
/* Test if a type supports weak references */
|
||||
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
|
||||
|
||||
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef Py_ODICTOBJECT_H
|
||||
#define Py_ODICTOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* OrderedDict */
|
||||
/* This API is optional and mostly redundant. */
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
|
||||
typedef struct _odictobject PyODictObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyODict_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyODictIter_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyODictKeys_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyODictItems_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyODictValues_Type;
|
||||
|
||||
#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type)
|
||||
#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type)
|
||||
#define PyODict_SIZE(op) PyDict_GET_SIZE((op))
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyODict_New(void);
|
||||
PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
|
||||
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
|
||||
|
||||
/* wrappers around PyDict* functions */
|
||||
#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key)
|
||||
#define PyODict_GetItemWithError(od, key) \
|
||||
PyDict_GetItemWithError(_PyObject_CAST(od), key)
|
||||
#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key)
|
||||
#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od))
|
||||
#define PyODict_GetItemString(od, key) \
|
||||
PyDict_GetItemString(_PyObject_CAST(od), key)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_ODICTOBJECT_H */
|
||||
@@ -0,0 +1,31 @@
|
||||
/* PickleBuffer object. This is built-in for ease of use from third-party
|
||||
* C extensions.
|
||||
*/
|
||||
|
||||
#ifndef Py_PICKLEBUFOBJECT_H
|
||||
#define Py_PICKLEBUFOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type;
|
||||
|
||||
#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type)
|
||||
|
||||
/* Create a PickleBuffer redirecting to the given buffer-enabled object */
|
||||
PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *);
|
||||
/* Get the PickleBuffer's underlying view to the original object
|
||||
* (NULL if released)
|
||||
*/
|
||||
PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *);
|
||||
/* Release the PickleBuffer. Returns 0 on success, -1 on error. */
|
||||
PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *);
|
||||
|
||||
#endif /* !Py_LIMITED_API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_PICKLEBUFOBJECT_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef PYCTYPE_H
|
||||
#define PYCTYPE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PY_CTF_LOWER 0x01
|
||||
#define PY_CTF_UPPER 0x02
|
||||
#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER)
|
||||
#define PY_CTF_DIGIT 0x04
|
||||
#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT)
|
||||
#define PY_CTF_SPACE 0x08
|
||||
#define PY_CTF_XDIGIT 0x10
|
||||
|
||||
PyAPI_DATA(const unsigned int) _Py_ctype_table[256];
|
||||
|
||||
/* Unlike their C counterparts, the following macros are not meant to
|
||||
* handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument
|
||||
* must be a signed/unsigned char. */
|
||||
#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER)
|
||||
#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER)
|
||||
#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA)
|
||||
#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT)
|
||||
#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT)
|
||||
#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM)
|
||||
#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE)
|
||||
|
||||
PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256];
|
||||
PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256];
|
||||
|
||||
#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)])
|
||||
#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)])
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !PYCTYPE_H */
|
||||
#endif /* !Py_LIMITED_API */
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_PYDEBUG_H
|
||||
#define Py_PYDEBUG_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(int) Py_DebugFlag;
|
||||
PyAPI_DATA(int) Py_VerboseFlag;
|
||||
PyAPI_DATA(int) Py_QuietFlag;
|
||||
PyAPI_DATA(int) Py_InteractiveFlag;
|
||||
PyAPI_DATA(int) Py_InspectFlag;
|
||||
PyAPI_DATA(int) Py_OptimizeFlag;
|
||||
PyAPI_DATA(int) Py_NoSiteFlag;
|
||||
PyAPI_DATA(int) Py_BytesWarningFlag;
|
||||
PyAPI_DATA(int) Py_FrozenFlag;
|
||||
PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
|
||||
PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
|
||||
PyAPI_DATA(int) Py_NoUserSiteDirectory;
|
||||
PyAPI_DATA(int) Py_UnbufferedStdioFlag;
|
||||
PyAPI_DATA(int) Py_HashRandomizationFlag;
|
||||
PyAPI_DATA(int) Py_IsolatedFlag;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag;
|
||||
PyAPI_DATA(int) Py_LegacyWindowsStdioFlag;
|
||||
#endif
|
||||
|
||||
/* this is a wrapper around getenv() that pays attention to
|
||||
Py_IgnoreEnvironmentFlag. It should be used for getting variables like
|
||||
PYTHONPATH and PYTHONHOME from the environment */
|
||||
#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_PYDEBUG_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,214 @@
|
||||
#ifndef Py_CPYTHON_ERRORS_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* Error objects */
|
||||
|
||||
/* PyException_HEAD defines the initial segment of every exception class. */
|
||||
#define PyException_HEAD PyObject_HEAD PyObject *dict;\
|
||||
PyObject *args; PyObject *traceback;\
|
||||
PyObject *context; PyObject *cause;\
|
||||
char suppress_context;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
} PyBaseExceptionObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *msg;
|
||||
PyObject *filename;
|
||||
PyObject *lineno;
|
||||
PyObject *offset;
|
||||
PyObject *end_lineno;
|
||||
PyObject *end_offset;
|
||||
PyObject *text;
|
||||
PyObject *print_file_and_line;
|
||||
} PySyntaxErrorObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *msg;
|
||||
PyObject *name;
|
||||
PyObject *path;
|
||||
} PyImportErrorObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *encoding;
|
||||
PyObject *object;
|
||||
Py_ssize_t start;
|
||||
Py_ssize_t end;
|
||||
PyObject *reason;
|
||||
} PyUnicodeErrorObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *code;
|
||||
} PySystemExitObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *myerrno;
|
||||
PyObject *strerror;
|
||||
PyObject *filename;
|
||||
PyObject *filename2;
|
||||
#ifdef MS_WINDOWS
|
||||
PyObject *winerror;
|
||||
#endif
|
||||
Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
|
||||
} PyOSErrorObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *value;
|
||||
} PyStopIterationObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *name;
|
||||
} PyNameErrorObject;
|
||||
|
||||
typedef struct {
|
||||
PyException_HEAD
|
||||
PyObject *obj;
|
||||
PyObject *name;
|
||||
} PyAttributeErrorObject;
|
||||
|
||||
/* Compatibility typedefs */
|
||||
typedef PyOSErrorObject PyEnvironmentErrorObject;
|
||||
#ifdef MS_WINDOWS
|
||||
typedef PyOSErrorObject PyWindowsErrorObject;
|
||||
#endif
|
||||
|
||||
/* Error handling definitions */
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
|
||||
PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate);
|
||||
PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **);
|
||||
|
||||
/* Context manipulation (PEP 3134) */
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
|
||||
|
||||
/* Convenience functions */
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
Py_DEPRECATED(3.3)
|
||||
PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
|
||||
PyObject *, const Py_UNICODE *);
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
/* Like PyErr_Format(), but saves current exception as __context__ and
|
||||
__cause__.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause(
|
||||
PyObject *exception,
|
||||
const char *format, /* ASCII-encoded string */
|
||||
...
|
||||
);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* XXX redeclare to use WSTRING */
|
||||
Py_DEPRECATED(3.3)
|
||||
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
|
||||
int, const Py_UNICODE *);
|
||||
Py_DEPRECATED(3.3)
|
||||
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
|
||||
PyObject *,int, const Py_UNICODE *);
|
||||
#endif
|
||||
|
||||
/* In exceptions.c */
|
||||
|
||||
/* Helper that attempts to replace the current exception with one of the
|
||||
* same type but with a prefix added to the exception text. The resulting
|
||||
* exception description looks like:
|
||||
*
|
||||
* prefix (exc_type: original_exc_str)
|
||||
*
|
||||
* Only some exceptions can be safely replaced. If the function determines
|
||||
* it isn't safe to perform the replacement, it will leave the original
|
||||
* unmodified exception in place.
|
||||
*
|
||||
* Returns a borrowed reference to the new exception (if any), NULL if the
|
||||
* existing exception was left in place.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause(
|
||||
const char *prefix_format, /* ASCII-encoded string */
|
||||
...
|
||||
);
|
||||
|
||||
/* In signalmodule.c */
|
||||
|
||||
int PySignal_SetWakeupFd(int fd);
|
||||
PyAPI_FUNC(int) _PyErr_CheckSignals(void);
|
||||
|
||||
/* Support for adding program text to SyntaxErrors */
|
||||
|
||||
PyAPI_FUNC(void) PyErr_SyntaxLocationObject(
|
||||
PyObject *filename,
|
||||
int lineno,
|
||||
int col_offset);
|
||||
|
||||
PyAPI_FUNC(void) PyErr_RangedSyntaxLocationObject(
|
||||
PyObject *filename,
|
||||
int lineno,
|
||||
int col_offset,
|
||||
int end_lineno,
|
||||
int end_col_offset);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject(
|
||||
PyObject *filename,
|
||||
int lineno);
|
||||
|
||||
/* Create a UnicodeEncodeError object.
|
||||
*
|
||||
* TODO: This API will be removed in Python 3.11.
|
||||
*/
|
||||
Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create(
|
||||
const char *encoding, /* UTF-8 encoded string */
|
||||
const Py_UNICODE *object,
|
||||
Py_ssize_t length,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t end,
|
||||
const char *reason /* UTF-8 encoded string */
|
||||
);
|
||||
|
||||
/* Create a UnicodeTranslateError object.
|
||||
*
|
||||
* TODO: This API will be removed in Python 3.11.
|
||||
*/
|
||||
Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create(
|
||||
const Py_UNICODE *object,
|
||||
Py_ssize_t length,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t end,
|
||||
const char *reason /* UTF-8 encoded string */
|
||||
);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject(
|
||||
PyObject *filename,
|
||||
int lineno,
|
||||
const char* encoding);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create(
|
||||
PyObject *object,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t end,
|
||||
const char *reason /* UTF-8 encoded string */
|
||||
);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg(
|
||||
const char *err_msg,
|
||||
PyObject *obj);
|
||||
|
||||
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc(
|
||||
const char *func,
|
||||
const char *message);
|
||||
|
||||
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat(
|
||||
const char *func,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message)
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef Py_PYFPE_H
|
||||
#define Py_PYFPE_H
|
||||
/* Header excluded from the stable API */
|
||||
#ifndef Py_LIMITED_API
|
||||
|
||||
/* These macros used to do something when Python was built with --with-fpectl,
|
||||
* but support for that was dropped in 3.7. We continue to define them though,
|
||||
* to avoid breaking API users.
|
||||
*/
|
||||
|
||||
#define PyFPE_START_PROTECT(err_string, leave_stmt)
|
||||
#define PyFPE_END_PROTECT(v)
|
||||
|
||||
#endif /* !defined(Py_LIMITED_API) */
|
||||
#endif /* !Py_PYFPE_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef Py_CPYTHON_PYLIFECYCLE_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
/* Py_FrozenMain is kept out of the Limited API until documented and present
|
||||
in all builds of Python */
|
||||
PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv);
|
||||
|
||||
/* Only used by applications that embed the interpreter and need to
|
||||
* override the standard encoding determination mechanism
|
||||
*/
|
||||
PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
|
||||
const char *errors);
|
||||
|
||||
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
|
||||
|
||||
PyAPI_FUNC(PyStatus) Py_PreInitialize(
|
||||
const PyPreConfig *src_config);
|
||||
PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs(
|
||||
const PyPreConfig *src_config,
|
||||
Py_ssize_t argc,
|
||||
char **argv);
|
||||
PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs(
|
||||
const PyPreConfig *src_config,
|
||||
Py_ssize_t argc,
|
||||
wchar_t **argv);
|
||||
|
||||
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
|
||||
|
||||
|
||||
/* Initialization and finalization */
|
||||
|
||||
PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
|
||||
const PyConfig *config);
|
||||
PyAPI_FUNC(PyStatus) _Py_InitializeMain(void);
|
||||
|
||||
PyAPI_FUNC(int) Py_RunMain(void);
|
||||
|
||||
|
||||
PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err);
|
||||
|
||||
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
|
||||
PyAPI_FUNC(void) _Py_RestoreSignals(void);
|
||||
|
||||
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
|
||||
PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename);
|
||||
|
||||
PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
|
||||
|
||||
PyAPI_FUNC(const char *) _Py_gitidentifier(void);
|
||||
PyAPI_FUNC(const char *) _Py_gitversion(void);
|
||||
|
||||
PyAPI_FUNC(int) _Py_IsFinalizing(void);
|
||||
|
||||
/* Random */
|
||||
PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size);
|
||||
PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size);
|
||||
|
||||
/* Legacy locale support */
|
||||
PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn);
|
||||
PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn);
|
||||
PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
|
||||
|
||||
PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter);
|
||||
@@ -0,0 +1,98 @@
|
||||
#ifndef Py_CPYTHON_PYMEM_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size);
|
||||
PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize);
|
||||
PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size);
|
||||
PyAPI_FUNC(void) PyMem_RawFree(void *ptr);
|
||||
|
||||
/* Try to get the allocators name set by _PyMem_SetupAllocators(). */
|
||||
PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);
|
||||
|
||||
/* strdup() using PyMem_RawMalloc() */
|
||||
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
|
||||
|
||||
/* strdup() using PyMem_Malloc() */
|
||||
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
|
||||
|
||||
/* wcsdup() using PyMem_RawMalloc() */
|
||||
PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str);
|
||||
|
||||
|
||||
typedef enum {
|
||||
/* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */
|
||||
PYMEM_DOMAIN_RAW,
|
||||
|
||||
/* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */
|
||||
PYMEM_DOMAIN_MEM,
|
||||
|
||||
/* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */
|
||||
PYMEM_DOMAIN_OBJ
|
||||
} PyMemAllocatorDomain;
|
||||
|
||||
typedef enum {
|
||||
PYMEM_ALLOCATOR_NOT_SET = 0,
|
||||
PYMEM_ALLOCATOR_DEFAULT = 1,
|
||||
PYMEM_ALLOCATOR_DEBUG = 2,
|
||||
PYMEM_ALLOCATOR_MALLOC = 3,
|
||||
PYMEM_ALLOCATOR_MALLOC_DEBUG = 4,
|
||||
#ifdef WITH_PYMALLOC
|
||||
PYMEM_ALLOCATOR_PYMALLOC = 5,
|
||||
PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6,
|
||||
#endif
|
||||
} PyMemAllocatorName;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* user context passed as the first argument to the 4 functions */
|
||||
void *ctx;
|
||||
|
||||
/* allocate a memory block */
|
||||
void* (*malloc) (void *ctx, size_t size);
|
||||
|
||||
/* allocate a memory block initialized by zeros */
|
||||
void* (*calloc) (void *ctx, size_t nelem, size_t elsize);
|
||||
|
||||
/* allocate or resize a memory block */
|
||||
void* (*realloc) (void *ctx, void *ptr, size_t new_size);
|
||||
|
||||
/* release a memory block */
|
||||
void (*free) (void *ctx, void *ptr);
|
||||
} PyMemAllocatorEx;
|
||||
|
||||
/* Get the memory block allocator of the specified domain. */
|
||||
PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain,
|
||||
PyMemAllocatorEx *allocator);
|
||||
|
||||
/* Set the memory block allocator of the specified domain.
|
||||
|
||||
The new allocator must return a distinct non-NULL pointer when requesting
|
||||
zero bytes.
|
||||
|
||||
For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL
|
||||
is not held when the allocator is called.
|
||||
|
||||
If the new allocator is not a hook (don't call the previous allocator), the
|
||||
PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks
|
||||
on top on the new allocator. */
|
||||
PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain,
|
||||
PyMemAllocatorEx *allocator);
|
||||
|
||||
/* Setup hooks to detect bugs in the following Python memory allocator
|
||||
functions:
|
||||
|
||||
- PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree()
|
||||
- PyMem_Malloc(), PyMem_Realloc(), PyMem_Free()
|
||||
- PyObject_Malloc(), PyObject_Realloc() and PyObject_Free()
|
||||
|
||||
Newly allocated memory is filled with the byte 0xCB, freed memory is filled
|
||||
with the byte 0xDB. Additional checks:
|
||||
|
||||
- detect API violations, ex: PyObject_Free() called on a buffer allocated
|
||||
by PyMem_Malloc()
|
||||
- detect write before the start of the buffer (buffer underflow)
|
||||
- detect write after the end of the buffer (buffer overflow)
|
||||
|
||||
The function does nothing if Python is not compiled is debug mode. */
|
||||
PyAPI_FUNC(void) PyMem_SetupDebugHooks(void);
|
||||
@@ -0,0 +1,305 @@
|
||||
#ifndef Py_CPYTHON_PYSTATE_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
|
||||
PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *);
|
||||
|
||||
/* State unique per thread */
|
||||
|
||||
/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
|
||||
typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *);
|
||||
|
||||
/* The following values are used for 'what' for tracefunc functions
|
||||
*
|
||||
* To add a new kind of trace event, also update "trace_init" in
|
||||
* Python/sysmodule.c to define the Python level event name
|
||||
*/
|
||||
#define PyTrace_CALL 0
|
||||
#define PyTrace_EXCEPTION 1
|
||||
#define PyTrace_LINE 2
|
||||
#define PyTrace_RETURN 3
|
||||
#define PyTrace_C_CALL 4
|
||||
#define PyTrace_C_EXCEPTION 5
|
||||
#define PyTrace_C_RETURN 6
|
||||
#define PyTrace_OPCODE 7
|
||||
|
||||
|
||||
typedef struct _cframe {
|
||||
/* This struct will be threaded through the C stack
|
||||
* allowing fast access to per-thread state that needs
|
||||
* to be accessed quickly by the interpreter, but can
|
||||
* be modified outside of the interpreter.
|
||||
*
|
||||
* WARNING: This makes data on the C stack accessible from
|
||||
* heap objects. Care must be taken to maintain stack
|
||||
* discipline and make sure that instances of this struct cannot
|
||||
* accessed outside of their lifetime.
|
||||
*/
|
||||
int use_tracing;
|
||||
struct _cframe *previous;
|
||||
} CFrame;
|
||||
|
||||
typedef struct _err_stackitem {
|
||||
/* This struct represents an entry on the exception stack, which is a
|
||||
* per-coroutine state. (Coroutine in the computer science sense,
|
||||
* including the thread and generators).
|
||||
* This ensures that the exception state is not impacted by "yields"
|
||||
* from an except handler.
|
||||
*/
|
||||
PyObject *exc_type, *exc_value, *exc_traceback;
|
||||
|
||||
struct _err_stackitem *previous_item;
|
||||
|
||||
} _PyErr_StackItem;
|
||||
|
||||
|
||||
// The PyThreadState typedef is in Include/pystate.h.
|
||||
struct _ts {
|
||||
/* See Python/ceval.c for comments explaining most fields */
|
||||
|
||||
struct _ts *prev;
|
||||
struct _ts *next;
|
||||
PyInterpreterState *interp;
|
||||
|
||||
/* Borrowed reference to the current frame (it can be NULL) */
|
||||
PyFrameObject *frame;
|
||||
int recursion_depth;
|
||||
int recursion_headroom; /* Allow 50 more calls to handle any errors. */
|
||||
int stackcheck_counter;
|
||||
|
||||
/* 'tracing' keeps track of the execution depth when tracing/profiling.
|
||||
This is to prevent the actual trace/profile code from being recorded in
|
||||
the trace/profile. */
|
||||
int tracing;
|
||||
|
||||
/* Pointer to current CFrame in the C stack frame of the currently,
|
||||
* or most recently, executing _PyEval_EvalFrameDefault. */
|
||||
CFrame *cframe;
|
||||
|
||||
Py_tracefunc c_profilefunc;
|
||||
Py_tracefunc c_tracefunc;
|
||||
PyObject *c_profileobj;
|
||||
PyObject *c_traceobj;
|
||||
|
||||
/* The exception currently being raised */
|
||||
PyObject *curexc_type;
|
||||
PyObject *curexc_value;
|
||||
PyObject *curexc_traceback;
|
||||
|
||||
/* The exception currently being handled, if no coroutines/generators
|
||||
* are present. Always last element on the stack referred to be exc_info.
|
||||
*/
|
||||
_PyErr_StackItem exc_state;
|
||||
|
||||
/* Pointer to the top of the stack of the exceptions currently
|
||||
* being handled */
|
||||
_PyErr_StackItem *exc_info;
|
||||
|
||||
PyObject *dict; /* Stores per-thread state */
|
||||
|
||||
int gilstate_counter;
|
||||
|
||||
PyObject *async_exc; /* Asynchronous exception to raise */
|
||||
unsigned long thread_id; /* Thread id where this tstate was created */
|
||||
|
||||
int trash_delete_nesting;
|
||||
PyObject *trash_delete_later;
|
||||
|
||||
/* Called when a thread state is deleted normally, but not when it
|
||||
* is destroyed after fork().
|
||||
* Pain: to prevent rare but fatal shutdown errors (issue 18808),
|
||||
* Thread.join() must wait for the join'ed thread's tstate to be unlinked
|
||||
* from the tstate chain. That happens at the end of a thread's life,
|
||||
* in pystate.c.
|
||||
* The obvious way doesn't quite work: create a lock which the tstate
|
||||
* unlinking code releases, and have Thread.join() wait to acquire that
|
||||
* lock. The problem is that we _are_ at the end of the thread's life:
|
||||
* if the thread holds the last reference to the lock, decref'ing the
|
||||
* lock will delete the lock, and that may trigger arbitrary Python code
|
||||
* if there's a weakref, with a callback, to the lock. But by this time
|
||||
* _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
|
||||
* of C code can be allowed to run (in particular it must not be possible to
|
||||
* release the GIL).
|
||||
* So instead of holding the lock directly, the tstate holds a weakref to
|
||||
* the lock: that's the value of on_delete_data below. Decref'ing a
|
||||
* weakref is harmless.
|
||||
* on_delete points to _threadmodule.c's static release_sentinel() function.
|
||||
* After the tstate is unlinked, release_sentinel is called with the
|
||||
* weakref-to-lock (on_delete_data) argument, and release_sentinel releases
|
||||
* the indirectly held lock.
|
||||
*/
|
||||
void (*on_delete)(void *);
|
||||
void *on_delete_data;
|
||||
|
||||
int coroutine_origin_tracking_depth;
|
||||
|
||||
PyObject *async_gen_firstiter;
|
||||
PyObject *async_gen_finalizer;
|
||||
|
||||
PyObject *context;
|
||||
uint64_t context_ver;
|
||||
|
||||
/* Unique thread state id. */
|
||||
uint64_t id;
|
||||
|
||||
CFrame root_cframe;
|
||||
|
||||
/* XXX signal handlers should also be here */
|
||||
|
||||
};
|
||||
|
||||
// Alias for backward compatibility with Python 3.8
|
||||
#define _PyInterpreterState_Get PyInterpreterState_Get
|
||||
|
||||
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
|
||||
|
||||
/* Similar to PyThreadState_Get(), but don't issue a fatal error
|
||||
* if it is NULL. */
|
||||
PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate);
|
||||
|
||||
/* PyGILState */
|
||||
|
||||
/* Helper/diagnostic function - return 1 if the current thread
|
||||
currently holds the GIL, 0 otherwise.
|
||||
|
||||
The function returns 1 if _PyGILState_check_enabled is non-zero. */
|
||||
PyAPI_FUNC(int) PyGILState_Check(void);
|
||||
|
||||
/* Get the single PyInterpreterState used by this process' GILState
|
||||
implementation.
|
||||
|
||||
This function doesn't check for error. Return NULL before _PyGILState_Init()
|
||||
is called and after _PyGILState_Fini() is called.
|
||||
|
||||
See also _PyInterpreterState_Get() and _PyInterpreterState_GET(). */
|
||||
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
|
||||
|
||||
/* The implementation of sys._current_frames() Returns a dict mapping
|
||||
thread id to that thread's current frame.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
|
||||
|
||||
/* The implementation of sys._current_exceptions() Returns a dict mapping
|
||||
thread id to that thread's current exception.
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void);
|
||||
|
||||
/* Routines for advanced debuggers, requested by David Beazley.
|
||||
Don't use unless you know what you are doing! */
|
||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
|
||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
|
||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
|
||||
PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
|
||||
PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
|
||||
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
|
||||
|
||||
/* Frame evaluation API */
|
||||
|
||||
typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, PyFrameObject *, int);
|
||||
|
||||
PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
|
||||
PyInterpreterState *interp);
|
||||
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
|
||||
PyInterpreterState *interp,
|
||||
_PyFrameEvalFunction eval_frame);
|
||||
|
||||
PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp);
|
||||
|
||||
/* Get a copy of the current interpreter configuration.
|
||||
|
||||
Return 0 on success. Raise an exception and return -1 on error.
|
||||
|
||||
The caller must initialize 'config', using PyConfig_InitPythonConfig()
|
||||
for example.
|
||||
|
||||
Python must be preinitialized to call this method.
|
||||
The caller must hold the GIL. */
|
||||
PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy(
|
||||
struct PyConfig *config);
|
||||
|
||||
/* Set the configuration of the current interpreter.
|
||||
|
||||
This function should be called during or just after the Python
|
||||
initialization.
|
||||
|
||||
Update the sys module with the new configuration. If the sys module was
|
||||
modified directly after the Python initialization, these changes are lost.
|
||||
|
||||
Some configuration like faulthandler or warnoptions can be updated in the
|
||||
configuration, but don't reconfigure Python (don't enable/disable
|
||||
faulthandler and don't reconfigure warnings filters).
|
||||
|
||||
Return 0 on success. Raise an exception and return -1 on error.
|
||||
|
||||
The configuration should come from _PyInterpreterState_GetConfigCopy(). */
|
||||
PyAPI_FUNC(int) _PyInterpreterState_SetConfig(
|
||||
const struct PyConfig *config);
|
||||
|
||||
// Get the configuration of the current interpreter.
|
||||
// The caller must hold the GIL.
|
||||
PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
|
||||
|
||||
|
||||
/* cross-interpreter data */
|
||||
|
||||
struct _xid;
|
||||
|
||||
// _PyCrossInterpreterData is similar to Py_buffer as an effectively
|
||||
// opaque struct that holds data outside the object machinery. This
|
||||
// is necessary to pass safely between interpreters in the same process.
|
||||
typedef struct _xid {
|
||||
// data is the cross-interpreter-safe derivation of a Python object
|
||||
// (see _PyObject_GetCrossInterpreterData). It will be NULL if the
|
||||
// new_object func (below) encodes the data.
|
||||
void *data;
|
||||
// obj is the Python object from which the data was derived. This
|
||||
// is non-NULL only if the data remains bound to the object in some
|
||||
// way, such that the object must be "released" (via a decref) when
|
||||
// the data is released. In that case the code that sets the field,
|
||||
// likely a registered "crossinterpdatafunc", is responsible for
|
||||
// ensuring it owns the reference (i.e. incref).
|
||||
PyObject *obj;
|
||||
// interp is the ID of the owning interpreter of the original
|
||||
// object. It corresponds to the active interpreter when
|
||||
// _PyObject_GetCrossInterpreterData() was called. This should only
|
||||
// be set by the cross-interpreter machinery.
|
||||
//
|
||||
// We use the ID rather than the PyInterpreterState to avoid issues
|
||||
// with deleted interpreters. Note that IDs are never re-used, so
|
||||
// each one will always correspond to a specific interpreter
|
||||
// (whether still alive or not).
|
||||
int64_t interp;
|
||||
// new_object is a function that returns a new object in the current
|
||||
// interpreter given the data. The resulting object (a new
|
||||
// reference) will be equivalent to the original object. This field
|
||||
// is required.
|
||||
PyObject *(*new_object)(struct _xid *);
|
||||
// free is called when the data is released. If it is NULL then
|
||||
// nothing will be done to free the data. For some types this is
|
||||
// okay (e.g. bytes) and for those types this field should be set
|
||||
// to NULL. However, for most the data was allocated just for
|
||||
// cross-interpreter use, so it must be freed when
|
||||
// _PyCrossInterpreterData_Release is called or the memory will
|
||||
// leak. In that case, at the very least this field should be set
|
||||
// to PyMem_RawFree (the default if not explicitly set to NULL).
|
||||
// The call will happen with the original interpreter activated.
|
||||
void (*free)(void *);
|
||||
} _PyCrossInterpreterData;
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
|
||||
PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
|
||||
PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
|
||||
|
||||
PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
|
||||
|
||||
/* cross-interpreter data registry */
|
||||
|
||||
typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *);
|
||||
|
||||
PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
|
||||
PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef Py_CPYTHON_PYTHONRUN_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
|
||||
PyAPI_FUNC(int) _PyRun_SimpleFileObject(
|
||||
FILE *fp,
|
||||
PyObject *filename,
|
||||
int closeit,
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) PyRun_AnyFileExFlags(
|
||||
FILE *fp,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
int closeit,
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) _PyRun_AnyFileObject(
|
||||
FILE *fp,
|
||||
PyObject *filename,
|
||||
int closeit,
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) PyRun_SimpleFileExFlags(
|
||||
FILE *fp,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
int closeit,
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) PyRun_InteractiveOneFlags(
|
||||
FILE *fp,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) PyRun_InteractiveOneObject(
|
||||
FILE *fp,
|
||||
PyObject *filename,
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(
|
||||
FILE *fp,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
PyCompilerFlags *flags);
|
||||
PyAPI_FUNC(int) _PyRun_InteractiveLoopObject(
|
||||
FILE *fp,
|
||||
PyObject *filename,
|
||||
PyCompilerFlags *flags);
|
||||
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *,
|
||||
PyObject *, PyCompilerFlags *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyRun_FileExFlags(
|
||||
FILE *fp,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
int start,
|
||||
PyObject *globals,
|
||||
PyObject *locals,
|
||||
int closeit,
|
||||
PyCompilerFlags *flags);
|
||||
|
||||
|
||||
PyAPI_FUNC(PyObject *) Py_CompileStringExFlags(
|
||||
const char *str,
|
||||
const char *filename, /* decoded from the filesystem encoding */
|
||||
int start,
|
||||
PyCompilerFlags *flags,
|
||||
int optimize);
|
||||
PyAPI_FUNC(PyObject *) Py_CompileStringObject(
|
||||
const char *str,
|
||||
PyObject *filename, int start,
|
||||
PyCompilerFlags *flags,
|
||||
int optimize);
|
||||
|
||||
#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1)
|
||||
#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1)
|
||||
|
||||
|
||||
PyAPI_FUNC(const char *) _Py_SourceAsString(
|
||||
PyObject *cmd,
|
||||
const char *funcname,
|
||||
const char *what,
|
||||
PyCompilerFlags *cf,
|
||||
PyObject **cmd_copy);
|
||||
|
||||
|
||||
/* A function flavor is also exported by libpython. It is required when
|
||||
libpython is accessed directly rather than using header files which defines
|
||||
macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to
|
||||
export functions in pythonXX.dll. */
|
||||
PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l);
|
||||
PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name);
|
||||
PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit);
|
||||
PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *);
|
||||
PyAPI_FUNC(int) PyRun_SimpleString(const char *s);
|
||||
PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p);
|
||||
PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c);
|
||||
PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p);
|
||||
PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p);
|
||||
PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l);
|
||||
PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c);
|
||||
PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags);
|
||||
|
||||
/* Use macros for a bunch of old variants */
|
||||
#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
|
||||
#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL)
|
||||
#define PyRun_AnyFileEx(fp, name, closeit) \
|
||||
PyRun_AnyFileExFlags(fp, name, closeit, NULL)
|
||||
#define PyRun_AnyFileFlags(fp, name, flags) \
|
||||
PyRun_AnyFileExFlags(fp, name, 0, flags)
|
||||
#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL)
|
||||
#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL)
|
||||
#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL)
|
||||
#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL)
|
||||
#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL)
|
||||
#define PyRun_File(fp, p, s, g, l) \
|
||||
PyRun_FileExFlags(fp, p, s, g, l, 0, NULL)
|
||||
#define PyRun_FileEx(fp, p, s, g, l, c) \
|
||||
PyRun_FileExFlags(fp, p, s, g, l, c, NULL)
|
||||
#define PyRun_FileFlags(fp, p, s, g, l, flags) \
|
||||
PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
|
||||
|
||||
|
||||
/* Stuff with no proper home (yet) */
|
||||
PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *);
|
||||
PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState;
|
||||
PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *);
|
||||
@@ -0,0 +1,247 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_PYTIME_H
|
||||
#define Py_PYTIME_H
|
||||
|
||||
/**************************************************************************
|
||||
Symbols and macros to supply platform-independent interfaces to time related
|
||||
functions and constants
|
||||
**************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
|
||||
store a duration, and so indirectly a date (related to another date, like
|
||||
UNIX epoch). */
|
||||
typedef int64_t _PyTime_t;
|
||||
#define _PyTime_MIN INT64_MIN
|
||||
#define _PyTime_MAX INT64_MAX
|
||||
|
||||
typedef enum {
|
||||
/* Round towards minus infinity (-inf).
|
||||
For example, used to read a clock. */
|
||||
_PyTime_ROUND_FLOOR=0,
|
||||
/* Round towards infinity (+inf).
|
||||
For example, used for timeout to wait "at least" N seconds. */
|
||||
_PyTime_ROUND_CEILING=1,
|
||||
/* Round to nearest with ties going to nearest even integer.
|
||||
For example, used to round from a Python float. */
|
||||
_PyTime_ROUND_HALF_EVEN=2,
|
||||
/* Round away from zero
|
||||
For example, used for timeout. _PyTime_ROUND_CEILING rounds
|
||||
-1e-9 to 0 milliseconds which causes bpo-31786 issue.
|
||||
_PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
|
||||
the timeout sign as expected. select.poll(timeout) must block
|
||||
for negative values." */
|
||||
_PyTime_ROUND_UP=3,
|
||||
/* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
|
||||
used for timeouts. */
|
||||
_PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
|
||||
} _PyTime_round_t;
|
||||
|
||||
|
||||
/* Convert a time_t to a PyLong. */
|
||||
PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
|
||||
time_t sec);
|
||||
|
||||
/* Convert a PyLong to a time_t. */
|
||||
PyAPI_FUNC(time_t) _PyLong_AsTime_t(
|
||||
PyObject *obj);
|
||||
|
||||
/* Convert a number of seconds, int or float, to time_t. */
|
||||
PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
|
||||
PyObject *obj,
|
||||
time_t *sec,
|
||||
_PyTime_round_t);
|
||||
|
||||
/* Convert a number of seconds, int or float, to a timeval structure.
|
||||
usec is in the range [0; 999999] and rounded towards zero.
|
||||
For example, -1.2 is converted to (-2, 800000). */
|
||||
PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
|
||||
PyObject *obj,
|
||||
time_t *sec,
|
||||
long *usec,
|
||||
_PyTime_round_t);
|
||||
|
||||
/* Convert a number of seconds, int or float, to a timespec structure.
|
||||
nsec is in the range [0; 999999999] and rounded towards zero.
|
||||
For example, -1.2 is converted to (-2, 800000000). */
|
||||
PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
|
||||
PyObject *obj,
|
||||
time_t *sec,
|
||||
long *nsec,
|
||||
_PyTime_round_t);
|
||||
|
||||
|
||||
/* Create a timestamp from a number of seconds. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
|
||||
|
||||
/* Macro to create a timestamp from a number of seconds, no integer overflow.
|
||||
Only use the macro for small values, prefer _PyTime_FromSeconds(). */
|
||||
#define _PYTIME_FROMSECONDS(seconds) \
|
||||
((_PyTime_t)(seconds) * (1000 * 1000 * 1000))
|
||||
|
||||
/* Create a timestamp from a number of nanoseconds. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns);
|
||||
|
||||
/* Create a timestamp from nanoseconds (Python int). */
|
||||
PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t,
|
||||
PyObject *obj);
|
||||
|
||||
/* Convert a number of seconds (Python float or int) to a timestamp.
|
||||
Raise an exception and return -1 on error, return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
|
||||
PyObject *obj,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
|
||||
Raise an exception and return -1 on error, return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
|
||||
PyObject *obj,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Convert a timestamp to a number of seconds as a C double. */
|
||||
PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
|
||||
|
||||
/* Convert timestamp to a number of milliseconds (10^-3 seconds). */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Convert timestamp to a number of microseconds (10^-6 seconds). */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
|
||||
object. */
|
||||
PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
|
||||
|
||||
/* Create a timestamp from a timeval structure.
|
||||
Raise an exception and return -1 on overflow, return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv);
|
||||
|
||||
/* Convert a timestamp to a timeval structure (microsecond resolution).
|
||||
tv_usec is always positive.
|
||||
Raise an exception and return -1 if the conversion overflowed,
|
||||
return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
|
||||
struct timeval *tv,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */
|
||||
PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t,
|
||||
struct timeval *tv,
|
||||
_PyTime_round_t round);
|
||||
|
||||
/* Convert a timestamp to a number of seconds (secs) and microseconds (us).
|
||||
us is always positive. This function is similar to _PyTime_AsTimeval()
|
||||
except that secs is always a time_t type, whereas the timeval structure
|
||||
uses a C long for tv_sec on Windows.
|
||||
Raise an exception and return -1 if the conversion overflowed,
|
||||
return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
|
||||
_PyTime_t t,
|
||||
time_t *secs,
|
||||
int *us,
|
||||
_PyTime_round_t round);
|
||||
|
||||
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
|
||||
/* Create a timestamp from a timespec structure.
|
||||
Raise an exception and return -1 on overflow, return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts);
|
||||
|
||||
/* Convert a timestamp to a timespec structure (nanosecond resolution).
|
||||
tv_nsec is always positive.
|
||||
Raise an exception and return -1 on error, return 0 on success. */
|
||||
PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
|
||||
#endif
|
||||
|
||||
/* Compute ticks * mul / div.
|
||||
The caller must ensure that ((div - 1) * mul) cannot overflow. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks,
|
||||
_PyTime_t mul,
|
||||
_PyTime_t div);
|
||||
|
||||
/* Structure used by time.get_clock_info() */
|
||||
typedef struct {
|
||||
const char *implementation;
|
||||
int monotonic;
|
||||
int adjustable;
|
||||
double resolution;
|
||||
} _Py_clock_info_t;
|
||||
|
||||
/* Get the current time from the system clock.
|
||||
|
||||
If the internal clock fails, silently ignore the error and return 0.
|
||||
On integer overflow, silently ignore the overflow and truncated the clock to
|
||||
_PyTime_MIN or _PyTime_MAX.
|
||||
|
||||
Use _PyTime_GetSystemClockWithInfo() to check for failure. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
|
||||
|
||||
/* Get the current time from the system clock.
|
||||
* On success, set *t and *info (if not NULL), and return 0.
|
||||
* On error, raise an exception and return -1.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
|
||||
_PyTime_t *t,
|
||||
_Py_clock_info_t *info);
|
||||
|
||||
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
|
||||
The clock is not affected by system clock updates. The reference point of
|
||||
the returned value is undefined, so that only the difference between the
|
||||
results of consecutive calls is valid.
|
||||
|
||||
If the internal clock fails, silently ignore the error and return 0.
|
||||
On integer overflow, silently ignore the overflow and truncated the clock to
|
||||
_PyTime_MIN or _PyTime_MAX.
|
||||
|
||||
Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
|
||||
|
||||
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
|
||||
The clock is not affected by system clock updates. The reference point of
|
||||
the returned value is undefined, so that only the difference between the
|
||||
results of consecutive calls is valid.
|
||||
|
||||
Fill info (if set) with information of the function used to get the time.
|
||||
|
||||
Return 0 on success, raise an exception and return -1 on error. */
|
||||
PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo(
|
||||
_PyTime_t *t,
|
||||
_Py_clock_info_t *info);
|
||||
|
||||
|
||||
/* Converts a timestamp to the Gregorian time, using the local time zone.
|
||||
Return 0 on success, raise an exception and return -1 on error. */
|
||||
PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
|
||||
|
||||
/* Converts a timestamp to the Gregorian time, assuming UTC.
|
||||
Return 0 on success, raise an exception and return -1 on error. */
|
||||
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
|
||||
|
||||
/* Get the performance counter: clock with the highest available resolution to
|
||||
measure a short duration.
|
||||
|
||||
If the internal clock fails, silently ignore the error and return 0.
|
||||
On integer overflow, silently ignore the overflow and truncated the clock to
|
||||
_PyTime_MIN or _PyTime_MAX.
|
||||
|
||||
Use _PyTime_GetPerfCounterWithInfo() to check for failure. */
|
||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
|
||||
|
||||
/* Get the performance counter: clock with the highest available resolution to
|
||||
measure a short duration.
|
||||
|
||||
Fill info (if set) with information of the function used to get the time.
|
||||
|
||||
Return 0 on success, raise an exception and return -1 on error. */
|
||||
PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
|
||||
_PyTime_t *t,
|
||||
_Py_clock_info_t *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Py_PYTIME_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef Py_CPYTHON_SYSMODULE_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key);
|
||||
PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *);
|
||||
|
||||
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
|
||||
|
||||
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
|
||||
|
||||
PyAPI_FUNC(int) PySys_Audit(
|
||||
const char *event,
|
||||
const char *argFormat,
|
||||
...);
|
||||
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef Py_CPYTHON_TRACEBACK_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef struct _traceback {
|
||||
PyObject_HEAD
|
||||
struct _traceback *tb_next;
|
||||
PyFrameObject *tb_frame;
|
||||
int tb_lasti;
|
||||
int tb_lineno;
|
||||
} PyTracebackObject;
|
||||
|
||||
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int);
|
||||
PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef Py_CPYTHON_TUPLEOBJECT_H
|
||||
# error "this header file must not be included directly"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_VAR_HEAD
|
||||
/* ob_item contains space for 'ob_size' elements.
|
||||
Items must normally not be NULL, except during construction when
|
||||
the tuple is not yet visible outside the function that builds it. */
|
||||
PyObject *ob_item[1];
|
||||
} PyTupleObject;
|
||||
|
||||
PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t);
|
||||
PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
|
||||
|
||||
/* Macros trading safety for speed */
|
||||
|
||||
/* Cast argument to PyTupleObject* type. */
|
||||
#define _PyTuple_CAST(op) (assert(PyTuple_Check(op)), (PyTupleObject *)(op))
|
||||
|
||||
#define PyTuple_GET_SIZE(op) Py_SIZE(_PyTuple_CAST(op))
|
||||
|
||||
#define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i])
|
||||
|
||||
/* Macro, *only* to be used to fill in brand new tuples */
|
||||
#define PyTuple_SET_ITEM(op, i, v) ((void)(_PyTuple_CAST(op)->ob_item[i] = v))
|
||||
|
||||
PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,267 @@
|
||||
/* datetime.h
|
||||
*/
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef DATETIME_H
|
||||
#define DATETIME_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Fields are packed into successive bytes, each viewed as unsigned and
|
||||
* big-endian, unless otherwise noted:
|
||||
*
|
||||
* byte offset
|
||||
* 0 year 2 bytes, 1-9999
|
||||
* 2 month 1 byte, 1-12
|
||||
* 3 day 1 byte, 1-31
|
||||
* 4 hour 1 byte, 0-23
|
||||
* 5 minute 1 byte, 0-59
|
||||
* 6 second 1 byte, 0-59
|
||||
* 7 usecond 3 bytes, 0-999999
|
||||
* 10
|
||||
*/
|
||||
|
||||
/* # of bytes for year, month, and day. */
|
||||
#define _PyDateTime_DATE_DATASIZE 4
|
||||
|
||||
/* # of bytes for hour, minute, second, and usecond. */
|
||||
#define _PyDateTime_TIME_DATASIZE 6
|
||||
|
||||
/* # of bytes for year, month, day, hour, minute, second, and usecond. */
|
||||
#define _PyDateTime_DATETIME_DATASIZE 10
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD
|
||||
Py_hash_t hashcode; /* -1 when unknown */
|
||||
int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
|
||||
int seconds; /* 0 <= seconds < 24*3600 is invariant */
|
||||
int microseconds; /* 0 <= microseconds < 1000000 is invariant */
|
||||
} PyDateTime_Delta;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PyObject_HEAD /* a pure abstract base class */
|
||||
} PyDateTime_TZInfo;
|
||||
|
||||
|
||||
/* The datetime and time types have hashcodes, and an optional tzinfo member,
|
||||
* present if and only if hastzinfo is true.
|
||||
*/
|
||||
#define _PyTZINFO_HEAD \
|
||||
PyObject_HEAD \
|
||||
Py_hash_t hashcode; \
|
||||
char hastzinfo; /* boolean flag */
|
||||
|
||||
/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
|
||||
* convenient to cast to, when getting at the hastzinfo member of objects
|
||||
* starting with _PyTZINFO_HEAD.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
_PyTZINFO_HEAD
|
||||
} _PyDateTime_BaseTZInfo;
|
||||
|
||||
/* All time objects are of PyDateTime_TimeType, but that can be allocated
|
||||
* in two ways, with or without a tzinfo member. Without is the same as
|
||||
* tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an
|
||||
* internal struct used to allocate the right amount of space for the
|
||||
* "without" case.
|
||||
*/
|
||||
#define _PyDateTime_TIMEHEAD \
|
||||
_PyTZINFO_HEAD \
|
||||
unsigned char data[_PyDateTime_TIME_DATASIZE];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_PyDateTime_TIMEHEAD
|
||||
} _PyDateTime_BaseTime; /* hastzinfo false */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_PyDateTime_TIMEHEAD
|
||||
unsigned char fold;
|
||||
PyObject *tzinfo;
|
||||
} PyDateTime_Time; /* hastzinfo true */
|
||||
|
||||
|
||||
/* All datetime objects are of PyDateTime_DateTimeType, but that can be
|
||||
* allocated in two ways too, just like for time objects above. In addition,
|
||||
* the plain date type is a base class for datetime, so it must also have
|
||||
* a hastzinfo member (although it's unused there).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
_PyTZINFO_HEAD
|
||||
unsigned char data[_PyDateTime_DATE_DATASIZE];
|
||||
} PyDateTime_Date;
|
||||
|
||||
#define _PyDateTime_DATETIMEHEAD \
|
||||
_PyTZINFO_HEAD \
|
||||
unsigned char data[_PyDateTime_DATETIME_DATASIZE];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_PyDateTime_DATETIMEHEAD
|
||||
} _PyDateTime_BaseDateTime; /* hastzinfo false */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_PyDateTime_DATETIMEHEAD
|
||||
unsigned char fold;
|
||||
PyObject *tzinfo;
|
||||
} PyDateTime_DateTime; /* hastzinfo true */
|
||||
|
||||
|
||||
/* Apply for date and datetime instances. */
|
||||
|
||||
// o is a pointer to a time or a datetime object.
|
||||
#define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo)
|
||||
|
||||
#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
||||
((PyDateTime_Date*)o)->data[1])
|
||||
#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
|
||||
#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3])
|
||||
|
||||
#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4])
|
||||
#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5])
|
||||
#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6])
|
||||
#define PyDateTime_DATE_GET_MICROSECOND(o) \
|
||||
((((PyDateTime_DateTime*)o)->data[7] << 16) | \
|
||||
(((PyDateTime_DateTime*)o)->data[8] << 8) | \
|
||||
((PyDateTime_DateTime*)o)->data[9])
|
||||
#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold)
|
||||
#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
||||
((PyDateTime_DateTime *)(o))->tzinfo : Py_None)
|
||||
|
||||
/* Apply for time instances. */
|
||||
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
|
||||
#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])
|
||||
#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2])
|
||||
#define PyDateTime_TIME_GET_MICROSECOND(o) \
|
||||
((((PyDateTime_Time*)o)->data[3] << 16) | \
|
||||
(((PyDateTime_Time*)o)->data[4] << 8) | \
|
||||
((PyDateTime_Time*)o)->data[5])
|
||||
#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold)
|
||||
#define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
||||
((PyDateTime_Time *)(o))->tzinfo : Py_None)
|
||||
|
||||
/* Apply for time delta instances */
|
||||
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
||||
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
|
||||
#define PyDateTime_DELTA_GET_MICROSECONDS(o) \
|
||||
(((PyDateTime_Delta*)o)->microseconds)
|
||||
|
||||
|
||||
/* Define structure for C API. */
|
||||
typedef struct {
|
||||
/* type objects */
|
||||
PyTypeObject *DateType;
|
||||
PyTypeObject *DateTimeType;
|
||||
PyTypeObject *TimeType;
|
||||
PyTypeObject *DeltaType;
|
||||
PyTypeObject *TZInfoType;
|
||||
|
||||
/* singletons */
|
||||
PyObject *TimeZone_UTC;
|
||||
|
||||
/* constructors */
|
||||
PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
|
||||
PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
|
||||
PyObject*, PyTypeObject*);
|
||||
PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
|
||||
PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
|
||||
PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name);
|
||||
|
||||
/* constructors for the DB API */
|
||||
PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
|
||||
PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
|
||||
|
||||
/* PEP 495 constructors */
|
||||
PyObject *(*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int,
|
||||
PyObject*, int, PyTypeObject*);
|
||||
PyObject *(*Time_FromTimeAndFold)(int, int, int, int, PyObject*, int, PyTypeObject*);
|
||||
|
||||
} PyDateTime_CAPI;
|
||||
|
||||
#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
|
||||
|
||||
|
||||
/* This block is only used as part of the public API and should not be
|
||||
* included in _datetimemodule.c, which does not use the C API capsule.
|
||||
* See bpo-35081 for more details.
|
||||
* */
|
||||
#ifndef _PY_DATETIME_IMPL
|
||||
/* Define global variable for the C API and a macro for setting it. */
|
||||
static PyDateTime_CAPI *PyDateTimeAPI = NULL;
|
||||
|
||||
#define PyDateTime_IMPORT \
|
||||
PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
|
||||
|
||||
/* Macro for access to the UTC singleton */
|
||||
#define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC
|
||||
|
||||
/* Macros for type checking when not building the Python core. */
|
||||
#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
|
||||
#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType)
|
||||
|
||||
#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
|
||||
#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType)
|
||||
|
||||
#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
|
||||
#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType)
|
||||
|
||||
#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
|
||||
#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType)
|
||||
|
||||
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
|
||||
#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType)
|
||||
|
||||
|
||||
/* Macros for accessing constructors in a simplified fashion. */
|
||||
#define PyDate_FromDate(year, month, day) \
|
||||
PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
|
||||
|
||||
#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
|
||||
PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
|
||||
min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
|
||||
|
||||
#define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \
|
||||
PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \
|
||||
min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType)
|
||||
|
||||
#define PyTime_FromTime(hour, minute, second, usecond) \
|
||||
PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
|
||||
Py_None, PyDateTimeAPI->TimeType)
|
||||
|
||||
#define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \
|
||||
PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \
|
||||
Py_None, fold, PyDateTimeAPI->TimeType)
|
||||
|
||||
#define PyDelta_FromDSU(days, seconds, useconds) \
|
||||
PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
|
||||
PyDateTimeAPI->DeltaType)
|
||||
|
||||
#define PyTimeZone_FromOffset(offset) \
|
||||
PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL)
|
||||
|
||||
#define PyTimeZone_FromOffsetAndName(offset, name) \
|
||||
PyDateTimeAPI->TimeZone_FromTimeZone(offset, name)
|
||||
|
||||
/* Macros supporting the DB API. */
|
||||
#define PyDateTime_FromTimestamp(args) \
|
||||
PyDateTimeAPI->DateTime_FromTimestamp( \
|
||||
(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
|
||||
|
||||
#define PyDate_FromTimestamp(args) \
|
||||
PyDateTimeAPI->Date_FromTimestamp( \
|
||||
(PyObject*) (PyDateTimeAPI->DateType), args)
|
||||
|
||||
#endif /* !defined(_PY_DATETIME_IMPL) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !Py_LIMITED_API */
|
||||
@@ -0,0 +1,108 @@
|
||||
/* Descriptors */
|
||||
#ifndef Py_DESCROBJECT_H
|
||||
#define Py_DESCROBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef PyObject *(*getter)(PyObject *, void *);
|
||||
typedef int (*setter)(PyObject *, PyObject *, void *);
|
||||
|
||||
typedef struct PyGetSetDef {
|
||||
const char *name;
|
||||
getter get;
|
||||
setter set;
|
||||
const char *doc;
|
||||
void *closure;
|
||||
} PyGetSetDef;
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
|
||||
void *wrapped);
|
||||
|
||||
typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
|
||||
void *wrapped, PyObject *kwds);
|
||||
|
||||
struct wrapperbase {
|
||||
const char *name;
|
||||
int offset;
|
||||
void *function;
|
||||
wrapperfunc wrapper;
|
||||
const char *doc;
|
||||
int flags;
|
||||
PyObject *name_strobj;
|
||||
};
|
||||
|
||||
/* Flags for above struct */
|
||||
#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */
|
||||
|
||||
/* Various kinds of descriptor objects */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyTypeObject *d_type;
|
||||
PyObject *d_name;
|
||||
PyObject *d_qualname;
|
||||
} PyDescrObject;
|
||||
|
||||
#define PyDescr_COMMON PyDescrObject d_common
|
||||
|
||||
#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
|
||||
#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
|
||||
|
||||
typedef struct {
|
||||
PyDescr_COMMON;
|
||||
PyMethodDef *d_method;
|
||||
vectorcallfunc vectorcall;
|
||||
} PyMethodDescrObject;
|
||||
|
||||
typedef struct {
|
||||
PyDescr_COMMON;
|
||||
struct PyMemberDef *d_member;
|
||||
} PyMemberDescrObject;
|
||||
|
||||
typedef struct {
|
||||
PyDescr_COMMON;
|
||||
PyGetSetDef *d_getset;
|
||||
} PyGetSetDescrObject;
|
||||
|
||||
typedef struct {
|
||||
PyDescr_COMMON;
|
||||
struct wrapperbase *d_base;
|
||||
void *d_wrapped; /* This can be any function pointer */
|
||||
} PyWrapperDescrObject;
|
||||
#endif /* Py_LIMITED_API */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyMemberDescr_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyMethodDescr_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type;
|
||||
#endif /* Py_LIMITED_API */
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
|
||||
PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *);
|
||||
struct PyMemberDef; /* forward declaration for following prototype */
|
||||
PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *,
|
||||
struct PyMemberDef *);
|
||||
PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
|
||||
struct PyGetSetDef *);
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
|
||||
struct wrapperbase *, void *);
|
||||
PyAPI_FUNC(int) PyDescr_IsData(PyObject *);
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);
|
||||
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyProperty_Type;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_DESCROBJECT_H */
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#ifndef Py_DICTOBJECT_H
|
||||
#define Py_DICTOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Dictionary object type -- mapping from hashable object to object */
|
||||
|
||||
/* The distribution includes a separate file, Objects/dictnotes.txt,
|
||||
describing explorations into dictionary design and optimization.
|
||||
It covers typical dictionary use patterns, the parameters for
|
||||
tuning dictionaries, and several ideas for possible optimizations.
|
||||
*/
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyDict_Type;
|
||||
|
||||
#define PyDict_Check(op) \
|
||||
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
|
||||
#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyDict_New(void);
|
||||
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
|
||||
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
|
||||
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
|
||||
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
|
||||
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
|
||||
PyAPI_FUNC(int) PyDict_Next(
|
||||
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
|
||||
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
|
||||
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
|
||||
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
|
||||
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
|
||||
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
|
||||
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
|
||||
|
||||
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
|
||||
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
|
||||
|
||||
/* PyDict_Merge updates/merges from a mapping object (an object that
|
||||
supports PyMapping_Keys() and PyObject_GetItem()). If override is true,
|
||||
the last occurrence of a key wins, else the first. The Python
|
||||
dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
|
||||
*/
|
||||
PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
|
||||
PyObject *other,
|
||||
int override);
|
||||
|
||||
/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
|
||||
iterable objects of length 2. If override is true, the last occurrence
|
||||
of a key wins, else the first. The Python dict constructor dict(seq2)
|
||||
is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
|
||||
*/
|
||||
PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
|
||||
PyObject *seq2,
|
||||
int override);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
|
||||
PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
|
||||
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
||||
PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
|
||||
#endif
|
||||
|
||||
/* Dictionary (keys, values, items) views */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictValues_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictItems_Type;
|
||||
|
||||
#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
|
||||
#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
|
||||
#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
|
||||
/* This excludes Values, since they are not sets. */
|
||||
# define PyDictViewSet_Check(op) \
|
||||
(PyDictKeys_Check(op) || PyDictItems_Check(op))
|
||||
|
||||
/* Dictionary (key, value, items) iterators */
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
|
||||
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_DICTOBJECT_H
|
||||
# include "cpython/dictobject.h"
|
||||
# undef Py_CPYTHON_DICTOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_DICTOBJECT_H */
|
||||
@@ -0,0 +1,499 @@
|
||||
/* Copyright (c) 2008-2009, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ---
|
||||
* Author: Kostya Serebryany
|
||||
* Copied to CPython by Jeffrey Yasskin, with all macros renamed to
|
||||
* start with _Py_ to avoid colliding with users embedding Python, and
|
||||
* with deprecated macros removed.
|
||||
*/
|
||||
|
||||
/* This file defines dynamic annotations for use with dynamic analysis
|
||||
tool such as valgrind, PIN, etc.
|
||||
|
||||
Dynamic annotation is a source code annotation that affects
|
||||
the generated code (that is, the annotation is not a comment).
|
||||
Each such annotation is attached to a particular
|
||||
instruction and/or to a particular object (address) in the program.
|
||||
|
||||
The annotations that should be used by users are macros in all upper-case
|
||||
(e.g., _Py_ANNOTATE_NEW_MEMORY).
|
||||
|
||||
Actual implementation of these macros may differ depending on the
|
||||
dynamic analysis tool being used.
|
||||
|
||||
See https://code.google.com/p/data-race-test/ for more information.
|
||||
|
||||
This file supports the following dynamic analysis tools:
|
||||
- None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).
|
||||
Macros are defined empty.
|
||||
- ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).
|
||||
Macros are defined as calls to non-inlinable empty functions
|
||||
that are intercepted by Valgrind. */
|
||||
|
||||
#ifndef __DYNAMIC_ANNOTATIONS_H__
|
||||
#define __DYNAMIC_ANNOTATIONS_H__
|
||||
|
||||
#ifndef DYNAMIC_ANNOTATIONS_ENABLED
|
||||
# define DYNAMIC_ANNOTATIONS_ENABLED 0
|
||||
#endif
|
||||
|
||||
#if DYNAMIC_ANNOTATIONS_ENABLED != 0
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when implementing condition variables such as CondVar,
|
||||
using conditional critical sections (Await/LockWhen) and when constructing
|
||||
user-defined synchronization mechanisms.
|
||||
|
||||
The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and
|
||||
_Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in
|
||||
user-defined synchronization mechanisms: the race detector will infer an
|
||||
arc from the former to the latter when they share the same argument
|
||||
pointer.
|
||||
|
||||
Example 1 (reference counting):
|
||||
|
||||
void Unref() {
|
||||
_Py_ANNOTATE_HAPPENS_BEFORE(&refcount_);
|
||||
if (AtomicDecrementByOne(&refcount_) == 0) {
|
||||
_Py_ANNOTATE_HAPPENS_AFTER(&refcount_);
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
Example 2 (message queue):
|
||||
|
||||
void MyQueue::Put(Type *e) {
|
||||
MutexLock lock(&mu_);
|
||||
_Py_ANNOTATE_HAPPENS_BEFORE(e);
|
||||
PutElementIntoMyQueue(e);
|
||||
}
|
||||
|
||||
Type *MyQueue::Get() {
|
||||
MutexLock lock(&mu_);
|
||||
Type *e = GetElementFromMyQueue();
|
||||
_Py_ANNOTATE_HAPPENS_AFTER(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
Note: when possible, please use the existing reference counting and message
|
||||
queue implementations instead of inventing new ones. */
|
||||
|
||||
/* Report that wait on the condition variable at address "cv" has succeeded
|
||||
and the lock at address "lock" is held. */
|
||||
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
|
||||
AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)
|
||||
|
||||
/* Report that wait on the condition variable at "cv" has succeeded. Variant
|
||||
w/o lock. */
|
||||
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \
|
||||
AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)
|
||||
|
||||
/* Report that we are about to signal on the condition variable at address
|
||||
"cv". */
|
||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \
|
||||
AnnotateCondVarSignal(__FILE__, __LINE__, cv)
|
||||
|
||||
/* Report that we are about to signal_all on the condition variable at "cv". */
|
||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
|
||||
AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)
|
||||
|
||||
/* Annotations for user-defined synchronization mechanisms. */
|
||||
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj)
|
||||
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj)
|
||||
|
||||
/* Report that the bytes in the range [pointer, pointer+size) are about
|
||||
to be published safely. The race checker will create a happens-before
|
||||
arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
|
||||
subsequent accesses to this memory.
|
||||
Note: this annotation may not work properly if the race detector uses
|
||||
sampling, i.e. does not observe all memory accesses.
|
||||
*/
|
||||
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
|
||||
AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)
|
||||
|
||||
/* Instruct the tool to create a happens-before arc between mu->Unlock() and
|
||||
mu->Lock(). This annotation may slow down the race detector and hide real
|
||||
races. Normally it is used only when it would be difficult to annotate each
|
||||
of the mutex's critical sections individually using the annotations above.
|
||||
This annotation makes sense only for hybrid race detectors. For pure
|
||||
happens-before detectors this is a no-op. For more details see
|
||||
https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */
|
||||
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
|
||||
AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when defining memory allocators, or when memory that
|
||||
was protected in one way starts to be protected in another. */
|
||||
|
||||
/* Report that a new memory at "address" of size "size" has been allocated.
|
||||
This might be used when the memory has been retrieved from a free list and
|
||||
is about to be reused, or when the locking discipline for a variable
|
||||
changes. */
|
||||
#define _Py_ANNOTATE_NEW_MEMORY(address, size) \
|
||||
AnnotateNewMemory(__FILE__, __LINE__, address, size)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when defining FIFO queues that transfer data between
|
||||
threads. */
|
||||
|
||||
/* Report that the producer-consumer queue (such as ProducerConsumerQueue) at
|
||||
address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should
|
||||
be used only for FIFO queues. For non-FIFO queues use
|
||||
_Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for
|
||||
get). */
|
||||
#define _Py_ANNOTATE_PCQ_CREATE(pcq) \
|
||||
AnnotatePCQCreate(__FILE__, __LINE__, pcq)
|
||||
|
||||
/* Report that the queue at address "pcq" is about to be destroyed. */
|
||||
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \
|
||||
AnnotatePCQDestroy(__FILE__, __LINE__, pcq)
|
||||
|
||||
/* Report that we are about to put an element into a FIFO queue at address
|
||||
"pcq". */
|
||||
#define _Py_ANNOTATE_PCQ_PUT(pcq) \
|
||||
AnnotatePCQPut(__FILE__, __LINE__, pcq)
|
||||
|
||||
/* Report that we've just got an element from a FIFO queue at address "pcq". */
|
||||
#define _Py_ANNOTATE_PCQ_GET(pcq) \
|
||||
AnnotatePCQGet(__FILE__, __LINE__, pcq)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations that suppress errors. It is usually better to express the
|
||||
program's synchronization using the other annotations, but these can
|
||||
be used when all else fails. */
|
||||
|
||||
/* Report that we may have a benign race at "pointer", with size
|
||||
"sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the
|
||||
point where "pointer" has been allocated, preferably close to the point
|
||||
where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */
|
||||
#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \
|
||||
AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
|
||||
sizeof(*(pointer)), description)
|
||||
|
||||
/* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to
|
||||
the memory range [address, address+size). */
|
||||
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
|
||||
AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
|
||||
|
||||
/* Request the analysis tool to ignore all reads in the current thread
|
||||
until _Py_ANNOTATE_IGNORE_READS_END is called.
|
||||
Useful to ignore intentional racey reads, while still checking
|
||||
other reads and all writes.
|
||||
See also _Py_ANNOTATE_UNPROTECTED_READ. */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \
|
||||
AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
|
||||
|
||||
/* Stop ignoring reads. */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_END() \
|
||||
AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
|
||||
|
||||
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
|
||||
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \
|
||||
AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
|
||||
|
||||
/* Stop ignoring writes. */
|
||||
#define _Py_ANNOTATE_IGNORE_WRITES_END() \
|
||||
AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
|
||||
|
||||
/* Start ignoring all memory accesses (reads and writes). */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
|
||||
do {\
|
||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();\
|
||||
_Py_ANNOTATE_IGNORE_WRITES_BEGIN();\
|
||||
}while(0)\
|
||||
|
||||
/* Stop ignoring all memory accesses. */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \
|
||||
do {\
|
||||
_Py_ANNOTATE_IGNORE_WRITES_END();\
|
||||
_Py_ANNOTATE_IGNORE_READS_END();\
|
||||
}while(0)\
|
||||
|
||||
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events:
|
||||
RWLOCK* and CONDVAR*. */
|
||||
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \
|
||||
AnnotateIgnoreSyncBegin(__FILE__, __LINE__)
|
||||
|
||||
/* Stop ignoring sync events. */
|
||||
#define _Py_ANNOTATE_IGNORE_SYNC_END() \
|
||||
AnnotateIgnoreSyncEnd(__FILE__, __LINE__)
|
||||
|
||||
|
||||
/* Enable (enable!=0) or disable (enable==0) race detection for all threads.
|
||||
This annotation could be useful if you want to skip expensive race analysis
|
||||
during some period of program execution, e.g. during initialization. */
|
||||
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \
|
||||
AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful for debugging. */
|
||||
|
||||
/* Request to trace every access to "address". */
|
||||
#define _Py_ANNOTATE_TRACE_MEMORY(address) \
|
||||
AnnotateTraceMemory(__FILE__, __LINE__, address)
|
||||
|
||||
/* Report the current thread name to a race detector. */
|
||||
#define _Py_ANNOTATE_THREAD_NAME(name) \
|
||||
AnnotateThreadName(__FILE__, __LINE__, name)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when implementing locks. They are not
|
||||
normally needed by modules that merely use locks.
|
||||
The "lock" argument is a pointer to the lock object. */
|
||||
|
||||
/* Report that a lock has been created at address "lock". */
|
||||
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \
|
||||
AnnotateRWLockCreate(__FILE__, __LINE__, lock)
|
||||
|
||||
/* Report that the lock at address "lock" is about to be destroyed. */
|
||||
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \
|
||||
AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
|
||||
|
||||
/* Report that the lock at address "lock" has been acquired.
|
||||
is_w=1 for writer lock, is_w=0 for reader lock. */
|
||||
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
|
||||
AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
|
||||
|
||||
/* Report that the lock at address "lock" is about to be released. */
|
||||
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
|
||||
AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful when implementing barriers. They are not
|
||||
normally needed by modules that merely use barriers.
|
||||
The "barrier" argument is a pointer to the barrier object. */
|
||||
|
||||
/* Report that the "barrier" has been initialized with initial "count".
|
||||
If 'reinitialization_allowed' is true, initialization is allowed to happen
|
||||
multiple times w/o calling barrier_destroy() */
|
||||
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
|
||||
AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \
|
||||
reinitialization_allowed)
|
||||
|
||||
/* Report that we are about to enter barrier_wait("barrier"). */
|
||||
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
|
||||
AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)
|
||||
|
||||
/* Report that we just exited barrier_wait("barrier"). */
|
||||
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
|
||||
AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)
|
||||
|
||||
/* Report that the "barrier" has been destroyed. */
|
||||
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \
|
||||
AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)
|
||||
|
||||
/* -------------------------------------------------------------
|
||||
Annotations useful for testing race detectors. */
|
||||
|
||||
/* Report that we expect a race on the variable at "address".
|
||||
Use only in unit tests for a race detector. */
|
||||
#define _Py_ANNOTATE_EXPECT_RACE(address, description) \
|
||||
AnnotateExpectRace(__FILE__, __LINE__, address, description)
|
||||
|
||||
/* A no-op. Insert where you like to test the interceptors. */
|
||||
#define _Py_ANNOTATE_NO_OP(arg) \
|
||||
AnnotateNoOp(__FILE__, __LINE__, arg)
|
||||
|
||||
/* Force the race detector to flush its state. The actual effect depends on
|
||||
* the implementation of the detector. */
|
||||
#define _Py_ANNOTATE_FLUSH_STATE() \
|
||||
AnnotateFlushState(__FILE__, __LINE__)
|
||||
|
||||
|
||||
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
|
||||
|
||||
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */
|
||||
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
|
||||
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
|
||||
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
|
||||
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */
|
||||
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */
|
||||
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */
|
||||
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */
|
||||
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */
|
||||
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */
|
||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */
|
||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */
|
||||
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */
|
||||
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */
|
||||
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */
|
||||
#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */
|
||||
#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */
|
||||
#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */
|
||||
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */
|
||||
#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */
|
||||
#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */
|
||||
#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */
|
||||
#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */
|
||||
#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */
|
||||
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
|
||||
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */
|
||||
#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */
|
||||
#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */
|
||||
#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */
|
||||
#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */
|
||||
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
|
||||
#define _Py_ANNOTATE_NO_OP(arg) /* empty */
|
||||
#define _Py_ANNOTATE_FLUSH_STATE() /* empty */
|
||||
|
||||
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
|
||||
|
||||
/* Use the macros above rather than using these functions directly. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void AnnotateRWLockCreate(const char *file, int line,
|
||||
const volatile void *lock);
|
||||
void AnnotateRWLockDestroy(const char *file, int line,
|
||||
const volatile void *lock);
|
||||
void AnnotateRWLockAcquired(const char *file, int line,
|
||||
const volatile void *lock, long is_w);
|
||||
void AnnotateRWLockReleased(const char *file, int line,
|
||||
const volatile void *lock, long is_w);
|
||||
void AnnotateBarrierInit(const char *file, int line,
|
||||
const volatile void *barrier, long count,
|
||||
long reinitialization_allowed);
|
||||
void AnnotateBarrierWaitBefore(const char *file, int line,
|
||||
const volatile void *barrier);
|
||||
void AnnotateBarrierWaitAfter(const char *file, int line,
|
||||
const volatile void *barrier);
|
||||
void AnnotateBarrierDestroy(const char *file, int line,
|
||||
const volatile void *barrier);
|
||||
void AnnotateCondVarWait(const char *file, int line,
|
||||
const volatile void *cv,
|
||||
const volatile void *lock);
|
||||
void AnnotateCondVarSignal(const char *file, int line,
|
||||
const volatile void *cv);
|
||||
void AnnotateCondVarSignalAll(const char *file, int line,
|
||||
const volatile void *cv);
|
||||
void AnnotatePublishMemoryRange(const char *file, int line,
|
||||
const volatile void *address,
|
||||
long size);
|
||||
void AnnotateUnpublishMemoryRange(const char *file, int line,
|
||||
const volatile void *address,
|
||||
long size);
|
||||
void AnnotatePCQCreate(const char *file, int line,
|
||||
const volatile void *pcq);
|
||||
void AnnotatePCQDestroy(const char *file, int line,
|
||||
const volatile void *pcq);
|
||||
void AnnotatePCQPut(const char *file, int line,
|
||||
const volatile void *pcq);
|
||||
void AnnotatePCQGet(const char *file, int line,
|
||||
const volatile void *pcq);
|
||||
void AnnotateNewMemory(const char *file, int line,
|
||||
const volatile void *address,
|
||||
long size);
|
||||
void AnnotateExpectRace(const char *file, int line,
|
||||
const volatile void *address,
|
||||
const char *description);
|
||||
void AnnotateBenignRace(const char *file, int line,
|
||||
const volatile void *address,
|
||||
const char *description);
|
||||
void AnnotateBenignRaceSized(const char *file, int line,
|
||||
const volatile void *address,
|
||||
long size,
|
||||
const char *description);
|
||||
void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
|
||||
const volatile void *mu);
|
||||
void AnnotateTraceMemory(const char *file, int line,
|
||||
const volatile void *arg);
|
||||
void AnnotateThreadName(const char *file, int line,
|
||||
const char *name);
|
||||
void AnnotateIgnoreReadsBegin(const char *file, int line);
|
||||
void AnnotateIgnoreReadsEnd(const char *file, int line);
|
||||
void AnnotateIgnoreWritesBegin(const char *file, int line);
|
||||
void AnnotateIgnoreWritesEnd(const char *file, int line);
|
||||
void AnnotateEnableRaceDetection(const char *file, int line, int enable);
|
||||
void AnnotateNoOp(const char *file, int line,
|
||||
const volatile void *arg);
|
||||
void AnnotateFlushState(const char *file, int line);
|
||||
|
||||
/* Return non-zero value if running under valgrind.
|
||||
|
||||
If "valgrind.h" is included into dynamic_annotations.c,
|
||||
the regular valgrind mechanism will be used.
|
||||
See http://valgrind.org/docs/manual/manual-core-adv.html about
|
||||
RUNNING_ON_VALGRIND and other valgrind "client requests".
|
||||
The file "valgrind.h" may be obtained by doing
|
||||
svn co svn://svn.valgrind.org/valgrind/trunk/include
|
||||
|
||||
If for some reason you can't use "valgrind.h" or want to fake valgrind,
|
||||
there are two ways to make this function return non-zero:
|
||||
- Use environment variable: export RUNNING_ON_VALGRIND=1
|
||||
- Make your tool intercept the function RunningOnValgrind() and
|
||||
change its return value.
|
||||
*/
|
||||
int RunningOnValgrind(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
|
||||
|
||||
/* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
|
||||
|
||||
Instead of doing
|
||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();
|
||||
... = x;
|
||||
_Py_ANNOTATE_IGNORE_READS_END();
|
||||
one can use
|
||||
... = _Py_ANNOTATE_UNPROTECTED_READ(x); */
|
||||
template <class T>
|
||||
inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) {
|
||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();
|
||||
T res = x;
|
||||
_Py_ANNOTATE_IGNORE_READS_END();
|
||||
return res;
|
||||
}
|
||||
/* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
|
||||
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
|
||||
namespace { \
|
||||
class static_var ## _annotator { \
|
||||
public: \
|
||||
static_var ## _annotator() { \
|
||||
_Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \
|
||||
sizeof(static_var), \
|
||||
# static_var ": " description); \
|
||||
} \
|
||||
}; \
|
||||
static static_var ## _annotator the ## static_var ## _annotator;\
|
||||
}
|
||||
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
|
||||
|
||||
#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x)
|
||||
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */
|
||||
|
||||
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
|
||||
|
||||
#endif /* __DYNAMIC_ANNOTATIONS_H__ */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef Py_ENUMOBJECT_H
|
||||
#define Py_ENUMOBJECT_H
|
||||
|
||||
/* Enumerate Object */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyEnum_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyReversed_Type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !Py_ENUMOBJECT_H */
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef Py_ERRCODE_H
|
||||
#define Py_ERRCODE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Error codes passed around between file input, tokenizer, parser and
|
||||
interpreter. This is necessary so we can turn them into Python
|
||||
exceptions at a higher level. Note that some errors have a
|
||||
slightly different meaning when passed from the tokenizer to the
|
||||
parser than when passed from the parser to the interpreter; e.g.
|
||||
the parser only returns E_EOF when it hits EOF immediately, and it
|
||||
never returns E_OK. */
|
||||
|
||||
#define E_OK 10 /* No error */
|
||||
#define E_EOF 11 /* End Of File */
|
||||
#define E_INTR 12 /* Interrupted */
|
||||
#define E_TOKEN 13 /* Bad token */
|
||||
#define E_SYNTAX 14 /* Syntax error */
|
||||
#define E_NOMEM 15 /* Ran out of memory */
|
||||
#define E_DONE 16 /* Parsing complete */
|
||||
#define E_ERROR 17 /* Execution error */
|
||||
#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */
|
||||
#define E_OVERFLOW 19 /* Node had too many children */
|
||||
#define E_TOODEEP 20 /* Too many indentation levels */
|
||||
#define E_DEDENT 21 /* No matching outer block for dedent */
|
||||
#define E_DECODE 22 /* Error in decoding into Unicode */
|
||||
#define E_EOFS 23 /* EOF in triple-quoted string */
|
||||
#define E_EOLS 24 /* EOL in single-quoted string */
|
||||
#define E_LINECONT 25 /* Unexpected characters after a line continuation */
|
||||
#define E_BADSINGLE 27 /* Ill-formed single statement input */
|
||||
#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_ERRCODE_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
/* Interface to execute compiled code */
|
||||
|
||||
#ifndef Py_EVAL_H
|
||||
#define Py_EVAL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co,
|
||||
PyObject *globals,
|
||||
PyObject *locals,
|
||||
PyObject *const *args, int argc,
|
||||
PyObject *const *kwds, int kwdc,
|
||||
PyObject *const *defs, int defc,
|
||||
PyObject *kwdefs, PyObject *closure);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_EVAL_H */
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef Py_EXPORTS_H
|
||||
#define Py_EXPORTS_H
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define Py_IMPORTED_SYMBOL __declspec(dllimport)
|
||||
#define Py_EXPORTED_SYMBOL __declspec(dllexport)
|
||||
#define Py_LOCAL_SYMBOL
|
||||
#else
|
||||
/*
|
||||
* If we only ever used gcc >= 5, we could use __has_attribute(visibility)
|
||||
* as a cross-platform way to determine if visibility is supported. However,
|
||||
* we may still need to support gcc >= 4, as some Ubuntu LTS and Centos versions
|
||||
* have 4 < gcc < 5.
|
||||
*/
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 4)) ||\
|
||||
(defined(__clang__) && __has_attribute(visibility))
|
||||
#define Py_IMPORTED_SYMBOL __attribute__ ((visibility ("default")))
|
||||
#define Py_EXPORTED_SYMBOL __attribute__ ((visibility ("default")))
|
||||
#define Py_LOCAL_SYMBOL __attribute__ ((visibility ("hidden")))
|
||||
#else
|
||||
#define Py_IMPORTED_SYMBOL
|
||||
#define Py_EXPORTED_SYMBOL
|
||||
#define Py_LOCAL_SYMBOL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* Py_EXPORTS_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
/* File object interface (what's left of it -- see io.py) */
|
||||
|
||||
#ifndef Py_FILEOBJECT_H
|
||||
#define Py_FILEOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PY_STDIOTEXTMODE "b"
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int,
|
||||
const char *, const char *,
|
||||
const char *, int);
|
||||
PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
|
||||
PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
|
||||
PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
|
||||
PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
|
||||
|
||||
/* The default encoding used by the platform file system APIs
|
||||
If non-NULL, this is different than the default encoding for strings
|
||||
*/
|
||||
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
|
||||
PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
|
||||
#endif
|
||||
PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
|
||||
PyAPI_DATA(int) Py_UTF8Mode;
|
||||
#endif
|
||||
|
||||
/* A routine to check if a file descriptor can be select()-ed. */
|
||||
#ifdef _MSC_VER
|
||||
/* On Windows, any socket fd can be select()-ed, no matter how high */
|
||||
#define _PyIsSelectable_fd(FD) (1)
|
||||
#else
|
||||
#define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE)
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_FILEOBJECT_H
|
||||
# include "cpython/fileobject.h"
|
||||
# undef Py_CPYTHON_FILEOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FILEOBJECT_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef Py_FILEUTILS_H
|
||||
#define Py_FILEUTILS_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
||||
PyAPI_FUNC(wchar_t *) Py_DecodeLocale(
|
||||
const char *arg,
|
||||
size_t *size);
|
||||
|
||||
PyAPI_FUNC(char*) Py_EncodeLocale(
|
||||
const wchar_t *text,
|
||||
size_t *error_pos);
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_FILEUTILS_H
|
||||
# include "cpython/fileutils.h"
|
||||
# undef Py_CPYTHON_FILEUTILS_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FILEUTILS_H */
|
||||
@@ -0,0 +1,118 @@
|
||||
|
||||
/* Float object interface */
|
||||
|
||||
/*
|
||||
PyFloatObject represents a (double precision) floating point number.
|
||||
*/
|
||||
|
||||
#ifndef Py_FLOATOBJECT_H
|
||||
#define Py_FLOATOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
double ob_fval;
|
||||
} PyFloatObject;
|
||||
#endif
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyFloat_Type;
|
||||
|
||||
#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
|
||||
#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type)
|
||||
|
||||
#ifdef Py_NAN
|
||||
#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN)
|
||||
#endif
|
||||
|
||||
#define Py_RETURN_INF(sign) do \
|
||||
if (copysign(1., sign) == 1.) { \
|
||||
return PyFloat_FromDouble(Py_HUGE_VAL); \
|
||||
} else { \
|
||||
return PyFloat_FromDouble(-Py_HUGE_VAL); \
|
||||
} while(0)
|
||||
|
||||
PyAPI_FUNC(double) PyFloat_GetMax(void);
|
||||
PyAPI_FUNC(double) PyFloat_GetMin(void);
|
||||
PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void);
|
||||
|
||||
/* Return Python float from string PyObject. */
|
||||
PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*);
|
||||
|
||||
/* Return Python float from C double. */
|
||||
PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double);
|
||||
|
||||
/* Extract C double from Python float. The macro version trades safety for
|
||||
speed. */
|
||||
PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *);
|
||||
#ifndef Py_LIMITED_API
|
||||
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
|
||||
#endif
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
/* _PyFloat_{Pack,Unpack}{4,8}
|
||||
*
|
||||
* The struct and pickle (at least) modules need an efficient platform-
|
||||
* independent way to store floating-point values as byte strings.
|
||||
* The Pack routines produce a string from a C double, and the Unpack
|
||||
* routines produce a C double from such a string. The suffix (4 or 8)
|
||||
* specifies the number of bytes in the string.
|
||||
*
|
||||
* On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats
|
||||
* these functions work by copying bits. On other platforms, the formats the
|
||||
* 4- byte format is identical to the IEEE-754 single precision format, and
|
||||
* the 8-byte format to the IEEE-754 double precision format, although the
|
||||
* packing of INFs and NaNs (if such things exist on the platform) isn't
|
||||
* handled correctly, and attempting to unpack a string containing an IEEE
|
||||
* INF or NaN will raise an exception.
|
||||
*
|
||||
* On non-IEEE platforms with more precision, or larger dynamic range, than
|
||||
* 754 supports, not all values can be packed; on non-IEEE platforms with less
|
||||
* precision, or smaller dynamic range, not all values can be unpacked. What
|
||||
* happens in such cases is partly accidental (alas).
|
||||
*/
|
||||
|
||||
/* The pack routines write 2, 4 or 8 bytes, starting at p. le is a bool
|
||||
* argument, true if you want the string in little-endian format (exponent
|
||||
* last, at p+1, p+3 or p+7), false if you want big-endian format (exponent
|
||||
* first, at p).
|
||||
* Return value: 0 if all is OK, -1 if error (and an exception is
|
||||
* set, most likely OverflowError).
|
||||
* There are two problems on non-IEEE platforms:
|
||||
* 1): What this does is undefined if x is a NaN or infinity.
|
||||
* 2): -0.0 and +0.0 produce the same string.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyFloat_Pack2(double x, unsigned char *p, int le);
|
||||
PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le);
|
||||
PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
|
||||
|
||||
/* The unpack routines read 2, 4 or 8 bytes, starting at p. le is a bool
|
||||
* argument, true if the string is in little-endian format (exponent
|
||||
* last, at p+1, p+3 or p+7), false if big-endian (exponent first, at p).
|
||||
* Return value: The unpacked double. On error, this is -1.0 and
|
||||
* PyErr_Occurred() is true (and an exception is set, most likely
|
||||
* OverflowError). Note that on a non-IEEE platform this will refuse
|
||||
* to unpack a string that represents a NaN or infinity.
|
||||
*/
|
||||
PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le);
|
||||
PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le);
|
||||
PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
|
||||
|
||||
PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out);
|
||||
|
||||
/* Format the object based on the format_spec, as defined in PEP 3101
|
||||
(Advanced String Formatting). */
|
||||
PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter(
|
||||
_PyUnicodeWriter *writer,
|
||||
PyObject *obj,
|
||||
PyObject *format_spec,
|
||||
Py_ssize_t start,
|
||||
Py_ssize_t end);
|
||||
#endif /* Py_LIMITED_API */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FLOATOBJECT_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Frame object interface */
|
||||
|
||||
#ifndef Py_FRAMEOBJECT_H
|
||||
#define Py_FRAMEOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pyframe.h"
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_FRAMEOBJECT_H
|
||||
# include "cpython/frameobject.h"
|
||||
# undef Py_CPYTHON_FRAMEOBJECT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FRAMEOBJECT_H */
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
/* Function object interface */
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_FUNCOBJECT_H
|
||||
#define Py_FUNCOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define COMMON_FIELDS(PREFIX) \
|
||||
PyObject *PREFIX ## globals; \
|
||||
PyObject *PREFIX ## builtins; \
|
||||
PyObject *PREFIX ## name; \
|
||||
PyObject *PREFIX ## qualname; \
|
||||
PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \
|
||||
PyObject *PREFIX ## defaults; /* NULL or a tuple */ \
|
||||
PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \
|
||||
PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */
|
||||
|
||||
typedef struct {
|
||||
COMMON_FIELDS(fc_)
|
||||
} PyFrameConstructor;
|
||||
|
||||
/* Function objects and code objects should not be confused with each other:
|
||||
*
|
||||
* Function objects are created by the execution of the 'def' statement.
|
||||
* They reference a code object in their __code__ attribute, which is a
|
||||
* purely syntactic object, i.e. nothing more than a compiled version of some
|
||||
* source code lines. There is one code object per source code "fragment",
|
||||
* but each code object can be referenced by zero or many function objects
|
||||
* depending only on how many times the 'def' statement in the source was
|
||||
* executed so far.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
COMMON_FIELDS(func_)
|
||||
PyObject *func_doc; /* The __doc__ attribute, can be anything */
|
||||
PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */
|
||||
PyObject *func_weakreflist; /* List of weak references */
|
||||
PyObject *func_module; /* The __module__ attribute, can be anything */
|
||||
PyObject *func_annotations; /* Annotations, a dict or NULL */
|
||||
vectorcallfunc vectorcall;
|
||||
|
||||
/* Invariant:
|
||||
* func_closure contains the bindings for func_code->co_freevars, so
|
||||
* PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code)
|
||||
* (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0).
|
||||
*/
|
||||
} PyFunctionObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyFunction_Type;
|
||||
|
||||
#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *);
|
||||
PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *);
|
||||
PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *);
|
||||
PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *);
|
||||
PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall(
|
||||
PyObject *func,
|
||||
PyObject *const *stack,
|
||||
size_t nargsf,
|
||||
PyObject *kwnames);
|
||||
#endif
|
||||
|
||||
/* Macros for direct access to these values. Type checks are *not*
|
||||
done, so use with care. */
|
||||
#define PyFunction_GET_CODE(func) \
|
||||
(((PyFunctionObject *)func) -> func_code)
|
||||
#define PyFunction_GET_GLOBALS(func) \
|
||||
(((PyFunctionObject *)func) -> func_globals)
|
||||
#define PyFunction_GET_MODULE(func) \
|
||||
(((PyFunctionObject *)func) -> func_module)
|
||||
#define PyFunction_GET_DEFAULTS(func) \
|
||||
(((PyFunctionObject *)func) -> func_defaults)
|
||||
#define PyFunction_GET_KW_DEFAULTS(func) \
|
||||
(((PyFunctionObject *)func) -> func_kwdefaults)
|
||||
#define PyFunction_GET_CLOSURE(func) \
|
||||
(((PyFunctionObject *)func) -> func_closure)
|
||||
#define PyFunction_GET_ANNOTATIONS(func) \
|
||||
(((PyFunctionObject *)func) -> func_annotations)
|
||||
|
||||
#define PyFunction_AS_FRAME_CONSTRUCTOR(func) \
|
||||
((PyFrameConstructor *)&((PyFunctionObject *)(func))->func_globals)
|
||||
|
||||
/* The classmethod and staticmethod types lives here, too */
|
||||
PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FUNCOBJECT_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,14 @@
|
||||
// Implementation of PEP 585: support list[int] etc.
|
||||
#ifndef Py_GENERICALIASOBJECT_H
|
||||
#define Py_GENERICALIASOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) Py_GenericAlias(PyObject *, PyObject *);
|
||||
PyAPI_DATA(PyTypeObject) Py_GenericAliasType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_GENERICALIASOBJECT_H */
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
/* Generator object interface */
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_GENOBJECT_H
|
||||
#define Py_GENOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pystate.h" /* _PyErr_StackItem */
|
||||
#include "abstract.h" /* PySendResult */
|
||||
|
||||
/* _PyGenObject_HEAD defines the initial segment of generator
|
||||
and coroutine objects. */
|
||||
#define _PyGenObject_HEAD(prefix) \
|
||||
PyObject_HEAD \
|
||||
/* Note: gi_frame can be NULL if the generator is "finished" */ \
|
||||
PyFrameObject *prefix##_frame; \
|
||||
/* The code object backing the generator */ \
|
||||
PyObject *prefix##_code; \
|
||||
/* List of weak reference. */ \
|
||||
PyObject *prefix##_weakreflist; \
|
||||
/* Name of the generator. */ \
|
||||
PyObject *prefix##_name; \
|
||||
/* Qualified name of the generator. */ \
|
||||
PyObject *prefix##_qualname; \
|
||||
_PyErr_StackItem prefix##_exc_state;
|
||||
|
||||
typedef struct {
|
||||
/* The gi_ prefix is intended to remind of generator-iterator. */
|
||||
_PyGenObject_HEAD(gi)
|
||||
} PyGenObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
||||
|
||||
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
|
||||
#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *);
|
||||
PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *,
|
||||
PyObject *name, PyObject *qualname);
|
||||
PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
|
||||
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
|
||||
PyObject *_PyGen_yf(PyGenObject *);
|
||||
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef struct {
|
||||
_PyGenObject_HEAD(cr)
|
||||
PyObject *cr_origin;
|
||||
} PyCoroObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyCoro_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type;
|
||||
|
||||
#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type)
|
||||
PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
|
||||
PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *,
|
||||
PyObject *name, PyObject *qualname);
|
||||
|
||||
/* Asynchronous Generators */
|
||||
|
||||
typedef struct {
|
||||
_PyGenObject_HEAD(ag)
|
||||
PyObject *ag_finalizer;
|
||||
|
||||
/* Flag is set to 1 when hooks set up by sys.set_asyncgen_hooks
|
||||
were called on the generator, to avoid calling them more
|
||||
than once. */
|
||||
int ag_hooks_inited;
|
||||
|
||||
/* Flag is set to 1 when aclose() is called for the first time, or
|
||||
when a StopAsyncIteration exception is raised. */
|
||||
int ag_closed;
|
||||
|
||||
int ag_running_async;
|
||||
} PyAsyncGenObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type;
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *,
|
||||
PyObject *name, PyObject *qualname);
|
||||
|
||||
#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type)
|
||||
|
||||
PyObject *_PyAsyncGenValueWrapperNew(PyObject *);
|
||||
|
||||
#endif
|
||||
|
||||
#undef _PyGenObject_HEAD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_GENOBJECT_H */
|
||||
#endif /* Py_LIMITED_API */
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Module definition and import interface */
|
||||
|
||||
#ifndef Py_IMPORT_H
|
||||
#define Py_IMPORT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(long) PyImport_GetMagicNumber(void);
|
||||
PyAPI_FUNC(const char *) PyImport_GetMagicTag(void);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(
|
||||
const char *name, /* UTF-8 encoded string */
|
||||
PyObject *co
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
|
||||
const char *name, /* UTF-8 encoded string */
|
||||
PyObject *co,
|
||||
const char *pathname /* decoded from the filesystem encoding */
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames(
|
||||
const char *name, /* UTF-8 encoded string */
|
||||
PyObject *co,
|
||||
const char *pathname, /* decoded from the filesystem encoding */
|
||||
const char *cpathname /* decoded from the filesystem encoding */
|
||||
);
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject(
|
||||
PyObject *name,
|
||||
PyObject *co,
|
||||
PyObject *pathname,
|
||||
PyObject *cpathname
|
||||
);
|
||||
#endif
|
||||
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
|
||||
PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name);
|
||||
#endif
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
||||
PyAPI_FUNC(PyObject *) PyImport_AddModuleObject(
|
||||
PyObject *name
|
||||
);
|
||||
#endif
|
||||
PyAPI_FUNC(PyObject *) PyImport_AddModule(
|
||||
const char *name /* UTF-8 encoded string */
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ImportModule(
|
||||
const char *name /* UTF-8 encoded string */
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(
|
||||
const char *name /* UTF-8 encoded string */
|
||||
);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(
|
||||
const char *name, /* UTF-8 encoded string */
|
||||
PyObject *globals,
|
||||
PyObject *locals,
|
||||
PyObject *fromlist,
|
||||
int level
|
||||
);
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject(
|
||||
PyObject *name,
|
||||
PyObject *globals,
|
||||
PyObject *locals,
|
||||
PyObject *fromlist,
|
||||
int level
|
||||
);
|
||||
#endif
|
||||
|
||||
#define PyImport_ImportModuleEx(n, g, l, f) \
|
||||
PyImport_ImportModuleLevel(n, g, l, f, 0)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path);
|
||||
PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name);
|
||||
PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m);
|
||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
||||
PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject(
|
||||
PyObject *name
|
||||
);
|
||||
#endif
|
||||
PyAPI_FUNC(int) PyImport_ImportFrozenModule(
|
||||
const char *name /* UTF-8 encoded string */
|
||||
);
|
||||
|
||||
PyAPI_FUNC(int) PyImport_AppendInittab(
|
||||
const char *name, /* ASCII encoded string */
|
||||
PyObject* (*initfunc)(void)
|
||||
);
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
# define Py_CPYTHON_IMPORT_H
|
||||
# include "cpython/import.h"
|
||||
# undef Py_CPYTHON_IMPORT_H
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_IMPORT_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef Py_INTERNAL_ABSTRACT_H
|
||||
#define Py_INTERNAL_ABSTRACT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
// Fast inlined version of PyIndex_Check()
|
||||
static inline int
|
||||
_PyIndex_Check(PyObject *obj)
|
||||
{
|
||||
PyNumberMethods *tp_as_number = Py_TYPE(obj)->tp_as_number;
|
||||
return (tp_as_number != NULL && tp_as_number->nb_index != NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_ABSTRACT_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_INTERNAL_ACCU_H
|
||||
#define Py_INTERNAL_ACCU_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*** This is a private API for use by the interpreter and the stdlib.
|
||||
*** Its definition may be changed or removed at any moment.
|
||||
***/
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A two-level accumulator of unicode objects that avoids both the overhead
|
||||
* of keeping a huge number of small separate objects, and the quadratic
|
||||
* behaviour of using a naive repeated concatenation scheme.
|
||||
*/
|
||||
|
||||
#undef small /* defined by some Windows headers */
|
||||
|
||||
typedef struct {
|
||||
PyObject *large; /* A list of previously accumulated large strings */
|
||||
PyObject *small; /* Pending small strings */
|
||||
} _PyAccu;
|
||||
|
||||
PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc);
|
||||
PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode);
|
||||
PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc);
|
||||
PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc);
|
||||
PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_ACCU_H */
|
||||
#endif /* !Py_LIMITED_API */
|
||||
@@ -0,0 +1,112 @@
|
||||
#ifndef Py_INTERNAL_ASDL_H
|
||||
#define Py_INTERNAL_ASDL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_pyarena.h" // _PyArena_Malloc()
|
||||
|
||||
typedef PyObject * identifier;
|
||||
typedef PyObject * string;
|
||||
typedef PyObject * object;
|
||||
typedef PyObject * constant;
|
||||
|
||||
/* It would be nice if the code generated by asdl_c.py was completely
|
||||
independent of Python, but it is a goal the requires too much work
|
||||
at this stage. So, for example, I'll represent identifiers as
|
||||
interned Python strings.
|
||||
*/
|
||||
|
||||
#define _ASDL_SEQ_HEAD \
|
||||
Py_ssize_t size; \
|
||||
void **elements;
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
} asdl_seq;
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
void *typed_elements[1];
|
||||
} asdl_generic_seq;
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
PyObject *typed_elements[1];
|
||||
} asdl_identifier_seq;
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
int typed_elements[1];
|
||||
} asdl_int_seq;
|
||||
|
||||
asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
|
||||
#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \
|
||||
asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \
|
||||
{ \
|
||||
asdl_ ## NAME ## _seq *seq = NULL; \
|
||||
size_t n; \
|
||||
/* check size is sane */ \
|
||||
if (size < 0 || \
|
||||
(size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \
|
||||
PyErr_NoMemory(); \
|
||||
return NULL; \
|
||||
} \
|
||||
n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \
|
||||
/* check if size can be added safely */ \
|
||||
if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \
|
||||
PyErr_NoMemory(); \
|
||||
return NULL; \
|
||||
} \
|
||||
n += sizeof(asdl_ ## NAME ## _seq); \
|
||||
seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \
|
||||
if (!seq) { \
|
||||
PyErr_NoMemory(); \
|
||||
return NULL; \
|
||||
} \
|
||||
memset(seq, 0, n); \
|
||||
seq->size = size; \
|
||||
seq->elements = (void**)seq->typed_elements; \
|
||||
return seq; \
|
||||
}
|
||||
|
||||
#define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)]
|
||||
#define asdl_seq_GET(S, I) (S)->typed_elements[(I)]
|
||||
#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
# define asdl_seq_SET(S, I, V) \
|
||||
do { \
|
||||
Py_ssize_t _asdl_i = (I); \
|
||||
assert((S) != NULL); \
|
||||
assert(0 <= _asdl_i && _asdl_i < (S)->size); \
|
||||
(S)->typed_elements[_asdl_i] = (V); \
|
||||
} while (0)
|
||||
#else
|
||||
# define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V)
|
||||
#endif
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
# define asdl_seq_SET_UNTYPED(S, I, V) \
|
||||
do { \
|
||||
Py_ssize_t _asdl_i = (I); \
|
||||
assert((S) != NULL); \
|
||||
assert(0 <= _asdl_i && _asdl_i < (S)->size); \
|
||||
(S)->elements[_asdl_i] = (V); \
|
||||
} while (0)
|
||||
#else
|
||||
# define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_ASDL_H */
|
||||
@@ -0,0 +1,855 @@
|
||||
// File automatically generated by Parser/asdl_c.py.
|
||||
|
||||
#ifndef Py_INTERNAL_AST_H
|
||||
#define Py_INTERNAL_AST_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_asdl.h"
|
||||
|
||||
typedef struct _mod *mod_ty;
|
||||
|
||||
typedef struct _stmt *stmt_ty;
|
||||
|
||||
typedef struct _expr *expr_ty;
|
||||
|
||||
typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty;
|
||||
|
||||
typedef enum _boolop { And=1, Or=2 } boolop_ty;
|
||||
|
||||
typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7,
|
||||
LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12,
|
||||
FloorDiv=13 } operator_ty;
|
||||
|
||||
typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty;
|
||||
|
||||
typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8,
|
||||
In=9, NotIn=10 } cmpop_ty;
|
||||
|
||||
typedef struct _comprehension *comprehension_ty;
|
||||
|
||||
typedef struct _excepthandler *excepthandler_ty;
|
||||
|
||||
typedef struct _arguments *arguments_ty;
|
||||
|
||||
typedef struct _arg *arg_ty;
|
||||
|
||||
typedef struct _keyword *keyword_ty;
|
||||
|
||||
typedef struct _alias *alias_ty;
|
||||
|
||||
typedef struct _withitem *withitem_ty;
|
||||
|
||||
typedef struct _match_case *match_case_ty;
|
||||
|
||||
typedef struct _pattern *pattern_ty;
|
||||
|
||||
typedef struct _type_ignore *type_ignore_ty;
|
||||
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
mod_ty typed_elements[1];
|
||||
} asdl_mod_seq;
|
||||
|
||||
asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
stmt_ty typed_elements[1];
|
||||
} asdl_stmt_seq;
|
||||
|
||||
asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
expr_ty typed_elements[1];
|
||||
} asdl_expr_seq;
|
||||
|
||||
asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
comprehension_ty typed_elements[1];
|
||||
} asdl_comprehension_seq;
|
||||
|
||||
asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena
|
||||
*arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
excepthandler_ty typed_elements[1];
|
||||
} asdl_excepthandler_seq;
|
||||
|
||||
asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena
|
||||
*arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
arguments_ty typed_elements[1];
|
||||
} asdl_arguments_seq;
|
||||
|
||||
asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
arg_ty typed_elements[1];
|
||||
} asdl_arg_seq;
|
||||
|
||||
asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
keyword_ty typed_elements[1];
|
||||
} asdl_keyword_seq;
|
||||
|
||||
asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
alias_ty typed_elements[1];
|
||||
} asdl_alias_seq;
|
||||
|
||||
asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
withitem_ty typed_elements[1];
|
||||
} asdl_withitem_seq;
|
||||
|
||||
asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
match_case_ty typed_elements[1];
|
||||
} asdl_match_case_seq;
|
||||
|
||||
asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena
|
||||
*arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
pattern_ty typed_elements[1];
|
||||
} asdl_pattern_seq;
|
||||
|
||||
asdl_pattern_seq *_Py_asdl_pattern_seq_new(Py_ssize_t size, PyArena *arena);
|
||||
|
||||
typedef struct {
|
||||
_ASDL_SEQ_HEAD
|
||||
type_ignore_ty typed_elements[1];
|
||||
} asdl_type_ignore_seq;
|
||||
|
||||
asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena
|
||||
*arena);
|
||||
|
||||
|
||||
enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
|
||||
FunctionType_kind=4};
|
||||
struct _mod {
|
||||
enum _mod_kind kind;
|
||||
union {
|
||||
struct {
|
||||
asdl_stmt_seq *body;
|
||||
asdl_type_ignore_seq *type_ignores;
|
||||
} Module;
|
||||
|
||||
struct {
|
||||
asdl_stmt_seq *body;
|
||||
} Interactive;
|
||||
|
||||
struct {
|
||||
expr_ty body;
|
||||
} Expression;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *argtypes;
|
||||
expr_ty returns;
|
||||
} FunctionType;
|
||||
|
||||
} v;
|
||||
};
|
||||
|
||||
enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3,
|
||||
Return_kind=4, Delete_kind=5, Assign_kind=6,
|
||||
AugAssign_kind=7, AnnAssign_kind=8, For_kind=9,
|
||||
AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13,
|
||||
AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17,
|
||||
Assert_kind=18, Import_kind=19, ImportFrom_kind=20,
|
||||
Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24,
|
||||
Break_kind=25, Continue_kind=26};
|
||||
struct _stmt {
|
||||
enum _stmt_kind kind;
|
||||
union {
|
||||
struct {
|
||||
identifier name;
|
||||
arguments_ty args;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_expr_seq *decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
} FunctionDef;
|
||||
|
||||
struct {
|
||||
identifier name;
|
||||
arguments_ty args;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_expr_seq *decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
} AsyncFunctionDef;
|
||||
|
||||
struct {
|
||||
identifier name;
|
||||
asdl_expr_seq *bases;
|
||||
asdl_keyword_seq *keywords;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_expr_seq *decorator_list;
|
||||
} ClassDef;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
} Return;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *targets;
|
||||
} Delete;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *targets;
|
||||
expr_ty value;
|
||||
string type_comment;
|
||||
} Assign;
|
||||
|
||||
struct {
|
||||
expr_ty target;
|
||||
operator_ty op;
|
||||
expr_ty value;
|
||||
} AugAssign;
|
||||
|
||||
struct {
|
||||
expr_ty target;
|
||||
expr_ty annotation;
|
||||
expr_ty value;
|
||||
int simple;
|
||||
} AnnAssign;
|
||||
|
||||
struct {
|
||||
expr_ty target;
|
||||
expr_ty iter;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_stmt_seq *orelse;
|
||||
string type_comment;
|
||||
} For;
|
||||
|
||||
struct {
|
||||
expr_ty target;
|
||||
expr_ty iter;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_stmt_seq *orelse;
|
||||
string type_comment;
|
||||
} AsyncFor;
|
||||
|
||||
struct {
|
||||
expr_ty test;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_stmt_seq *orelse;
|
||||
} While;
|
||||
|
||||
struct {
|
||||
expr_ty test;
|
||||
asdl_stmt_seq *body;
|
||||
asdl_stmt_seq *orelse;
|
||||
} If;
|
||||
|
||||
struct {
|
||||
asdl_withitem_seq *items;
|
||||
asdl_stmt_seq *body;
|
||||
string type_comment;
|
||||
} With;
|
||||
|
||||
struct {
|
||||
asdl_withitem_seq *items;
|
||||
asdl_stmt_seq *body;
|
||||
string type_comment;
|
||||
} AsyncWith;
|
||||
|
||||
struct {
|
||||
expr_ty subject;
|
||||
asdl_match_case_seq *cases;
|
||||
} Match;
|
||||
|
||||
struct {
|
||||
expr_ty exc;
|
||||
expr_ty cause;
|
||||
} Raise;
|
||||
|
||||
struct {
|
||||
asdl_stmt_seq *body;
|
||||
asdl_excepthandler_seq *handlers;
|
||||
asdl_stmt_seq *orelse;
|
||||
asdl_stmt_seq *finalbody;
|
||||
} Try;
|
||||
|
||||
struct {
|
||||
expr_ty test;
|
||||
expr_ty msg;
|
||||
} Assert;
|
||||
|
||||
struct {
|
||||
asdl_alias_seq *names;
|
||||
} Import;
|
||||
|
||||
struct {
|
||||
identifier module;
|
||||
asdl_alias_seq *names;
|
||||
int level;
|
||||
} ImportFrom;
|
||||
|
||||
struct {
|
||||
asdl_identifier_seq *names;
|
||||
} Global;
|
||||
|
||||
struct {
|
||||
asdl_identifier_seq *names;
|
||||
} Nonlocal;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
} Expr;
|
||||
|
||||
} v;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4,
|
||||
Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8,
|
||||
ListComp_kind=9, SetComp_kind=10, DictComp_kind=11,
|
||||
GeneratorExp_kind=12, Await_kind=13, Yield_kind=14,
|
||||
YieldFrom_kind=15, Compare_kind=16, Call_kind=17,
|
||||
FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20,
|
||||
Attribute_kind=21, Subscript_kind=22, Starred_kind=23,
|
||||
Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27};
|
||||
struct _expr {
|
||||
enum _expr_kind kind;
|
||||
union {
|
||||
struct {
|
||||
boolop_ty op;
|
||||
asdl_expr_seq *values;
|
||||
} BoolOp;
|
||||
|
||||
struct {
|
||||
expr_ty target;
|
||||
expr_ty value;
|
||||
} NamedExpr;
|
||||
|
||||
struct {
|
||||
expr_ty left;
|
||||
operator_ty op;
|
||||
expr_ty right;
|
||||
} BinOp;
|
||||
|
||||
struct {
|
||||
unaryop_ty op;
|
||||
expr_ty operand;
|
||||
} UnaryOp;
|
||||
|
||||
struct {
|
||||
arguments_ty args;
|
||||
expr_ty body;
|
||||
} Lambda;
|
||||
|
||||
struct {
|
||||
expr_ty test;
|
||||
expr_ty body;
|
||||
expr_ty orelse;
|
||||
} IfExp;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *keys;
|
||||
asdl_expr_seq *values;
|
||||
} Dict;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *elts;
|
||||
} Set;
|
||||
|
||||
struct {
|
||||
expr_ty elt;
|
||||
asdl_comprehension_seq *generators;
|
||||
} ListComp;
|
||||
|
||||
struct {
|
||||
expr_ty elt;
|
||||
asdl_comprehension_seq *generators;
|
||||
} SetComp;
|
||||
|
||||
struct {
|
||||
expr_ty key;
|
||||
expr_ty value;
|
||||
asdl_comprehension_seq *generators;
|
||||
} DictComp;
|
||||
|
||||
struct {
|
||||
expr_ty elt;
|
||||
asdl_comprehension_seq *generators;
|
||||
} GeneratorExp;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
} Await;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
} Yield;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
} YieldFrom;
|
||||
|
||||
struct {
|
||||
expr_ty left;
|
||||
asdl_int_seq *ops;
|
||||
asdl_expr_seq *comparators;
|
||||
} Compare;
|
||||
|
||||
struct {
|
||||
expr_ty func;
|
||||
asdl_expr_seq *args;
|
||||
asdl_keyword_seq *keywords;
|
||||
} Call;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
int conversion;
|
||||
expr_ty format_spec;
|
||||
} FormattedValue;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *values;
|
||||
} JoinedStr;
|
||||
|
||||
struct {
|
||||
constant value;
|
||||
string kind;
|
||||
} Constant;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
identifier attr;
|
||||
expr_context_ty ctx;
|
||||
} Attribute;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
expr_ty slice;
|
||||
expr_context_ty ctx;
|
||||
} Subscript;
|
||||
|
||||
struct {
|
||||
expr_ty value;
|
||||
expr_context_ty ctx;
|
||||
} Starred;
|
||||
|
||||
struct {
|
||||
identifier id;
|
||||
expr_context_ty ctx;
|
||||
} Name;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *elts;
|
||||
expr_context_ty ctx;
|
||||
} List;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *elts;
|
||||
expr_context_ty ctx;
|
||||
} Tuple;
|
||||
|
||||
struct {
|
||||
expr_ty lower;
|
||||
expr_ty upper;
|
||||
expr_ty step;
|
||||
} Slice;
|
||||
|
||||
} v;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
struct _comprehension {
|
||||
expr_ty target;
|
||||
expr_ty iter;
|
||||
asdl_expr_seq *ifs;
|
||||
int is_async;
|
||||
};
|
||||
|
||||
enum _excepthandler_kind {ExceptHandler_kind=1};
|
||||
struct _excepthandler {
|
||||
enum _excepthandler_kind kind;
|
||||
union {
|
||||
struct {
|
||||
expr_ty type;
|
||||
identifier name;
|
||||
asdl_stmt_seq *body;
|
||||
} ExceptHandler;
|
||||
|
||||
} v;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
struct _arguments {
|
||||
asdl_arg_seq *posonlyargs;
|
||||
asdl_arg_seq *args;
|
||||
arg_ty vararg;
|
||||
asdl_arg_seq *kwonlyargs;
|
||||
asdl_expr_seq *kw_defaults;
|
||||
arg_ty kwarg;
|
||||
asdl_expr_seq *defaults;
|
||||
};
|
||||
|
||||
struct _arg {
|
||||
identifier arg;
|
||||
expr_ty annotation;
|
||||
string type_comment;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
struct _keyword {
|
||||
identifier arg;
|
||||
expr_ty value;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
struct _alias {
|
||||
identifier name;
|
||||
identifier asname;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
struct _withitem {
|
||||
expr_ty context_expr;
|
||||
expr_ty optional_vars;
|
||||
};
|
||||
|
||||
struct _match_case {
|
||||
pattern_ty pattern;
|
||||
expr_ty guard;
|
||||
asdl_stmt_seq *body;
|
||||
};
|
||||
|
||||
enum _pattern_kind {MatchValue_kind=1, MatchSingleton_kind=2,
|
||||
MatchSequence_kind=3, MatchMapping_kind=4,
|
||||
MatchClass_kind=5, MatchStar_kind=6, MatchAs_kind=7,
|
||||
MatchOr_kind=8};
|
||||
struct _pattern {
|
||||
enum _pattern_kind kind;
|
||||
union {
|
||||
struct {
|
||||
expr_ty value;
|
||||
} MatchValue;
|
||||
|
||||
struct {
|
||||
constant value;
|
||||
} MatchSingleton;
|
||||
|
||||
struct {
|
||||
asdl_pattern_seq *patterns;
|
||||
} MatchSequence;
|
||||
|
||||
struct {
|
||||
asdl_expr_seq *keys;
|
||||
asdl_pattern_seq *patterns;
|
||||
identifier rest;
|
||||
} MatchMapping;
|
||||
|
||||
struct {
|
||||
expr_ty cls;
|
||||
asdl_pattern_seq *patterns;
|
||||
asdl_identifier_seq *kwd_attrs;
|
||||
asdl_pattern_seq *kwd_patterns;
|
||||
} MatchClass;
|
||||
|
||||
struct {
|
||||
identifier name;
|
||||
} MatchStar;
|
||||
|
||||
struct {
|
||||
pattern_ty pattern;
|
||||
identifier name;
|
||||
} MatchAs;
|
||||
|
||||
struct {
|
||||
asdl_pattern_seq *patterns;
|
||||
} MatchOr;
|
||||
|
||||
} v;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
int end_col_offset;
|
||||
};
|
||||
|
||||
enum _type_ignore_kind {TypeIgnore_kind=1};
|
||||
struct _type_ignore {
|
||||
enum _type_ignore_kind kind;
|
||||
union {
|
||||
struct {
|
||||
int lineno;
|
||||
string tag;
|
||||
} TypeIgnore;
|
||||
|
||||
} v;
|
||||
};
|
||||
|
||||
|
||||
// Note: these macros affect function definitions, not only call sites.
|
||||
mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores,
|
||||
PyArena *arena);
|
||||
mod_ty _PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena);
|
||||
mod_ty _PyAST_Expression(expr_ty body, PyArena *arena);
|
||||
mod_ty _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena
|
||||
*arena);
|
||||
stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
|
||||
body, asdl_expr_seq * decorator_list, expr_ty
|
||||
returns, string type_comment, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args,
|
||||
asdl_stmt_seq * body, asdl_expr_seq *
|
||||
decorator_list, expr_ty returns, string
|
||||
type_comment, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases,
|
||||
asdl_keyword_seq * keywords, asdl_stmt_seq * body,
|
||||
asdl_expr_seq * decorator_list, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string
|
||||
type_comment, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int
|
||||
simple, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body,
|
||||
asdl_stmt_seq * orelse, string type_comment, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
stmt_ty _PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body,
|
||||
asdl_stmt_seq * orelse, string type_comment, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq *
|
||||
orelse, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse,
|
||||
int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string
|
||||
type_comment, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body,
|
||||
string type_comment, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
stmt_ty _PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
|
||||
asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level,
|
||||
int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
stmt_ty _PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Pass(int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Break(int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
stmt_ty _PyAST_Continue(int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
expr_ty _PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
expr_ty _PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
expr_ty _PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq *
|
||||
generators, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators,
|
||||
int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq *
|
||||
comparators, int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq *
|
||||
keywords, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty
|
||||
format_spec, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Constant(constant value, string kind, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx,
|
||||
int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
expr_ty _PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
expr_ty _PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
comprehension_ty _PyAST_comprehension(expr_ty target, expr_ty iter,
|
||||
asdl_expr_seq * ifs, int is_async,
|
||||
PyArena *arena);
|
||||
excepthandler_ty _PyAST_ExceptHandler(expr_ty type, identifier name,
|
||||
asdl_stmt_seq * body, int lineno, int
|
||||
col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
arguments_ty _PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args,
|
||||
arg_ty vararg, asdl_arg_seq * kwonlyargs,
|
||||
asdl_expr_seq * kw_defaults, arg_ty kwarg,
|
||||
asdl_expr_seq * defaults, PyArena *arena);
|
||||
arg_ty _PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
keyword_ty _PyAST_keyword(identifier arg, expr_ty value, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
alias_ty _PyAST_alias(identifier name, identifier asname, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
withitem_ty _PyAST_withitem(expr_ty context_expr, expr_ty optional_vars,
|
||||
PyArena *arena);
|
||||
match_case_ty _PyAST_match_case(pattern_ty pattern, expr_ty guard,
|
||||
asdl_stmt_seq * body, PyArena *arena);
|
||||
pattern_ty _PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
pattern_ty _PyAST_MatchSingleton(constant value, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
pattern_ty _PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
pattern_ty _PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq *
|
||||
patterns, identifier rest, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
pattern_ty _PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns,
|
||||
asdl_identifier_seq * kwd_attrs, asdl_pattern_seq
|
||||
* kwd_patterns, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
pattern_ty _PyAST_MatchStar(identifier name, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
pattern_ty _PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena);
|
||||
|
||||
|
||||
PyObject* PyAST_mod2obj(mod_ty t);
|
||||
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);
|
||||
int PyAST_Check(PyObject* obj);
|
||||
|
||||
extern int _PyAST_Validate(mod_ty);
|
||||
|
||||
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
|
||||
extern PyObject* _PyAST_ExprAsUnicode(expr_ty);
|
||||
|
||||
/* Return the borrowed reference to the first literal string in the
|
||||
sequence of statements or NULL if it doesn't start from a literal string.
|
||||
Doesn't set exception. */
|
||||
extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_AST_H */
|
||||
@@ -0,0 +1,255 @@
|
||||
// File automatically generated by Parser/asdl_c.py.
|
||||
|
||||
#ifndef Py_INTERNAL_AST_STATE_H
|
||||
#define Py_INTERNAL_AST_STATE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
struct ast_state {
|
||||
int initialized;
|
||||
PyObject *AST_type;
|
||||
PyObject *Add_singleton;
|
||||
PyObject *Add_type;
|
||||
PyObject *And_singleton;
|
||||
PyObject *And_type;
|
||||
PyObject *AnnAssign_type;
|
||||
PyObject *Assert_type;
|
||||
PyObject *Assign_type;
|
||||
PyObject *AsyncFor_type;
|
||||
PyObject *AsyncFunctionDef_type;
|
||||
PyObject *AsyncWith_type;
|
||||
PyObject *Attribute_type;
|
||||
PyObject *AugAssign_type;
|
||||
PyObject *Await_type;
|
||||
PyObject *BinOp_type;
|
||||
PyObject *BitAnd_singleton;
|
||||
PyObject *BitAnd_type;
|
||||
PyObject *BitOr_singleton;
|
||||
PyObject *BitOr_type;
|
||||
PyObject *BitXor_singleton;
|
||||
PyObject *BitXor_type;
|
||||
PyObject *BoolOp_type;
|
||||
PyObject *Break_type;
|
||||
PyObject *Call_type;
|
||||
PyObject *ClassDef_type;
|
||||
PyObject *Compare_type;
|
||||
PyObject *Constant_type;
|
||||
PyObject *Continue_type;
|
||||
PyObject *Del_singleton;
|
||||
PyObject *Del_type;
|
||||
PyObject *Delete_type;
|
||||
PyObject *DictComp_type;
|
||||
PyObject *Dict_type;
|
||||
PyObject *Div_singleton;
|
||||
PyObject *Div_type;
|
||||
PyObject *Eq_singleton;
|
||||
PyObject *Eq_type;
|
||||
PyObject *ExceptHandler_type;
|
||||
PyObject *Expr_type;
|
||||
PyObject *Expression_type;
|
||||
PyObject *FloorDiv_singleton;
|
||||
PyObject *FloorDiv_type;
|
||||
PyObject *For_type;
|
||||
PyObject *FormattedValue_type;
|
||||
PyObject *FunctionDef_type;
|
||||
PyObject *FunctionType_type;
|
||||
PyObject *GeneratorExp_type;
|
||||
PyObject *Global_type;
|
||||
PyObject *GtE_singleton;
|
||||
PyObject *GtE_type;
|
||||
PyObject *Gt_singleton;
|
||||
PyObject *Gt_type;
|
||||
PyObject *IfExp_type;
|
||||
PyObject *If_type;
|
||||
PyObject *ImportFrom_type;
|
||||
PyObject *Import_type;
|
||||
PyObject *In_singleton;
|
||||
PyObject *In_type;
|
||||
PyObject *Interactive_type;
|
||||
PyObject *Invert_singleton;
|
||||
PyObject *Invert_type;
|
||||
PyObject *IsNot_singleton;
|
||||
PyObject *IsNot_type;
|
||||
PyObject *Is_singleton;
|
||||
PyObject *Is_type;
|
||||
PyObject *JoinedStr_type;
|
||||
PyObject *LShift_singleton;
|
||||
PyObject *LShift_type;
|
||||
PyObject *Lambda_type;
|
||||
PyObject *ListComp_type;
|
||||
PyObject *List_type;
|
||||
PyObject *Load_singleton;
|
||||
PyObject *Load_type;
|
||||
PyObject *LtE_singleton;
|
||||
PyObject *LtE_type;
|
||||
PyObject *Lt_singleton;
|
||||
PyObject *Lt_type;
|
||||
PyObject *MatMult_singleton;
|
||||
PyObject *MatMult_type;
|
||||
PyObject *MatchAs_type;
|
||||
PyObject *MatchClass_type;
|
||||
PyObject *MatchMapping_type;
|
||||
PyObject *MatchOr_type;
|
||||
PyObject *MatchSequence_type;
|
||||
PyObject *MatchSingleton_type;
|
||||
PyObject *MatchStar_type;
|
||||
PyObject *MatchValue_type;
|
||||
PyObject *Match_type;
|
||||
PyObject *Mod_singleton;
|
||||
PyObject *Mod_type;
|
||||
PyObject *Module_type;
|
||||
PyObject *Mult_singleton;
|
||||
PyObject *Mult_type;
|
||||
PyObject *Name_type;
|
||||
PyObject *NamedExpr_type;
|
||||
PyObject *Nonlocal_type;
|
||||
PyObject *NotEq_singleton;
|
||||
PyObject *NotEq_type;
|
||||
PyObject *NotIn_singleton;
|
||||
PyObject *NotIn_type;
|
||||
PyObject *Not_singleton;
|
||||
PyObject *Not_type;
|
||||
PyObject *Or_singleton;
|
||||
PyObject *Or_type;
|
||||
PyObject *Pass_type;
|
||||
PyObject *Pow_singleton;
|
||||
PyObject *Pow_type;
|
||||
PyObject *RShift_singleton;
|
||||
PyObject *RShift_type;
|
||||
PyObject *Raise_type;
|
||||
PyObject *Return_type;
|
||||
PyObject *SetComp_type;
|
||||
PyObject *Set_type;
|
||||
PyObject *Slice_type;
|
||||
PyObject *Starred_type;
|
||||
PyObject *Store_singleton;
|
||||
PyObject *Store_type;
|
||||
PyObject *Sub_singleton;
|
||||
PyObject *Sub_type;
|
||||
PyObject *Subscript_type;
|
||||
PyObject *Try_type;
|
||||
PyObject *Tuple_type;
|
||||
PyObject *TypeIgnore_type;
|
||||
PyObject *UAdd_singleton;
|
||||
PyObject *UAdd_type;
|
||||
PyObject *USub_singleton;
|
||||
PyObject *USub_type;
|
||||
PyObject *UnaryOp_type;
|
||||
PyObject *While_type;
|
||||
PyObject *With_type;
|
||||
PyObject *YieldFrom_type;
|
||||
PyObject *Yield_type;
|
||||
PyObject *__dict__;
|
||||
PyObject *__doc__;
|
||||
PyObject *__match_args__;
|
||||
PyObject *__module__;
|
||||
PyObject *_attributes;
|
||||
PyObject *_fields;
|
||||
PyObject *alias_type;
|
||||
PyObject *annotation;
|
||||
PyObject *arg;
|
||||
PyObject *arg_type;
|
||||
PyObject *args;
|
||||
PyObject *argtypes;
|
||||
PyObject *arguments_type;
|
||||
PyObject *asname;
|
||||
PyObject *ast;
|
||||
PyObject *attr;
|
||||
PyObject *bases;
|
||||
PyObject *body;
|
||||
PyObject *boolop_type;
|
||||
PyObject *cases;
|
||||
PyObject *cause;
|
||||
PyObject *cls;
|
||||
PyObject *cmpop_type;
|
||||
PyObject *col_offset;
|
||||
PyObject *comparators;
|
||||
PyObject *comprehension_type;
|
||||
PyObject *context_expr;
|
||||
PyObject *conversion;
|
||||
PyObject *ctx;
|
||||
PyObject *decorator_list;
|
||||
PyObject *defaults;
|
||||
PyObject *elt;
|
||||
PyObject *elts;
|
||||
PyObject *end_col_offset;
|
||||
PyObject *end_lineno;
|
||||
PyObject *exc;
|
||||
PyObject *excepthandler_type;
|
||||
PyObject *expr_context_type;
|
||||
PyObject *expr_type;
|
||||
PyObject *finalbody;
|
||||
PyObject *format_spec;
|
||||
PyObject *func;
|
||||
PyObject *generators;
|
||||
PyObject *guard;
|
||||
PyObject *handlers;
|
||||
PyObject *id;
|
||||
PyObject *ifs;
|
||||
PyObject *is_async;
|
||||
PyObject *items;
|
||||
PyObject *iter;
|
||||
PyObject *key;
|
||||
PyObject *keys;
|
||||
PyObject *keyword_type;
|
||||
PyObject *keywords;
|
||||
PyObject *kind;
|
||||
PyObject *kw_defaults;
|
||||
PyObject *kwarg;
|
||||
PyObject *kwd_attrs;
|
||||
PyObject *kwd_patterns;
|
||||
PyObject *kwonlyargs;
|
||||
PyObject *left;
|
||||
PyObject *level;
|
||||
PyObject *lineno;
|
||||
PyObject *lower;
|
||||
PyObject *match_case_type;
|
||||
PyObject *mod_type;
|
||||
PyObject *module;
|
||||
PyObject *msg;
|
||||
PyObject *name;
|
||||
PyObject *names;
|
||||
PyObject *op;
|
||||
PyObject *operand;
|
||||
PyObject *operator_type;
|
||||
PyObject *ops;
|
||||
PyObject *optional_vars;
|
||||
PyObject *orelse;
|
||||
PyObject *pattern;
|
||||
PyObject *pattern_type;
|
||||
PyObject *patterns;
|
||||
PyObject *posonlyargs;
|
||||
PyObject *rest;
|
||||
PyObject *returns;
|
||||
PyObject *right;
|
||||
PyObject *simple;
|
||||
PyObject *slice;
|
||||
PyObject *step;
|
||||
PyObject *stmt_type;
|
||||
PyObject *subject;
|
||||
PyObject *tag;
|
||||
PyObject *target;
|
||||
PyObject *targets;
|
||||
PyObject *test;
|
||||
PyObject *type;
|
||||
PyObject *type_comment;
|
||||
PyObject *type_ignore_type;
|
||||
PyObject *type_ignores;
|
||||
PyObject *unaryop_type;
|
||||
PyObject *upper;
|
||||
PyObject *value;
|
||||
PyObject *values;
|
||||
PyObject *vararg;
|
||||
PyObject *withitem_type;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_AST_STATE_H */
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
#ifndef Py_ATOMIC_H
|
||||
#define Py_ATOMIC_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */
|
||||
#include "pyconfig.h"
|
||||
|
||||
#ifdef HAVE_STD_ATOMIC
|
||||
# include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#if defined(_M_IX86) || defined(_M_X64)
|
||||
# include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is modeled after the atomics interface from C1x, according to
|
||||
* the draft at
|
||||
* http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf.
|
||||
* Operations and types are named the same except with a _Py_ prefix
|
||||
* and have the same semantics.
|
||||
*
|
||||
* Beware, the implementations here are deep magic.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_STD_ATOMIC)
|
||||
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed = memory_order_relaxed,
|
||||
_Py_memory_order_acquire = memory_order_acquire,
|
||||
_Py_memory_order_release = memory_order_release,
|
||||
_Py_memory_order_acq_rel = memory_order_acq_rel,
|
||||
_Py_memory_order_seq_cst = memory_order_seq_cst
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
atomic_uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
atomic_int _value;
|
||||
} _Py_atomic_int;
|
||||
|
||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
|
||||
atomic_signal_fence(ORDER)
|
||||
|
||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
|
||||
atomic_thread_fence(ORDER)
|
||||
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)
|
||||
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER)
|
||||
|
||||
// Use builtin atomic operations in GCC >= 4.7 and clang
|
||||
#elif defined(HAVE_BUILTIN_ATOMIC)
|
||||
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
_Py_memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||
_Py_memory_order_release = __ATOMIC_RELEASE,
|
||||
_Py_memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||
_Py_memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
int _value;
|
||||
} _Py_atomic_int;
|
||||
|
||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
|
||||
__atomic_signal_fence(ORDER)
|
||||
|
||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
|
||||
__atomic_thread_fence(ORDER)
|
||||
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
(assert((ORDER) == __ATOMIC_RELAXED \
|
||||
|| (ORDER) == __ATOMIC_SEQ_CST \
|
||||
|| (ORDER) == __ATOMIC_RELEASE), \
|
||||
__atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER))
|
||||
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
(assert((ORDER) == __ATOMIC_RELAXED \
|
||||
|| (ORDER) == __ATOMIC_SEQ_CST \
|
||||
|| (ORDER) == __ATOMIC_ACQUIRE \
|
||||
|| (ORDER) == __ATOMIC_CONSUME), \
|
||||
__atomic_load_n(&((ATOMIC_VAL)->_value), ORDER))
|
||||
|
||||
/* Only support GCC (for expression statements) and x86 (for simple
|
||||
* atomic semantics) and MSVC x86/x64/ARM */
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64))
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed,
|
||||
_Py_memory_order_acquire,
|
||||
_Py_memory_order_release,
|
||||
_Py_memory_order_acq_rel,
|
||||
_Py_memory_order_seq_cst
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
int _value;
|
||||
} _Py_atomic_int;
|
||||
|
||||
|
||||
static __inline__ void
|
||||
_Py_atomic_signal_fence(_Py_memory_order order)
|
||||
{
|
||||
if (order != _Py_memory_order_relaxed)
|
||||
__asm__ volatile("":::"memory");
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
_Py_atomic_thread_fence(_Py_memory_order order)
|
||||
{
|
||||
if (order != _Py_memory_order_relaxed)
|
||||
__asm__ volatile("mfence":::"memory");
|
||||
}
|
||||
|
||||
/* Tell the race checker about this operation's effects. */
|
||||
static __inline__ void
|
||||
_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order)
|
||||
{
|
||||
(void)address; /* shut up -Wunused-parameter */
|
||||
switch(order) {
|
||||
case _Py_memory_order_release:
|
||||
case _Py_memory_order_acq_rel:
|
||||
case _Py_memory_order_seq_cst:
|
||||
_Py_ANNOTATE_HAPPENS_BEFORE(address);
|
||||
break;
|
||||
case _Py_memory_order_relaxed:
|
||||
case _Py_memory_order_acquire:
|
||||
break;
|
||||
}
|
||||
switch(order) {
|
||||
case _Py_memory_order_acquire:
|
||||
case _Py_memory_order_acq_rel:
|
||||
case _Py_memory_order_seq_cst:
|
||||
_Py_ANNOTATE_HAPPENS_AFTER(address);
|
||||
break;
|
||||
case _Py_memory_order_relaxed:
|
||||
case _Py_memory_order_release:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
__extension__ ({ \
|
||||
__typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
|
||||
__typeof__(atomic_val->_value) new_val = NEW_VAL;\
|
||||
volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \
|
||||
_Py_memory_order order = ORDER; \
|
||||
_Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
|
||||
\
|
||||
/* Perform the operation. */ \
|
||||
_Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \
|
||||
switch(order) { \
|
||||
case _Py_memory_order_release: \
|
||||
_Py_atomic_signal_fence(_Py_memory_order_release); \
|
||||
/* fallthrough */ \
|
||||
case _Py_memory_order_relaxed: \
|
||||
*volatile_data = new_val; \
|
||||
break; \
|
||||
\
|
||||
case _Py_memory_order_acquire: \
|
||||
case _Py_memory_order_acq_rel: \
|
||||
case _Py_memory_order_seq_cst: \
|
||||
__asm__ volatile("xchg %0, %1" \
|
||||
: "+r"(new_val) \
|
||||
: "m"(atomic_val->_value) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
} \
|
||||
_Py_ANNOTATE_IGNORE_WRITES_END(); \
|
||||
})
|
||||
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
__extension__ ({ \
|
||||
__typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
|
||||
__typeof__(atomic_val->_value) result; \
|
||||
volatile __typeof__(result) *volatile_data = &atomic_val->_value; \
|
||||
_Py_memory_order order = ORDER; \
|
||||
_Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
|
||||
\
|
||||
/* Perform the operation. */ \
|
||||
_Py_ANNOTATE_IGNORE_READS_BEGIN(); \
|
||||
switch(order) { \
|
||||
case _Py_memory_order_release: \
|
||||
case _Py_memory_order_acq_rel: \
|
||||
case _Py_memory_order_seq_cst: \
|
||||
/* Loads on x86 are not releases by default, so need a */ \
|
||||
/* thread fence. */ \
|
||||
_Py_atomic_thread_fence(_Py_memory_order_release); \
|
||||
break; \
|
||||
default: \
|
||||
/* No fence */ \
|
||||
break; \
|
||||
} \
|
||||
result = *volatile_data; \
|
||||
switch(order) { \
|
||||
case _Py_memory_order_acquire: \
|
||||
case _Py_memory_order_acq_rel: \
|
||||
case _Py_memory_order_seq_cst: \
|
||||
/* Loads on x86 are automatically acquire operations so */ \
|
||||
/* can get by with just a compiler fence. */ \
|
||||
_Py_atomic_signal_fence(_Py_memory_order_acquire); \
|
||||
break; \
|
||||
default: \
|
||||
/* No fence */ \
|
||||
break; \
|
||||
} \
|
||||
_Py_ANNOTATE_IGNORE_READS_END(); \
|
||||
result; \
|
||||
})
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
/* _Interlocked* functions provide a full memory barrier and are therefore
|
||||
enough for acq_rel and seq_cst. If the HLE variants aren't available
|
||||
in hardware they will fall back to a full memory barrier as well.
|
||||
|
||||
This might affect performance but likely only in some very specific and
|
||||
hard to measure scenario.
|
||||
*/
|
||||
#if defined(_M_IX86) || defined(_M_X64)
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed,
|
||||
_Py_memory_order_acquire,
|
||||
_Py_memory_order_release,
|
||||
_Py_memory_order_acq_rel,
|
||||
_Py_memory_order_seq_cst
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
volatile uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
volatile int _value;
|
||||
} _Py_atomic_int;
|
||||
|
||||
|
||||
#if defined(_M_X64)
|
||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
switch (ORDER) { \
|
||||
case _Py_memory_order_acquire: \
|
||||
_InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
||||
break; \
|
||||
case _Py_memory_order_release: \
|
||||
_InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
||||
break; \
|
||||
default: \
|
||||
_InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
||||
break; \
|
||||
}
|
||||
#else
|
||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
|
||||
#endif
|
||||
|
||||
#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
switch (ORDER) { \
|
||||
case _Py_memory_order_acquire: \
|
||||
_InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
||||
break; \
|
||||
case _Py_memory_order_release: \
|
||||
_InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
||||
break; \
|
||||
default: \
|
||||
_InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#if defined(_M_X64)
|
||||
/* This has to be an intptr_t for now.
|
||||
gil_created() uses -1 as a sentinel value, if this returns
|
||||
a uintptr_t it will do an unsigned compare and crash
|
||||
*/
|
||||
inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
|
||||
__int64 old;
|
||||
switch (order) {
|
||||
case _Py_memory_order_acquire:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_release:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_relaxed:
|
||||
old = *value;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
|
||||
_Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
|
||||
|
||||
#else
|
||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
|
||||
#endif
|
||||
|
||||
inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
|
||||
long old;
|
||||
switch (order) {
|
||||
case _Py_memory_order_acquire:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_release:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_relaxed:
|
||||
old = *value;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange((volatile long*)value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
|
||||
_Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
|
||||
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
if (sizeof((ATOMIC_VAL)->_value) == 8) { \
|
||||
_Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \
|
||||
_Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) }
|
||||
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
( \
|
||||
sizeof((ATOMIC_VAL)->_value) == 8 ? \
|
||||
_Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \
|
||||
_Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \
|
||||
)
|
||||
#elif defined(_M_ARM) || defined(_M_ARM64)
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed,
|
||||
_Py_memory_order_acquire,
|
||||
_Py_memory_order_release,
|
||||
_Py_memory_order_acq_rel,
|
||||
_Py_memory_order_seq_cst
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
volatile uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
volatile int _value;
|
||||
} _Py_atomic_int;
|
||||
|
||||
|
||||
#if defined(_M_ARM64)
|
||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
switch (ORDER) { \
|
||||
case _Py_memory_order_acquire: \
|
||||
_InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
||||
break; \
|
||||
case _Py_memory_order_release: \
|
||||
_InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
||||
break; \
|
||||
default: \
|
||||
_InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
||||
break; \
|
||||
}
|
||||
#else
|
||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
|
||||
#endif
|
||||
|
||||
#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
switch (ORDER) { \
|
||||
case _Py_memory_order_acquire: \
|
||||
_InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
||||
break; \
|
||||
case _Py_memory_order_release: \
|
||||
_InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
||||
break; \
|
||||
default: \
|
||||
_InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#if defined(_M_ARM64)
|
||||
/* This has to be an intptr_t for now.
|
||||
gil_created() uses -1 as a sentinel value, if this returns
|
||||
a uintptr_t it will do an unsigned compare and crash
|
||||
*/
|
||||
inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
|
||||
uintptr_t old;
|
||||
switch (order) {
|
||||
case _Py_memory_order_acquire:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64_acq(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_release:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64_rel(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_relaxed:
|
||||
old = *value;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange64(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
|
||||
_Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
|
||||
|
||||
#else
|
||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
|
||||
#endif
|
||||
|
||||
inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
|
||||
int old;
|
||||
switch (order) {
|
||||
case _Py_memory_order_acquire:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange_acq(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_release:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange_rel(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
case _Py_memory_order_relaxed:
|
||||
old = *value;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
do {
|
||||
old = *value;
|
||||
} while(_InterlockedCompareExchange(value, old, old) != old);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
|
||||
_Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
|
||||
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
if (sizeof((ATOMIC_VAL)->_value) == 8) { \
|
||||
_Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \
|
||||
_Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) }
|
||||
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
( \
|
||||
sizeof((ATOMIC_VAL)->_value) == 8 ? \
|
||||
_Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \
|
||||
_Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \
|
||||
)
|
||||
#endif
|
||||
#else /* !gcc x86 !_msc_ver */
|
||||
typedef enum _Py_memory_order {
|
||||
_Py_memory_order_relaxed,
|
||||
_Py_memory_order_acquire,
|
||||
_Py_memory_order_release,
|
||||
_Py_memory_order_acq_rel,
|
||||
_Py_memory_order_seq_cst
|
||||
} _Py_memory_order;
|
||||
|
||||
typedef struct _Py_atomic_address {
|
||||
uintptr_t _value;
|
||||
} _Py_atomic_address;
|
||||
|
||||
typedef struct _Py_atomic_int {
|
||||
int _value;
|
||||
} _Py_atomic_int;
|
||||
/* Fall back to other compilers and processors by assuming that simple
|
||||
volatile accesses are atomic. This is false, so people should port
|
||||
this. */
|
||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0)
|
||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0)
|
||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
||||
((ATOMIC_VAL)->_value = NEW_VAL)
|
||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
||||
((ATOMIC_VAL)->_value)
|
||||
#endif
|
||||
|
||||
/* Standardized shortcuts. */
|
||||
#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \
|
||||
_Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst)
|
||||
#define _Py_atomic_load(ATOMIC_VAL) \
|
||||
_Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst)
|
||||
|
||||
/* Python-local extensions */
|
||||
|
||||
#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \
|
||||
_Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed)
|
||||
#define _Py_atomic_load_relaxed(ATOMIC_VAL) \
|
||||
_Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* Py_ATOMIC_H */
|
||||
@@ -0,0 +1,94 @@
|
||||
/* Atomic functions: similar to pycore_atomic.h, but don't need
|
||||
to declare variables as atomic.
|
||||
|
||||
Py_ssize_t type:
|
||||
|
||||
* value = _Py_atomic_size_get(&var)
|
||||
* _Py_atomic_size_set(&var, value)
|
||||
|
||||
Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order):
|
||||
enforce total ordering with all other atomic functions.
|
||||
*/
|
||||
#ifndef Py_ATOMIC_FUNC_H
|
||||
#define Py_ATOMIC_FUNC_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# include <intrin.h> // _InterlockedExchange()
|
||||
#endif
|
||||
|
||||
|
||||
// Use builtin atomic operations in GCC >= 4.7 and clang
|
||||
#ifdef HAVE_BUILTIN_ATOMIC
|
||||
|
||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
||||
{
|
||||
return __atomic_load_n(var, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
||||
{
|
||||
__atomic_store_n(var, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
||||
{
|
||||
#if SIZEOF_VOID_P == 8
|
||||
Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
|
||||
volatile __int64 *volatile_var = (volatile __int64 *)var;
|
||||
__int64 old;
|
||||
do {
|
||||
old = *volatile_var;
|
||||
} while(_InterlockedCompareExchange64(volatile_var, old, old) != old);
|
||||
#else
|
||||
Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
|
||||
volatile long *volatile_var = (volatile long *)var;
|
||||
long old;
|
||||
do {
|
||||
old = *volatile_var;
|
||||
} while(_InterlockedCompareExchange(volatile_var, old, old) != old);
|
||||
#endif
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
||||
{
|
||||
#if SIZEOF_VOID_P == 8
|
||||
Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
|
||||
volatile __int64 *volatile_var = (volatile __int64 *)var;
|
||||
_InterlockedExchange64(volatile_var, value);
|
||||
#else
|
||||
Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
|
||||
volatile long *volatile_var = (volatile long *)var;
|
||||
_InterlockedExchange(volatile_var, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
// Fallback implementation using volatile
|
||||
|
||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
||||
{
|
||||
volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
|
||||
return *volatile_var;
|
||||
}
|
||||
|
||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
||||
{
|
||||
volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
|
||||
*volatile_var = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* Py_ATOMIC_FUNC_H */
|
||||
@@ -0,0 +1,176 @@
|
||||
/* Bit and bytes utilities.
|
||||
|
||||
Bytes swap functions, reverse order of bytes:
|
||||
|
||||
- _Py_bswap16(uint16_t)
|
||||
- _Py_bswap32(uint32_t)
|
||||
- _Py_bswap64(uint64_t)
|
||||
*/
|
||||
|
||||
#ifndef Py_INTERNAL_BITUTILS_H
|
||||
#define Py_INTERNAL_BITUTILS_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) \
|
||||
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
|
||||
/* __builtin_bswap16() is available since GCC 4.8,
|
||||
__builtin_bswap32() is available since GCC 4.3,
|
||||
__builtin_bswap64() is available since GCC 4.3. */
|
||||
# define _PY_HAVE_BUILTIN_BSWAP
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
static inline uint16_t
|
||||
_Py_bswap16(uint16_t word)
|
||||
{
|
||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16)
|
||||
return __builtin_bswap16(word);
|
||||
#elif defined(_MSC_VER)
|
||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short));
|
||||
return _byteswap_ushort(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT16_C(0x00FF)) << 8)
|
||||
| ((word & UINT16_C(0xFF00)) >> 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
_Py_bswap32(uint32_t word)
|
||||
{
|
||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32)
|
||||
return __builtin_bswap32(word);
|
||||
#elif defined(_MSC_VER)
|
||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long));
|
||||
return _byteswap_ulong(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT32_C(0x000000FF)) << 24)
|
||||
| ((word & UINT32_C(0x0000FF00)) << 8)
|
||||
| ((word & UINT32_C(0x00FF0000)) >> 8)
|
||||
| ((word & UINT32_C(0xFF000000)) >> 24));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
_Py_bswap64(uint64_t word)
|
||||
{
|
||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64)
|
||||
return __builtin_bswap64(word);
|
||||
#elif defined(_MSC_VER)
|
||||
return _byteswap_uint64(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT64_C(0x00000000000000FF)) << 56)
|
||||
| ((word & UINT64_C(0x000000000000FF00)) << 40)
|
||||
| ((word & UINT64_C(0x0000000000FF0000)) << 24)
|
||||
| ((word & UINT64_C(0x00000000FF000000)) << 8)
|
||||
| ((word & UINT64_C(0x000000FF00000000)) >> 8)
|
||||
| ((word & UINT64_C(0x0000FF0000000000)) >> 24)
|
||||
| ((word & UINT64_C(0x00FF000000000000)) >> 40)
|
||||
| ((word & UINT64_C(0xFF00000000000000)) >> 56));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Population count: count the number of 1's in 'x'
|
||||
// (number of bits set to 1), also known as the hamming weight.
|
||||
//
|
||||
// Implementation note. CPUID is not used, to test if x86 POPCNT instruction
|
||||
// can be used, to keep the implementation simple. For example, Visual Studio
|
||||
// __popcnt() is not used this reason. The clang and GCC builtin function can
|
||||
// use the x86 POPCNT instruction if the target architecture has SSE4a or
|
||||
// newer.
|
||||
static inline int
|
||||
_Py_popcount32(uint32_t x)
|
||||
{
|
||||
#if (defined(__clang__) || defined(__GNUC__))
|
||||
|
||||
#if SIZEOF_INT >= 4
|
||||
Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned int));
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
// The C standard guarantees that unsigned long will always be big enough
|
||||
// to hold a uint32_t value without losing information.
|
||||
Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned long));
|
||||
return __builtin_popcountl(x);
|
||||
#endif
|
||||
|
||||
#else
|
||||
// 32-bit SWAR (SIMD Within A Register) popcount
|
||||
|
||||
// Binary: 0 1 0 1 ...
|
||||
const uint32_t M1 = 0x55555555;
|
||||
// Binary: 00 11 00 11. ..
|
||||
const uint32_t M2 = 0x33333333;
|
||||
// Binary: 0000 1111 0000 1111 ...
|
||||
const uint32_t M4 = 0x0F0F0F0F;
|
||||
// 256**4 + 256**3 + 256**2 + 256**1
|
||||
const uint32_t SUM = 0x01010101;
|
||||
|
||||
// Put count of each 2 bits into those 2 bits
|
||||
x = x - ((x >> 1) & M1);
|
||||
// Put count of each 4 bits into those 4 bits
|
||||
x = (x & M2) + ((x >> 2) & M2);
|
||||
// Put count of each 8 bits into those 8 bits
|
||||
x = (x + (x >> 4)) & M4;
|
||||
// Sum of the 4 byte counts
|
||||
return (uint32_t)((uint64_t)x * (uint64_t)SUM) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Return the index of the most significant 1 bit in 'x'. This is the smallest
|
||||
// integer k such that x < 2**k. Equivalent to floor(log2(x)) + 1 for x != 0.
|
||||
static inline int
|
||||
_Py_bit_length(unsigned long x)
|
||||
{
|
||||
#if (defined(__clang__) || defined(__GNUC__))
|
||||
if (x != 0) {
|
||||
// __builtin_clzl() is available since GCC 3.4.
|
||||
// Undefined behavior for x == 0.
|
||||
return (int)sizeof(unsigned long) * 8 - __builtin_clzl(x);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
#elif defined(_MSC_VER)
|
||||
// _BitScanReverse() is documented to search 32 bits.
|
||||
Py_BUILD_ASSERT(sizeof(unsigned long) <= 4);
|
||||
unsigned long msb;
|
||||
if (_BitScanReverse(&msb, x)) {
|
||||
return (int)msb + 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
const int BIT_LENGTH_TABLE[32] = {
|
||||
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
};
|
||||
int msb = 0;
|
||||
while (x >= 32) {
|
||||
msb += 6;
|
||||
x >>= 6;
|
||||
}
|
||||
msb += BIT_LENGTH_TABLE[x];
|
||||
return msb;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_BITUTILS_H */
|
||||
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
_BlocksOutputBuffer is used to maintain an output buffer
|
||||
that has unpredictable size. Suitable for compression/decompression
|
||||
API (bz2/lzma/zlib) that has stream->next_out and stream->avail_out:
|
||||
|
||||
stream->next_out: point to the next output position.
|
||||
stream->avail_out: the number of available bytes left in the buffer.
|
||||
|
||||
It maintains a list of bytes object, so there is no overhead of resizing
|
||||
the buffer.
|
||||
|
||||
Usage:
|
||||
|
||||
1, Initialize the struct instance like this:
|
||||
_BlocksOutputBuffer buffer = {.list = NULL};
|
||||
Set .list to NULL for _BlocksOutputBuffer_OnError()
|
||||
|
||||
2, Initialize the buffer use one of these functions:
|
||||
_BlocksOutputBuffer_InitAndGrow()
|
||||
_BlocksOutputBuffer_InitWithSize()
|
||||
|
||||
3, If (avail_out == 0), grow the buffer:
|
||||
_BlocksOutputBuffer_Grow()
|
||||
|
||||
4, Get the current outputted data size:
|
||||
_BlocksOutputBuffer_GetDataSize()
|
||||
|
||||
5, Finish the buffer, and return a bytes object:
|
||||
_BlocksOutputBuffer_Finish()
|
||||
|
||||
6, Clean up the buffer when an error occurred:
|
||||
_BlocksOutputBuffer_OnError()
|
||||
*/
|
||||
|
||||
#ifndef Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H
|
||||
#define Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
typedef struct {
|
||||
// List of bytes objects
|
||||
PyObject *list;
|
||||
// Number of whole allocated size
|
||||
Py_ssize_t allocated;
|
||||
// Max length of the buffer, negative number means unlimited length.
|
||||
Py_ssize_t max_length;
|
||||
} _BlocksOutputBuffer;
|
||||
|
||||
static const char unable_allocate_msg[] = "Unable to allocate output buffer.";
|
||||
|
||||
/* In 32-bit build, the max block size should <= INT32_MAX. */
|
||||
#define OUTPUT_BUFFER_MAX_BLOCK_SIZE (256*1024*1024)
|
||||
|
||||
/* Block size sequence */
|
||||
#define KB (1024)
|
||||
#define MB (1024*1024)
|
||||
static const Py_ssize_t BUFFER_BLOCK_SIZE[] =
|
||||
{ 32*KB, 64*KB, 256*KB, 1*MB, 4*MB, 8*MB, 16*MB, 16*MB,
|
||||
32*MB, 32*MB, 32*MB, 32*MB, 64*MB, 64*MB, 128*MB, 128*MB,
|
||||
OUTPUT_BUFFER_MAX_BLOCK_SIZE };
|
||||
#undef KB
|
||||
#undef MB
|
||||
|
||||
/* According to the block sizes defined by BUFFER_BLOCK_SIZE, the whole
|
||||
allocated size growth step is:
|
||||
1 32 KB +32 KB
|
||||
2 96 KB +64 KB
|
||||
3 352 KB +256 KB
|
||||
4 1.34 MB +1 MB
|
||||
5 5.34 MB +4 MB
|
||||
6 13.34 MB +8 MB
|
||||
7 29.34 MB +16 MB
|
||||
8 45.34 MB +16 MB
|
||||
9 77.34 MB +32 MB
|
||||
10 109.34 MB +32 MB
|
||||
11 141.34 MB +32 MB
|
||||
12 173.34 MB +32 MB
|
||||
13 237.34 MB +64 MB
|
||||
14 301.34 MB +64 MB
|
||||
15 429.34 MB +128 MB
|
||||
16 557.34 MB +128 MB
|
||||
17 813.34 MB +256 MB
|
||||
18 1069.34 MB +256 MB
|
||||
19 1325.34 MB +256 MB
|
||||
20 1581.34 MB +256 MB
|
||||
21 1837.34 MB +256 MB
|
||||
22 2093.34 MB +256 MB
|
||||
...
|
||||
*/
|
||||
|
||||
/* Initialize the buffer, and grow the buffer.
|
||||
|
||||
max_length: Max length of the buffer, -1 for unlimited length.
|
||||
|
||||
On success, return allocated size (>=0)
|
||||
On failure, return -1
|
||||
*/
|
||||
static inline Py_ssize_t
|
||||
_BlocksOutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer,
|
||||
const Py_ssize_t max_length,
|
||||
void **next_out)
|
||||
{
|
||||
PyObject *b;
|
||||
Py_ssize_t block_size;
|
||||
|
||||
// ensure .list was set to NULL
|
||||
assert(buffer->list == NULL);
|
||||
|
||||
// get block size
|
||||
if (0 <= max_length && max_length < BUFFER_BLOCK_SIZE[0]) {
|
||||
block_size = max_length;
|
||||
} else {
|
||||
block_size = BUFFER_BLOCK_SIZE[0];
|
||||
}
|
||||
|
||||
// the first block
|
||||
b = PyBytes_FromStringAndSize(NULL, block_size);
|
||||
if (b == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create the list
|
||||
buffer->list = PyList_New(1);
|
||||
if (buffer->list == NULL) {
|
||||
Py_DECREF(b);
|
||||
return -1;
|
||||
}
|
||||
PyList_SET_ITEM(buffer->list, 0, b);
|
||||
|
||||
// set variables
|
||||
buffer->allocated = block_size;
|
||||
buffer->max_length = max_length;
|
||||
|
||||
*next_out = PyBytes_AS_STRING(b);
|
||||
return block_size;
|
||||
}
|
||||
|
||||
/* Initialize the buffer, with an initial size.
|
||||
|
||||
Check block size limit in the outer wrapper function. For example, some libs
|
||||
accept UINT32_MAX as the maximum block size, then init_size should <= it.
|
||||
|
||||
On success, return allocated size (>=0)
|
||||
On failure, return -1
|
||||
*/
|
||||
static inline Py_ssize_t
|
||||
_BlocksOutputBuffer_InitWithSize(_BlocksOutputBuffer *buffer,
|
||||
const Py_ssize_t init_size,
|
||||
void **next_out)
|
||||
{
|
||||
PyObject *b;
|
||||
|
||||
// ensure .list was set to NULL
|
||||
assert(buffer->list == NULL);
|
||||
|
||||
// the first block
|
||||
b = PyBytes_FromStringAndSize(NULL, init_size);
|
||||
if (b == NULL) {
|
||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create the list
|
||||
buffer->list = PyList_New(1);
|
||||
if (buffer->list == NULL) {
|
||||
Py_DECREF(b);
|
||||
return -1;
|
||||
}
|
||||
PyList_SET_ITEM(buffer->list, 0, b);
|
||||
|
||||
// set variables
|
||||
buffer->allocated = init_size;
|
||||
buffer->max_length = -1;
|
||||
|
||||
*next_out = PyBytes_AS_STRING(b);
|
||||
return init_size;
|
||||
}
|
||||
|
||||
/* Grow the buffer. The avail_out must be 0, please check it before calling.
|
||||
|
||||
On success, return allocated size (>=0)
|
||||
On failure, return -1
|
||||
*/
|
||||
static inline Py_ssize_t
|
||||
_BlocksOutputBuffer_Grow(_BlocksOutputBuffer *buffer,
|
||||
void **next_out,
|
||||
const Py_ssize_t avail_out)
|
||||
{
|
||||
PyObject *b;
|
||||
const Py_ssize_t list_len = Py_SIZE(buffer->list);
|
||||
Py_ssize_t block_size;
|
||||
|
||||
// ensure no gaps in the data
|
||||
if (avail_out != 0) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"avail_out is non-zero in _BlocksOutputBuffer_Grow().");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get block size
|
||||
if (list_len < (Py_ssize_t) Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE)) {
|
||||
block_size = BUFFER_BLOCK_SIZE[list_len];
|
||||
} else {
|
||||
block_size = BUFFER_BLOCK_SIZE[Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE) - 1];
|
||||
}
|
||||
|
||||
// check max_length
|
||||
if (buffer->max_length >= 0) {
|
||||
// if (rest == 0), should not grow the buffer.
|
||||
Py_ssize_t rest = buffer->max_length - buffer->allocated;
|
||||
assert(rest > 0);
|
||||
|
||||
// block_size of the last block
|
||||
if (block_size > rest) {
|
||||
block_size = rest;
|
||||
}
|
||||
}
|
||||
|
||||
// check buffer->allocated overflow
|
||||
if (block_size > PY_SSIZE_T_MAX - buffer->allocated) {
|
||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create the block
|
||||
b = PyBytes_FromStringAndSize(NULL, block_size);
|
||||
if (b == NULL) {
|
||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
||||
return -1;
|
||||
}
|
||||
if (PyList_Append(buffer->list, b) < 0) {
|
||||
Py_DECREF(b);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(b);
|
||||
|
||||
// set variables
|
||||
buffer->allocated += block_size;
|
||||
|
||||
*next_out = PyBytes_AS_STRING(b);
|
||||
return block_size;
|
||||
}
|
||||
|
||||
/* Return the current outputted data size. */
|
||||
static inline Py_ssize_t
|
||||
_BlocksOutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer,
|
||||
const Py_ssize_t avail_out)
|
||||
{
|
||||
return buffer->allocated - avail_out;
|
||||
}
|
||||
|
||||
/* Finish the buffer.
|
||||
|
||||
Return a bytes object on success
|
||||
Return NULL on failure
|
||||
*/
|
||||
static inline PyObject *
|
||||
_BlocksOutputBuffer_Finish(_BlocksOutputBuffer *buffer,
|
||||
const Py_ssize_t avail_out)
|
||||
{
|
||||
PyObject *result, *block;
|
||||
const Py_ssize_t list_len = Py_SIZE(buffer->list);
|
||||
|
||||
// fast path for single block
|
||||
if ((list_len == 1 && avail_out == 0) ||
|
||||
(list_len == 2 && Py_SIZE(PyList_GET_ITEM(buffer->list, 1)) == avail_out))
|
||||
{
|
||||
block = PyList_GET_ITEM(buffer->list, 0);
|
||||
Py_INCREF(block);
|
||||
|
||||
Py_CLEAR(buffer->list);
|
||||
return block;
|
||||
}
|
||||
|
||||
// final bytes object
|
||||
result = PyBytes_FromStringAndSize(NULL, buffer->allocated - avail_out);
|
||||
if (result == NULL) {
|
||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// memory copy
|
||||
if (list_len > 0) {
|
||||
char *posi = PyBytes_AS_STRING(result);
|
||||
|
||||
// blocks except the last one
|
||||
Py_ssize_t i = 0;
|
||||
for (; i < list_len-1; i++) {
|
||||
block = PyList_GET_ITEM(buffer->list, i);
|
||||
memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block));
|
||||
posi += Py_SIZE(block);
|
||||
}
|
||||
// the last block
|
||||
block = PyList_GET_ITEM(buffer->list, i);
|
||||
memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block) - avail_out);
|
||||
} else {
|
||||
assert(Py_SIZE(result) == 0);
|
||||
}
|
||||
|
||||
Py_CLEAR(buffer->list);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Clean up the buffer when an error occurred. */
|
||||
static inline void
|
||||
_BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer)
|
||||
{
|
||||
Py_CLEAR(buffer->list);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_BYTES_CTYPE_H
|
||||
#define Py_BYTES_CTYPE_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray)
|
||||
* methods of the given names, they operate on ASCII byte strings.
|
||||
*/
|
||||
extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len);
|
||||
extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len);
|
||||
|
||||
/* These store their len sized answer in the given preallocated *result arg. */
|
||||
extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len);
|
||||
extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len);
|
||||
extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len);
|
||||
extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len);
|
||||
extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len);
|
||||
|
||||
extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg);
|
||||
extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args);
|
||||
extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args);
|
||||
|
||||
/* The maketrans() static method. */
|
||||
extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to);
|
||||
|
||||
/* Shared __doc__ strings. */
|
||||
extern const char _Py_isspace__doc__[];
|
||||
extern const char _Py_isalpha__doc__[];
|
||||
extern const char _Py_isalnum__doc__[];
|
||||
extern const char _Py_isascii__doc__[];
|
||||
extern const char _Py_isdigit__doc__[];
|
||||
extern const char _Py_islower__doc__[];
|
||||
extern const char _Py_isupper__doc__[];
|
||||
extern const char _Py_istitle__doc__[];
|
||||
extern const char _Py_lower__doc__[];
|
||||
extern const char _Py_upper__doc__[];
|
||||
extern const char _Py_title__doc__[];
|
||||
extern const char _Py_capitalize__doc__[];
|
||||
extern const char _Py_swapcase__doc__[];
|
||||
extern const char _Py_count__doc__[];
|
||||
extern const char _Py_find__doc__[];
|
||||
extern const char _Py_index__doc__[];
|
||||
extern const char _Py_rfind__doc__[];
|
||||
extern const char _Py_rindex__doc__[];
|
||||
extern const char _Py_startswith__doc__[];
|
||||
extern const char _Py_endswith__doc__[];
|
||||
extern const char _Py_maketrans__doc__[];
|
||||
extern const char _Py_expandtabs__doc__[];
|
||||
extern const char _Py_ljust__doc__[];
|
||||
extern const char _Py_rjust__doc__[];
|
||||
extern const char _Py_center__doc__[];
|
||||
extern const char _Py_zfill__doc__[];
|
||||
|
||||
/* this is needed because some docs are shared from the .o, not static */
|
||||
#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str)
|
||||
|
||||
#endif /* !Py_BYTES_CTYPE_H */
|
||||
#endif /* !Py_LIMITED_API */
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef Py_INTERNAL_CALL_H
|
||||
#define Py_INTERNAL_CALL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *obj,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *const *args,
|
||||
size_t nargsf,
|
||||
PyObject *kwargs);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_Call(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallNoArgTstate(PyThreadState *tstate, PyObject *func) {
|
||||
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_CALL_H */
|
||||
@@ -0,0 +1,114 @@
|
||||
#ifndef Py_INTERNAL_CEVAL_H
|
||||
#define Py_INTERNAL_CEVAL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
struct pyruntimestate;
|
||||
struct _ceval_runtime_state;
|
||||
|
||||
#include "pycore_interp.h" /* PyInterpreterState.eval_frame */
|
||||
|
||||
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
|
||||
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
|
||||
extern int _PyEval_InitState(struct _ceval_state *ceval);
|
||||
extern void _PyEval_FiniState(struct _ceval_state *ceval);
|
||||
PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp);
|
||||
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
||||
PyInterpreterState *interp,
|
||||
int (*func)(void *),
|
||||
void *arg);
|
||||
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp);
|
||||
#ifdef HAVE_FORK
|
||||
extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate);
|
||||
#endif
|
||||
PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth(
|
||||
PyThreadState *tstate,
|
||||
int new_depth);
|
||||
|
||||
void _PyEval_Fini(void);
|
||||
|
||||
|
||||
extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate);
|
||||
extern PyObject *_PyEval_BuiltinsFromGlobals(
|
||||
PyThreadState *tstate,
|
||||
PyObject *globals);
|
||||
|
||||
|
||||
static inline PyObject*
|
||||
_PyEval_EvalFrame(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
||||
{
|
||||
return tstate->interp->eval_frame(tstate, f, throwflag);
|
||||
}
|
||||
|
||||
extern PyObject *
|
||||
_PyEval_Vector(PyThreadState *tstate,
|
||||
PyFrameConstructor *desc, PyObject *locals,
|
||||
PyObject* const* args, size_t argcount,
|
||||
PyObject *kwnames);
|
||||
|
||||
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
|
||||
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
|
||||
#else
|
||||
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
|
||||
#endif
|
||||
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
|
||||
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
|
||||
|
||||
extern void _PyEval_ReleaseLock(PyThreadState *tstate);
|
||||
|
||||
extern void _PyEval_DeactivateOpCache(void);
|
||||
|
||||
|
||||
/* --- _Py_EnterRecursiveCall() ----------------------------------------- */
|
||||
|
||||
#ifdef USE_STACKCHECK
|
||||
/* With USE_STACKCHECK macro defined, trigger stack checks in
|
||||
_Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */
|
||||
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
||||
return (++tstate->recursion_depth > tstate->interp->ceval.recursion_limit
|
||||
|| ++tstate->stackcheck_counter > 64);
|
||||
}
|
||||
#else
|
||||
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
||||
return (++tstate->recursion_depth > tstate->interp->ceval.recursion_limit);
|
||||
}
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(int) _Py_CheckRecursiveCall(
|
||||
PyThreadState *tstate,
|
||||
const char *where);
|
||||
|
||||
static inline int _Py_EnterRecursiveCall(PyThreadState *tstate,
|
||||
const char *where) {
|
||||
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
|
||||
}
|
||||
|
||||
static inline int _Py_EnterRecursiveCall_inline(const char *where) {
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
return _Py_EnterRecursiveCall(tstate, where);
|
||||
}
|
||||
|
||||
#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where)
|
||||
|
||||
static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) {
|
||||
tstate->recursion_depth--;
|
||||
}
|
||||
|
||||
static inline void _Py_LeaveRecursiveCall_inline(void) {
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
_Py_LeaveRecursiveCall(tstate);
|
||||
}
|
||||
|
||||
#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline()
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_CEVAL_H */
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef Py_INTERNAL_CODE_H
|
||||
#define Py_INTERNAL_CODE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject *ptr; /* Cached pointer (borrowed reference) */
|
||||
uint64_t globals_ver; /* ma_version of global dict */
|
||||
uint64_t builtins_ver; /* ma_version of builtin dict */
|
||||
} _PyOpcache_LoadGlobal;
|
||||
|
||||
typedef struct {
|
||||
PyTypeObject *type;
|
||||
Py_ssize_t hint;
|
||||
unsigned int tp_version_tag;
|
||||
} _PyOpCodeOpt_LoadAttr;
|
||||
|
||||
struct _PyOpcache {
|
||||
union {
|
||||
_PyOpcache_LoadGlobal lg;
|
||||
_PyOpCodeOpt_LoadAttr la;
|
||||
} u;
|
||||
char optimized;
|
||||
};
|
||||
|
||||
/* Private API */
|
||||
int _PyCode_InitOpcache(PyCodeObject *co);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_CODE_H */
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef Py_INTERNAL_COMPILE_H
|
||||
#define Py_INTERNAL_COMPILE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
struct _arena; // Type defined in pycore_pyarena.h
|
||||
struct _mod; // Type defined in pycore_ast.h
|
||||
|
||||
// Export the symbol for test_peg_generator (built as a library)
|
||||
PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
|
||||
struct _mod *mod,
|
||||
PyObject *filename,
|
||||
PyCompilerFlags *flags,
|
||||
int optimize,
|
||||
struct _arena *arena);
|
||||
extern PyFutureFeatures* _PyFuture_FromAST(
|
||||
struct _mod * mod,
|
||||
PyObject *filename
|
||||
);
|
||||
|
||||
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
|
||||
|
||||
typedef struct {
|
||||
int optimize;
|
||||
int ff_features;
|
||||
|
||||
int recursion_depth; /* current recursion depth */
|
||||
int recursion_limit; /* recursion limit */
|
||||
} _PyASTOptimizeState;
|
||||
|
||||
extern int _PyAST_Optimize(
|
||||
struct _mod *,
|
||||
struct _arena *arena,
|
||||
_PyASTOptimizeState *state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_COMPILE_H */
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef Py_INTERNAL_CONDVAR_H
|
||||
#define Py_INTERNAL_CONDVAR_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_THREADS
|
||||
/* This means pthreads are not implemented in libc headers, hence the macro
|
||||
not present in unistd.h. But they still can be implemented as an external
|
||||
library (e.g. gnu pth in pthread emulation) */
|
||||
# ifdef HAVE_PTHREAD_H
|
||||
# include <pthread.h> /* _POSIX_THREADS */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _POSIX_THREADS
|
||||
/*
|
||||
* POSIX support
|
||||
*/
|
||||
#define Py_HAVE_CONDVAR
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define PyMUTEX_T pthread_mutex_t
|
||||
#define PyCOND_T pthread_cond_t
|
||||
|
||||
#elif defined(NT_THREADS)
|
||||
/*
|
||||
* Windows (XP, 2003 server and later, as well as (hopefully) CE) support
|
||||
*
|
||||
* Emulated condition variables ones that work with XP and later, plus
|
||||
* example native support on VISTA and onwards.
|
||||
*/
|
||||
#define Py_HAVE_CONDVAR
|
||||
|
||||
/* include windows if it hasn't been done before */
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
/* options */
|
||||
/* non-emulated condition variables are provided for those that want
|
||||
* to target Windows Vista. Modify this macro to enable them.
|
||||
*/
|
||||
#ifndef _PY_EMULATED_WIN_CV
|
||||
#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */
|
||||
#endif
|
||||
|
||||
/* fall back to emulation if not targeting Vista */
|
||||
#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA
|
||||
#undef _PY_EMULATED_WIN_CV
|
||||
#define _PY_EMULATED_WIN_CV 1
|
||||
#endif
|
||||
|
||||
#if _PY_EMULATED_WIN_CV
|
||||
|
||||
typedef CRITICAL_SECTION PyMUTEX_T;
|
||||
|
||||
/* The ConditionVariable object. From XP onwards it is easily emulated
|
||||
with a Semaphore.
|
||||
Semaphores are available on Windows XP (2003 server) and later.
|
||||
We use a Semaphore rather than an auto-reset event, because although
|
||||
an auto-resent event might appear to solve the lost-wakeup bug (race
|
||||
condition between releasing the outer lock and waiting) because it
|
||||
maintains state even though a wait hasn't happened, there is still
|
||||
a lost wakeup problem if more than one thread are interrupted in the
|
||||
critical place. A semaphore solves that, because its state is
|
||||
counted, not Boolean.
|
||||
Because it is ok to signal a condition variable with no one
|
||||
waiting, we need to keep track of the number of
|
||||
waiting threads. Otherwise, the semaphore's state could rise
|
||||
without bound. This also helps reduce the number of "spurious wakeups"
|
||||
that would otherwise happen.
|
||||
*/
|
||||
|
||||
typedef struct _PyCOND_T
|
||||
{
|
||||
HANDLE sem;
|
||||
int waiting; /* to allow PyCOND_SIGNAL to be a no-op */
|
||||
} PyCOND_T;
|
||||
|
||||
#else /* !_PY_EMULATED_WIN_CV */
|
||||
|
||||
/* Use native Win7 primitives if build target is Win7 or higher */
|
||||
|
||||
/* SRWLOCK is faster and better than CriticalSection */
|
||||
typedef SRWLOCK PyMUTEX_T;
|
||||
|
||||
typedef CONDITION_VARIABLE PyCOND_T;
|
||||
|
||||
#endif /* _PY_EMULATED_WIN_CV */
|
||||
|
||||
#endif /* _POSIX_THREADS, NT_THREADS */
|
||||
|
||||
#endif /* Py_INTERNAL_CONDVAR_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef Py_INTERNAL_CONTEXT_H
|
||||
#define Py_INTERNAL_CONTEXT_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_hamt.h" /* PyHamtObject */
|
||||
|
||||
struct _pycontextobject {
|
||||
PyObject_HEAD
|
||||
PyContext *ctx_prev;
|
||||
PyHamtObject *ctx_vars;
|
||||
PyObject *ctx_weakreflist;
|
||||
int ctx_entered;
|
||||
};
|
||||
|
||||
|
||||
struct _pycontextvarobject {
|
||||
PyObject_HEAD
|
||||
PyObject *var_name;
|
||||
PyObject *var_default;
|
||||
PyObject *var_cached;
|
||||
uint64_t var_cached_tsid;
|
||||
uint64_t var_cached_tsver;
|
||||
Py_hash_t var_hash;
|
||||
};
|
||||
|
||||
|
||||
struct _pycontexttokenobject {
|
||||
PyObject_HEAD
|
||||
PyContext *tok_ctx;
|
||||
PyContextVar *tok_var;
|
||||
PyObject *tok_oldval;
|
||||
int tok_used;
|
||||
};
|
||||
|
||||
|
||||
int _PyContext_Init(void);
|
||||
void _PyContext_Fini(PyInterpreterState *interp);
|
||||
|
||||
#endif /* !Py_INTERNAL_CONTEXT_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef PY_NO_SHORT_FLOAT_REPR
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* These functions are used by modules compiled as C extension like math:
|
||||
they must be exported. */
|
||||
|
||||
PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr);
|
||||
PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits,
|
||||
int *decpt, int *sign, char **rve);
|
||||
PyAPI_FUNC(void) _Py_dg_freedtoa(char *s);
|
||||
PyAPI_FUNC(double) _Py_dg_stdnan(int sign);
|
||||
PyAPI_FUNC(double) _Py_dg_infinity(int sign);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !PY_NO_SHORT_FLOAT_REPR */
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef Py_INTERNAL_FILEUTILS_H
|
||||
#define Py_INTERNAL_FILEUTILS_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "Py_BUILD_CORE must be defined to include this header"
|
||||
#endif
|
||||
|
||||
#include <locale.h> /* struct lconv */
|
||||
|
||||
PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors;
|
||||
|
||||
PyAPI_FUNC(int) _Py_DecodeUTF8Ex(
|
||||
const char *arg,
|
||||
Py_ssize_t arglen,
|
||||
wchar_t **wstr,
|
||||
size_t *wlen,
|
||||
const char **reason,
|
||||
_Py_error_handler errors);
|
||||
|
||||
PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
|
||||
const wchar_t *text,
|
||||
char **str,
|
||||
size_t *error_pos,
|
||||
const char **reason,
|
||||
int raw_malloc,
|
||||
_Py_error_handler errors);
|
||||
|
||||
PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
|
||||
const char *arg,
|
||||
Py_ssize_t arglen,
|
||||
size_t *wlen);
|
||||
|
||||
PyAPI_FUNC(int) _Py_GetForceASCII(void);
|
||||
|
||||
/* Reset "force ASCII" mode (if it was initialized).
|
||||
|
||||
This function should be called when Python changes the LC_CTYPE locale,
|
||||
so the "force ASCII" mode can be detected again on the new locale
|
||||
encoding. */
|
||||
PyAPI_FUNC(void) _Py_ResetForceASCII(void);
|
||||
|
||||
|
||||
PyAPI_FUNC(int) _Py_GetLocaleconvNumeric(
|
||||
struct lconv *lc,
|
||||
PyObject **decimal_point,
|
||||
PyObject **thousands_sep);
|
||||
|
||||
PyAPI_FUNC(void) _Py_closerange(int first, int last);
|
||||
|
||||
PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void);
|
||||
PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void);
|
||||
|
||||
#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
|
||||
extern int _Py_LocaleUsesNonUnicodeWchar(void);
|
||||
|
||||
extern wchar_t* _Py_DecodeNonUnicodeWchar(
|
||||
const wchar_t* native,
|
||||
Py_ssize_t size);
|
||||
|
||||
extern int _Py_EncodeNonUnicodeWchar_InPlace(
|
||||
wchar_t* unicode,
|
||||
Py_ssize_t size);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_FILEUTILS_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef Py_INTERNAL_FORMAT_H
|
||||
#define Py_INTERNAL_FORMAT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* Format codes
|
||||
* F_LJUST '-'
|
||||
* F_SIGN '+'
|
||||
* F_BLANK ' '
|
||||
* F_ALT '#'
|
||||
* F_ZERO '0'
|
||||
*/
|
||||
#define F_LJUST (1<<0)
|
||||
#define F_SIGN (1<<1)
|
||||
#define F_BLANK (1<<2)
|
||||
#define F_ALT (1<<3)
|
||||
#define F_ZERO (1<<4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_FORMAT_H */
|
||||
@@ -0,0 +1,181 @@
|
||||
#ifndef Py_INTERNAL_GC_H
|
||||
#define Py_INTERNAL_GC_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* GC information is stored BEFORE the object structure. */
|
||||
typedef struct {
|
||||
// Pointer to next object in the list.
|
||||
// 0 means the object is not tracked
|
||||
uintptr_t _gc_next;
|
||||
|
||||
// Pointer to previous object in the list.
|
||||
// Lowest two bits are used for flags documented later.
|
||||
uintptr_t _gc_prev;
|
||||
} PyGC_Head;
|
||||
|
||||
#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
|
||||
|
||||
/* True if the object is currently tracked by the GC. */
|
||||
#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)
|
||||
|
||||
/* True if the object may be tracked by the GC in the future, or already is.
|
||||
This can be useful to implement some optimizations. */
|
||||
#define _PyObject_GC_MAY_BE_TRACKED(obj) \
|
||||
(PyObject_IS_GC(obj) && \
|
||||
(!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
|
||||
|
||||
|
||||
/* Bit flags for _gc_prev */
|
||||
/* Bit 0 is set when tp_finalize is called */
|
||||
#define _PyGC_PREV_MASK_FINALIZED (1)
|
||||
/* Bit 1 is set when the object is in generation which is GCed currently. */
|
||||
#define _PyGC_PREV_MASK_COLLECTING (2)
|
||||
/* The (N-2) most significant bits contain the real address. */
|
||||
#define _PyGC_PREV_SHIFT (2)
|
||||
#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
|
||||
|
||||
// Lowest bit of _gc_next is used for flags only in GC.
|
||||
// But it is always 0 for normal code.
|
||||
#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next)
|
||||
#define _PyGCHead_SET_NEXT(g, p) ((g)->_gc_next = (uintptr_t)(p))
|
||||
|
||||
// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
|
||||
#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))
|
||||
#define _PyGCHead_SET_PREV(g, p) do { \
|
||||
assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \
|
||||
(g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \
|
||||
| ((uintptr_t)(p)); \
|
||||
} while (0)
|
||||
|
||||
#define _PyGCHead_FINALIZED(g) \
|
||||
(((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
|
||||
#define _PyGCHead_SET_FINALIZED(g) \
|
||||
((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
|
||||
|
||||
#define _PyGC_FINALIZED(o) \
|
||||
_PyGCHead_FINALIZED(_Py_AS_GC(o))
|
||||
#define _PyGC_SET_FINALIZED(o) \
|
||||
_PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
|
||||
|
||||
|
||||
/* GC runtime state */
|
||||
|
||||
/* If we change this, we need to change the default value in the
|
||||
signature of gc.collect. */
|
||||
#define NUM_GENERATIONS 3
|
||||
/*
|
||||
NOTE: about untracking of mutable objects.
|
||||
|
||||
Certain types of container cannot participate in a reference cycle, and
|
||||
so do not need to be tracked by the garbage collector. Untracking these
|
||||
objects reduces the cost of garbage collections. However, determining
|
||||
which objects may be untracked is not free, and the costs must be
|
||||
weighed against the benefits for garbage collection.
|
||||
|
||||
There are two possible strategies for when to untrack a container:
|
||||
|
||||
i) When the container is created.
|
||||
ii) When the container is examined by the garbage collector.
|
||||
|
||||
Tuples containing only immutable objects (integers, strings etc, and
|
||||
recursively, tuples of immutable objects) do not need to be tracked.
|
||||
The interpreter creates a large number of tuples, many of which will
|
||||
not survive until garbage collection. It is therefore not worthwhile
|
||||
to untrack eligible tuples at creation time.
|
||||
|
||||
Instead, all tuples except the empty tuple are tracked when created.
|
||||
During garbage collection it is determined whether any surviving tuples
|
||||
can be untracked. A tuple can be untracked if all of its contents are
|
||||
already not tracked. Tuples are examined for untracking in all garbage
|
||||
collection cycles. It may take more than one cycle to untrack a tuple.
|
||||
|
||||
Dictionaries containing only immutable objects also do not need to be
|
||||
tracked. Dictionaries are untracked when created. If a tracked item is
|
||||
inserted into a dictionary (either as a key or value), the dictionary
|
||||
becomes tracked. During a full garbage collection (all generations),
|
||||
the collector will untrack any dictionaries whose contents are not
|
||||
tracked.
|
||||
|
||||
The module provides the python function is_tracked(obj), which returns
|
||||
the CURRENT tracking status of the object. Subsequent garbage
|
||||
collections may change the tracking status of the object.
|
||||
|
||||
Untracking of certain containers was introduced in issue #4688, and
|
||||
the algorithm was refined in response to issue #14775.
|
||||
*/
|
||||
|
||||
struct gc_generation {
|
||||
PyGC_Head head;
|
||||
int threshold; /* collection threshold */
|
||||
int count; /* count of allocations or collections of younger
|
||||
generations */
|
||||
};
|
||||
|
||||
/* Running stats per generation */
|
||||
struct gc_generation_stats {
|
||||
/* total number of collections */
|
||||
Py_ssize_t collections;
|
||||
/* total number of collected objects */
|
||||
Py_ssize_t collected;
|
||||
/* total number of uncollectable objects (put into gc.garbage) */
|
||||
Py_ssize_t uncollectable;
|
||||
};
|
||||
|
||||
struct _gc_runtime_state {
|
||||
/* List of objects that still need to be cleaned up, singly linked
|
||||
* via their gc headers' gc_prev pointers. */
|
||||
PyObject *trash_delete_later;
|
||||
/* Current call-stack depth of tp_dealloc calls. */
|
||||
int trash_delete_nesting;
|
||||
|
||||
int enabled;
|
||||
int debug;
|
||||
/* linked lists of container objects */
|
||||
struct gc_generation generations[NUM_GENERATIONS];
|
||||
PyGC_Head *generation0;
|
||||
/* a permanent generation which won't be collected */
|
||||
struct gc_generation permanent_generation;
|
||||
struct gc_generation_stats generation_stats[NUM_GENERATIONS];
|
||||
/* true if we are currently running the collector */
|
||||
int collecting;
|
||||
/* list of uncollectable objects */
|
||||
PyObject *garbage;
|
||||
/* a list of callbacks to be invoked when collection is performed */
|
||||
PyObject *callbacks;
|
||||
/* This is the number of objects that survived the last full
|
||||
collection. It approximates the number of long lived objects
|
||||
tracked by the GC.
|
||||
|
||||
(by "full collection", we mean a collection of the oldest
|
||||
generation). */
|
||||
Py_ssize_t long_lived_total;
|
||||
/* This is the number of objects that survived all "non-full"
|
||||
collections, and are awaiting to undergo a full collection for
|
||||
the first time. */
|
||||
Py_ssize_t long_lived_pending;
|
||||
};
|
||||
|
||||
extern void _PyGC_InitState(struct _gc_runtime_state *);
|
||||
|
||||
extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
|
||||
|
||||
|
||||
// Functions to clear types free lists
|
||||
extern void _PyFrame_ClearFreeList(PyInterpreterState *interp);
|
||||
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
|
||||
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
|
||||
extern void _PyList_ClearFreeList(PyInterpreterState *interp);
|
||||
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
|
||||
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
|
||||
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_GC_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef Py_INTERNAL_PYGETOPT_H
|
||||
#define Py_INTERNAL_PYGETOPT_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
extern int _PyOS_opterr;
|
||||
extern Py_ssize_t _PyOS_optind;
|
||||
extern const wchar_t *_PyOS_optarg;
|
||||
|
||||
extern void _PyOS_ResetGetOpt(void);
|
||||
|
||||
typedef struct {
|
||||
const wchar_t *name;
|
||||
int has_arg;
|
||||
int val;
|
||||
} _PyOS_LongOption;
|
||||
|
||||
extern int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex);
|
||||
|
||||
#endif /* !Py_INTERNAL_PYGETOPT_H */
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef Py_INTERNAL_GIL_H
|
||||
#define Py_INTERNAL_GIL_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_atomic.h" /* _Py_atomic_address */
|
||||
#include "pycore_condvar.h" /* PyCOND_T */
|
||||
|
||||
#ifndef Py_HAVE_CONDVAR
|
||||
# error You need either a POSIX-compatible or a Windows system!
|
||||
#endif
|
||||
|
||||
/* Enable if you want to force the switching of threads at least
|
||||
every `interval`. */
|
||||
#undef FORCE_SWITCHING
|
||||
#define FORCE_SWITCHING
|
||||
|
||||
struct _gil_runtime_state {
|
||||
/* microseconds (the Python API uses seconds, though) */
|
||||
unsigned long interval;
|
||||
/* Last PyThreadState holding / having held the GIL. This helps us
|
||||
know whether anyone else was scheduled after we dropped the GIL. */
|
||||
_Py_atomic_address last_holder;
|
||||
/* Whether the GIL is already taken (-1 if uninitialized). This is
|
||||
atomic because it can be read without any lock taken in ceval.c. */
|
||||
_Py_atomic_int locked;
|
||||
/* Number of GIL switches since the beginning. */
|
||||
unsigned long switch_number;
|
||||
/* This condition variable allows one or several threads to wait
|
||||
until the GIL is released. In addition, the mutex also protects
|
||||
the above variables. */
|
||||
PyCOND_T cond;
|
||||
PyMUTEX_T mutex;
|
||||
#ifdef FORCE_SWITCHING
|
||||
/* This condition variable helps the GIL-releasing thread wait for
|
||||
a GIL-awaiting thread to be scheduled and take the GIL. */
|
||||
PyCOND_T switch_cond;
|
||||
PyMUTEX_T switch_mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_GIL_H */
|
||||
@@ -0,0 +1,128 @@
|
||||
#ifndef Py_INTERNAL_HAMT_H
|
||||
#define Py_INTERNAL_HAMT_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes
|
||||
the exact position of the key in one level of the tree. Since we're using
|
||||
32 bit hashes, we can have at most 7 such levels. Although if there are
|
||||
two distinct keys with equal hashes, they will have to occupy the same
|
||||
cell in the 7th level of the tree -- so we'd put them in a "collision" node.
|
||||
Which brings the total possible tree depth to 8. Read more about the actual
|
||||
layout of the HAMT tree in `hamt.c`.
|
||||
|
||||
This constant is used to define a datastucture for storing iteration state.
|
||||
*/
|
||||
#define _Py_HAMT_MAX_TREE_DEPTH 8
|
||||
|
||||
|
||||
#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type)
|
||||
|
||||
|
||||
/* Abstract tree node. */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
} PyHamtNode;
|
||||
|
||||
|
||||
/* An HAMT immutable mapping collection. */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyHamtNode *h_root;
|
||||
PyObject *h_weakreflist;
|
||||
Py_ssize_t h_count;
|
||||
} PyHamtObject;
|
||||
|
||||
|
||||
/* A struct to hold the state of depth-first traverse of the tree.
|
||||
|
||||
HAMT is an immutable collection. Iterators will hold a strong reference
|
||||
to it, and every node in the HAMT has strong references to its children.
|
||||
|
||||
So for iterators, we can implement zero allocations and zero reference
|
||||
inc/dec depth-first iteration.
|
||||
|
||||
- i_nodes: an array of seven pointers to tree nodes
|
||||
- i_level: the current node in i_nodes
|
||||
- i_pos: an array of positions within nodes in i_nodes.
|
||||
*/
|
||||
typedef struct {
|
||||
PyHamtNode *i_nodes[_Py_HAMT_MAX_TREE_DEPTH];
|
||||
Py_ssize_t i_pos[_Py_HAMT_MAX_TREE_DEPTH];
|
||||
int8_t i_level;
|
||||
} PyHamtIteratorState;
|
||||
|
||||
|
||||
/* Base iterator object.
|
||||
|
||||
Contains the iteration state, a pointer to the HAMT tree,
|
||||
and a pointer to the 'yield function'. The latter is a simple
|
||||
function that returns a key/value tuple for the 'Items' iterator,
|
||||
just a key for the 'Keys' iterator, and a value for the 'Values'
|
||||
iterator.
|
||||
*/
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyHamtObject *hi_obj;
|
||||
PyHamtIteratorState hi_iter;
|
||||
binaryfunc hi_yield;
|
||||
} PyHamtIterator;
|
||||
|
||||
|
||||
PyAPI_DATA(PyTypeObject) _PyHamt_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamt_ArrayNode_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamt_BitmapNode_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamt_CollisionNode_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamtKeys_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamtValues_Type;
|
||||
PyAPI_DATA(PyTypeObject) _PyHamtItems_Type;
|
||||
|
||||
|
||||
/* Create a new HAMT immutable mapping. */
|
||||
PyHamtObject * _PyHamt_New(void);
|
||||
|
||||
/* Return a new collection based on "o", but with an additional
|
||||
key/val pair. */
|
||||
PyHamtObject * _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val);
|
||||
|
||||
/* Return a new collection based on "o", but without "key". */
|
||||
PyHamtObject * _PyHamt_Without(PyHamtObject *o, PyObject *key);
|
||||
|
||||
/* Find "key" in the "o" collection.
|
||||
|
||||
Return:
|
||||
- -1: An error occurred.
|
||||
- 0: "key" wasn't found in "o".
|
||||
- 1: "key" is in "o"; "*val" is set to its value (a borrowed ref).
|
||||
*/
|
||||
int _PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val);
|
||||
|
||||
/* Check if "v" is equal to "w".
|
||||
|
||||
Return:
|
||||
- 0: v != w
|
||||
- 1: v == w
|
||||
- -1: An error occurred.
|
||||
*/
|
||||
int _PyHamt_Eq(PyHamtObject *v, PyHamtObject *w);
|
||||
|
||||
/* Return the size of "o"; equivalent of "len(o)". */
|
||||
Py_ssize_t _PyHamt_Len(PyHamtObject *o);
|
||||
|
||||
/* Return a Keys iterator over "o". */
|
||||
PyObject * _PyHamt_NewIterKeys(PyHamtObject *o);
|
||||
|
||||
/* Return a Values iterator over "o". */
|
||||
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 */
|
||||
@@ -0,0 +1,148 @@
|
||||
#ifndef Py_INTERNAL_HASHTABLE_H
|
||||
#define Py_INTERNAL_HASHTABLE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* Single linked list */
|
||||
|
||||
typedef struct _Py_slist_item_s {
|
||||
struct _Py_slist_item_s *next;
|
||||
} _Py_slist_item_t;
|
||||
|
||||
typedef struct {
|
||||
_Py_slist_item_t *head;
|
||||
} _Py_slist_t;
|
||||
|
||||
#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next)
|
||||
|
||||
#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head)
|
||||
|
||||
|
||||
/* _Py_hashtable: table entry */
|
||||
|
||||
typedef struct {
|
||||
/* used by _Py_hashtable_t.buckets to link entries */
|
||||
_Py_slist_item_t _Py_slist_item;
|
||||
|
||||
Py_uhash_t key_hash;
|
||||
void *key;
|
||||
void *value;
|
||||
} _Py_hashtable_entry_t;
|
||||
|
||||
|
||||
/* _Py_hashtable: prototypes */
|
||||
|
||||
/* Forward declaration */
|
||||
struct _Py_hashtable_t;
|
||||
typedef struct _Py_hashtable_t _Py_hashtable_t;
|
||||
|
||||
typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key);
|
||||
typedef int (*_Py_hashtable_compare_func) (const void *key1, const void *key2);
|
||||
typedef void (*_Py_hashtable_destroy_func) (void *key);
|
||||
typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht,
|
||||
const void *key);
|
||||
|
||||
typedef struct {
|
||||
// Allocate a memory block
|
||||
void* (*malloc) (size_t size);
|
||||
|
||||
// Release a memory block
|
||||
void (*free) (void *ptr);
|
||||
} _Py_hashtable_allocator_t;
|
||||
|
||||
|
||||
/* _Py_hashtable: table */
|
||||
struct _Py_hashtable_t {
|
||||
size_t nentries; // Total number of entries in the table
|
||||
size_t nbuckets;
|
||||
_Py_slist_t *buckets;
|
||||
|
||||
_Py_hashtable_get_entry_func get_entry_func;
|
||||
_Py_hashtable_hash_func hash_func;
|
||||
_Py_hashtable_compare_func compare_func;
|
||||
_Py_hashtable_destroy_func key_destroy_func;
|
||||
_Py_hashtable_destroy_func value_destroy_func;
|
||||
_Py_hashtable_allocator_t alloc;
|
||||
};
|
||||
|
||||
/* Hash a pointer (void*) */
|
||||
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key);
|
||||
|
||||
/* Comparison using memcmp() */
|
||||
PyAPI_FUNC(int) _Py_hashtable_compare_direct(
|
||||
const void *key1,
|
||||
const void *key2);
|
||||
|
||||
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
|
||||
_Py_hashtable_hash_func hash_func,
|
||||
_Py_hashtable_compare_func compare_func);
|
||||
|
||||
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full(
|
||||
_Py_hashtable_hash_func hash_func,
|
||||
_Py_hashtable_compare_func compare_func,
|
||||
_Py_hashtable_destroy_func key_destroy_func,
|
||||
_Py_hashtable_destroy_func value_destroy_func,
|
||||
_Py_hashtable_allocator_t *allocator);
|
||||
|
||||
PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht);
|
||||
|
||||
PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht);
|
||||
|
||||
typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht,
|
||||
const void *key, const void *value,
|
||||
void *user_data);
|
||||
|
||||
/* Call func() on each entry of the hashtable.
|
||||
Iteration stops if func() result is non-zero, in this case it's the result
|
||||
of the call. Otherwise, the function returns 0. */
|
||||
PyAPI_FUNC(int) _Py_hashtable_foreach(
|
||||
_Py_hashtable_t *ht,
|
||||
_Py_hashtable_foreach_func func,
|
||||
void *user_data);
|
||||
|
||||
PyAPI_FUNC(size_t) _Py_hashtable_size(const _Py_hashtable_t *ht);
|
||||
|
||||
/* Add a new entry to the hash. The key must not be present in the hash table.
|
||||
Return 0 on success, -1 on memory error. */
|
||||
PyAPI_FUNC(int) _Py_hashtable_set(
|
||||
_Py_hashtable_t *ht,
|
||||
const void *key,
|
||||
void *value);
|
||||
|
||||
|
||||
/* Get an entry.
|
||||
Return NULL if the key does not exist. */
|
||||
static inline _Py_hashtable_entry_t *
|
||||
_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key)
|
||||
{
|
||||
return ht->get_entry_func(ht, key);
|
||||
}
|
||||
|
||||
|
||||
/* Get value from an entry.
|
||||
Return NULL if the entry is not found.
|
||||
|
||||
Use _Py_hashtable_get_entry() to distinguish entry value equal to NULL
|
||||
and entry not found. */
|
||||
PyAPI_FUNC(void*) _Py_hashtable_get(_Py_hashtable_t *ht, const void *key);
|
||||
|
||||
|
||||
/* Remove a key and its associated value without calling key and value destroy
|
||||
functions.
|
||||
|
||||
Return the removed value if the key was found.
|
||||
Return NULL if the key was not found. */
|
||||
PyAPI_FUNC(void*) _Py_hashtable_steal(
|
||||
_Py_hashtable_t *ht,
|
||||
const void *key);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_HASHTABLE_H */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef Py_LIMITED_API
|
||||
#ifndef Py_INTERNAL_IMPORT_H
|
||||
#define Py_INTERNAL_IMPORT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FORK
|
||||
extern PyStatus _PyImport_ReInitLock(void);
|
||||
#endif
|
||||
extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_IMPORT_H */
|
||||
#endif /* !Py_LIMITED_API */
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef Py_INTERNAL_CORECONFIG_H
|
||||
#define Py_INTERNAL_CORECONFIG_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
/* Forward declaration */
|
||||
struct pyruntimestate;
|
||||
|
||||
/* --- PyStatus ----------------------------------------------- */
|
||||
|
||||
/* Almost all errors causing Python initialization to fail */
|
||||
#ifdef _MSC_VER
|
||||
/* Visual Studio 2015 doesn't implement C99 __func__ in C */
|
||||
# define _PyStatus_GET_FUNC() __FUNCTION__
|
||||
#else
|
||||
# define _PyStatus_GET_FUNC() __func__
|
||||
#endif
|
||||
|
||||
#define _PyStatus_OK() \
|
||||
(PyStatus){._type = _PyStatus_TYPE_OK,}
|
||||
/* other fields are set to 0 */
|
||||
#define _PyStatus_ERR(ERR_MSG) \
|
||||
(PyStatus){ \
|
||||
._type = _PyStatus_TYPE_ERROR, \
|
||||
.func = _PyStatus_GET_FUNC(), \
|
||||
.err_msg = (ERR_MSG)}
|
||||
/* other fields are set to 0 */
|
||||
#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed")
|
||||
#define _PyStatus_EXIT(EXITCODE) \
|
||||
(PyStatus){ \
|
||||
._type = _PyStatus_TYPE_EXIT, \
|
||||
.exitcode = (EXITCODE)}
|
||||
#define _PyStatus_IS_ERROR(err) \
|
||||
(err._type == _PyStatus_TYPE_ERROR)
|
||||
#define _PyStatus_IS_EXIT(err) \
|
||||
(err._type == _PyStatus_TYPE_EXIT)
|
||||
#define _PyStatus_EXCEPTION(err) \
|
||||
(err._type != _PyStatus_TYPE_OK)
|
||||
#define _PyStatus_UPDATE_FUNC(err) \
|
||||
do { err.func = _PyStatus_GET_FUNC(); } while (0)
|
||||
|
||||
PyObject* _PyErr_SetFromPyStatus(PyStatus status);
|
||||
|
||||
/* --- PyWideStringList ------------------------------------------------ */
|
||||
|
||||
#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}
|
||||
|
||||
#ifndef NDEBUG
|
||||
PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list);
|
||||
#endif
|
||||
PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list);
|
||||
PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list,
|
||||
const PyWideStringList *list2);
|
||||
PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list,
|
||||
const PyWideStringList *list2);
|
||||
PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list);
|
||||
|
||||
|
||||
/* --- _PyArgv ---------------------------------------------------- */
|
||||
|
||||
typedef struct _PyArgv {
|
||||
Py_ssize_t argc;
|
||||
int use_bytes_argv;
|
||||
char * const *bytes_argv;
|
||||
wchar_t * const *wchar_argv;
|
||||
} _PyArgv;
|
||||
|
||||
PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args,
|
||||
PyWideStringList *list);
|
||||
|
||||
|
||||
/* --- Helper functions ------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(int) _Py_str_to_int(
|
||||
const char *str,
|
||||
int *result);
|
||||
PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
|
||||
const PyWideStringList *xoptions,
|
||||
const wchar_t *name);
|
||||
PyAPI_FUNC(const char*) _Py_GetEnv(
|
||||
int use_environment,
|
||||
const char *name);
|
||||
PyAPI_FUNC(void) _Py_get_env_flag(
|
||||
int use_environment,
|
||||
int *flag,
|
||||
const char *name);
|
||||
|
||||
/* Py_GetArgcArgv() helper */
|
||||
PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
|
||||
|
||||
|
||||
/* --- _PyPreCmdline ------------------------------------------------- */
|
||||
|
||||
typedef struct {
|
||||
PyWideStringList argv;
|
||||
PyWideStringList xoptions; /* "-X value" option */
|
||||
int isolated; /* -I option */
|
||||
int use_environment; /* -E option */
|
||||
int dev_mode; /* -X dev and PYTHONDEVMODE */
|
||||
int warn_default_encoding; /* -X warn_default_encoding and PYTHONWARNDEFAULTENCODING */
|
||||
} _PyPreCmdline;
|
||||
|
||||
#define _PyPreCmdline_INIT \
|
||||
(_PyPreCmdline){ \
|
||||
.use_environment = -1, \
|
||||
.isolated = -1, \
|
||||
.dev_mode = -1}
|
||||
/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
|
||||
|
||||
extern void _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
|
||||
extern PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
|
||||
const _PyArgv *args);
|
||||
extern PyStatus _PyPreCmdline_SetConfig(
|
||||
const _PyPreCmdline *cmdline,
|
||||
PyConfig *config);
|
||||
extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline,
|
||||
const PyPreConfig *preconfig);
|
||||
|
||||
|
||||
/* --- PyPreConfig ----------------------------------------------- */
|
||||
|
||||
PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig);
|
||||
extern void _PyPreConfig_InitFromConfig(
|
||||
PyPreConfig *preconfig,
|
||||
const PyConfig *config);
|
||||
extern PyStatus _PyPreConfig_InitFromPreConfig(
|
||||
PyPreConfig *preconfig,
|
||||
const PyPreConfig *config2);
|
||||
extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig);
|
||||
extern void _PyPreConfig_GetConfig(PyPreConfig *preconfig,
|
||||
const PyConfig *config);
|
||||
extern PyStatus _PyPreConfig_Read(PyPreConfig *preconfig,
|
||||
const _PyArgv *args);
|
||||
extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig);
|
||||
|
||||
|
||||
/* --- PyConfig ---------------------------------------------- */
|
||||
|
||||
typedef enum {
|
||||
/* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */
|
||||
_PyConfig_INIT_COMPAT = 1,
|
||||
_PyConfig_INIT_PYTHON = 2,
|
||||
_PyConfig_INIT_ISOLATED = 3
|
||||
} _PyConfigInitEnum;
|
||||
|
||||
PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config);
|
||||
extern PyStatus _PyConfig_Copy(
|
||||
PyConfig *config,
|
||||
const PyConfig *config2);
|
||||
extern PyStatus _PyConfig_InitPathConfig(
|
||||
PyConfig *config,
|
||||
int compute_path_config);
|
||||
extern PyStatus _PyConfig_Read(PyConfig *config, int compute_path_config);
|
||||
extern PyStatus _PyConfig_Write(const PyConfig *config,
|
||||
struct pyruntimestate *runtime);
|
||||
extern PyStatus _PyConfig_SetPyArgv(
|
||||
PyConfig *config,
|
||||
const _PyArgv *args);
|
||||
|
||||
PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config);
|
||||
PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict);
|
||||
|
||||
extern int _Py_global_config_int_max_str_digits;
|
||||
|
||||
|
||||
/* --- Function used for testing ---------------------------------- */
|
||||
|
||||
PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_CORECONFIG_H */
|
||||
@@ -0,0 +1,339 @@
|
||||
#ifndef Py_INTERNAL_INTERP_H
|
||||
#define Py_INTERNAL_INTERP_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_atomic.h" // _Py_atomic_address
|
||||
#include "pycore_ast_state.h" // struct ast_state
|
||||
#include "pycore_gil.h" // struct _gil_runtime_state
|
||||
#include "pycore_gc.h" // struct _gc_runtime_state
|
||||
#include "pycore_warnings.h" // struct _warnings_runtime_state
|
||||
|
||||
struct _pending_calls {
|
||||
PyThread_type_lock lock;
|
||||
/* Request for running pending calls. */
|
||||
_Py_atomic_int calls_to_do;
|
||||
/* Request for looking at the `async_exc` field of the current
|
||||
thread state.
|
||||
Guarded by the GIL. */
|
||||
int async_exc;
|
||||
#define NPENDINGCALLS 32
|
||||
struct {
|
||||
int (*func)(void *);
|
||||
void *arg;
|
||||
} calls[NPENDINGCALLS];
|
||||
int first;
|
||||
int last;
|
||||
};
|
||||
|
||||
struct _ceval_state {
|
||||
int recursion_limit;
|
||||
/* This single variable consolidates all requests to break out of
|
||||
the fast path in the eval loop. */
|
||||
_Py_atomic_int eval_breaker;
|
||||
/* Request for dropping the GIL */
|
||||
_Py_atomic_int gil_drop_request;
|
||||
struct _pending_calls pending;
|
||||
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
|
||||
struct _gil_runtime_state gil;
|
||||
#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;
|
||||
|
||||
// Unused member kept for ABI backward compatibility with Python 3.10.0:
|
||||
// see bpo-46006.
|
||||
PyObject *unused_interned;
|
||||
|
||||
// Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
|
||||
struct _Py_unicode_ids ids;
|
||||
};
|
||||
|
||||
struct _Py_float_state {
|
||||
/* 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;
|
||||
};
|
||||
|
||||
/* 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 {
|
||||
PyListObject *free_list[PyList_MAXFREELIST];
|
||||
int numfree;
|
||||
};
|
||||
|
||||
#ifndef PyDict_MAXFREELIST
|
||||
# define PyDict_MAXFREELIST 80
|
||||
#endif
|
||||
|
||||
struct _Py_dict_state {
|
||||
/* 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;
|
||||
};
|
||||
|
||||
struct _Py_frame_state {
|
||||
PyFrameObject *free_list;
|
||||
/* number of frames currently in free_list */
|
||||
int numfree;
|
||||
};
|
||||
|
||||
#ifndef _PyAsyncGen_MAXFREELIST
|
||||
# define _PyAsyncGen_MAXFREELIST 80
|
||||
#endif
|
||||
|
||||
struct _Py_async_gen_state {
|
||||
/* 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;
|
||||
};
|
||||
|
||||
struct _Py_context_state {
|
||||
// List of free PyContext objects
|
||||
PyContext *freelist;
|
||||
int numfree;
|
||||
};
|
||||
|
||||
struct _Py_exc_state {
|
||||
// The dict mapping from errno codes to OSError subclasses
|
||||
PyObject *errnomap;
|
||||
PyBaseExceptionObject *memerrors_freelist;
|
||||
int memerrors_numfree;
|
||||
};
|
||||
|
||||
|
||||
// atexit state
|
||||
typedef struct {
|
||||
PyObject *func;
|
||||
PyObject *args;
|
||||
PyObject *kwargs;
|
||||
} atexit_callback;
|
||||
|
||||
struct atexit_state {
|
||||
atexit_callback **callbacks;
|
||||
int ncallbacks;
|
||||
int callback_len;
|
||||
};
|
||||
|
||||
|
||||
// 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 */
|
||||
|
||||
#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
|
||||
|
||||
// The PyInterpreterState typedef is in Include/pystate.h.
|
||||
struct _is {
|
||||
|
||||
struct _is *next;
|
||||
struct _ts *tstate_head;
|
||||
|
||||
/* Reference to the _PyRuntime global variable. This field exists
|
||||
to not have to pass runtime in addition to tstate to a function.
|
||||
Get runtime from tstate: tstate->interp->runtime. */
|
||||
struct pyruntimestate *runtime;
|
||||
|
||||
int64_t id;
|
||||
int64_t id_refcount;
|
||||
int requires_idref;
|
||||
PyThread_type_lock id_mutex;
|
||||
|
||||
int finalizing;
|
||||
|
||||
struct _ceval_state ceval;
|
||||
struct _gc_runtime_state gc;
|
||||
|
||||
// sys.modules dictionary
|
||||
PyObject *modules;
|
||||
PyObject *modules_by_index;
|
||||
// Dictionary of the sys module
|
||||
PyObject *sysdict;
|
||||
// Dictionary of the builtins module
|
||||
PyObject *builtins;
|
||||
// importlib module
|
||||
PyObject *importlib;
|
||||
|
||||
/* Used in Modules/_threadmodule.c. */
|
||||
long num_threads;
|
||||
/* Support for runtime thread stack size tuning.
|
||||
A value of 0 means using the platform's default stack size
|
||||
or the size specified by the THREAD_STACK_SIZE macro. */
|
||||
/* Used in Python/thread.c. */
|
||||
size_t pythread_stacksize;
|
||||
|
||||
PyObject *codec_search_path;
|
||||
PyObject *codec_search_cache;
|
||||
PyObject *codec_error_registry;
|
||||
int codecs_initialized;
|
||||
|
||||
PyConfig config;
|
||||
#ifdef HAVE_DLOPEN
|
||||
int dlopenflags;
|
||||
#endif
|
||||
|
||||
PyObject *dict; /* Stores per-interpreter state */
|
||||
|
||||
PyObject *builtins_copy;
|
||||
PyObject *import_func;
|
||||
// Initialized to _PyEval_EvalFrameDefault().
|
||||
_PyFrameEvalFunction eval_frame;
|
||||
|
||||
Py_ssize_t co_extra_user_count;
|
||||
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
|
||||
|
||||
#ifdef HAVE_FORK
|
||||
PyObject *before_forkers;
|
||||
PyObject *after_forkers_parent;
|
||||
PyObject *after_forkers_child;
|
||||
#endif
|
||||
|
||||
uint64_t tstate_next_unique_id;
|
||||
|
||||
struct _warnings_runtime_state warnings;
|
||||
struct atexit_state atexit;
|
||||
|
||||
PyObject *audit_hooks;
|
||||
|
||||
/* 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_bytes_state bytes;
|
||||
struct _Py_unicode_state unicode;
|
||||
struct _Py_float_state float_state;
|
||||
/* Using a cache is very effective since typically only a single slice is
|
||||
created and then deleted again. */
|
||||
PySliceObject *slice_cache;
|
||||
|
||||
struct _Py_tuple_state tuple;
|
||||
struct _Py_list_state list;
|
||||
struct _Py_dict_state dict_state;
|
||||
struct _Py_frame_state frame;
|
||||
struct _Py_async_gen_state async_gen;
|
||||
struct _Py_context_state context;
|
||||
struct _Py_exc_state exc_state;
|
||||
|
||||
struct ast_state ast;
|
||||
struct type_cache type_cache;
|
||||
|
||||
int int_max_str_digits;
|
||||
};
|
||||
|
||||
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
|
||||
extern void _PyInterpreterState_Clear(PyThreadState *tstate);
|
||||
|
||||
|
||||
/* cross-interpreter data registry */
|
||||
|
||||
/* For now we use a global registry of shareable classes. An
|
||||
alternative would be to add a tp_* slot for a class's
|
||||
crossinterpdatafunc. It would be simpler and more efficient. */
|
||||
|
||||
struct _xidregitem;
|
||||
|
||||
struct _xidregitem {
|
||||
PyTypeObject *cls;
|
||||
crossinterpdatafunc getdata;
|
||||
struct _xidregitem *next;
|
||||
};
|
||||
|
||||
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(int64_t);
|
||||
|
||||
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
|
||||
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *);
|
||||
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_INTERP_H */
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef Py_INTERNAL_LIST_H
|
||||
#define Py_INTERNAL_LIST_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "listobject.h" // _PyList_CAST()
|
||||
|
||||
|
||||
#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_LIST_H */
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef Py_INTERNAL_LONG_H
|
||||
#define Py_INTERNAL_LONG_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_interp.h" // PyInterpreterState.small_ints
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
|
||||
/*
|
||||
* Default int base conversion size limitation: Denial of Service prevention.
|
||||
*
|
||||
* Chosen such that this isn't wildly slow on modern hardware and so that
|
||||
* everyone's existing deployed numpy test suite passes before
|
||||
* https://github.com/numpy/numpy/issues/22098 is widely available.
|
||||
*
|
||||
* $ python -m timeit -s 's = "1"*4300' 'int(s)'
|
||||
* 2000 loops, best of 5: 125 usec per loop
|
||||
* $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)'
|
||||
* 1000 loops, best of 5: 311 usec per loop
|
||||
* (zen2 cloud VM)
|
||||
*
|
||||
* 4300 decimal digits fits a ~14284 bit number.
|
||||
*/
|
||||
#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
|
||||
/*
|
||||
* Threshold for max digits check. For performance reasons int() and
|
||||
* int.__str__() don't checks values that are smaller than this
|
||||
* threshold. Acts as a guaranteed minimum size limit for bignums that
|
||||
* applications can expect from CPython.
|
||||
*
|
||||
* % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))'
|
||||
* 20000 loops, best of 5: 12 usec per loop
|
||||
*
|
||||
* "640 digits should be enough for anyone." - gps
|
||||
* fits a ~2126 bit decimal number.
|
||||
*/
|
||||
#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
|
||||
|
||||
#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
|
||||
(_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
|
||||
# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
|
||||
#endif
|
||||
|
||||
// Don't call this function but _PyLong_GetZero() and _PyLong_GetOne()
|
||||
static inline PyObject* __PyLong_GetSmallInt_internal(int value)
|
||||
{
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS);
|
||||
size_t index = _PY_NSMALLNEGINTS + value;
|
||||
PyObject *obj = (PyObject*)interp->small_ints[index];
|
||||
// _PyLong_GetZero(), _PyLong_GetOne() and get_small_int() must not be
|
||||
// called before _PyLong_Init() nor after _PyLong_Fini().
|
||||
assert(obj != NULL);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Return a borrowed reference to the zero singleton.
|
||||
// The function cannot return NULL.
|
||||
static inline PyObject* _PyLong_GetZero(void)
|
||||
{ return __PyLong_GetSmallInt_internal(0); }
|
||||
|
||||
// Return a borrowed reference to the one singleton.
|
||||
// The function cannot return NULL.
|
||||
static inline PyObject* _PyLong_GetOne(void)
|
||||
{ return __PyLong_GetSmallInt_internal(1); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_LONG_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef Py_INTERNAL_MODULEOBJECT_H
|
||||
#define Py_INTERNAL_MODULEOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *md_dict;
|
||||
struct PyModuleDef *md_def;
|
||||
void *md_state;
|
||||
PyObject *md_weaklist;
|
||||
// for logging purposes after md_dict is cleared
|
||||
PyObject *md_name;
|
||||
} PyModuleObject;
|
||||
|
||||
static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) {
|
||||
assert(PyModule_Check(mod));
|
||||
return ((PyModuleObject *)mod)->md_def;
|
||||
}
|
||||
|
||||
static inline void* _PyModule_GetState(PyObject* mod) {
|
||||
assert(PyModule_Check(mod));
|
||||
return ((PyModuleObject *)mod)->md_state;
|
||||
}
|
||||
|
||||
static inline PyObject* _PyModule_GetDict(PyObject *mod) {
|
||||
assert(PyModule_Check(mod));
|
||||
PyObject *dict = ((PyModuleObject *)mod) -> md_dict;
|
||||
// _PyModule_GetDict(mod) must not be used after calling module_clear(mod)
|
||||
assert(dict != NULL);
|
||||
return dict;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_MODULEOBJECT_H */
|
||||
@@ -0,0 +1,186 @@
|
||||
#ifndef Py_INTERNAL_OBJECT_H
|
||||
#define Py_INTERNAL_OBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
|
||||
#include "pycore_interp.h" // PyInterpreterState.gc
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
|
||||
PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
|
||||
PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
|
||||
|
||||
/* Update the Python traceback of an object. This function must be called
|
||||
when a memory block is reused from a free list.
|
||||
|
||||
Internal function called by _Py_NewReference(). */
|
||||
extern int _PyTraceMalloc_NewReference(PyObject *op);
|
||||
|
||||
// Fast inlined version of PyType_HasFeature()
|
||||
static inline int
|
||||
_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
|
||||
return ((type->tp_flags & feature) != 0);
|
||||
}
|
||||
|
||||
extern void _PyType_InitCache(PyInterpreterState *interp);
|
||||
|
||||
/* Only private in Python 3.10 and 3.9.8+; public in 3.11 */
|
||||
extern PyObject *_PyType_GetQualName(PyTypeObject *type);
|
||||
|
||||
/* Inline functions trading binary compatibility for speed:
|
||||
_PyObject_Init() is the fast version of PyObject_Init(), and
|
||||
_PyObject_InitVar() is the fast version of PyObject_InitVar().
|
||||
|
||||
These inline functions must not be called with op=NULL. */
|
||||
static inline void
|
||||
_PyObject_Init(PyObject *op, PyTypeObject *typeobj)
|
||||
{
|
||||
assert(op != NULL);
|
||||
Py_SET_TYPE(op, typeobj);
|
||||
if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
|
||||
Py_INCREF(typeobj);
|
||||
}
|
||||
_Py_NewReference(op);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
|
||||
{
|
||||
assert(op != NULL);
|
||||
Py_SET_SIZE(op, size);
|
||||
_PyObject_Init((PyObject *)op, typeobj);
|
||||
}
|
||||
|
||||
|
||||
/* Tell the GC to track this object.
|
||||
*
|
||||
* The object must not be tracked by the GC.
|
||||
*
|
||||
* NB: While the object is tracked by the collector, it must be safe to call the
|
||||
* ob_traverse method.
|
||||
*
|
||||
* Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags
|
||||
* because it's not object header. So we don't use _PyGCHead_PREV() and
|
||||
* _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
|
||||
*
|
||||
* See also the public PyObject_GC_Track() function.
|
||||
*/
|
||||
static inline void _PyObject_GC_TRACK(
|
||||
// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
|
||||
#ifndef NDEBUG
|
||||
const char *filename, int lineno,
|
||||
#endif
|
||||
PyObject *op)
|
||||
{
|
||||
_PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
|
||||
"object already tracked by the garbage collector",
|
||||
filename, lineno, __func__);
|
||||
|
||||
PyGC_Head *gc = _Py_AS_GC(op);
|
||||
_PyObject_ASSERT_FROM(op,
|
||||
(gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
|
||||
"object is in generation which is garbage collected",
|
||||
filename, lineno, __func__);
|
||||
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
PyGC_Head *generation0 = interp->gc.generation0;
|
||||
PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
|
||||
_PyGCHead_SET_NEXT(last, gc);
|
||||
_PyGCHead_SET_PREV(gc, last);
|
||||
_PyGCHead_SET_NEXT(gc, generation0);
|
||||
generation0->_gc_prev = (uintptr_t)gc;
|
||||
}
|
||||
|
||||
/* Tell the GC to stop tracking this object.
|
||||
*
|
||||
* Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING
|
||||
* must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
|
||||
*
|
||||
* The object must be tracked by the GC.
|
||||
*
|
||||
* See also the public PyObject_GC_UnTrack() which accept an object which is
|
||||
* not tracked.
|
||||
*/
|
||||
static inline void _PyObject_GC_UNTRACK(
|
||||
// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
|
||||
#ifndef NDEBUG
|
||||
const char *filename, int lineno,
|
||||
#endif
|
||||
PyObject *op)
|
||||
{
|
||||
_PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
|
||||
"object not tracked by the garbage collector",
|
||||
filename, lineno, __func__);
|
||||
|
||||
PyGC_Head *gc = _Py_AS_GC(op);
|
||||
PyGC_Head *prev = _PyGCHead_PREV(gc);
|
||||
PyGC_Head *next = _PyGCHead_NEXT(gc);
|
||||
_PyGCHead_SET_NEXT(prev, next);
|
||||
_PyGCHead_SET_PREV(next, prev);
|
||||
gc->_gc_next = 0;
|
||||
gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
|
||||
}
|
||||
|
||||
// Macros to accept any type for the parameter, and to automatically pass
|
||||
// the filename and the filename (if NDEBUG is not defined) where the macro
|
||||
// is called.
|
||||
#ifdef NDEBUG
|
||||
# define _PyObject_GC_TRACK(op) \
|
||||
_PyObject_GC_TRACK(_PyObject_CAST(op))
|
||||
# define _PyObject_GC_UNTRACK(op) \
|
||||
_PyObject_GC_UNTRACK(_PyObject_CAST(op))
|
||||
#else
|
||||
# define _PyObject_GC_TRACK(op) \
|
||||
_PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op))
|
||||
# define _PyObject_GC_UNTRACK(op) \
|
||||
_PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
|
||||
#endif
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
extern void _PyDebug_PrintTotalRefs(void);
|
||||
#endif
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
extern void _Py_AddToAllObjects(PyObject *op, int force);
|
||||
extern void _Py_PrintReferences(FILE *);
|
||||
extern void _Py_PrintReferenceAddresses(FILE *);
|
||||
#endif
|
||||
|
||||
static inline PyObject **
|
||||
_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
|
||||
{
|
||||
Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
|
||||
return (PyObject **)((char *)op + offset);
|
||||
}
|
||||
|
||||
// Fast inlined version of PyObject_IS_GC()
|
||||
static inline int
|
||||
_PyObject_IS_GC(PyObject *obj)
|
||||
{
|
||||
return (PyType_IS_GC(Py_TYPE(obj))
|
||||
&& (Py_TYPE(obj)->tp_is_gc == NULL
|
||||
|| Py_TYPE(obj)->tp_is_gc(obj)));
|
||||
}
|
||||
|
||||
// Fast inlined version of PyType_IS_GC()
|
||||
#define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
|
||||
|
||||
// Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL));
|
||||
extern int _Py_CheckSlotResult(
|
||||
PyObject *obj,
|
||||
const char *slot_name,
|
||||
int success);
|
||||
|
||||
// PyType_Ready() must be called if _PyType_IsReady() is false.
|
||||
// See also the Py_TPFLAGS_READY flag.
|
||||
#define _PyType_IsReady(type) ((type)->tp_dict != NULL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_OBJECT_H */
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef Py_INTERNAL_PARSER_H
|
||||
#define Py_INTERNAL_PARSER_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
extern struct _mod* _PyParser_ASTFromString(
|
||||
const char *str,
|
||||
PyObject* filename,
|
||||
int mode,
|
||||
PyCompilerFlags *flags,
|
||||
PyArena *arena);
|
||||
extern struct _mod* _PyParser_ASTFromFile(
|
||||
FILE *fp,
|
||||
PyObject *filename_ob,
|
||||
const char *enc,
|
||||
int mode,
|
||||
const char *ps1,
|
||||
const char *ps2,
|
||||
PyCompilerFlags *flags,
|
||||
int *errcode,
|
||||
PyArena *arena);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_PARSER_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef Py_INTERNAL_PATHCONFIG_H
|
||||
#define Py_INTERNAL_PATHCONFIG_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
typedef struct _PyPathConfig {
|
||||
/* Full path to the Python program */
|
||||
wchar_t *program_full_path;
|
||||
wchar_t *prefix;
|
||||
wchar_t *exec_prefix;
|
||||
/* Set by Py_SetPath(), or computed by _PyConfig_InitPathConfig() */
|
||||
wchar_t *module_search_path;
|
||||
/* Python program name */
|
||||
wchar_t *program_name;
|
||||
/* Set by Py_SetPythonHome() or PYTHONHOME environment variable */
|
||||
wchar_t *home;
|
||||
#ifdef MS_WINDOWS
|
||||
/* isolated and site_import are used to set Py_IsolatedFlag and
|
||||
Py_NoSiteFlag flags on Windows in read_pth_file(). These fields
|
||||
are ignored when their value are equal to -1 (unset). */
|
||||
int isolated;
|
||||
int site_import;
|
||||
/* Set when a venv is detected */
|
||||
wchar_t *base_executable;
|
||||
#endif
|
||||
} _PyPathConfig;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
# define _PyPathConfig_INIT \
|
||||
{.module_search_path = NULL, \
|
||||
.isolated = -1, \
|
||||
.site_import = -1}
|
||||
#else
|
||||
# define _PyPathConfig_INIT \
|
||||
{.module_search_path = NULL}
|
||||
#endif
|
||||
/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */
|
||||
|
||||
PyAPI_DATA(_PyPathConfig) _Py_path_config;
|
||||
#ifdef MS_WINDOWS
|
||||
PyAPI_DATA(wchar_t*) _Py_dll_path;
|
||||
#endif
|
||||
|
||||
extern void _PyPathConfig_ClearGlobal(void);
|
||||
|
||||
extern PyStatus _PyPathConfig_Calculate(
|
||||
_PyPathConfig *pathconfig,
|
||||
const PyConfig *config);
|
||||
extern int _PyPathConfig_ComputeSysPath0(
|
||||
const PyWideStringList *argv,
|
||||
PyObject **path0);
|
||||
extern PyStatus _Py_FindEnvConfigValue(
|
||||
FILE *env_file,
|
||||
const wchar_t *key,
|
||||
wchar_t **value_p);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
extern wchar_t* _Py_GetDLLPath(void);
|
||||
#endif
|
||||
|
||||
extern PyStatus _PyConfig_WritePathConfig(const PyConfig *config);
|
||||
extern void _Py_DumpPathConfig(PyThreadState *tstate);
|
||||
extern PyObject* _PyPathConfig_AsDict(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_PATHCONFIG_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
/* An arena-like memory interface for the compiler.
|
||||
*/
|
||||
|
||||
#ifndef Py_INTERNAL_PYARENA_H
|
||||
#define Py_INTERNAL_PYARENA_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
typedef struct _arena PyArena;
|
||||
|
||||
/* _PyArena_New() and _PyArena_Free() create a new arena and free it,
|
||||
respectively. Once an arena has been created, it can be used
|
||||
to allocate memory via _PyArena_Malloc(). Pointers to PyObject can
|
||||
also be registered with the arena via _PyArena_AddPyObject(), and the
|
||||
arena will ensure that the PyObjects stay alive at least until
|
||||
_PyArena_Free() is called. When an arena is freed, all the memory it
|
||||
allocated is freed, the arena releases internal references to registered
|
||||
PyObject*, and none of its pointers are valid.
|
||||
XXX (tim) What does "none of its pointers are valid" mean? Does it
|
||||
XXX mean that pointers previously obtained via _PyArena_Malloc() are
|
||||
XXX no longer valid? (That's clearly true, but not sure that's what
|
||||
XXX the text is trying to say.)
|
||||
|
||||
_PyArena_New() returns an arena pointer. On error, it
|
||||
returns a negative number and sets an exception.
|
||||
XXX (tim): Not true. On error, _PyArena_New() actually returns NULL,
|
||||
XXX and looks like it may or may not set an exception (e.g., if the
|
||||
XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on
|
||||
XXX and an exception is set; OTOH, if the internal
|
||||
XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but
|
||||
XXX an exception is not set in that case).
|
||||
*/
|
||||
PyAPI_FUNC(PyArena*) _PyArena_New(void);
|
||||
PyAPI_FUNC(void) _PyArena_Free(PyArena *);
|
||||
|
||||
/* Mostly like malloc(), return the address of a block of memory spanning
|
||||
* `size` bytes, or return NULL (without setting an exception) if enough
|
||||
* new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with
|
||||
* size=0 does not guarantee to return a unique pointer (the pointer
|
||||
* returned may equal one or more other pointers obtained from
|
||||
* _PyArena_Malloc()).
|
||||
* Note that pointers obtained via _PyArena_Malloc() must never be passed to
|
||||
* the system free() or realloc(), or to any of Python's similar memory-
|
||||
* management functions. _PyArena_Malloc()-obtained pointers remain valid
|
||||
* until _PyArena_Free(ar) is called, at which point all pointers obtained
|
||||
* from the arena `ar` become invalid simultaneously.
|
||||
*/
|
||||
PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size);
|
||||
|
||||
/* This routine isn't a proper arena allocation routine. It takes
|
||||
* a PyObject* and records it so that it can be DECREFed when the
|
||||
* arena is freed.
|
||||
*/
|
||||
PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_PYARENA_H */
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifndef Py_INTERNAL_PYERRORS_H
|
||||
#define Py_INTERNAL_PYERRORS_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
|
||||
{
|
||||
assert(tstate != NULL);
|
||||
return tstate->curexc_type;
|
||||
}
|
||||
|
||||
static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state)
|
||||
{
|
||||
PyObject *t, *v, *tb;
|
||||
t = exc_state->exc_type;
|
||||
v = exc_state->exc_value;
|
||||
tb = exc_state->exc_traceback;
|
||||
exc_state->exc_type = NULL;
|
||||
exc_state->exc_value = NULL;
|
||||
exc_state->exc_traceback = NULL;
|
||||
Py_XDECREF(t);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(tb);
|
||||
}
|
||||
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_Fetch(
|
||||
PyThreadState *tstate,
|
||||
PyObject **type,
|
||||
PyObject **value,
|
||||
PyObject **traceback);
|
||||
|
||||
PyAPI_FUNC(int) _PyErr_ExceptionMatches(
|
||||
PyThreadState *tstate,
|
||||
PyObject *exc);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_Restore(
|
||||
PyThreadState *tstate,
|
||||
PyObject *type,
|
||||
PyObject *value,
|
||||
PyObject *traceback);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_SetObject(
|
||||
PyThreadState *tstate,
|
||||
PyObject *type,
|
||||
PyObject *value);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_ChainStackItem(
|
||||
_PyErr_StackItem *exc_info);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyErr_NoMemory(PyThreadState *tstate);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_SetString(
|
||||
PyThreadState *tstate,
|
||||
PyObject *exception,
|
||||
const char *string);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyErr_Format(
|
||||
PyThreadState *tstate,
|
||||
PyObject *exception,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_NormalizeException(
|
||||
PyThreadState *tstate,
|
||||
PyObject **exc,
|
||||
PyObject **val,
|
||||
PyObject **tb);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate(
|
||||
PyThreadState *tstate,
|
||||
PyObject *exception,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate);
|
||||
|
||||
PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp);
|
||||
|
||||
extern PyObject* _Py_Offer_Suggestions(PyObject* exception);
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b,
|
||||
Py_ssize_t max_cost);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_PYERRORS_H */
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef Py_INTERNAL_HASH_H
|
||||
#define Py_INTERNAL_HASH_H
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
#ifndef Py_INTERNAL_LIFECYCLE_H
|
||||
#define Py_INTERNAL_LIFECYCLE_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "pycore_runtime.h" // _PyRuntimeState
|
||||
|
||||
#ifndef NSIG
|
||||
# if defined(_NSIG)
|
||||
# define NSIG _NSIG /* For BSD/SysV */
|
||||
# elif defined(_SIGMAX)
|
||||
# define NSIG (_SIGMAX + 1) /* For QNX */
|
||||
# elif defined(SIGMAX)
|
||||
# define NSIG (SIGMAX + 1) /* For djgpp */
|
||||
# else
|
||||
# define NSIG 64 /* Use a reasonable default value */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
struct _PyArgv;
|
||||
struct pyruntimestate;
|
||||
|
||||
/* True if the main interpreter thread exited due to an unhandled
|
||||
* KeyboardInterrupt exception, suggesting the user pressed ^C. */
|
||||
PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt;
|
||||
|
||||
extern int _Py_SetFileSystemEncoding(
|
||||
const char *encoding,
|
||||
const char *errors);
|
||||
extern void _Py_ClearFileSystemEncoding(void);
|
||||
extern PyStatus _PyUnicode_InitEncodings(PyThreadState *tstate);
|
||||
#ifdef MS_WINDOWS
|
||||
extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void);
|
||||
#endif
|
||||
|
||||
PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void);
|
||||
|
||||
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 int _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);
|
||||
extern PyStatus _PySys_Create(
|
||||
PyThreadState *tstate,
|
||||
PyObject **sysmod_p);
|
||||
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);
|
||||
|
||||
|
||||
/* 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_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);
|
||||
extern void _PyWarnings_Fini(PyInterpreterState *interp);
|
||||
extern void _PyAST_Fini(PyInterpreterState *interp);
|
||||
extern void _PyAtExit_Fini(PyInterpreterState *interp);
|
||||
|
||||
extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime);
|
||||
extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate);
|
||||
extern void _PyGILState_Fini(PyInterpreterState *interp);
|
||||
|
||||
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp);
|
||||
|
||||
PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv(
|
||||
const PyPreConfig *src_config,
|
||||
const struct _PyArgv *args);
|
||||
PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig(
|
||||
const PyConfig *config,
|
||||
const struct _PyArgv *args);
|
||||
|
||||
|
||||
PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);
|
||||
|
||||
PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
|
||||
|
||||
PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate);
|
||||
PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception,
|
||||
PyObject *value, PyObject *tb);
|
||||
|
||||
PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate);
|
||||
|
||||
extern void _PyAtExit_Call(PyInterpreterState *interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_LIFECYCLE_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user