Rithwik Ravi commited on
Commit ·
128809c
1
Parent(s): 084f95a
fix: optimize GRPO trainer, ignore checkpoints and binary libs
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitignore +0 -0
- Dockerfile +24 -6
- Include/Python.h +140 -0
- Include/abstract.h +921 -0
- Include/bltinmodule.h +14 -0
- Include/boolobject.h +54 -0
- Include/bytearrayobject.h +44 -0
- Include/bytesobject.h +66 -0
- Include/ceval.h +145 -0
- Include/codecs.h +176 -0
- Include/compile.h +22 -0
- Include/complexobject.h +30 -0
- Include/cpython/abstract.h +87 -0
- Include/cpython/bytearrayobject.h +34 -0
- Include/cpython/bytesobject.h +37 -0
- Include/cpython/cellobject.h +44 -0
- Include/cpython/ceval.h +25 -0
- Include/cpython/classobject.h +71 -0
- Include/cpython/code.h +358 -0
- Include/cpython/compile.h +50 -0
- Include/cpython/complexobject.h +33 -0
- Include/cpython/context.h +74 -0
- Include/cpython/critical_section.h +134 -0
- Include/cpython/descrobject.h +62 -0
- Include/cpython/dictobject.h +102 -0
- Include/cpython/fileobject.h +16 -0
- Include/cpython/fileutils.h +8 -0
- Include/cpython/floatobject.h +27 -0
- Include/cpython/frameobject.h +35 -0
- Include/cpython/funcobject.h +184 -0
- Include/cpython/genobject.h +83 -0
- Include/cpython/import.h +25 -0
- Include/cpython/initconfig.h +274 -0
- Include/cpython/listobject.h +53 -0
- Include/cpython/lock.h +63 -0
- Include/cpython/longintrepr.h +146 -0
- Include/cpython/longobject.h +116 -0
- Include/cpython/memoryobject.h +50 -0
- Include/cpython/methodobject.h +66 -0
- Include/cpython/modsupport.h +26 -0
- Include/cpython/monitoring.h +250 -0
- Include/cpython/object.h +525 -0
- Include/cpython/objimpl.h +104 -0
- Include/cpython/odictobject.h +43 -0
- Include/cpython/picklebufobject.h +31 -0
- Include/cpython/pthread_stubs.h +105 -0
- Include/cpython/pyatomic.h +569 -0
- Include/cpython/pyatomic_gcc.h +551 -0
- Include/cpython/pyatomic_msc.h +1095 -0
- Include/cpython/pyatomic_std.h +976 -0
.gitignore
CHANGED
|
Binary files a/.gitignore and b/.gitignore differ
|
|
|
Dockerfile
CHANGED
|
@@ -1,15 +1,33 @@
|
|
| 1 |
-
FROM python:3.
|
| 2 |
|
| 3 |
-
#
|
| 4 |
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 5 |
build-essential \
|
| 6 |
&& rm -rf /var/lib/apt/lists/*
|
| 7 |
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
RUN pip install --no-cache-dir -r requirements.txt
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
-
|
|
|
|
| 14 |
|
| 15 |
-
|
|
|
|
|
|
| 1 |
+
FROM python:3.13-slim
|
| 2 |
|
| 3 |
+
# Install system dependencies
|
| 4 |
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 5 |
build-essential \
|
| 6 |
&& rm -rf /var/lib/apt/lists/*
|
| 7 |
|
| 8 |
+
# Hugging Face Spaces requires running as a non-root user (UID 1000)
|
| 9 |
+
RUN useradd -m -u 1000 user
|
| 10 |
+
USER user
|
| 11 |
+
ENV HOME=/home/user \
|
| 12 |
+
PATH=/home/user/.local/bin:$PATH
|
| 13 |
|
| 14 |
+
WORKDIR $HOME/app
|
| 15 |
+
|
| 16 |
+
# Copy requirements
|
| 17 |
+
COPY --chown=user requirements.txt .
|
| 18 |
+
|
| 19 |
+
# Install PyTorch 2.11 with cu126 (matching our local battle-tested environment)
|
| 20 |
+
RUN pip install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126 --upgrade
|
| 21 |
+
|
| 22 |
+
# Install remaining requirements and Triton explicitly for Linux cloud environment
|
| 23 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 24 |
+
RUN pip install --no-cache-dir triton
|
| 25 |
+
|
| 26 |
+
# Copy application files
|
| 27 |
+
COPY --chown=user . .
|
| 28 |
|
| 29 |
+
# Expose the mandatory port required by Hugging Face Spaces
|
| 30 |
+
EXPOSE 7860
|
| 31 |
|
| 32 |
+
# Launch the core FastAPI application on the expected HF Spaces port
|
| 33 |
+
CMD ["python", "-m", "uvicorn", "src.api.server:app", "--host", "0.0.0.0", "--port", "7860"]
|
Include/Python.h
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Entry point of the Python C API.
|
| 2 |
+
// C extensions should only #include <Python.h>, and not include directly
|
| 3 |
+
// the other Python header files included by <Python.h>.
|
| 4 |
+
|
| 5 |
+
#ifndef Py_PYTHON_H
|
| 6 |
+
#define Py_PYTHON_H
|
| 7 |
+
|
| 8 |
+
// Since this is a "meta-include" file, "#ifdef __cplusplus / extern "C" {"
|
| 9 |
+
// is not needed.
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
// Include Python header files
|
| 13 |
+
#include "patchlevel.h"
|
| 14 |
+
#include "pyconfig.h"
|
| 15 |
+
#include "pymacconfig.h"
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
// Include standard header files
|
| 19 |
+
// When changing these files, remember to update Doc/extending/extending.rst.
|
| 20 |
+
#include <assert.h> // assert()
|
| 21 |
+
#include <inttypes.h> // uintptr_t
|
| 22 |
+
#include <limits.h> // INT_MAX
|
| 23 |
+
#include <math.h> // HUGE_VAL
|
| 24 |
+
#include <stdarg.h> // va_list
|
| 25 |
+
#include <wchar.h> // wchar_t
|
| 26 |
+
#ifdef HAVE_SYS_TYPES_H
|
| 27 |
+
# include <sys/types.h> // ssize_t
|
| 28 |
+
#endif
|
| 29 |
+
|
| 30 |
+
// <errno.h>, <stdio.h>, <stdlib.h> and <string.h> headers are no longer used
|
| 31 |
+
// by Python, but kept for the backward compatibility of existing third party C
|
| 32 |
+
// extensions. They are not included by limited C API version 3.11 and newer.
|
| 33 |
+
//
|
| 34 |
+
// The <ctype.h> and <unistd.h> headers are not included by limited C API
|
| 35 |
+
// version 3.13 and newer.
|
| 36 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
| 37 |
+
# include <errno.h> // errno
|
| 38 |
+
# include <stdio.h> // FILE*
|
| 39 |
+
# include <stdlib.h> // getenv()
|
| 40 |
+
# include <string.h> // memcpy()
|
| 41 |
+
#endif
|
| 42 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000
|
| 43 |
+
# include <ctype.h> // tolower()
|
| 44 |
+
# ifndef MS_WINDOWS
|
| 45 |
+
# include <unistd.h> // close()
|
| 46 |
+
# endif
|
| 47 |
+
#endif
|
| 48 |
+
|
| 49 |
+
// gh-111506: The free-threaded build is not compatible with the limited API
|
| 50 |
+
// or the stable ABI.
|
| 51 |
+
#if defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED)
|
| 52 |
+
# error "The limited API is not currently supported in the free-threaded build"
|
| 53 |
+
#endif
|
| 54 |
+
|
| 55 |
+
#if defined(Py_GIL_DISABLED) && defined(_MSC_VER)
|
| 56 |
+
# include <intrin.h> // __readgsqword()
|
| 57 |
+
#endif
|
| 58 |
+
|
| 59 |
+
#if defined(Py_GIL_DISABLED) && defined(__MINGW32__)
|
| 60 |
+
# include <intrin.h> // __readgsqword()
|
| 61 |
+
#endif
|
| 62 |
+
|
| 63 |
+
// Include Python header files
|
| 64 |
+
#include "pyport.h"
|
| 65 |
+
#include "pymacro.h"
|
| 66 |
+
#include "pymath.h"
|
| 67 |
+
#include "pymem.h"
|
| 68 |
+
#include "pytypedefs.h"
|
| 69 |
+
#include "pybuffer.h"
|
| 70 |
+
#include "pystats.h"
|
| 71 |
+
#include "pyatomic.h"
|
| 72 |
+
#include "lock.h"
|
| 73 |
+
#include "object.h"
|
| 74 |
+
#include "objimpl.h"
|
| 75 |
+
#include "typeslots.h"
|
| 76 |
+
#include "pyhash.h"
|
| 77 |
+
#include "cpython/pydebug.h"
|
| 78 |
+
#include "bytearrayobject.h"
|
| 79 |
+
#include "bytesobject.h"
|
| 80 |
+
#include "unicodeobject.h"
|
| 81 |
+
#include "pyerrors.h"
|
| 82 |
+
#include "longobject.h"
|
| 83 |
+
#include "cpython/longintrepr.h"
|
| 84 |
+
#include "boolobject.h"
|
| 85 |
+
#include "floatobject.h"
|
| 86 |
+
#include "complexobject.h"
|
| 87 |
+
#include "rangeobject.h"
|
| 88 |
+
#include "memoryobject.h"
|
| 89 |
+
#include "tupleobject.h"
|
| 90 |
+
#include "listobject.h"
|
| 91 |
+
#include "dictobject.h"
|
| 92 |
+
#include "cpython/odictobject.h"
|
| 93 |
+
#include "enumobject.h"
|
| 94 |
+
#include "setobject.h"
|
| 95 |
+
#include "methodobject.h"
|
| 96 |
+
#include "moduleobject.h"
|
| 97 |
+
#include "monitoring.h"
|
| 98 |
+
#include "cpython/funcobject.h"
|
| 99 |
+
#include "cpython/classobject.h"
|
| 100 |
+
#include "fileobject.h"
|
| 101 |
+
#include "pycapsule.h"
|
| 102 |
+
#include "cpython/code.h"
|
| 103 |
+
#include "pyframe.h"
|
| 104 |
+
#include "traceback.h"
|
| 105 |
+
#include "sliceobject.h"
|
| 106 |
+
#include "cpython/cellobject.h"
|
| 107 |
+
#include "iterobject.h"
|
| 108 |
+
#include "cpython/initconfig.h"
|
| 109 |
+
#include "pystate.h"
|
| 110 |
+
#include "cpython/genobject.h"
|
| 111 |
+
#include "descrobject.h"
|
| 112 |
+
#include "genericaliasobject.h"
|
| 113 |
+
#include "warnings.h"
|
| 114 |
+
#include "weakrefobject.h"
|
| 115 |
+
#include "structseq.h"
|
| 116 |
+
#include "cpython/picklebufobject.h"
|
| 117 |
+
#include "cpython/pytime.h"
|
| 118 |
+
#include "codecs.h"
|
| 119 |
+
#include "pythread.h"
|
| 120 |
+
#include "cpython/context.h"
|
| 121 |
+
#include "modsupport.h"
|
| 122 |
+
#include "compile.h"
|
| 123 |
+
#include "pythonrun.h"
|
| 124 |
+
#include "pylifecycle.h"
|
| 125 |
+
#include "ceval.h"
|
| 126 |
+
#include "sysmodule.h"
|
| 127 |
+
#include "osmodule.h"
|
| 128 |
+
#include "intrcheck.h"
|
| 129 |
+
#include "import.h"
|
| 130 |
+
#include "abstract.h"
|
| 131 |
+
#include "bltinmodule.h"
|
| 132 |
+
#include "critical_section.h"
|
| 133 |
+
#include "cpython/pyctype.h"
|
| 134 |
+
#include "pystrtod.h"
|
| 135 |
+
#include "pystrcmp.h"
|
| 136 |
+
#include "fileutils.h"
|
| 137 |
+
#include "cpython/pyfpe.h"
|
| 138 |
+
#include "cpython/tracemalloc.h"
|
| 139 |
+
|
| 140 |
+
#endif /* !Py_PYTHON_H */
|
Include/abstract.h
ADDED
|
@@ -0,0 +1,921 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Abstract Object Interface (many thanks to Jim Fulton) */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_ABSTRACTOBJECT_H
|
| 4 |
+
#define Py_ABSTRACTOBJECT_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
/* === Object Protocol ================================================== */
|
| 10 |
+
|
| 11 |
+
/* Implemented elsewhere:
|
| 12 |
+
|
| 13 |
+
int PyObject_Print(PyObject *o, FILE *fp, int flags);
|
| 14 |
+
|
| 15 |
+
Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument
|
| 16 |
+
is used to enable certain printing options. The only option currently
|
| 17 |
+
supported is Py_PRINT_RAW. By default (flags=0), PyObject_Print() formats
|
| 18 |
+
the object by calling PyObject_Repr(). If flags equals to Py_PRINT_RAW, it
|
| 19 |
+
formats the object by calling PyObject_Str(). */
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
/* Implemented elsewhere:
|
| 23 |
+
|
| 24 |
+
int PyObject_HasAttrString(PyObject *o, const char *attr_name);
|
| 25 |
+
|
| 26 |
+
Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise.
|
| 27 |
+
|
| 28 |
+
This is equivalent to the Python expression: hasattr(o,attr_name).
|
| 29 |
+
|
| 30 |
+
This function always succeeds. */
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
/* Implemented elsewhere:
|
| 34 |
+
|
| 35 |
+
PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name);
|
| 36 |
+
|
| 37 |
+
Retrieve an attributed named attr_name form object o.
|
| 38 |
+
Returns the attribute value on success, or NULL on failure.
|
| 39 |
+
|
| 40 |
+
This is the equivalent of the Python expression: o.attr_name. */
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
/* Implemented elsewhere:
|
| 44 |
+
|
| 45 |
+
int PyObject_HasAttr(PyObject *o, PyObject *attr_name);
|
| 46 |
+
|
| 47 |
+
Returns 1 if o has the attribute attr_name, and 0 otherwise.
|
| 48 |
+
|
| 49 |
+
This is equivalent to the Python expression: hasattr(o,attr_name).
|
| 50 |
+
|
| 51 |
+
This function always succeeds. */
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
/* Implemented elsewhere:
|
| 55 |
+
|
| 56 |
+
int PyObject_HasAttrStringWithError(PyObject *o, const char *attr_name);
|
| 57 |
+
|
| 58 |
+
Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise.
|
| 59 |
+
This is equivalent to the Python expression: hasattr(o,attr_name).
|
| 60 |
+
Returns -1 on failure. */
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
/* Implemented elsewhere:
|
| 64 |
+
|
| 65 |
+
int PyObject_HasAttrWithError(PyObject *o, PyObject *attr_name);
|
| 66 |
+
|
| 67 |
+
Returns 1 if o has the attribute attr_name, and 0 otherwise.
|
| 68 |
+
This is equivalent to the Python expression: hasattr(o,attr_name).
|
| 69 |
+
Returns -1 on failure. */
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
/* Implemented elsewhere:
|
| 73 |
+
|
| 74 |
+
PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name);
|
| 75 |
+
|
| 76 |
+
Retrieve an attributed named 'attr_name' form object 'o'.
|
| 77 |
+
Returns the attribute value on success, or NULL on failure.
|
| 78 |
+
|
| 79 |
+
This is the equivalent of the Python expression: o.attr_name. */
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
/* Implemented elsewhere:
|
| 83 |
+
|
| 84 |
+
int PyObject_GetOptionalAttr(PyObject *obj, PyObject *attr_name, PyObject **result);
|
| 85 |
+
|
| 86 |
+
Variant of PyObject_GetAttr() which doesn't raise AttributeError
|
| 87 |
+
if the attribute is not found.
|
| 88 |
+
|
| 89 |
+
If the attribute is found, return 1 and set *result to a new strong
|
| 90 |
+
reference to the attribute.
|
| 91 |
+
If the attribute is not found, return 0 and set *result to NULL;
|
| 92 |
+
the AttributeError is silenced.
|
| 93 |
+
If an error other than AttributeError is raised, return -1 and
|
| 94 |
+
set *result to NULL.
|
| 95 |
+
*/
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
/* Implemented elsewhere:
|
| 99 |
+
|
| 100 |
+
int PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject **result);
|
| 101 |
+
|
| 102 |
+
Variant of PyObject_GetAttrString() which doesn't raise AttributeError
|
| 103 |
+
if the attribute is not found.
|
| 104 |
+
|
| 105 |
+
If the attribute is found, return 1 and set *result to a new strong
|
| 106 |
+
reference to the attribute.
|
| 107 |
+
If the attribute is not found, return 0 and set *result to NULL;
|
| 108 |
+
the AttributeError is silenced.
|
| 109 |
+
If an error other than AttributeError is raised, return -1 and
|
| 110 |
+
set *result to NULL.
|
| 111 |
+
*/
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
/* Implemented elsewhere:
|
| 115 |
+
|
| 116 |
+
int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v);
|
| 117 |
+
|
| 118 |
+
Set the value of the attribute named attr_name, for object 'o',
|
| 119 |
+
to the value 'v'. Raise an exception and return -1 on failure; return 0 on
|
| 120 |
+
success.
|
| 121 |
+
|
| 122 |
+
This is the equivalent of the Python statement o.attr_name=v. */
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
/* Implemented elsewhere:
|
| 126 |
+
|
| 127 |
+
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
|
| 128 |
+
|
| 129 |
+
Set the value of the attribute named attr_name, for object 'o', to the value
|
| 130 |
+
'v'. an exception and return -1 on failure; return 0 on success.
|
| 131 |
+
|
| 132 |
+
This is the equivalent of the Python statement o.attr_name=v. */
|
| 133 |
+
|
| 134 |
+
/* Implemented elsewhere:
|
| 135 |
+
|
| 136 |
+
int PyObject_DelAttrString(PyObject *o, const char *attr_name);
|
| 137 |
+
|
| 138 |
+
Delete attribute named attr_name, for object o. Returns
|
| 139 |
+
-1 on failure.
|
| 140 |
+
|
| 141 |
+
This is the equivalent of the Python statement: del o.attr_name.
|
| 142 |
+
|
| 143 |
+
Implemented as a macro in the limited C API 3.12 and older. */
|
| 144 |
+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000
|
| 145 |
+
# define PyObject_DelAttrString(O, A) PyObject_SetAttrString((O), (A), NULL)
|
| 146 |
+
#endif
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
/* Implemented elsewhere:
|
| 150 |
+
|
| 151 |
+
int PyObject_DelAttr(PyObject *o, PyObject *attr_name);
|
| 152 |
+
|
| 153 |
+
Delete attribute named attr_name, for object o. Returns -1
|
| 154 |
+
on failure. This is the equivalent of the Python
|
| 155 |
+
statement: del o.attr_name.
|
| 156 |
+
|
| 157 |
+
Implemented as a macro in the limited C API 3.12 and older. */
|
| 158 |
+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000
|
| 159 |
+
# define PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL)
|
| 160 |
+
#endif
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
/* Implemented elsewhere:
|
| 164 |
+
|
| 165 |
+
PyObject *PyObject_Repr(PyObject *o);
|
| 166 |
+
|
| 167 |
+
Compute the string representation of object 'o'. Returns the
|
| 168 |
+
string representation on success, NULL on failure.
|
| 169 |
+
|
| 170 |
+
This is the equivalent of the Python expression: repr(o).
|
| 171 |
+
|
| 172 |
+
Called by the repr() built-in function. */
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
/* Implemented elsewhere:
|
| 176 |
+
|
| 177 |
+
PyObject *PyObject_Str(PyObject *o);
|
| 178 |
+
|
| 179 |
+
Compute the string representation of object, o. Returns the
|
| 180 |
+
string representation on success, NULL on failure.
|
| 181 |
+
|
| 182 |
+
This is the equivalent of the Python expression: str(o).
|
| 183 |
+
|
| 184 |
+
Called by the str() and print() built-in functions. */
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
/* Declared elsewhere
|
| 188 |
+
|
| 189 |
+
PyAPI_FUNC(int) PyCallable_Check(PyObject *o);
|
| 190 |
+
|
| 191 |
+
Determine if the object, o, is callable. Return 1 if the object is callable
|
| 192 |
+
and 0 otherwise.
|
| 193 |
+
|
| 194 |
+
This function always succeeds. */
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
|
| 198 |
+
/* Call a callable Python object without any arguments */
|
| 199 |
+
PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func);
|
| 200 |
+
#endif
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
/* Call a callable Python object 'callable' with arguments given by the
|
| 204 |
+
tuple 'args' and keywords arguments given by the dictionary 'kwargs'.
|
| 205 |
+
|
| 206 |
+
'args' must not be NULL, use an empty tuple if no arguments are
|
| 207 |
+
needed. If no named arguments are needed, 'kwargs' can be NULL.
|
| 208 |
+
|
| 209 |
+
This is the equivalent of the Python expression:
|
| 210 |
+
callable(*args, **kwargs). */
|
| 211 |
+
PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable,
|
| 212 |
+
PyObject *args, PyObject *kwargs);
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
/* Call a callable Python object 'callable', with arguments given by the
|
| 216 |
+
tuple 'args'. If no arguments are needed, then 'args' can be NULL.
|
| 217 |
+
|
| 218 |
+
Returns the result of the call on success, or NULL on failure.
|
| 219 |
+
|
| 220 |
+
This is the equivalent of the Python expression:
|
| 221 |
+
callable(*args). */
|
| 222 |
+
PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable,
|
| 223 |
+
PyObject *args);
|
| 224 |
+
|
| 225 |
+
/* Call a callable Python object, callable, with a variable number of C
|
| 226 |
+
arguments. The C arguments are described using a mkvalue-style format
|
| 227 |
+
string.
|
| 228 |
+
|
| 229 |
+
The format may be NULL, indicating that no arguments are provided.
|
| 230 |
+
|
| 231 |
+
Returns the result of the call on success, or NULL on failure.
|
| 232 |
+
|
| 233 |
+
This is the equivalent of the Python expression:
|
| 234 |
+
callable(arg1, arg2, ...). */
|
| 235 |
+
PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable,
|
| 236 |
+
const char *format, ...);
|
| 237 |
+
|
| 238 |
+
/* Call the method named 'name' of object 'obj' with a variable number of
|
| 239 |
+
C arguments. The C arguments are described by a mkvalue format string.
|
| 240 |
+
|
| 241 |
+
The format can be NULL, indicating that no arguments are provided.
|
| 242 |
+
|
| 243 |
+
Returns the result of the call on success, or NULL on failure.
|
| 244 |
+
|
| 245 |
+
This is the equivalent of the Python expression:
|
| 246 |
+
obj.name(arg1, arg2, ...). */
|
| 247 |
+
PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj,
|
| 248 |
+
const char *name,
|
| 249 |
+
const char *format, ...);
|
| 250 |
+
|
| 251 |
+
/* Call a callable Python object 'callable' with a variable number of C
|
| 252 |
+
arguments. The C arguments are provided as PyObject* values, terminated
|
| 253 |
+
by a NULL.
|
| 254 |
+
|
| 255 |
+
Returns the result of the call on success, or NULL on failure.
|
| 256 |
+
|
| 257 |
+
This is the equivalent of the Python expression:
|
| 258 |
+
callable(arg1, arg2, ...). */
|
| 259 |
+
PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable,
|
| 260 |
+
...);
|
| 261 |
+
|
| 262 |
+
/* Call the method named 'name' of object 'obj' with a variable number of
|
| 263 |
+
C arguments. The C arguments are provided as PyObject* values, terminated
|
| 264 |
+
by NULL.
|
| 265 |
+
|
| 266 |
+
Returns the result of the call on success, or NULL on failure.
|
| 267 |
+
|
| 268 |
+
This is the equivalent of the Python expression: obj.name(*args). */
|
| 269 |
+
|
| 270 |
+
PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(
|
| 271 |
+
PyObject *obj,
|
| 272 |
+
PyObject *name,
|
| 273 |
+
...);
|
| 274 |
+
|
| 275 |
+
/* Given a vectorcall nargsf argument, return the actual number of arguments.
|
| 276 |
+
* (For use outside the limited API, this is re-defined as a static inline
|
| 277 |
+
* function in cpython/abstract.h)
|
| 278 |
+
*/
|
| 279 |
+
PyAPI_FUNC(Py_ssize_t) PyVectorcall_NARGS(size_t nargsf);
|
| 280 |
+
|
| 281 |
+
/* Call "callable" (which must support vectorcall) with positional arguments
|
| 282 |
+
"tuple" and keyword arguments "dict". "dict" may also be NULL */
|
| 283 |
+
PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
|
| 284 |
+
|
| 285 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
|
| 286 |
+
#define PY_VECTORCALL_ARGUMENTS_OFFSET \
|
| 287 |
+
(_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1))
|
| 288 |
+
|
| 289 |
+
/* Perform a PEP 590-style vector call on 'callable' */
|
| 290 |
+
PyAPI_FUNC(PyObject *) PyObject_Vectorcall(
|
| 291 |
+
PyObject *callable,
|
| 292 |
+
PyObject *const *args,
|
| 293 |
+
size_t nargsf,
|
| 294 |
+
PyObject *kwnames);
|
| 295 |
+
|
| 296 |
+
/* Call the method 'name' on args[0] with arguments in args[1..nargsf-1]. */
|
| 297 |
+
PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
|
| 298 |
+
PyObject *name, PyObject *const *args,
|
| 299 |
+
size_t nargsf, PyObject *kwnames);
|
| 300 |
+
#endif
|
| 301 |
+
|
| 302 |
+
/* Implemented elsewhere:
|
| 303 |
+
|
| 304 |
+
Py_hash_t PyObject_Hash(PyObject *o);
|
| 305 |
+
|
| 306 |
+
Compute and return the hash, hash_value, of an object, o. On
|
| 307 |
+
failure, return -1.
|
| 308 |
+
|
| 309 |
+
This is the equivalent of the Python expression: hash(o). */
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
/* Implemented elsewhere:
|
| 313 |
+
|
| 314 |
+
int PyObject_IsTrue(PyObject *o);
|
| 315 |
+
|
| 316 |
+
Returns 1 if the object, o, is considered to be true, 0 if o is
|
| 317 |
+
considered to be false and -1 on failure.
|
| 318 |
+
|
| 319 |
+
This is equivalent to the Python expression: not not o. */
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
/* Implemented elsewhere:
|
| 323 |
+
|
| 324 |
+
int PyObject_Not(PyObject *o);
|
| 325 |
+
|
| 326 |
+
Returns 0 if the object, o, is considered to be true, 1 if o is
|
| 327 |
+
considered to be false and -1 on failure.
|
| 328 |
+
|
| 329 |
+
This is equivalent to the Python expression: not o. */
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
/* Get the type of an object.
|
| 333 |
+
|
| 334 |
+
On success, returns a type object corresponding to the object type of object
|
| 335 |
+
'o'. On failure, returns NULL.
|
| 336 |
+
|
| 337 |
+
This is equivalent to the Python expression: type(o) */
|
| 338 |
+
PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o);
|
| 339 |
+
|
| 340 |
+
|
| 341 |
+
/* Return the size of object 'o'. If the object 'o' provides both sequence and
|
| 342 |
+
mapping protocols, the sequence size is returned.
|
| 343 |
+
|
| 344 |
+
On error, -1 is returned.
|
| 345 |
+
|
| 346 |
+
This is the equivalent to the Python expression: len(o) */
|
| 347 |
+
PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o);
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
/* For DLL compatibility */
|
| 351 |
+
#undef PyObject_Length
|
| 352 |
+
PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
|
| 353 |
+
#define PyObject_Length PyObject_Size
|
| 354 |
+
|
| 355 |
+
/* Return element of 'o' corresponding to the object 'key'. Return NULL
|
| 356 |
+
on failure.
|
| 357 |
+
|
| 358 |
+
This is the equivalent of the Python expression: o[key] */
|
| 359 |
+
PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
|
| 360 |
+
|
| 361 |
+
|
| 362 |
+
/* Map the object 'key' to the value 'v' into 'o'.
|
| 363 |
+
|
| 364 |
+
Raise an exception and return -1 on failure; return 0 on success.
|
| 365 |
+
|
| 366 |
+
This is the equivalent of the Python statement: o[key]=v. */
|
| 367 |
+
PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
|
| 368 |
+
|
| 369 |
+
/* Remove the mapping for the string 'key' from the object 'o'.
|
| 370 |
+
Returns -1 on failure.
|
| 371 |
+
|
| 372 |
+
This is equivalent to the Python statement: del o[key]. */
|
| 373 |
+
PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
|
| 374 |
+
|
| 375 |
+
/* Delete the mapping for the object 'key' from the object 'o'.
|
| 376 |
+
Returns -1 on failure.
|
| 377 |
+
|
| 378 |
+
This is the equivalent of the Python statement: del o[key]. */
|
| 379 |
+
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
/* Takes an arbitrary object and returns the result of calling
|
| 383 |
+
obj.__format__(format_spec). */
|
| 384 |
+
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
|
| 385 |
+
PyObject *format_spec);
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
/* ==== Iterators ================================================ */
|
| 389 |
+
|
| 390 |
+
/* Takes an object and returns an iterator for it.
|
| 391 |
+
This is typically a new iterator but if the argument is an iterator, this
|
| 392 |
+
returns itself. */
|
| 393 |
+
PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
|
| 394 |
+
|
| 395 |
+
/* Takes an AsyncIterable object and returns an AsyncIterator for it.
|
| 396 |
+
This is typically a new iterator but if the argument is an AsyncIterator,
|
| 397 |
+
this returns itself. */
|
| 398 |
+
PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *);
|
| 399 |
+
|
| 400 |
+
/* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise.
|
| 401 |
+
|
| 402 |
+
This function always succeeds. */
|
| 403 |
+
PyAPI_FUNC(int) PyIter_Check(PyObject *);
|
| 404 |
+
|
| 405 |
+
/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise.
|
| 406 |
+
|
| 407 |
+
This function always succeeds. */
|
| 408 |
+
PyAPI_FUNC(int) PyAIter_Check(PyObject *);
|
| 409 |
+
|
| 410 |
+
/* Takes an iterator object and calls its tp_iternext slot,
|
| 411 |
+
returning the next value.
|
| 412 |
+
|
| 413 |
+
If the iterator is exhausted, this returns NULL without setting an
|
| 414 |
+
exception.
|
| 415 |
+
|
| 416 |
+
NULL with an exception means an error occurred. */
|
| 417 |
+
PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
|
| 418 |
+
|
| 419 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
| 420 |
+
|
| 421 |
+
/* Takes generator, coroutine or iterator object and sends the value into it.
|
| 422 |
+
Returns:
|
| 423 |
+
- PYGEN_RETURN (0) if generator has returned.
|
| 424 |
+
'result' parameter is filled with return value
|
| 425 |
+
- PYGEN_ERROR (-1) if exception was raised.
|
| 426 |
+
'result' parameter is NULL
|
| 427 |
+
- PYGEN_NEXT (1) if generator has yielded.
|
| 428 |
+
'result' parameter is filled with yielded value. */
|
| 429 |
+
PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **);
|
| 430 |
+
#endif
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
/* === Number Protocol ================================================== */
|
| 434 |
+
|
| 435 |
+
/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise.
|
| 436 |
+
|
| 437 |
+
This function always succeeds. */
|
| 438 |
+
PyAPI_FUNC(int) PyNumber_Check(PyObject *o);
|
| 439 |
+
|
| 440 |
+
/* Returns the result of adding o1 and o2, or NULL on failure.
|
| 441 |
+
|
| 442 |
+
This is the equivalent of the Python expression: o1 + o2. */
|
| 443 |
+
PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2);
|
| 444 |
+
|
| 445 |
+
/* Returns the result of subtracting o2 from o1, or NULL on failure.
|
| 446 |
+
|
| 447 |
+
This is the equivalent of the Python expression: o1 - o2. */
|
| 448 |
+
PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2);
|
| 449 |
+
|
| 450 |
+
/* Returns the result of multiplying o1 and o2, or NULL on failure.
|
| 451 |
+
|
| 452 |
+
This is the equivalent of the Python expression: o1 * o2. */
|
| 453 |
+
PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2);
|
| 454 |
+
|
| 455 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
| 456 |
+
/* This is the equivalent of the Python expression: o1 @ o2. */
|
| 457 |
+
PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2);
|
| 458 |
+
#endif
|
| 459 |
+
|
| 460 |
+
/* Returns the result of dividing o1 by o2 giving an integral result,
|
| 461 |
+
or NULL on failure.
|
| 462 |
+
|
| 463 |
+
This is the equivalent of the Python expression: o1 // o2. */
|
| 464 |
+
PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2);
|
| 465 |
+
|
| 466 |
+
/* Returns the result of dividing o1 by o2 giving a float result, or NULL on
|
| 467 |
+
failure.
|
| 468 |
+
|
| 469 |
+
This is the equivalent of the Python expression: o1 / o2. */
|
| 470 |
+
PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2);
|
| 471 |
+
|
| 472 |
+
/* Returns the remainder of dividing o1 by o2, or NULL on failure.
|
| 473 |
+
|
| 474 |
+
This is the equivalent of the Python expression: o1 % o2. */
|
| 475 |
+
PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2);
|
| 476 |
+
|
| 477 |
+
/* See the built-in function divmod.
|
| 478 |
+
|
| 479 |
+
Returns NULL on failure.
|
| 480 |
+
|
| 481 |
+
This is the equivalent of the Python expression: divmod(o1, o2). */
|
| 482 |
+
PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2);
|
| 483 |
+
|
| 484 |
+
/* See the built-in function pow. Returns NULL on failure.
|
| 485 |
+
|
| 486 |
+
This is the equivalent of the Python expression: pow(o1, o2, o3),
|
| 487 |
+
where o3 is optional. */
|
| 488 |
+
PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2,
|
| 489 |
+
PyObject *o3);
|
| 490 |
+
|
| 491 |
+
/* Returns the negation of o on success, or NULL on failure.
|
| 492 |
+
|
| 493 |
+
This is the equivalent of the Python expression: -o. */
|
| 494 |
+
PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o);
|
| 495 |
+
|
| 496 |
+
/* Returns the positive of o on success, or NULL on failure.
|
| 497 |
+
|
| 498 |
+
This is the equivalent of the Python expression: +o. */
|
| 499 |
+
PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o);
|
| 500 |
+
|
| 501 |
+
/* Returns the absolute value of 'o', or NULL on failure.
|
| 502 |
+
|
| 503 |
+
This is the equivalent of the Python expression: abs(o). */
|
| 504 |
+
PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o);
|
| 505 |
+
|
| 506 |
+
/* Returns the bitwise negation of 'o' on success, or NULL on failure.
|
| 507 |
+
|
| 508 |
+
This is the equivalent of the Python expression: ~o. */
|
| 509 |
+
PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o);
|
| 510 |
+
|
| 511 |
+
/* Returns the result of left shifting o1 by o2 on success, or NULL on failure.
|
| 512 |
+
|
| 513 |
+
This is the equivalent of the Python expression: o1 << o2. */
|
| 514 |
+
PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2);
|
| 515 |
+
|
| 516 |
+
/* Returns the result of right shifting o1 by o2 on success, or NULL on
|
| 517 |
+
failure.
|
| 518 |
+
|
| 519 |
+
This is the equivalent of the Python expression: o1 >> o2. */
|
| 520 |
+
PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2);
|
| 521 |
+
|
| 522 |
+
/* Returns the result of bitwise and of o1 and o2 on success, or NULL on
|
| 523 |
+
failure.
|
| 524 |
+
|
| 525 |
+
This is the equivalent of the Python expression: o1 & o2. */
|
| 526 |
+
PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2);
|
| 527 |
+
|
| 528 |
+
/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure.
|
| 529 |
+
|
| 530 |
+
This is the equivalent of the Python expression: o1 ^ o2. */
|
| 531 |
+
PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2);
|
| 532 |
+
|
| 533 |
+
/* Returns the result of bitwise or on o1 and o2 on success, or NULL on
|
| 534 |
+
failure.
|
| 535 |
+
|
| 536 |
+
This is the equivalent of the Python expression: o1 | o2. */
|
| 537 |
+
PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2);
|
| 538 |
+
|
| 539 |
+
/* Returns 1 if obj is an index integer (has the nb_index slot of the
|
| 540 |
+
tp_as_number structure filled in), and 0 otherwise. */
|
| 541 |
+
PyAPI_FUNC(int) PyIndex_Check(PyObject *);
|
| 542 |
+
|
| 543 |
+
/* Returns the object 'o' converted to a Python int, or NULL with an exception
|
| 544 |
+
raised on failure. */
|
| 545 |
+
PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o);
|
| 546 |
+
|
| 547 |
+
/* Returns the object 'o' converted to Py_ssize_t by going through
|
| 548 |
+
PyNumber_Index() first.
|
| 549 |
+
|
| 550 |
+
If an overflow error occurs while converting the int to Py_ssize_t, then the
|
| 551 |
+
second argument 'exc' is the error-type to return. If it is NULL, then the
|
| 552 |
+
overflow error is cleared and the value is clipped. */
|
| 553 |
+
PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc);
|
| 554 |
+
|
| 555 |
+
/* Returns the object 'o' converted to an integer object on success, or NULL
|
| 556 |
+
on failure.
|
| 557 |
+
|
| 558 |
+
This is the equivalent of the Python expression: int(o). */
|
| 559 |
+
PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o);
|
| 560 |
+
|
| 561 |
+
/* Returns the object 'o' converted to a float object on success, or NULL
|
| 562 |
+
on failure.
|
| 563 |
+
|
| 564 |
+
This is the equivalent of the Python expression: float(o). */
|
| 565 |
+
PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o);
|
| 566 |
+
|
| 567 |
+
|
| 568 |
+
/* --- In-place variants of (some of) the above number protocol functions -- */
|
| 569 |
+
|
| 570 |
+
/* Returns the result of adding o2 to o1, possibly in-place, or NULL
|
| 571 |
+
on failure.
|
| 572 |
+
|
| 573 |
+
This is the equivalent of the Python expression: o1 += o2. */
|
| 574 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2);
|
| 575 |
+
|
| 576 |
+
/* Returns the result of subtracting o2 from o1, possibly in-place or
|
| 577 |
+
NULL on failure.
|
| 578 |
+
|
| 579 |
+
This is the equivalent of the Python expression: o1 -= o2. */
|
| 580 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2);
|
| 581 |
+
|
| 582 |
+
/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on
|
| 583 |
+
failure.
|
| 584 |
+
|
| 585 |
+
This is the equivalent of the Python expression: o1 *= o2. */
|
| 586 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2);
|
| 587 |
+
|
| 588 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
| 589 |
+
/* This is the equivalent of the Python expression: o1 @= o2. */
|
| 590 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2);
|
| 591 |
+
#endif
|
| 592 |
+
|
| 593 |
+
/* Returns the result of dividing o1 by o2 giving an integral result, possibly
|
| 594 |
+
in-place, or NULL on failure.
|
| 595 |
+
|
| 596 |
+
This is the equivalent of the Python expression: o1 /= o2. */
|
| 597 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1,
|
| 598 |
+
PyObject *o2);
|
| 599 |
+
|
| 600 |
+
/* Returns the result of dividing o1 by o2 giving a float result, possibly
|
| 601 |
+
in-place, or null on failure.
|
| 602 |
+
|
| 603 |
+
This is the equivalent of the Python expression: o1 /= o2. */
|
| 604 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1,
|
| 605 |
+
PyObject *o2);
|
| 606 |
+
|
| 607 |
+
/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on
|
| 608 |
+
failure.
|
| 609 |
+
|
| 610 |
+
This is the equivalent of the Python expression: o1 %= o2. */
|
| 611 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2);
|
| 612 |
+
|
| 613 |
+
/* Returns the result of raising o1 to the power of o2, possibly in-place,
|
| 614 |
+
or NULL on failure.
|
| 615 |
+
|
| 616 |
+
This is the equivalent of the Python expression: o1 **= o2,
|
| 617 |
+
or o1 = pow(o1, o2, o3) if o3 is present. */
|
| 618 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2,
|
| 619 |
+
PyObject *o3);
|
| 620 |
+
|
| 621 |
+
/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL
|
| 622 |
+
on failure.
|
| 623 |
+
|
| 624 |
+
This is the equivalent of the Python expression: o1 <<= o2. */
|
| 625 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2);
|
| 626 |
+
|
| 627 |
+
/* Returns the result of right shifting o1 by o2, possibly in-place or NULL
|
| 628 |
+
on failure.
|
| 629 |
+
|
| 630 |
+
This is the equivalent of the Python expression: o1 >>= o2. */
|
| 631 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2);
|
| 632 |
+
|
| 633 |
+
/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL
|
| 634 |
+
on failure.
|
| 635 |
+
|
| 636 |
+
This is the equivalent of the Python expression: o1 &= o2. */
|
| 637 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2);
|
| 638 |
+
|
| 639 |
+
/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL
|
| 640 |
+
on failure.
|
| 641 |
+
|
| 642 |
+
This is the equivalent of the Python expression: o1 ^= o2. */
|
| 643 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2);
|
| 644 |
+
|
| 645 |
+
/* Returns the result of bitwise or of o1 and o2, possibly in-place,
|
| 646 |
+
or NULL on failure.
|
| 647 |
+
|
| 648 |
+
This is the equivalent of the Python expression: o1 |= o2. */
|
| 649 |
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2);
|
| 650 |
+
|
| 651 |
+
/* Returns the integer n converted to a string with a base, with a base
|
| 652 |
+
marker of 0b, 0o or 0x prefixed if applicable.
|
| 653 |
+
|
| 654 |
+
If n is not an int object, it is converted with PyNumber_Index first. */
|
| 655 |
+
PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base);
|
| 656 |
+
|
| 657 |
+
|
| 658 |
+
/* === Sequence protocol ================================================ */
|
| 659 |
+
|
| 660 |
+
/* Return 1 if the object provides sequence protocol, and zero
|
| 661 |
+
otherwise.
|
| 662 |
+
|
| 663 |
+
This function always succeeds. */
|
| 664 |
+
PyAPI_FUNC(int) PySequence_Check(PyObject *o);
|
| 665 |
+
|
| 666 |
+
/* Return the size of sequence object o, or -1 on failure. */
|
| 667 |
+
PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o);
|
| 668 |
+
|
| 669 |
+
/* For DLL compatibility */
|
| 670 |
+
#undef PySequence_Length
|
| 671 |
+
PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o);
|
| 672 |
+
#define PySequence_Length PySequence_Size
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
/* Return the concatenation of o1 and o2 on success, and NULL on failure.
|
| 676 |
+
|
| 677 |
+
This is the equivalent of the Python expression: o1 + o2. */
|
| 678 |
+
PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2);
|
| 679 |
+
|
| 680 |
+
/* Return the result of repeating sequence object 'o' 'count' times,
|
| 681 |
+
or NULL on failure.
|
| 682 |
+
|
| 683 |
+
This is the equivalent of the Python expression: o * count. */
|
| 684 |
+
PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count);
|
| 685 |
+
|
| 686 |
+
/* Return the ith element of o, or NULL on failure.
|
| 687 |
+
|
| 688 |
+
This is the equivalent of the Python expression: o[i]. */
|
| 689 |
+
PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i);
|
| 690 |
+
|
| 691 |
+
/* Return the slice of sequence object o between i1 and i2, or NULL on failure.
|
| 692 |
+
|
| 693 |
+
This is the equivalent of the Python expression: o[i1:i2]. */
|
| 694 |
+
PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
| 695 |
+
|
| 696 |
+
/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception
|
| 697 |
+
and return -1 on failure; return 0 on success.
|
| 698 |
+
|
| 699 |
+
This is the equivalent of the Python statement o[i] = v. */
|
| 700 |
+
PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
|
| 701 |
+
|
| 702 |
+
/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure.
|
| 703 |
+
|
| 704 |
+
This is the equivalent of the Python statement: del o[i]. */
|
| 705 |
+
PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
|
| 706 |
+
|
| 707 |
+
/* Assign the sequence object 'v' to the slice in sequence object 'o',
|
| 708 |
+
from 'i1' to 'i2'. Returns -1 on failure.
|
| 709 |
+
|
| 710 |
+
This is the equivalent of the Python statement: o[i1:i2] = v. */
|
| 711 |
+
PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2,
|
| 712 |
+
PyObject *v);
|
| 713 |
+
|
| 714 |
+
/* Delete the slice in sequence object 'o' from 'i1' to 'i2'.
|
| 715 |
+
Returns -1 on failure.
|
| 716 |
+
|
| 717 |
+
This is the equivalent of the Python statement: del o[i1:i2]. */
|
| 718 |
+
PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
| 719 |
+
|
| 720 |
+
/* Returns the sequence 'o' as a tuple on success, and NULL on failure.
|
| 721 |
+
|
| 722 |
+
This is equivalent to the Python expression: tuple(o). */
|
| 723 |
+
PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o);
|
| 724 |
+
|
| 725 |
+
/* Returns the sequence 'o' as a list on success, and NULL on failure.
|
| 726 |
+
This is equivalent to the Python expression: list(o) */
|
| 727 |
+
PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o);
|
| 728 |
+
|
| 729 |
+
/* Return the sequence 'o' as a list, unless it's already a tuple or list.
|
| 730 |
+
|
| 731 |
+
Use PySequence_Fast_GET_ITEM to access the members of this list, and
|
| 732 |
+
PySequence_Fast_GET_SIZE to get its length.
|
| 733 |
+
|
| 734 |
+
Returns NULL on failure. If the object does not support iteration, raises a
|
| 735 |
+
TypeError exception with 'm' as the message text. */
|
| 736 |
+
PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
|
| 737 |
+
|
| 738 |
+
/* Return the size of the sequence 'o', assuming that 'o' was returned by
|
| 739 |
+
PySequence_Fast and is not NULL. */
|
| 740 |
+
#define PySequence_Fast_GET_SIZE(o) \
|
| 741 |
+
(PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
|
| 742 |
+
|
| 743 |
+
/* Return the 'i'-th element of the sequence 'o', assuming that o was returned
|
| 744 |
+
by PySequence_Fast, and that i is within bounds. */
|
| 745 |
+
#define PySequence_Fast_GET_ITEM(o, i)\
|
| 746 |
+
(PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i)))
|
| 747 |
+
|
| 748 |
+
/* Return a pointer to the underlying item array for
|
| 749 |
+
an object returned by PySequence_Fast */
|
| 750 |
+
#define PySequence_Fast_ITEMS(sf) \
|
| 751 |
+
(PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \
|
| 752 |
+
: ((PyTupleObject *)(sf))->ob_item)
|
| 753 |
+
|
| 754 |
+
/* Return the number of occurrences on value on 'o', that is, return
|
| 755 |
+
the number of keys for which o[key] == value.
|
| 756 |
+
|
| 757 |
+
On failure, return -1. This is equivalent to the Python expression:
|
| 758 |
+
o.count(value). */
|
| 759 |
+
PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value);
|
| 760 |
+
|
| 761 |
+
/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence
|
| 762 |
+
'seq'; -1 on error.
|
| 763 |
+
|
| 764 |
+
Use __contains__ if possible, else _PySequence_IterSearch(). */
|
| 765 |
+
PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);
|
| 766 |
+
|
| 767 |
+
/* For DLL-level backwards compatibility */
|
| 768 |
+
#undef PySequence_In
|
| 769 |
+
/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal
|
| 770 |
+
to 'value', return 1, otherwise return 0. On error, return -1.
|
| 771 |
+
|
| 772 |
+
This is equivalent to the Python expression: value in o. */
|
| 773 |
+
PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value);
|
| 774 |
+
|
| 775 |
+
/* For source-level backwards compatibility */
|
| 776 |
+
#define PySequence_In PySequence_Contains
|
| 777 |
+
|
| 778 |
+
|
| 779 |
+
/* Return the first index for which o[i] == value.
|
| 780 |
+
On error, return -1.
|
| 781 |
+
|
| 782 |
+
This is equivalent to the Python expression: o.index(value). */
|
| 783 |
+
PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value);
|
| 784 |
+
|
| 785 |
+
|
| 786 |
+
/* --- In-place versions of some of the above Sequence functions --- */
|
| 787 |
+
|
| 788 |
+
/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the
|
| 789 |
+
resulting object, which could be 'o1', or NULL on failure.
|
| 790 |
+
|
| 791 |
+
This is the equivalent of the Python expression: o1 += o2. */
|
| 792 |
+
PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2);
|
| 793 |
+
|
| 794 |
+
/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting
|
| 795 |
+
object, which could be 'o', or NULL on failure.
|
| 796 |
+
|
| 797 |
+
This is the equivalent of the Python expression: o1 *= count. */
|
| 798 |
+
PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count);
|
| 799 |
+
|
| 800 |
+
|
| 801 |
+
/* === Mapping protocol ================================================= */
|
| 802 |
+
|
| 803 |
+
/* Return 1 if the object provides mapping protocol, and 0 otherwise.
|
| 804 |
+
|
| 805 |
+
This function always succeeds. */
|
| 806 |
+
PyAPI_FUNC(int) PyMapping_Check(PyObject *o);
|
| 807 |
+
|
| 808 |
+
/* Returns the number of keys in mapping object 'o' on success, and -1 on
|
| 809 |
+
failure. This is equivalent to the Python expression: len(o). */
|
| 810 |
+
PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o);
|
| 811 |
+
|
| 812 |
+
/* For DLL compatibility */
|
| 813 |
+
#undef PyMapping_Length
|
| 814 |
+
PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o);
|
| 815 |
+
#define PyMapping_Length PyMapping_Size
|
| 816 |
+
|
| 817 |
+
|
| 818 |
+
/* Implemented as a macro:
|
| 819 |
+
|
| 820 |
+
int PyMapping_DelItemString(PyObject *o, const char *key);
|
| 821 |
+
|
| 822 |
+
Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on
|
| 823 |
+
failure.
|
| 824 |
+
|
| 825 |
+
This is equivalent to the Python statement: del o[key]. */
|
| 826 |
+
#define PyMapping_DelItemString(O, K) PyObject_DelItemString((O), (K))
|
| 827 |
+
|
| 828 |
+
/* Implemented as a macro:
|
| 829 |
+
|
| 830 |
+
int PyMapping_DelItem(PyObject *o, PyObject *key);
|
| 831 |
+
|
| 832 |
+
Remove the mapping for the object 'key' from the mapping object 'o'.
|
| 833 |
+
Returns -1 on failure.
|
| 834 |
+
|
| 835 |
+
This is equivalent to the Python statement: del o[key]. */
|
| 836 |
+
#define PyMapping_DelItem(O, K) PyObject_DelItem((O), (K))
|
| 837 |
+
|
| 838 |
+
/* On success, return 1 if the mapping object 'o' has the key 'key',
|
| 839 |
+
and 0 otherwise.
|
| 840 |
+
|
| 841 |
+
This is equivalent to the Python expression: key in o.
|
| 842 |
+
|
| 843 |
+
This function always succeeds. */
|
| 844 |
+
PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key);
|
| 845 |
+
|
| 846 |
+
/* Return 1 if the mapping object has the key 'key', and 0 otherwise.
|
| 847 |
+
|
| 848 |
+
This is equivalent to the Python expression: key in o.
|
| 849 |
+
|
| 850 |
+
This function always succeeds. */
|
| 851 |
+
PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key);
|
| 852 |
+
|
| 853 |
+
/* Return 1 if the mapping object has the key 'key', and 0 otherwise.
|
| 854 |
+
This is equivalent to the Python expression: key in o.
|
| 855 |
+
On failure, return -1. */
|
| 856 |
+
|
| 857 |
+
PyAPI_FUNC(int) PyMapping_HasKeyWithError(PyObject *o, PyObject *key);
|
| 858 |
+
|
| 859 |
+
/* Return 1 if the mapping object has the key 'key', and 0 otherwise.
|
| 860 |
+
This is equivalent to the Python expression: key in o.
|
| 861 |
+
On failure, return -1. */
|
| 862 |
+
|
| 863 |
+
PyAPI_FUNC(int) PyMapping_HasKeyStringWithError(PyObject *o, const char *key);
|
| 864 |
+
|
| 865 |
+
/* On success, return a list or tuple of the keys in mapping object 'o'.
|
| 866 |
+
On failure, return NULL. */
|
| 867 |
+
PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o);
|
| 868 |
+
|
| 869 |
+
/* On success, return a list or tuple of the values in mapping object 'o'.
|
| 870 |
+
On failure, return NULL. */
|
| 871 |
+
PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o);
|
| 872 |
+
|
| 873 |
+
/* On success, return a list or tuple of the items in mapping object 'o',
|
| 874 |
+
where each item is a tuple containing a key-value pair. On failure, return
|
| 875 |
+
NULL. */
|
| 876 |
+
PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o);
|
| 877 |
+
|
| 878 |
+
/* Return element of 'o' corresponding to the string 'key' or NULL on failure.
|
| 879 |
+
|
| 880 |
+
This is the equivalent of the Python expression: o[key]. */
|
| 881 |
+
PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
|
| 882 |
+
const char *key);
|
| 883 |
+
|
| 884 |
+
/* Variants of PyObject_GetItem() and PyMapping_GetItemString() which don't
|
| 885 |
+
raise KeyError if the key is not found.
|
| 886 |
+
|
| 887 |
+
If the key is found, return 1 and set *result to a new strong
|
| 888 |
+
reference to the corresponding value.
|
| 889 |
+
If the key is not found, return 0 and set *result to NULL;
|
| 890 |
+
the KeyError is silenced.
|
| 891 |
+
If an error other than KeyError is raised, return -1 and
|
| 892 |
+
set *result to NULL.
|
| 893 |
+
*/
|
| 894 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
|
| 895 |
+
PyAPI_FUNC(int) PyMapping_GetOptionalItem(PyObject *, PyObject *, PyObject **);
|
| 896 |
+
PyAPI_FUNC(int) PyMapping_GetOptionalItemString(PyObject *, const char *, PyObject **);
|
| 897 |
+
#endif
|
| 898 |
+
|
| 899 |
+
/* Map the string 'key' to the value 'v' in the mapping 'o'.
|
| 900 |
+
Returns -1 on failure.
|
| 901 |
+
|
| 902 |
+
This is the equivalent of the Python statement: o[key]=v. */
|
| 903 |
+
PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key,
|
| 904 |
+
PyObject *value);
|
| 905 |
+
|
| 906 |
+
/* isinstance(object, typeorclass) */
|
| 907 |
+
PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
|
| 908 |
+
|
| 909 |
+
/* issubclass(object, typeorclass) */
|
| 910 |
+
PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
|
| 911 |
+
|
| 912 |
+
#ifndef Py_LIMITED_API
|
| 913 |
+
# define Py_CPYTHON_ABSTRACTOBJECT_H
|
| 914 |
+
# include "cpython/abstract.h"
|
| 915 |
+
# undef Py_CPYTHON_ABSTRACTOBJECT_H
|
| 916 |
+
#endif
|
| 917 |
+
|
| 918 |
+
#ifdef __cplusplus
|
| 919 |
+
}
|
| 920 |
+
#endif
|
| 921 |
+
#endif /* Py_ABSTRACTOBJECT_H */
|
Include/bltinmodule.h
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_BLTINMODULE_H
|
| 2 |
+
#define Py_BLTINMODULE_H
|
| 3 |
+
#ifdef __cplusplus
|
| 4 |
+
extern "C" {
|
| 5 |
+
#endif
|
| 6 |
+
|
| 7 |
+
PyAPI_DATA(PyTypeObject) PyFilter_Type;
|
| 8 |
+
PyAPI_DATA(PyTypeObject) PyMap_Type;
|
| 9 |
+
PyAPI_DATA(PyTypeObject) PyZip_Type;
|
| 10 |
+
|
| 11 |
+
#ifdef __cplusplus
|
| 12 |
+
}
|
| 13 |
+
#endif
|
| 14 |
+
#endif /* !Py_BLTINMODULE_H */
|
Include/boolobject.h
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Boolean object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_BOOLOBJECT_H
|
| 4 |
+
#define Py_BOOLOBJECT_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
// PyBool_Type is declared by object.h
|
| 11 |
+
|
| 12 |
+
#define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type)
|
| 13 |
+
|
| 14 |
+
/* Py_False and Py_True are the only two bools in existence. */
|
| 15 |
+
|
| 16 |
+
/* Don't use these directly */
|
| 17 |
+
PyAPI_DATA(PyLongObject) _Py_FalseStruct;
|
| 18 |
+
PyAPI_DATA(PyLongObject) _Py_TrueStruct;
|
| 19 |
+
|
| 20 |
+
/* Use these macros */
|
| 21 |
+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030D0000
|
| 22 |
+
# define Py_False Py_GetConstantBorrowed(Py_CONSTANT_FALSE)
|
| 23 |
+
# define Py_True Py_GetConstantBorrowed(Py_CONSTANT_TRUE)
|
| 24 |
+
#else
|
| 25 |
+
# define Py_False _PyObject_CAST(&_Py_FalseStruct)
|
| 26 |
+
# define Py_True _PyObject_CAST(&_Py_TrueStruct)
|
| 27 |
+
#endif
|
| 28 |
+
|
| 29 |
+
// Test if an object is the True singleton, the same as "x is True" in Python.
|
| 30 |
+
PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
|
| 31 |
+
#define Py_IsTrue(x) Py_Is((x), Py_True)
|
| 32 |
+
|
| 33 |
+
// Test if an object is the False singleton, the same as "x is False" in Python.
|
| 34 |
+
PyAPI_FUNC(int) Py_IsFalse(PyObject *x);
|
| 35 |
+
#define Py_IsFalse(x) Py_Is((x), Py_False)
|
| 36 |
+
|
| 37 |
+
/* Macros for returning Py_True or Py_False, respectively.
|
| 38 |
+
* Only treat Py_True and Py_False as immortal in the limited C API 3.12
|
| 39 |
+
* and newer. */
|
| 40 |
+
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030c0000
|
| 41 |
+
# define Py_RETURN_TRUE return Py_NewRef(Py_True)
|
| 42 |
+
# define Py_RETURN_FALSE return Py_NewRef(Py_False)
|
| 43 |
+
#else
|
| 44 |
+
# define Py_RETURN_TRUE return Py_True
|
| 45 |
+
# define Py_RETURN_FALSE return Py_False
|
| 46 |
+
#endif
|
| 47 |
+
|
| 48 |
+
/* Function to return a bool from a C long */
|
| 49 |
+
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
|
| 50 |
+
|
| 51 |
+
#ifdef __cplusplus
|
| 52 |
+
}
|
| 53 |
+
#endif
|
| 54 |
+
#endif /* !Py_BOOLOBJECT_H */
|
Include/bytearrayobject.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ByteArray object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_BYTEARRAYOBJECT_H
|
| 4 |
+
#define Py_BYTEARRAYOBJECT_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
/* Type PyByteArrayObject represents a mutable array of bytes.
|
| 10 |
+
* The Python API is that of a sequence;
|
| 11 |
+
* the bytes are mapped to ints in [0, 256).
|
| 12 |
+
* Bytes are not characters; they may be used to encode characters.
|
| 13 |
+
* The only way to go between bytes and str/unicode is via encoding
|
| 14 |
+
* and decoding.
|
| 15 |
+
* For the convenience of C programmers, the bytes type is considered
|
| 16 |
+
* to contain a char pointer, not an unsigned char pointer.
|
| 17 |
+
*/
|
| 18 |
+
|
| 19 |
+
/* Type object */
|
| 20 |
+
PyAPI_DATA(PyTypeObject) PyByteArray_Type;
|
| 21 |
+
PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type;
|
| 22 |
+
|
| 23 |
+
/* Type check macros */
|
| 24 |
+
#define PyByteArray_Check(self) PyObject_TypeCheck((self), &PyByteArray_Type)
|
| 25 |
+
#define PyByteArray_CheckExact(self) Py_IS_TYPE((self), &PyByteArray_Type)
|
| 26 |
+
|
| 27 |
+
/* Direct API functions */
|
| 28 |
+
PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *);
|
| 29 |
+
PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *);
|
| 30 |
+
PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t);
|
| 31 |
+
PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *);
|
| 32 |
+
PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *);
|
| 33 |
+
PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
|
| 34 |
+
|
| 35 |
+
#ifndef Py_LIMITED_API
|
| 36 |
+
# define Py_CPYTHON_BYTEARRAYOBJECT_H
|
| 37 |
+
# include "cpython/bytearrayobject.h"
|
| 38 |
+
# undef Py_CPYTHON_BYTEARRAYOBJECT_H
|
| 39 |
+
#endif
|
| 40 |
+
|
| 41 |
+
#ifdef __cplusplus
|
| 42 |
+
}
|
| 43 |
+
#endif
|
| 44 |
+
#endif /* !Py_BYTEARRAYOBJECT_H */
|
Include/bytesobject.h
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Bytes object interface
|
| 2 |
+
|
| 3 |
+
#ifndef Py_BYTESOBJECT_H
|
| 4 |
+
#define Py_BYTESOBJECT_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
/*
|
| 10 |
+
Type PyBytesObject represents a byte string. An extra zero byte is
|
| 11 |
+
reserved at the end to ensure it is zero-terminated, but a size is
|
| 12 |
+
present so strings with null bytes in them can be represented. This
|
| 13 |
+
is an immutable object type.
|
| 14 |
+
|
| 15 |
+
There are functions to create new bytes objects, to test
|
| 16 |
+
an object for bytes-ness, and to get the
|
| 17 |
+
byte string value. The latter function returns a null pointer
|
| 18 |
+
if the object is not of the proper type.
|
| 19 |
+
There is a variant that takes an explicit size as well as a
|
| 20 |
+
variant that assumes a zero-terminated string. Note that none of the
|
| 21 |
+
functions should be applied to NULL pointer.
|
| 22 |
+
*/
|
| 23 |
+
|
| 24 |
+
PyAPI_DATA(PyTypeObject) PyBytes_Type;
|
| 25 |
+
PyAPI_DATA(PyTypeObject) PyBytesIter_Type;
|
| 26 |
+
|
| 27 |
+
#define PyBytes_Check(op) \
|
| 28 |
+
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
|
| 29 |
+
#define PyBytes_CheckExact(op) Py_IS_TYPE((op), &PyBytes_Type)
|
| 30 |
+
|
| 31 |
+
PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t);
|
| 32 |
+
PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *);
|
| 33 |
+
PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *);
|
| 34 |
+
PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list)
|
| 35 |
+
Py_GCC_ATTRIBUTE((format(printf, 1, 0)));
|
| 36 |
+
PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...)
|
| 37 |
+
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
| 38 |
+
PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *);
|
| 39 |
+
PyAPI_FUNC(char *) PyBytes_AsString(PyObject *);
|
| 40 |
+
PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int);
|
| 41 |
+
PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *);
|
| 42 |
+
PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *);
|
| 43 |
+
PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t,
|
| 44 |
+
const char *, Py_ssize_t,
|
| 45 |
+
const char *);
|
| 46 |
+
|
| 47 |
+
/* Provides access to the internal data buffer and size of a bytes object.
|
| 48 |
+
Passing NULL as len parameter will force the string buffer to be
|
| 49 |
+
0-terminated (passing a string with embedded NUL characters will
|
| 50 |
+
cause an exception). */
|
| 51 |
+
PyAPI_FUNC(int) PyBytes_AsStringAndSize(
|
| 52 |
+
PyObject *obj, /* bytes object */
|
| 53 |
+
char **s, /* pointer to buffer variable */
|
| 54 |
+
Py_ssize_t *len /* pointer to length variable or NULL */
|
| 55 |
+
);
|
| 56 |
+
|
| 57 |
+
#ifndef Py_LIMITED_API
|
| 58 |
+
# define Py_CPYTHON_BYTESOBJECT_H
|
| 59 |
+
# include "cpython/bytesobject.h"
|
| 60 |
+
# undef Py_CPYTHON_BYTESOBJECT_H
|
| 61 |
+
#endif
|
| 62 |
+
|
| 63 |
+
#ifdef __cplusplus
|
| 64 |
+
}
|
| 65 |
+
#endif
|
| 66 |
+
#endif /* !Py_BYTESOBJECT_H */
|
Include/ceval.h
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Interface to random parts in ceval.c */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_CEVAL_H
|
| 4 |
+
#define Py_CEVAL_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *);
|
| 11 |
+
|
| 12 |
+
PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co,
|
| 13 |
+
PyObject *globals,
|
| 14 |
+
PyObject *locals,
|
| 15 |
+
PyObject *const *args, int argc,
|
| 16 |
+
PyObject *const *kwds, int kwdc,
|
| 17 |
+
PyObject *const *defs, int defc,
|
| 18 |
+
PyObject *kwdefs, PyObject *closure);
|
| 19 |
+
|
| 20 |
+
PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void);
|
| 21 |
+
PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
|
| 22 |
+
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
|
| 23 |
+
PyAPI_FUNC(PyFrameObject *) PyEval_GetFrame(void);
|
| 24 |
+
|
| 25 |
+
PyAPI_FUNC(PyObject *) PyEval_GetFrameBuiltins(void);
|
| 26 |
+
PyAPI_FUNC(PyObject *) PyEval_GetFrameGlobals(void);
|
| 27 |
+
PyAPI_FUNC(PyObject *) PyEval_GetFrameLocals(void);
|
| 28 |
+
|
| 29 |
+
PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
|
| 30 |
+
PyAPI_FUNC(int) Py_MakePendingCalls(void);
|
| 31 |
+
|
| 32 |
+
/* Protection against deeply nested recursive calls
|
| 33 |
+
|
| 34 |
+
In Python 3.0, this protection has two levels:
|
| 35 |
+
* normal anti-recursion protection is triggered when the recursion level
|
| 36 |
+
exceeds the current recursion limit. It raises a RecursionError, and sets
|
| 37 |
+
the "overflowed" flag in the thread state structure. This flag
|
| 38 |
+
temporarily *disables* the normal protection; this allows cleanup code
|
| 39 |
+
to potentially outgrow the recursion limit while processing the
|
| 40 |
+
RecursionError.
|
| 41 |
+
* "last chance" anti-recursion protection is triggered when the recursion
|
| 42 |
+
level exceeds "current recursion limit + 50". By construction, this
|
| 43 |
+
protection can only be triggered when the "overflowed" flag is set. It
|
| 44 |
+
means the cleanup code has itself gone into an infinite loop, or the
|
| 45 |
+
RecursionError has been mistakingly ignored. When this protection is
|
| 46 |
+
triggered, the interpreter aborts with a Fatal Error.
|
| 47 |
+
|
| 48 |
+
In addition, the "overflowed" flag is automatically reset when the
|
| 49 |
+
recursion level drops below "current recursion limit - 50". This heuristic
|
| 50 |
+
is meant to ensure that the normal anti-recursion protection doesn't get
|
| 51 |
+
disabled too long.
|
| 52 |
+
|
| 53 |
+
Please note: this scheme has its own limitations. See:
|
| 54 |
+
http://mail.python.org/pipermail/python-dev/2008-August/082106.html
|
| 55 |
+
for some observations.
|
| 56 |
+
*/
|
| 57 |
+
PyAPI_FUNC(void) Py_SetRecursionLimit(int);
|
| 58 |
+
PyAPI_FUNC(int) Py_GetRecursionLimit(void);
|
| 59 |
+
|
| 60 |
+
PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where);
|
| 61 |
+
PyAPI_FUNC(void) Py_LeaveRecursiveCall(void);
|
| 62 |
+
|
| 63 |
+
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
|
| 64 |
+
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
|
| 65 |
+
|
| 66 |
+
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(PyFrameObject *);
|
| 67 |
+
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
|
| 68 |
+
|
| 69 |
+
/* Interface for threads.
|
| 70 |
+
|
| 71 |
+
A module that plans to do a blocking system call (or something else
|
| 72 |
+
that lasts a long time and doesn't touch Python data) can allow other
|
| 73 |
+
threads to run as follows:
|
| 74 |
+
|
| 75 |
+
...preparations here...
|
| 76 |
+
Py_BEGIN_ALLOW_THREADS
|
| 77 |
+
...blocking system call here...
|
| 78 |
+
Py_END_ALLOW_THREADS
|
| 79 |
+
...interpret result here...
|
| 80 |
+
|
| 81 |
+
The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a
|
| 82 |
+
{}-surrounded block.
|
| 83 |
+
To leave the block in the middle (e.g., with return), you must insert
|
| 84 |
+
a line containing Py_BLOCK_THREADS before the return, e.g.
|
| 85 |
+
|
| 86 |
+
if (...premature_exit...) {
|
| 87 |
+
Py_BLOCK_THREADS
|
| 88 |
+
PyErr_SetFromErrno(PyExc_OSError);
|
| 89 |
+
return NULL;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
An alternative is:
|
| 93 |
+
|
| 94 |
+
Py_BLOCK_THREADS
|
| 95 |
+
if (...premature_exit...) {
|
| 96 |
+
PyErr_SetFromErrno(PyExc_OSError);
|
| 97 |
+
return NULL;
|
| 98 |
+
}
|
| 99 |
+
Py_UNBLOCK_THREADS
|
| 100 |
+
|
| 101 |
+
For convenience, that the value of 'errno' is restored across
|
| 102 |
+
Py_END_ALLOW_THREADS and Py_BLOCK_THREADS.
|
| 103 |
+
|
| 104 |
+
WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
|
| 105 |
+
Py_END_ALLOW_THREADS!!!
|
| 106 |
+
|
| 107 |
+
Note that not yet all candidates have been converted to use this
|
| 108 |
+
mechanism!
|
| 109 |
+
*/
|
| 110 |
+
|
| 111 |
+
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
|
| 112 |
+
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
| 113 |
+
|
| 114 |
+
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
|
| 115 |
+
|
| 116 |
+
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
|
| 117 |
+
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
|
| 118 |
+
|
| 119 |
+
#define Py_BEGIN_ALLOW_THREADS { \
|
| 120 |
+
PyThreadState *_save; \
|
| 121 |
+
_save = PyEval_SaveThread();
|
| 122 |
+
#define Py_BLOCK_THREADS PyEval_RestoreThread(_save);
|
| 123 |
+
#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread();
|
| 124 |
+
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
/* Masks and values used by FORMAT_VALUE opcode. */
|
| 128 |
+
#define FVC_MASK 0x3
|
| 129 |
+
#define FVC_NONE 0x0
|
| 130 |
+
#define FVC_STR 0x1
|
| 131 |
+
#define FVC_REPR 0x2
|
| 132 |
+
#define FVC_ASCII 0x3
|
| 133 |
+
#define FVS_MASK 0x4
|
| 134 |
+
#define FVS_HAVE_SPEC 0x4
|
| 135 |
+
|
| 136 |
+
#ifndef Py_LIMITED_API
|
| 137 |
+
# define Py_CPYTHON_CEVAL_H
|
| 138 |
+
# include "cpython/ceval.h"
|
| 139 |
+
# undef Py_CPYTHON_CEVAL_H
|
| 140 |
+
#endif
|
| 141 |
+
|
| 142 |
+
#ifdef __cplusplus
|
| 143 |
+
}
|
| 144 |
+
#endif
|
| 145 |
+
#endif /* !Py_CEVAL_H */
|
Include/codecs.h
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CODECREGISTRY_H
|
| 2 |
+
#define Py_CODECREGISTRY_H
|
| 3 |
+
#ifdef __cplusplus
|
| 4 |
+
extern "C" {
|
| 5 |
+
#endif
|
| 6 |
+
|
| 7 |
+
/* ------------------------------------------------------------------------
|
| 8 |
+
|
| 9 |
+
Python Codec Registry and support functions
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
Written by Marc-Andre Lemburg (mal@lemburg.com).
|
| 13 |
+
|
| 14 |
+
Copyright (c) Corporation for National Research Initiatives.
|
| 15 |
+
|
| 16 |
+
------------------------------------------------------------------------ */
|
| 17 |
+
|
| 18 |
+
/* Register a new codec search function.
|
| 19 |
+
|
| 20 |
+
As side effect, this tries to load the encodings package, if not
|
| 21 |
+
yet done, to make sure that it is always first in the list of
|
| 22 |
+
search functions.
|
| 23 |
+
|
| 24 |
+
The search_function's refcount is incremented by this function. */
|
| 25 |
+
|
| 26 |
+
PyAPI_FUNC(int) PyCodec_Register(
|
| 27 |
+
PyObject *search_function
|
| 28 |
+
);
|
| 29 |
+
|
| 30 |
+
/* Unregister a codec search function and clear the registry's cache.
|
| 31 |
+
If the search function is not registered, do nothing.
|
| 32 |
+
Return 0 on success. Raise an exception and return -1 on error. */
|
| 33 |
+
|
| 34 |
+
PyAPI_FUNC(int) PyCodec_Unregister(
|
| 35 |
+
PyObject *search_function
|
| 36 |
+
);
|
| 37 |
+
|
| 38 |
+
/* Codec registry encoding check API.
|
| 39 |
+
|
| 40 |
+
Returns 1/0 depending on whether there is a registered codec for
|
| 41 |
+
the given encoding.
|
| 42 |
+
|
| 43 |
+
*/
|
| 44 |
+
|
| 45 |
+
PyAPI_FUNC(int) PyCodec_KnownEncoding(
|
| 46 |
+
const char *encoding
|
| 47 |
+
);
|
| 48 |
+
|
| 49 |
+
/* Generic codec based encoding API.
|
| 50 |
+
|
| 51 |
+
object is passed through the encoder function found for the given
|
| 52 |
+
encoding using the error handling method defined by errors. errors
|
| 53 |
+
may be NULL to use the default method defined for the codec.
|
| 54 |
+
|
| 55 |
+
Raises a LookupError in case no encoder can be found.
|
| 56 |
+
|
| 57 |
+
*/
|
| 58 |
+
|
| 59 |
+
PyAPI_FUNC(PyObject *) PyCodec_Encode(
|
| 60 |
+
PyObject *object,
|
| 61 |
+
const char *encoding,
|
| 62 |
+
const char *errors
|
| 63 |
+
);
|
| 64 |
+
|
| 65 |
+
/* Generic codec based decoding API.
|
| 66 |
+
|
| 67 |
+
object is passed through the decoder function found for the given
|
| 68 |
+
encoding using the error handling method defined by errors. errors
|
| 69 |
+
may be NULL to use the default method defined for the codec.
|
| 70 |
+
|
| 71 |
+
Raises a LookupError in case no encoder can be found.
|
| 72 |
+
|
| 73 |
+
*/
|
| 74 |
+
|
| 75 |
+
PyAPI_FUNC(PyObject *) PyCodec_Decode(
|
| 76 |
+
PyObject *object,
|
| 77 |
+
const char *encoding,
|
| 78 |
+
const char *errors
|
| 79 |
+
);
|
| 80 |
+
|
| 81 |
+
// --- Codec Lookup APIs --------------------------------------------------
|
| 82 |
+
|
| 83 |
+
/* Codec registry lookup API.
|
| 84 |
+
|
| 85 |
+
Looks up the given encoding and returns a CodecInfo object with
|
| 86 |
+
function attributes which implement the different aspects of
|
| 87 |
+
processing the encoding.
|
| 88 |
+
|
| 89 |
+
The encoding string is looked up converted to all lower-case
|
| 90 |
+
characters. This makes encodings looked up through this mechanism
|
| 91 |
+
effectively case-insensitive.
|
| 92 |
+
|
| 93 |
+
If no codec is found, a KeyError is set and NULL returned.
|
| 94 |
+
|
| 95 |
+
As side effect, this tries to load the encodings package, if not
|
| 96 |
+
yet done. This is part of the lazy load strategy for the encodings
|
| 97 |
+
package.
|
| 98 |
+
*/
|
| 99 |
+
|
| 100 |
+
/* Get an encoder function for the given encoding. */
|
| 101 |
+
|
| 102 |
+
PyAPI_FUNC(PyObject *) PyCodec_Encoder(const char *encoding);
|
| 103 |
+
|
| 104 |
+
/* Get a decoder function for the given encoding. */
|
| 105 |
+
|
| 106 |
+
PyAPI_FUNC(PyObject *) PyCodec_Decoder(const char *encoding);
|
| 107 |
+
|
| 108 |
+
/* Get an IncrementalEncoder object for the given encoding. */
|
| 109 |
+
|
| 110 |
+
PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
|
| 111 |
+
const char *encoding,
|
| 112 |
+
const char *errors);
|
| 113 |
+
|
| 114 |
+
/* Get an IncrementalDecoder object function for the given encoding. */
|
| 115 |
+
|
| 116 |
+
PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
|
| 117 |
+
const char *encoding,
|
| 118 |
+
const char *errors);
|
| 119 |
+
|
| 120 |
+
/* Get a StreamReader factory function for the given encoding. */
|
| 121 |
+
|
| 122 |
+
PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
|
| 123 |
+
const char *encoding,
|
| 124 |
+
PyObject *stream,
|
| 125 |
+
const char *errors);
|
| 126 |
+
|
| 127 |
+
/* Get a StreamWriter factory function for the given encoding. */
|
| 128 |
+
|
| 129 |
+
PyAPI_FUNC(PyObject *) PyCodec_StreamWriter(
|
| 130 |
+
const char *encoding,
|
| 131 |
+
PyObject *stream,
|
| 132 |
+
const char *errors);
|
| 133 |
+
|
| 134 |
+
/* Unicode encoding error handling callback registry API */
|
| 135 |
+
|
| 136 |
+
/* Register the error handling callback function error under the given
|
| 137 |
+
name. This function will be called by the codec when it encounters
|
| 138 |
+
unencodable characters/undecodable bytes and doesn't know the
|
| 139 |
+
callback name, when name is specified as the error parameter
|
| 140 |
+
in the call to the encode/decode function.
|
| 141 |
+
Return 0 on success, -1 on error */
|
| 142 |
+
PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error);
|
| 143 |
+
|
| 144 |
+
/* Lookup the error handling callback function registered under the given
|
| 145 |
+
name. As a special case NULL can be passed, in which case
|
| 146 |
+
the error handling callback for "strict" will be returned. */
|
| 147 |
+
PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name);
|
| 148 |
+
|
| 149 |
+
/* raise exc as an exception */
|
| 150 |
+
PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc);
|
| 151 |
+
|
| 152 |
+
/* ignore the unicode error, skipping the faulty input */
|
| 153 |
+
PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc);
|
| 154 |
+
|
| 155 |
+
/* replace the unicode encode error with ? or U+FFFD */
|
| 156 |
+
PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc);
|
| 157 |
+
|
| 158 |
+
/* replace the unicode encode error with XML character references */
|
| 159 |
+
PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc);
|
| 160 |
+
|
| 161 |
+
/* replace the unicode encode error with backslash escapes (\x, \u and \U) */
|
| 162 |
+
PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc);
|
| 163 |
+
|
| 164 |
+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
| 165 |
+
/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */
|
| 166 |
+
PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc);
|
| 167 |
+
#endif
|
| 168 |
+
|
| 169 |
+
#ifndef Py_LIMITED_API
|
| 170 |
+
PyAPI_DATA(const char *) Py_hexdigits;
|
| 171 |
+
#endif
|
| 172 |
+
|
| 173 |
+
#ifdef __cplusplus
|
| 174 |
+
}
|
| 175 |
+
#endif
|
| 176 |
+
#endif /* !Py_CODECREGISTRY_H */
|
Include/compile.h
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_COMPILE_H
|
| 2 |
+
#define Py_COMPILE_H
|
| 3 |
+
#ifdef __cplusplus
|
| 4 |
+
extern "C" {
|
| 5 |
+
#endif
|
| 6 |
+
|
| 7 |
+
/* These definitions must match corresponding definitions in graminit.h. */
|
| 8 |
+
#define Py_single_input 256
|
| 9 |
+
#define Py_file_input 257
|
| 10 |
+
#define Py_eval_input 258
|
| 11 |
+
#define Py_func_type_input 345
|
| 12 |
+
|
| 13 |
+
#ifndef Py_LIMITED_API
|
| 14 |
+
# define Py_CPYTHON_COMPILE_H
|
| 15 |
+
# include "cpython/compile.h"
|
| 16 |
+
# undef Py_CPYTHON_COMPILE_H
|
| 17 |
+
#endif
|
| 18 |
+
|
| 19 |
+
#ifdef __cplusplus
|
| 20 |
+
}
|
| 21 |
+
#endif
|
| 22 |
+
#endif /* !Py_COMPILE_H */
|
Include/complexobject.h
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Complex number structure */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_COMPLEXOBJECT_H
|
| 4 |
+
#define Py_COMPLEXOBJECT_H
|
| 5 |
+
#ifdef __cplusplus
|
| 6 |
+
extern "C" {
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
/* Complex object interface */
|
| 10 |
+
|
| 11 |
+
PyAPI_DATA(PyTypeObject) PyComplex_Type;
|
| 12 |
+
|
| 13 |
+
#define PyComplex_Check(op) PyObject_TypeCheck((op), &PyComplex_Type)
|
| 14 |
+
#define PyComplex_CheckExact(op) Py_IS_TYPE((op), &PyComplex_Type)
|
| 15 |
+
|
| 16 |
+
PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
|
| 17 |
+
|
| 18 |
+
PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
|
| 19 |
+
PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
|
| 20 |
+
|
| 21 |
+
#ifndef Py_LIMITED_API
|
| 22 |
+
# define Py_CPYTHON_COMPLEXOBJECT_H
|
| 23 |
+
# include "cpython/complexobject.h"
|
| 24 |
+
# undef Py_CPYTHON_COMPLEXOBJECT_H
|
| 25 |
+
#endif
|
| 26 |
+
|
| 27 |
+
#ifdef __cplusplus
|
| 28 |
+
}
|
| 29 |
+
#endif
|
| 30 |
+
#endif /* !Py_COMPLEXOBJECT_H */
|
Include/cpython/abstract.h
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
/* === Object Protocol ================================================== */
|
| 6 |
+
|
| 7 |
+
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
|
| 8 |
+
as the method name. */
|
| 9 |
+
PyAPI_FUNC(PyObject*) _PyObject_CallMethodId(
|
| 10 |
+
PyObject *obj,
|
| 11 |
+
_Py_Identifier *name,
|
| 12 |
+
const char *format, ...);
|
| 13 |
+
|
| 14 |
+
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
|
| 15 |
+
format to a Python dictionary ("kwargs" dict).
|
| 16 |
+
|
| 17 |
+
The type of kwnames keys is not checked. The final function getting
|
| 18 |
+
arguments is responsible to check if all keys are strings, for example using
|
| 19 |
+
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
|
| 20 |
+
|
| 21 |
+
Duplicate keys are merged using the last value. If duplicate keys must raise
|
| 22 |
+
an exception, the caller is responsible to implement an explicit keys on
|
| 23 |
+
kwnames. */
|
| 24 |
+
PyAPI_FUNC(PyObject*) _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
/* === Vectorcall protocol (PEP 590) ============================= */
|
| 28 |
+
|
| 29 |
+
// PyVectorcall_NARGS() is exported as a function for the stable ABI.
|
| 30 |
+
// Here (when we are not using the stable ABI), the name is overridden to
|
| 31 |
+
// call a static inline function for best performance.
|
| 32 |
+
static inline Py_ssize_t
|
| 33 |
+
_PyVectorcall_NARGS(size_t n)
|
| 34 |
+
{
|
| 35 |
+
return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
|
| 36 |
+
}
|
| 37 |
+
#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n)
|
| 38 |
+
|
| 39 |
+
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
|
| 40 |
+
|
| 41 |
+
// Backwards compatibility aliases (PEP 590) for API that was provisional
|
| 42 |
+
// in Python 3.8
|
| 43 |
+
#define _PyObject_Vectorcall PyObject_Vectorcall
|
| 44 |
+
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
|
| 45 |
+
#define _PyObject_FastCallDict PyObject_VectorcallDict
|
| 46 |
+
#define _PyVectorcall_Function PyVectorcall_Function
|
| 47 |
+
#define _PyObject_CallOneArg PyObject_CallOneArg
|
| 48 |
+
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
|
| 49 |
+
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
|
| 50 |
+
|
| 51 |
+
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
|
| 52 |
+
dict, which may be NULL if there are no keyword arguments. */
|
| 53 |
+
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
|
| 54 |
+
PyObject *callable,
|
| 55 |
+
PyObject *const *args,
|
| 56 |
+
size_t nargsf,
|
| 57 |
+
PyObject *kwargs);
|
| 58 |
+
|
| 59 |
+
PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg);
|
| 60 |
+
|
| 61 |
+
static inline PyObject *
|
| 62 |
+
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
|
| 63 |
+
{
|
| 64 |
+
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
| 65 |
+
return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
static inline PyObject *
|
| 69 |
+
PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
| 70 |
+
{
|
| 71 |
+
PyObject *args[2] = {self, arg};
|
| 72 |
+
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
| 73 |
+
assert(arg != NULL);
|
| 74 |
+
return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
/* Guess the size of object 'o' using len(o) or o.__length_hint__().
|
| 78 |
+
If neither of those return a non-negative value, then return the default
|
| 79 |
+
value. If one of the calls fails, this function returns -1. */
|
| 80 |
+
PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
|
| 81 |
+
|
| 82 |
+
/* === Sequence protocol ================================================ */
|
| 83 |
+
|
| 84 |
+
/* Assume tp_as_sequence and sq_item exist and that 'i' does not
|
| 85 |
+
need to be corrected for a negative index. */
|
| 86 |
+
#define PySequence_ITEM(o, i)\
|
| 87 |
+
( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) )
|
Include/cpython/bytearrayobject.h
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
/* Object layout */
|
| 6 |
+
typedef struct {
|
| 7 |
+
PyObject_VAR_HEAD
|
| 8 |
+
Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */
|
| 9 |
+
char *ob_bytes; /* Physical backing buffer */
|
| 10 |
+
char *ob_start; /* Logical start inside ob_bytes */
|
| 11 |
+
Py_ssize_t ob_exports; /* How many buffer exports */
|
| 12 |
+
} PyByteArrayObject;
|
| 13 |
+
|
| 14 |
+
PyAPI_DATA(char) _PyByteArray_empty_string[];
|
| 15 |
+
|
| 16 |
+
/* Macros and static inline functions, trading safety for speed */
|
| 17 |
+
#define _PyByteArray_CAST(op) \
|
| 18 |
+
(assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op))
|
| 19 |
+
|
| 20 |
+
static inline char* PyByteArray_AS_STRING(PyObject *op)
|
| 21 |
+
{
|
| 22 |
+
PyByteArrayObject *self = _PyByteArray_CAST(op);
|
| 23 |
+
if (Py_SIZE(self)) {
|
| 24 |
+
return self->ob_start;
|
| 25 |
+
}
|
| 26 |
+
return _PyByteArray_empty_string;
|
| 27 |
+
}
|
| 28 |
+
#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
|
| 29 |
+
|
| 30 |
+
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
|
| 31 |
+
PyByteArrayObject *self = _PyByteArray_CAST(op);
|
| 32 |
+
return Py_SIZE(self);
|
| 33 |
+
}
|
| 34 |
+
#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))
|
Include/cpython/bytesobject.h
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_BYTESOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef struct {
|
| 6 |
+
PyObject_VAR_HEAD
|
| 7 |
+
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
|
| 8 |
+
char ob_sval[1];
|
| 9 |
+
|
| 10 |
+
/* Invariants:
|
| 11 |
+
* ob_sval contains space for 'ob_size+1' elements.
|
| 12 |
+
* ob_sval[ob_size] == 0.
|
| 13 |
+
* ob_shash is the hash of the byte string or -1 if not computed yet.
|
| 14 |
+
*/
|
| 15 |
+
} PyBytesObject;
|
| 16 |
+
|
| 17 |
+
PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t);
|
| 18 |
+
|
| 19 |
+
/* Macros and static inline functions, trading safety for speed */
|
| 20 |
+
#define _PyBytes_CAST(op) \
|
| 21 |
+
(assert(PyBytes_Check(op)), _Py_CAST(PyBytesObject*, op))
|
| 22 |
+
|
| 23 |
+
static inline char* PyBytes_AS_STRING(PyObject *op)
|
| 24 |
+
{
|
| 25 |
+
return _PyBytes_CAST(op)->ob_sval;
|
| 26 |
+
}
|
| 27 |
+
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
|
| 28 |
+
|
| 29 |
+
static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) {
|
| 30 |
+
PyBytesObject *self = _PyBytes_CAST(op);
|
| 31 |
+
return Py_SIZE(self);
|
| 32 |
+
}
|
| 33 |
+
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
|
| 34 |
+
|
| 35 |
+
/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*,
|
| 36 |
+
x must be an iterable object. */
|
| 37 |
+
PyAPI_FUNC(PyObject*) _PyBytes_Join(PyObject *sep, PyObject *x);
|
Include/cpython/cellobject.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Cell object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_LIMITED_API
|
| 4 |
+
#ifndef Py_CELLOBJECT_H
|
| 5 |
+
#define Py_CELLOBJECT_H
|
| 6 |
+
#ifdef __cplusplus
|
| 7 |
+
extern "C" {
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
typedef struct {
|
| 11 |
+
PyObject_HEAD
|
| 12 |
+
/* Content of the cell or NULL when empty */
|
| 13 |
+
PyObject *ob_ref;
|
| 14 |
+
} PyCellObject;
|
| 15 |
+
|
| 16 |
+
PyAPI_DATA(PyTypeObject) PyCell_Type;
|
| 17 |
+
|
| 18 |
+
#define PyCell_Check(op) Py_IS_TYPE((op), &PyCell_Type)
|
| 19 |
+
|
| 20 |
+
PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
|
| 21 |
+
PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);
|
| 22 |
+
PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *);
|
| 23 |
+
|
| 24 |
+
static inline PyObject* PyCell_GET(PyObject *op) {
|
| 25 |
+
PyCellObject *cell;
|
| 26 |
+
assert(PyCell_Check(op));
|
| 27 |
+
cell = _Py_CAST(PyCellObject*, op);
|
| 28 |
+
return cell->ob_ref;
|
| 29 |
+
}
|
| 30 |
+
#define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op))
|
| 31 |
+
|
| 32 |
+
static inline void PyCell_SET(PyObject *op, PyObject *value) {
|
| 33 |
+
PyCellObject *cell;
|
| 34 |
+
assert(PyCell_Check(op));
|
| 35 |
+
cell = _Py_CAST(PyCellObject*, op);
|
| 36 |
+
cell->ob_ref = value;
|
| 37 |
+
}
|
| 38 |
+
#define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value))
|
| 39 |
+
|
| 40 |
+
#ifdef __cplusplus
|
| 41 |
+
}
|
| 42 |
+
#endif
|
| 43 |
+
#endif /* !Py_TUPLEOBJECT_H */
|
| 44 |
+
#endif /* Py_LIMITED_API */
|
Include/cpython/ceval.h
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_CEVAL_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
|
| 6 |
+
PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *);
|
| 7 |
+
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
|
| 8 |
+
PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *);
|
| 9 |
+
|
| 10 |
+
/* Look at the current frame's (if any) code's co_flags, and turn on
|
| 11 |
+
the corresponding compiler flags in cf->cf_flags. Return 1 if any
|
| 12 |
+
flag was set, else return 0. */
|
| 13 |
+
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
|
| 14 |
+
|
| 15 |
+
PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc);
|
| 16 |
+
|
| 17 |
+
PyAPI_FUNC(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc);
|
| 18 |
+
// Old name -- remove when this API changes:
|
| 19 |
+
_Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t
|
| 20 |
+
_PyEval_RequestCodeExtraIndex(freefunc f) {
|
| 21 |
+
return PyUnstable_Eval_RequestCodeExtraIndex(f);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
| 25 |
+
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
Include/cpython/classobject.h
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Former class object interface -- now only bound methods are here */
|
| 2 |
+
|
| 3 |
+
/* Revealing some structures (not for general use) */
|
| 4 |
+
|
| 5 |
+
#ifndef Py_LIMITED_API
|
| 6 |
+
#ifndef Py_CLASSOBJECT_H
|
| 7 |
+
#define Py_CLASSOBJECT_H
|
| 8 |
+
#ifdef __cplusplus
|
| 9 |
+
extern "C" {
|
| 10 |
+
#endif
|
| 11 |
+
|
| 12 |
+
typedef struct {
|
| 13 |
+
PyObject_HEAD
|
| 14 |
+
PyObject *im_func; /* The callable object implementing the method */
|
| 15 |
+
PyObject *im_self; /* The instance it is bound to */
|
| 16 |
+
PyObject *im_weakreflist; /* List of weak references */
|
| 17 |
+
vectorcallfunc vectorcall;
|
| 18 |
+
} PyMethodObject;
|
| 19 |
+
|
| 20 |
+
PyAPI_DATA(PyTypeObject) PyMethod_Type;
|
| 21 |
+
|
| 22 |
+
#define PyMethod_Check(op) Py_IS_TYPE((op), &PyMethod_Type)
|
| 23 |
+
|
| 24 |
+
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
|
| 25 |
+
|
| 26 |
+
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
|
| 27 |
+
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
|
| 28 |
+
|
| 29 |
+
#define _PyMethod_CAST(meth) \
|
| 30 |
+
(assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth))
|
| 31 |
+
|
| 32 |
+
/* Static inline functions for direct access to these values.
|
| 33 |
+
Type checks are *not* done, so use with care. */
|
| 34 |
+
static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) {
|
| 35 |
+
return _PyMethod_CAST(meth)->im_func;
|
| 36 |
+
}
|
| 37 |
+
#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth))
|
| 38 |
+
|
| 39 |
+
static inline PyObject* PyMethod_GET_SELF(PyObject *meth) {
|
| 40 |
+
return _PyMethod_CAST(meth)->im_self;
|
| 41 |
+
}
|
| 42 |
+
#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth))
|
| 43 |
+
|
| 44 |
+
typedef struct {
|
| 45 |
+
PyObject_HEAD
|
| 46 |
+
PyObject *func;
|
| 47 |
+
} PyInstanceMethodObject;
|
| 48 |
+
|
| 49 |
+
PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type;
|
| 50 |
+
|
| 51 |
+
#define PyInstanceMethod_Check(op) Py_IS_TYPE((op), &PyInstanceMethod_Type)
|
| 52 |
+
|
| 53 |
+
PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *);
|
| 54 |
+
PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *);
|
| 55 |
+
|
| 56 |
+
#define _PyInstanceMethod_CAST(meth) \
|
| 57 |
+
(assert(PyInstanceMethod_Check(meth)), \
|
| 58 |
+
_Py_CAST(PyInstanceMethodObject*, meth))
|
| 59 |
+
|
| 60 |
+
/* Static inline function for direct access to these values.
|
| 61 |
+
Type checks are *not* done, so use with care. */
|
| 62 |
+
static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) {
|
| 63 |
+
return _PyInstanceMethod_CAST(meth)->func;
|
| 64 |
+
}
|
| 65 |
+
#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth))
|
| 66 |
+
|
| 67 |
+
#ifdef __cplusplus
|
| 68 |
+
}
|
| 69 |
+
#endif
|
| 70 |
+
#endif // !Py_CLASSOBJECT_H
|
| 71 |
+
#endif // !Py_LIMITED_API
|
Include/cpython/code.h
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Definitions for bytecode */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_LIMITED_API
|
| 4 |
+
#ifndef Py_CODE_H
|
| 5 |
+
#define Py_CODE_H
|
| 6 |
+
|
| 7 |
+
#ifdef __cplusplus
|
| 8 |
+
extern "C" {
|
| 9 |
+
#endif
|
| 10 |
+
|
| 11 |
+
/* Count of all local monitoring events */
|
| 12 |
+
#define _PY_MONITORING_LOCAL_EVENTS 10
|
| 13 |
+
/* Count of all "real" monitoring events (not derived from other events) */
|
| 14 |
+
#define _PY_MONITORING_UNGROUPED_EVENTS 15
|
| 15 |
+
/* Count of all monitoring events */
|
| 16 |
+
#define _PY_MONITORING_EVENTS 17
|
| 17 |
+
|
| 18 |
+
/* Tables of which tools are active for each monitored event. */
|
| 19 |
+
typedef struct _Py_LocalMonitors {
|
| 20 |
+
uint8_t tools[_PY_MONITORING_LOCAL_EVENTS];
|
| 21 |
+
} _Py_LocalMonitors;
|
| 22 |
+
|
| 23 |
+
typedef struct _Py_GlobalMonitors {
|
| 24 |
+
uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS];
|
| 25 |
+
} _Py_GlobalMonitors;
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
typedef struct {
|
| 29 |
+
PyObject *_co_code;
|
| 30 |
+
PyObject *_co_varnames;
|
| 31 |
+
PyObject *_co_cellvars;
|
| 32 |
+
PyObject *_co_freevars;
|
| 33 |
+
} _PyCoCached;
|
| 34 |
+
|
| 35 |
+
/* Ancillary data structure used for instrumentation.
|
| 36 |
+
Line instrumentation creates this with sufficient
|
| 37 |
+
space for one entry per code unit. The total size
|
| 38 |
+
of the data will be `bytes_per_entry * Py_SIZE(code)` */
|
| 39 |
+
typedef struct {
|
| 40 |
+
uint8_t bytes_per_entry;
|
| 41 |
+
uint8_t data[1];
|
| 42 |
+
} _PyCoLineInstrumentationData;
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
typedef struct {
|
| 46 |
+
int size;
|
| 47 |
+
int capacity;
|
| 48 |
+
struct _PyExecutorObject *executors[1];
|
| 49 |
+
} _PyExecutorArray;
|
| 50 |
+
|
| 51 |
+
/* Main data structure used for instrumentation.
|
| 52 |
+
* This is allocated when needed for instrumentation
|
| 53 |
+
*/
|
| 54 |
+
typedef struct {
|
| 55 |
+
/* Monitoring specific to this code object */
|
| 56 |
+
_Py_LocalMonitors local_monitors;
|
| 57 |
+
/* Monitoring that is active on this code object */
|
| 58 |
+
_Py_LocalMonitors active_monitors;
|
| 59 |
+
/* The tools that are to be notified for events for the matching code unit */
|
| 60 |
+
uint8_t *tools;
|
| 61 |
+
/* Information to support line events */
|
| 62 |
+
_PyCoLineInstrumentationData *lines;
|
| 63 |
+
/* The tools that are to be notified for line events for the matching code unit */
|
| 64 |
+
uint8_t *line_tools;
|
| 65 |
+
/* Information to support instruction events */
|
| 66 |
+
/* The underlying instructions, which can themselves be instrumented */
|
| 67 |
+
uint8_t *per_instruction_opcodes;
|
| 68 |
+
/* The tools that are to be notified for instruction events for the matching code unit */
|
| 69 |
+
uint8_t *per_instruction_tools;
|
| 70 |
+
} _PyCoMonitoringData;
|
| 71 |
+
|
| 72 |
+
// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are
|
| 73 |
+
// defined in this macro:
|
| 74 |
+
#define _PyCode_DEF(SIZE) { \
|
| 75 |
+
PyObject_VAR_HEAD \
|
| 76 |
+
\
|
| 77 |
+
/* Note only the following fields are used in hash and/or comparisons \
|
| 78 |
+
* \
|
| 79 |
+
* - co_name \
|
| 80 |
+
* - co_argcount \
|
| 81 |
+
* - co_posonlyargcount \
|
| 82 |
+
* - co_kwonlyargcount \
|
| 83 |
+
* - co_nlocals \
|
| 84 |
+
* - co_stacksize \
|
| 85 |
+
* - co_flags \
|
| 86 |
+
* - co_firstlineno \
|
| 87 |
+
* - co_consts \
|
| 88 |
+
* - co_names \
|
| 89 |
+
* - co_localsplusnames \
|
| 90 |
+
* This is done to preserve the name and line number for tracebacks \
|
| 91 |
+
* and debuggers; otherwise, constant de-duplication would collapse \
|
| 92 |
+
* identical functions/lambdas defined on different lines. \
|
| 93 |
+
*/ \
|
| 94 |
+
\
|
| 95 |
+
/* These fields are set with provided values on new code objects. */ \
|
| 96 |
+
\
|
| 97 |
+
/* The hottest fields (in the eval loop) are grouped here at the top. */ \
|
| 98 |
+
PyObject *co_consts; /* list (constants used) */ \
|
| 99 |
+
PyObject *co_names; /* list of strings (names used) */ \
|
| 100 |
+
PyObject *co_exceptiontable; /* Byte string encoding exception handling \
|
| 101 |
+
table */ \
|
| 102 |
+
int co_flags; /* CO_..., see below */ \
|
| 103 |
+
\
|
| 104 |
+
/* The rest are not so impactful on performance. */ \
|
| 105 |
+
int co_argcount; /* #arguments, except *args */ \
|
| 106 |
+
int co_posonlyargcount; /* #positional only arguments */ \
|
| 107 |
+
int co_kwonlyargcount; /* #keyword only arguments */ \
|
| 108 |
+
int co_stacksize; /* #entries needed for evaluation stack */ \
|
| 109 |
+
int co_firstlineno; /* first source line number */ \
|
| 110 |
+
\
|
| 111 |
+
/* redundant values (derived from co_localsplusnames and \
|
| 112 |
+
co_localspluskinds) */ \
|
| 113 |
+
int co_nlocalsplus; /* number of local + cell + free variables */ \
|
| 114 |
+
int co_framesize; /* Size of frame in words */ \
|
| 115 |
+
int co_nlocals; /* number of local variables */ \
|
| 116 |
+
int co_ncellvars; /* total number of cell variables */ \
|
| 117 |
+
int co_nfreevars; /* number of free variables */ \
|
| 118 |
+
uint32_t co_version; /* version number */ \
|
| 119 |
+
\
|
| 120 |
+
PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \
|
| 121 |
+
PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \
|
| 122 |
+
per variable) */ \
|
| 123 |
+
PyObject *co_filename; /* unicode (where it was loaded from) */ \
|
| 124 |
+
PyObject *co_name; /* unicode (name, for reference) */ \
|
| 125 |
+
PyObject *co_qualname; /* unicode (qualname, for reference) */ \
|
| 126 |
+
PyObject *co_linetable; /* bytes object that holds location info */ \
|
| 127 |
+
PyObject *co_weakreflist; /* to support weakrefs to code objects */ \
|
| 128 |
+
_PyExecutorArray *co_executors; /* executors from optimizer */ \
|
| 129 |
+
_PyCoCached *_co_cached; /* cached co_* attributes */ \
|
| 130 |
+
uintptr_t _co_instrumentation_version; /* current instrumentation version */ \
|
| 131 |
+
_PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \
|
| 132 |
+
int _co_firsttraceable; /* index of first traceable instruction */ \
|
| 133 |
+
/* Scratch space for extra data relating to the code object. \
|
| 134 |
+
Type is a void* to keep the format private in codeobject.c to force \
|
| 135 |
+
people to go through the proper APIs. */ \
|
| 136 |
+
void *co_extra; \
|
| 137 |
+
char co_code_adaptive[(SIZE)]; \
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
/* Bytecode object */
|
| 141 |
+
struct PyCodeObject _PyCode_DEF(1);
|
| 142 |
+
|
| 143 |
+
/* Masks for co_flags above */
|
| 144 |
+
#define CO_OPTIMIZED 0x0001
|
| 145 |
+
#define CO_NEWLOCALS 0x0002
|
| 146 |
+
#define CO_VARARGS 0x0004
|
| 147 |
+
#define CO_VARKEYWORDS 0x0008
|
| 148 |
+
#define CO_NESTED 0x0010
|
| 149 |
+
#define CO_GENERATOR 0x0020
|
| 150 |
+
|
| 151 |
+
/* The CO_COROUTINE flag is set for coroutine functions (defined with
|
| 152 |
+
``async def`` keywords) */
|
| 153 |
+
#define CO_COROUTINE 0x0080
|
| 154 |
+
#define CO_ITERABLE_COROUTINE 0x0100
|
| 155 |
+
#define CO_ASYNC_GENERATOR 0x0200
|
| 156 |
+
|
| 157 |
+
/* bpo-39562: These constant values are changed in Python 3.9
|
| 158 |
+
to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
|
| 159 |
+
constants must be kept unique. PyCF_ constants can use bits from
|
| 160 |
+
0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
|
| 161 |
+
#define CO_FUTURE_DIVISION 0x20000
|
| 162 |
+
#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */
|
| 163 |
+
#define CO_FUTURE_WITH_STATEMENT 0x80000
|
| 164 |
+
#define CO_FUTURE_PRINT_FUNCTION 0x100000
|
| 165 |
+
#define CO_FUTURE_UNICODE_LITERALS 0x200000
|
| 166 |
+
|
| 167 |
+
#define CO_FUTURE_BARRY_AS_BDFL 0x400000
|
| 168 |
+
#define CO_FUTURE_GENERATOR_STOP 0x800000
|
| 169 |
+
#define CO_FUTURE_ANNOTATIONS 0x1000000
|
| 170 |
+
|
| 171 |
+
#define CO_NO_MONITORING_EVENTS 0x2000000
|
| 172 |
+
|
| 173 |
+
/* This should be defined if a future statement modifies the syntax.
|
| 174 |
+
For example, when a keyword is added.
|
| 175 |
+
*/
|
| 176 |
+
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
| 177 |
+
|
| 178 |
+
#define CO_MAXBLOCKS 21 /* Max static block nesting within a function */
|
| 179 |
+
|
| 180 |
+
PyAPI_DATA(PyTypeObject) PyCode_Type;
|
| 181 |
+
|
| 182 |
+
#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type)
|
| 183 |
+
|
| 184 |
+
static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
|
| 185 |
+
assert(PyCode_Check(op));
|
| 186 |
+
return op->co_nfreevars;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
static inline int PyUnstable_Code_GetFirstFree(PyCodeObject *op) {
|
| 190 |
+
assert(PyCode_Check(op));
|
| 191 |
+
return op->co_nlocalsplus - op->co_nfreevars;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
Py_DEPRECATED(3.13) static inline int PyCode_GetFirstFree(PyCodeObject *op) {
|
| 195 |
+
return PyUnstable_Code_GetFirstFree(op);
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
/* Unstable public interface */
|
| 199 |
+
PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New(
|
| 200 |
+
int, int, int, int, int, PyObject *, PyObject *,
|
| 201 |
+
PyObject *, PyObject *, PyObject *, PyObject *,
|
| 202 |
+
PyObject *, PyObject *, PyObject *, int, PyObject *,
|
| 203 |
+
PyObject *);
|
| 204 |
+
|
| 205 |
+
PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs(
|
| 206 |
+
int, int, int, int, int, int, PyObject *, PyObject *,
|
| 207 |
+
PyObject *, PyObject *, PyObject *, PyObject *,
|
| 208 |
+
PyObject *, PyObject *, PyObject *, int, PyObject *,
|
| 209 |
+
PyObject *);
|
| 210 |
+
/* same as struct above */
|
| 211 |
+
// Old names -- remove when this API changes:
|
| 212 |
+
_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
|
| 213 |
+
PyCode_New(
|
| 214 |
+
int a, int b, int c, int d, int e, PyObject *f, PyObject *g,
|
| 215 |
+
PyObject *h, PyObject *i, PyObject *j, PyObject *k,
|
| 216 |
+
PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
|
| 217 |
+
PyObject *q)
|
| 218 |
+
{
|
| 219 |
+
return PyUnstable_Code_New(
|
| 220 |
+
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
|
| 221 |
+
}
|
| 222 |
+
_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
|
| 223 |
+
PyCode_NewWithPosOnlyArgs(
|
| 224 |
+
int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g,
|
| 225 |
+
PyObject *h, PyObject *i, PyObject *j, PyObject *k,
|
| 226 |
+
PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
|
| 227 |
+
PyObject *q)
|
| 228 |
+
{
|
| 229 |
+
return PyUnstable_Code_NewWithPosOnlyArgs(
|
| 230 |
+
a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/* Creates a new empty code object with the specified source location. */
|
| 234 |
+
PyAPI_FUNC(PyCodeObject *)
|
| 235 |
+
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
|
| 236 |
+
|
| 237 |
+
/* Return the line number associated with the specified bytecode index
|
| 238 |
+
in this code object. If you just need the line number of a frame,
|
| 239 |
+
use PyFrame_GetLineNumber() instead. */
|
| 240 |
+
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
|
| 241 |
+
|
| 242 |
+
PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *);
|
| 243 |
+
|
| 244 |
+
#define PY_FOREACH_CODE_EVENT(V) \
|
| 245 |
+
V(CREATE) \
|
| 246 |
+
V(DESTROY)
|
| 247 |
+
|
| 248 |
+
typedef enum {
|
| 249 |
+
#define PY_DEF_EVENT(op) PY_CODE_EVENT_##op,
|
| 250 |
+
PY_FOREACH_CODE_EVENT(PY_DEF_EVENT)
|
| 251 |
+
#undef PY_DEF_EVENT
|
| 252 |
+
} PyCodeEvent;
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
/*
|
| 256 |
+
* A callback that is invoked for different events in a code object's lifecycle.
|
| 257 |
+
*
|
| 258 |
+
* The callback is invoked with a borrowed reference to co, after it is
|
| 259 |
+
* created and before it is destroyed.
|
| 260 |
+
*
|
| 261 |
+
* If the callback sets an exception, it must return -1. Otherwise
|
| 262 |
+
* it should return 0.
|
| 263 |
+
*/
|
| 264 |
+
typedef int (*PyCode_WatchCallback)(
|
| 265 |
+
PyCodeEvent event,
|
| 266 |
+
PyCodeObject* co);
|
| 267 |
+
|
| 268 |
+
/*
|
| 269 |
+
* Register a per-interpreter callback that will be invoked for code object
|
| 270 |
+
* lifecycle events.
|
| 271 |
+
*
|
| 272 |
+
* Returns a handle that may be passed to PyCode_ClearWatcher on success,
|
| 273 |
+
* or -1 and sets an error if no more handles are available.
|
| 274 |
+
*/
|
| 275 |
+
PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback);
|
| 276 |
+
|
| 277 |
+
/*
|
| 278 |
+
* Clear the watcher associated with the watcher_id handle.
|
| 279 |
+
*
|
| 280 |
+
* Returns 0 on success or -1 if no watcher exists for the provided id.
|
| 281 |
+
*/
|
| 282 |
+
PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id);
|
| 283 |
+
|
| 284 |
+
/* for internal use only */
|
| 285 |
+
struct _opaque {
|
| 286 |
+
int computed_line;
|
| 287 |
+
const uint8_t *lo_next;
|
| 288 |
+
const uint8_t *limit;
|
| 289 |
+
};
|
| 290 |
+
|
| 291 |
+
typedef struct _line_offsets {
|
| 292 |
+
int ar_start;
|
| 293 |
+
int ar_end;
|
| 294 |
+
int ar_line;
|
| 295 |
+
struct _opaque opaque;
|
| 296 |
+
} PyCodeAddressRange;
|
| 297 |
+
|
| 298 |
+
/* Update *bounds to describe the first and one-past-the-last instructions in the
|
| 299 |
+
same line as lasti. Return the number of that line.
|
| 300 |
+
*/
|
| 301 |
+
PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds);
|
| 302 |
+
|
| 303 |
+
/* Create a comparable key used to compare constants taking in account the
|
| 304 |
+
* object type. It is used to make sure types are not coerced (e.g., float and
|
| 305 |
+
* complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
|
| 306 |
+
*
|
| 307 |
+
* Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
|
| 308 |
+
* depending on the type and the value. The type is the first item to not
|
| 309 |
+
* compare bytes and str which can raise a BytesWarning exception. */
|
| 310 |
+
PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
|
| 311 |
+
|
| 312 |
+
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
|
| 313 |
+
PyObject *names, PyObject *lnotab);
|
| 314 |
+
|
| 315 |
+
PyAPI_FUNC(int) PyUnstable_Code_GetExtra(
|
| 316 |
+
PyObject *code, Py_ssize_t index, void **extra);
|
| 317 |
+
PyAPI_FUNC(int) PyUnstable_Code_SetExtra(
|
| 318 |
+
PyObject *code, Py_ssize_t index, void *extra);
|
| 319 |
+
// Old names -- remove when this API changes:
|
| 320 |
+
_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
|
| 321 |
+
_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
|
| 322 |
+
{
|
| 323 |
+
return PyUnstable_Code_GetExtra(code, index, extra);
|
| 324 |
+
}
|
| 325 |
+
_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
|
| 326 |
+
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
|
| 327 |
+
{
|
| 328 |
+
return PyUnstable_Code_SetExtra(code, index, extra);
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
/* Equivalent to getattr(code, 'co_code') in Python.
|
| 332 |
+
Returns a strong reference to a bytes object. */
|
| 333 |
+
PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code);
|
| 334 |
+
/* Equivalent to getattr(code, 'co_varnames') in Python. */
|
| 335 |
+
PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code);
|
| 336 |
+
/* Equivalent to getattr(code, 'co_cellvars') in Python. */
|
| 337 |
+
PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code);
|
| 338 |
+
/* Equivalent to getattr(code, 'co_freevars') in Python. */
|
| 339 |
+
PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code);
|
| 340 |
+
|
| 341 |
+
typedef enum _PyCodeLocationInfoKind {
|
| 342 |
+
/* short forms are 0 to 9 */
|
| 343 |
+
PY_CODE_LOCATION_INFO_SHORT0 = 0,
|
| 344 |
+
/* one lineforms are 10 to 12 */
|
| 345 |
+
PY_CODE_LOCATION_INFO_ONE_LINE0 = 10,
|
| 346 |
+
PY_CODE_LOCATION_INFO_ONE_LINE1 = 11,
|
| 347 |
+
PY_CODE_LOCATION_INFO_ONE_LINE2 = 12,
|
| 348 |
+
|
| 349 |
+
PY_CODE_LOCATION_INFO_NO_COLUMNS = 13,
|
| 350 |
+
PY_CODE_LOCATION_INFO_LONG = 14,
|
| 351 |
+
PY_CODE_LOCATION_INFO_NONE = 15
|
| 352 |
+
} _PyCodeLocationInfoKind;
|
| 353 |
+
|
| 354 |
+
#ifdef __cplusplus
|
| 355 |
+
}
|
| 356 |
+
#endif
|
| 357 |
+
#endif // !Py_CODE_H
|
| 358 |
+
#endif // !Py_LIMITED_API
|
Include/cpython/compile.h
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_COMPILE_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
/* Public interface */
|
| 6 |
+
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
|
| 7 |
+
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
|
| 8 |
+
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
|
| 9 |
+
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
|
| 10 |
+
#define PyCF_MASK_OBSOLETE (CO_NESTED)
|
| 11 |
+
|
| 12 |
+
/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique.
|
| 13 |
+
PyCF_ constants can use bits from 0x0100 to 0x10000.
|
| 14 |
+
CO_FUTURE_ constants use bits starting at 0x20000. */
|
| 15 |
+
#define PyCF_SOURCE_IS_UTF8 0x0100
|
| 16 |
+
#define PyCF_DONT_IMPLY_DEDENT 0x0200
|
| 17 |
+
#define PyCF_ONLY_AST 0x0400
|
| 18 |
+
#define PyCF_IGNORE_COOKIE 0x0800
|
| 19 |
+
#define PyCF_TYPE_COMMENTS 0x1000
|
| 20 |
+
#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
|
| 21 |
+
#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000
|
| 22 |
+
#define PyCF_OPTIMIZED_AST (0x8000 | PyCF_ONLY_AST)
|
| 23 |
+
#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
|
| 24 |
+
PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \
|
| 25 |
+
PyCF_ALLOW_INCOMPLETE_INPUT | PyCF_OPTIMIZED_AST)
|
| 26 |
+
|
| 27 |
+
typedef struct {
|
| 28 |
+
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
|
| 29 |
+
int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */
|
| 30 |
+
} PyCompilerFlags;
|
| 31 |
+
|
| 32 |
+
#define _PyCompilerFlags_INIT \
|
| 33 |
+
(PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}
|
| 34 |
+
|
| 35 |
+
/* Future feature support */
|
| 36 |
+
|
| 37 |
+
#define FUTURE_NESTED_SCOPES "nested_scopes"
|
| 38 |
+
#define FUTURE_GENERATORS "generators"
|
| 39 |
+
#define FUTURE_DIVISION "division"
|
| 40 |
+
#define FUTURE_ABSOLUTE_IMPORT "absolute_import"
|
| 41 |
+
#define FUTURE_WITH_STATEMENT "with_statement"
|
| 42 |
+
#define FUTURE_PRINT_FUNCTION "print_function"
|
| 43 |
+
#define FUTURE_UNICODE_LITERALS "unicode_literals"
|
| 44 |
+
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
|
| 45 |
+
#define FUTURE_GENERATOR_STOP "generator_stop"
|
| 46 |
+
#define FUTURE_ANNOTATIONS "annotations"
|
| 47 |
+
|
| 48 |
+
#define PY_INVALID_STACK_EFFECT INT_MAX
|
| 49 |
+
PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg);
|
| 50 |
+
PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump);
|
Include/cpython/complexobject.h
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_COMPLEXOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef struct {
|
| 6 |
+
double real;
|
| 7 |
+
double imag;
|
| 8 |
+
} Py_complex;
|
| 9 |
+
|
| 10 |
+
// Operations on complex numbers.
|
| 11 |
+
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
|
| 12 |
+
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
|
| 13 |
+
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
|
| 14 |
+
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
|
| 15 |
+
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
|
| 16 |
+
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
|
| 17 |
+
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
/* Complex object interface */
|
| 21 |
+
|
| 22 |
+
/*
|
| 23 |
+
PyComplexObject represents a complex number with double-precision
|
| 24 |
+
real and imaginary parts.
|
| 25 |
+
*/
|
| 26 |
+
typedef struct {
|
| 27 |
+
PyObject_HEAD
|
| 28 |
+
Py_complex cval;
|
| 29 |
+
} PyComplexObject;
|
| 30 |
+
|
| 31 |
+
PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
|
| 32 |
+
|
| 33 |
+
PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
|
Include/cpython/context.h
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_LIMITED_API
|
| 2 |
+
#ifndef Py_CONTEXT_H
|
| 3 |
+
#define Py_CONTEXT_H
|
| 4 |
+
#ifdef __cplusplus
|
| 5 |
+
extern "C" {
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
PyAPI_DATA(PyTypeObject) PyContext_Type;
|
| 9 |
+
typedef struct _pycontextobject PyContext;
|
| 10 |
+
|
| 11 |
+
PyAPI_DATA(PyTypeObject) PyContextVar_Type;
|
| 12 |
+
typedef struct _pycontextvarobject PyContextVar;
|
| 13 |
+
|
| 14 |
+
PyAPI_DATA(PyTypeObject) PyContextToken_Type;
|
| 15 |
+
typedef struct _pycontexttokenobject PyContextToken;
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
#define PyContext_CheckExact(o) Py_IS_TYPE((o), &PyContext_Type)
|
| 19 |
+
#define PyContextVar_CheckExact(o) Py_IS_TYPE((o), &PyContextVar_Type)
|
| 20 |
+
#define PyContextToken_CheckExact(o) Py_IS_TYPE((o), &PyContextToken_Type)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
PyAPI_FUNC(PyObject *) PyContext_New(void);
|
| 24 |
+
PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *);
|
| 25 |
+
PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void);
|
| 26 |
+
|
| 27 |
+
PyAPI_FUNC(int) PyContext_Enter(PyObject *);
|
| 28 |
+
PyAPI_FUNC(int) PyContext_Exit(PyObject *);
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
/* Create a new context variable.
|
| 32 |
+
|
| 33 |
+
default_value can be NULL.
|
| 34 |
+
*/
|
| 35 |
+
PyAPI_FUNC(PyObject *) PyContextVar_New(
|
| 36 |
+
const char *name, PyObject *default_value);
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
/* Get a value for the variable.
|
| 40 |
+
|
| 41 |
+
Returns -1 if an error occurred during lookup.
|
| 42 |
+
|
| 43 |
+
Returns 0 if value either was or was not found.
|
| 44 |
+
|
| 45 |
+
If value was found, *value will point to it.
|
| 46 |
+
If not, it will point to:
|
| 47 |
+
|
| 48 |
+
- default_value, if not NULL;
|
| 49 |
+
- the default value of "var", if not NULL;
|
| 50 |
+
- NULL.
|
| 51 |
+
|
| 52 |
+
'*value' will be a new ref, if not NULL.
|
| 53 |
+
*/
|
| 54 |
+
PyAPI_FUNC(int) PyContextVar_Get(
|
| 55 |
+
PyObject *var, PyObject *default_value, PyObject **value);
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
/* Set a new value for the variable.
|
| 59 |
+
Returns NULL if an error occurs.
|
| 60 |
+
*/
|
| 61 |
+
PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value);
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
/* Reset a variable to its previous value.
|
| 65 |
+
Returns 0 on success, -1 on error.
|
| 66 |
+
*/
|
| 67 |
+
PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token);
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
#ifdef __cplusplus
|
| 71 |
+
}
|
| 72 |
+
#endif
|
| 73 |
+
#endif /* !Py_CONTEXT_H */
|
| 74 |
+
#endif /* !Py_LIMITED_API */
|
Include/cpython/critical_section.h
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_CRITICAL_SECTION_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
// Python critical sections
|
| 6 |
+
//
|
| 7 |
+
// Conceptually, critical sections are a deadlock avoidance layer on top of
|
| 8 |
+
// per-object locks. These helpers, in combination with those locks, replace
|
| 9 |
+
// our usage of the global interpreter lock to provide thread-safety for
|
| 10 |
+
// otherwise thread-unsafe objects, such as dict.
|
| 11 |
+
//
|
| 12 |
+
// NOTE: These APIs are no-ops in non-free-threaded builds.
|
| 13 |
+
//
|
| 14 |
+
// Straightforward per-object locking could introduce deadlocks that were not
|
| 15 |
+
// present when running with the GIL. Threads may hold locks for multiple
|
| 16 |
+
// objects simultaneously because Python operations can nest. If threads were
|
| 17 |
+
// to acquire the same locks in different orders, they would deadlock.
|
| 18 |
+
//
|
| 19 |
+
// One way to avoid deadlocks is to allow threads to hold only the lock (or
|
| 20 |
+
// locks) for a single operation at a time (typically a single lock, but some
|
| 21 |
+
// operations involve two locks). When a thread begins a nested operation it
|
| 22 |
+
// could suspend the locks for any outer operation: before beginning the nested
|
| 23 |
+
// operation, the locks for the outer operation are released and when the
|
| 24 |
+
// nested operation completes, the locks for the outer operation are
|
| 25 |
+
// reacquired.
|
| 26 |
+
//
|
| 27 |
+
// To improve performance, this API uses a variation of the above scheme.
|
| 28 |
+
// Instead of immediately suspending locks any time a nested operation begins,
|
| 29 |
+
// locks are only suspended if the thread would block. This reduces the number
|
| 30 |
+
// of lock acquisitions and releases for nested operations, while still
|
| 31 |
+
// avoiding deadlocks.
|
| 32 |
+
//
|
| 33 |
+
// Additionally, the locks for any active operation are suspended around
|
| 34 |
+
// other potentially blocking operations, such as I/O. This is because the
|
| 35 |
+
// interaction between locks and blocking operations can lead to deadlocks in
|
| 36 |
+
// the same way as the interaction between multiple locks.
|
| 37 |
+
//
|
| 38 |
+
// Each thread's critical sections and their corresponding locks are tracked in
|
| 39 |
+
// a stack in `PyThreadState.critical_section`. When a thread calls
|
| 40 |
+
// `_PyThreadState_Detach()`, such as before a blocking I/O operation or when
|
| 41 |
+
// waiting to acquire a lock, the thread suspends all of its active critical
|
| 42 |
+
// sections, temporarily releasing the associated locks. When the thread calls
|
| 43 |
+
// `_PyThreadState_Attach()`, it resumes the top-most (i.e., most recent)
|
| 44 |
+
// critical section by reacquiring the associated lock or locks. See
|
| 45 |
+
// `_PyCriticalSection_Resume()`.
|
| 46 |
+
//
|
| 47 |
+
// NOTE: Only the top-most critical section is guaranteed to be active.
|
| 48 |
+
// Operations that need to lock two objects at once must use
|
| 49 |
+
// `Py_BEGIN_CRITICAL_SECTION2()`. You *CANNOT* use nested critical sections
|
| 50 |
+
// to lock more than one object at once, because the inner critical section
|
| 51 |
+
// may suspend the outer critical sections. This API does not provide a way
|
| 52 |
+
// to lock more than two objects at once (though it could be added later
|
| 53 |
+
// if actually needed).
|
| 54 |
+
//
|
| 55 |
+
// NOTE: Critical sections implicitly behave like reentrant locks because
|
| 56 |
+
// attempting to acquire the same lock will suspend any outer (earlier)
|
| 57 |
+
// critical sections. However, they are less efficient for this use case than
|
| 58 |
+
// purposefully designed reentrant locks.
|
| 59 |
+
//
|
| 60 |
+
// Example usage:
|
| 61 |
+
// Py_BEGIN_CRITICAL_SECTION(op);
|
| 62 |
+
// ...
|
| 63 |
+
// Py_END_CRITICAL_SECTION();
|
| 64 |
+
//
|
| 65 |
+
// To lock two objects at once:
|
| 66 |
+
// Py_BEGIN_CRITICAL_SECTION2(op1, op2);
|
| 67 |
+
// ...
|
| 68 |
+
// Py_END_CRITICAL_SECTION2();
|
| 69 |
+
|
| 70 |
+
typedef struct PyCriticalSection PyCriticalSection;
|
| 71 |
+
typedef struct PyCriticalSection2 PyCriticalSection2;
|
| 72 |
+
|
| 73 |
+
PyAPI_FUNC(void)
|
| 74 |
+
PyCriticalSection_Begin(PyCriticalSection *c, PyObject *op);
|
| 75 |
+
|
| 76 |
+
PyAPI_FUNC(void)
|
| 77 |
+
PyCriticalSection_End(PyCriticalSection *c);
|
| 78 |
+
|
| 79 |
+
PyAPI_FUNC(void)
|
| 80 |
+
PyCriticalSection2_Begin(PyCriticalSection2 *c, PyObject *a, PyObject *b);
|
| 81 |
+
|
| 82 |
+
PyAPI_FUNC(void)
|
| 83 |
+
PyCriticalSection2_End(PyCriticalSection2 *c);
|
| 84 |
+
|
| 85 |
+
#ifndef Py_GIL_DISABLED
|
| 86 |
+
# define Py_BEGIN_CRITICAL_SECTION(op) \
|
| 87 |
+
{
|
| 88 |
+
# define Py_END_CRITICAL_SECTION() \
|
| 89 |
+
}
|
| 90 |
+
# define Py_BEGIN_CRITICAL_SECTION2(a, b) \
|
| 91 |
+
{
|
| 92 |
+
# define Py_END_CRITICAL_SECTION2() \
|
| 93 |
+
}
|
| 94 |
+
#else /* !Py_GIL_DISABLED */
|
| 95 |
+
|
| 96 |
+
// NOTE: the contents of this struct are private and may change betweeen
|
| 97 |
+
// Python releases without a deprecation period.
|
| 98 |
+
struct PyCriticalSection {
|
| 99 |
+
// Tagged pointer to an outer active critical section (or 0).
|
| 100 |
+
uintptr_t _cs_prev;
|
| 101 |
+
|
| 102 |
+
// Mutex used to protect critical section
|
| 103 |
+
PyMutex *_cs_mutex;
|
| 104 |
+
};
|
| 105 |
+
|
| 106 |
+
// A critical section protected by two mutexes. Use
|
| 107 |
+
// Py_BEGIN_CRITICAL_SECTION2 and Py_END_CRITICAL_SECTION2.
|
| 108 |
+
// NOTE: the contents of this struct are private and may change betweeen
|
| 109 |
+
// Python releases without a deprecation period.
|
| 110 |
+
struct PyCriticalSection2 {
|
| 111 |
+
PyCriticalSection _cs_base;
|
| 112 |
+
|
| 113 |
+
PyMutex *_cs_mutex2;
|
| 114 |
+
};
|
| 115 |
+
|
| 116 |
+
# define Py_BEGIN_CRITICAL_SECTION(op) \
|
| 117 |
+
{ \
|
| 118 |
+
PyCriticalSection _py_cs; \
|
| 119 |
+
PyCriticalSection_Begin(&_py_cs, _PyObject_CAST(op))
|
| 120 |
+
|
| 121 |
+
# define Py_END_CRITICAL_SECTION() \
|
| 122 |
+
PyCriticalSection_End(&_py_cs); \
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
# define Py_BEGIN_CRITICAL_SECTION2(a, b) \
|
| 126 |
+
{ \
|
| 127 |
+
PyCriticalSection2 _py_cs2; \
|
| 128 |
+
PyCriticalSection2_Begin(&_py_cs2, _PyObject_CAST(a), _PyObject_CAST(b))
|
| 129 |
+
|
| 130 |
+
# define Py_END_CRITICAL_SECTION2() \
|
| 131 |
+
PyCriticalSection2_End(&_py_cs2); \
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
#endif
|
Include/cpython/descrobject.h
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_DESCROBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
|
| 6 |
+
void *wrapped);
|
| 7 |
+
|
| 8 |
+
typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
|
| 9 |
+
void *wrapped, PyObject *kwds);
|
| 10 |
+
|
| 11 |
+
struct wrapperbase {
|
| 12 |
+
const char *name;
|
| 13 |
+
int offset;
|
| 14 |
+
void *function;
|
| 15 |
+
wrapperfunc wrapper;
|
| 16 |
+
const char *doc;
|
| 17 |
+
int flags;
|
| 18 |
+
PyObject *name_strobj;
|
| 19 |
+
};
|
| 20 |
+
|
| 21 |
+
/* Flags for above struct */
|
| 22 |
+
#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */
|
| 23 |
+
|
| 24 |
+
/* Various kinds of descriptor objects */
|
| 25 |
+
|
| 26 |
+
typedef struct {
|
| 27 |
+
PyObject_HEAD
|
| 28 |
+
PyTypeObject *d_type;
|
| 29 |
+
PyObject *d_name;
|
| 30 |
+
PyObject *d_qualname;
|
| 31 |
+
} PyDescrObject;
|
| 32 |
+
|
| 33 |
+
#define PyDescr_COMMON PyDescrObject d_common
|
| 34 |
+
|
| 35 |
+
#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
|
| 36 |
+
#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
|
| 37 |
+
|
| 38 |
+
typedef struct {
|
| 39 |
+
PyDescr_COMMON;
|
| 40 |
+
PyMethodDef *d_method;
|
| 41 |
+
vectorcallfunc vectorcall;
|
| 42 |
+
} PyMethodDescrObject;
|
| 43 |
+
|
| 44 |
+
typedef struct {
|
| 45 |
+
PyDescr_COMMON;
|
| 46 |
+
PyMemberDef *d_member;
|
| 47 |
+
} PyMemberDescrObject;
|
| 48 |
+
|
| 49 |
+
typedef struct {
|
| 50 |
+
PyDescr_COMMON;
|
| 51 |
+
PyGetSetDef *d_getset;
|
| 52 |
+
} PyGetSetDescrObject;
|
| 53 |
+
|
| 54 |
+
typedef struct {
|
| 55 |
+
PyDescr_COMMON;
|
| 56 |
+
struct wrapperbase *d_base;
|
| 57 |
+
void *d_wrapped; /* This can be any function pointer */
|
| 58 |
+
} PyWrapperDescrObject;
|
| 59 |
+
|
| 60 |
+
PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
|
| 61 |
+
struct wrapperbase *, void *);
|
| 62 |
+
PyAPI_FUNC(int) PyDescr_IsData(PyObject *);
|
Include/cpython/dictobject.h
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_DICTOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef struct _dictkeysobject PyDictKeysObject;
|
| 6 |
+
typedef struct _dictvalues PyDictValues;
|
| 7 |
+
|
| 8 |
+
/* The ma_values pointer is NULL for a combined table
|
| 9 |
+
* or points to an array of PyObject* for a split table
|
| 10 |
+
*/
|
| 11 |
+
typedef struct {
|
| 12 |
+
PyObject_HEAD
|
| 13 |
+
|
| 14 |
+
/* Number of items in the dictionary */
|
| 15 |
+
Py_ssize_t ma_used;
|
| 16 |
+
|
| 17 |
+
/* Dictionary version: globally unique, value change each time
|
| 18 |
+
the dictionary is modified */
|
| 19 |
+
#ifdef Py_BUILD_CORE
|
| 20 |
+
/* Bits 0-7 are for dict watchers.
|
| 21 |
+
* Bits 8-11 are for the watched mutation counter (used by tier2 optimization)
|
| 22 |
+
* The remaining bits (12-63) are the actual version tag. */
|
| 23 |
+
uint64_t ma_version_tag;
|
| 24 |
+
#else
|
| 25 |
+
Py_DEPRECATED(3.12) uint64_t ma_version_tag;
|
| 26 |
+
#endif
|
| 27 |
+
|
| 28 |
+
PyDictKeysObject *ma_keys;
|
| 29 |
+
|
| 30 |
+
/* If ma_values is NULL, the table is "combined": keys and values
|
| 31 |
+
are stored in ma_keys.
|
| 32 |
+
|
| 33 |
+
If ma_values is not NULL, the table is split:
|
| 34 |
+
keys are stored in ma_keys and values are stored in ma_values */
|
| 35 |
+
PyDictValues *ma_values;
|
| 36 |
+
} PyDictObject;
|
| 37 |
+
|
| 38 |
+
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
|
| 39 |
+
Py_hash_t hash);
|
| 40 |
+
PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
|
| 41 |
+
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
|
| 42 |
+
PyObject *mp, PyObject *key, PyObject *defaultobj);
|
| 43 |
+
|
| 44 |
+
// Inserts `key` with a value `default_value`, if `key` is not already present
|
| 45 |
+
// in the dictionary. If `result` is not NULL, then the value associated
|
| 46 |
+
// with `key` is returned in `*result` (either the existing value, or the now
|
| 47 |
+
// inserted `default_value`).
|
| 48 |
+
// Returns:
|
| 49 |
+
// -1 on error
|
| 50 |
+
// 0 if `key` was not present and `default_value` was inserted
|
| 51 |
+
// 1 if `key` was present and `default_value` was not inserted
|
| 52 |
+
PyAPI_FUNC(int) PyDict_SetDefaultRef(PyObject *mp, PyObject *key, PyObject *default_value, PyObject **result);
|
| 53 |
+
|
| 54 |
+
/* Get the number of items of a dictionary. */
|
| 55 |
+
static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
|
| 56 |
+
PyDictObject *mp;
|
| 57 |
+
assert(PyDict_Check(op));
|
| 58 |
+
mp = _Py_CAST(PyDictObject*, op);
|
| 59 |
+
#ifdef Py_GIL_DISABLED
|
| 60 |
+
return _Py_atomic_load_ssize_relaxed(&mp->ma_used);
|
| 61 |
+
#else
|
| 62 |
+
return mp->ma_used;
|
| 63 |
+
#endif
|
| 64 |
+
}
|
| 65 |
+
#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
|
| 66 |
+
|
| 67 |
+
PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
|
| 68 |
+
|
| 69 |
+
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
|
| 70 |
+
|
| 71 |
+
PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
|
| 72 |
+
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
|
| 73 |
+
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);
|
| 74 |
+
|
| 75 |
+
/* Dictionary watchers */
|
| 76 |
+
|
| 77 |
+
#define PY_FOREACH_DICT_EVENT(V) \
|
| 78 |
+
V(ADDED) \
|
| 79 |
+
V(MODIFIED) \
|
| 80 |
+
V(DELETED) \
|
| 81 |
+
V(CLONED) \
|
| 82 |
+
V(CLEARED) \
|
| 83 |
+
V(DEALLOCATED)
|
| 84 |
+
|
| 85 |
+
typedef enum {
|
| 86 |
+
#define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT,
|
| 87 |
+
PY_FOREACH_DICT_EVENT(PY_DEF_EVENT)
|
| 88 |
+
#undef PY_DEF_EVENT
|
| 89 |
+
} PyDict_WatchEvent;
|
| 90 |
+
|
| 91 |
+
// Callback to be invoked when a watched dict is cleared, dealloced, or modified.
|
| 92 |
+
// In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the
|
| 93 |
+
// new value for key, NULL if key is being deleted.
|
| 94 |
+
typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value);
|
| 95 |
+
|
| 96 |
+
// Register/unregister a dict-watcher callback
|
| 97 |
+
PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback);
|
| 98 |
+
PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id);
|
| 99 |
+
|
| 100 |
+
// Mark given dictionary as "watched" (callback will be called if it is modified)
|
| 101 |
+
PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict);
|
| 102 |
+
PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict);
|
Include/cpython/fileobject.h
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_FILEOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
|
| 6 |
+
|
| 7 |
+
/* The std printer acts as a preliminary sys.stderr until the new io
|
| 8 |
+
infrastructure is in place. */
|
| 9 |
+
PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
|
| 10 |
+
PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
|
| 11 |
+
|
| 12 |
+
typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *);
|
| 13 |
+
|
| 14 |
+
PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path);
|
| 15 |
+
PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path);
|
| 16 |
+
PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData);
|
Include/cpython/fileutils.h
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_FILEUTILS_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
// Used by _testcapi which must not use the internal C API
|
| 6 |
+
PyAPI_FUNC(FILE*) _Py_fopen_obj(
|
| 7 |
+
PyObject *path,
|
| 8 |
+
const char *mode);
|
Include/cpython/floatobject.h
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_FLOATOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef struct {
|
| 6 |
+
PyObject_HEAD
|
| 7 |
+
double ob_fval;
|
| 8 |
+
} PyFloatObject;
|
| 9 |
+
|
| 10 |
+
#define _PyFloat_CAST(op) \
|
| 11 |
+
(assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op))
|
| 12 |
+
|
| 13 |
+
// Static inline version of PyFloat_AsDouble() trading safety for speed.
|
| 14 |
+
// It doesn't check if op is a double object.
|
| 15 |
+
static inline double PyFloat_AS_DOUBLE(PyObject *op) {
|
| 16 |
+
return _PyFloat_CAST(op)->ob_fval;
|
| 17 |
+
}
|
| 18 |
+
#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op))
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le);
|
| 22 |
+
PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le);
|
| 23 |
+
PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le);
|
| 24 |
+
|
| 25 |
+
PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le);
|
| 26 |
+
PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le);
|
| 27 |
+
PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le);
|
Include/cpython/frameobject.h
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Frame object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_CPYTHON_FRAMEOBJECT_H
|
| 4 |
+
# error "this header file must not be included directly"
|
| 5 |
+
#endif
|
| 6 |
+
|
| 7 |
+
/* Standard object interface */
|
| 8 |
+
|
| 9 |
+
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
|
| 10 |
+
PyObject *, PyObject *);
|
| 11 |
+
|
| 12 |
+
/* The rest of the interface is specific for frame objects */
|
| 13 |
+
|
| 14 |
+
/* Conversions between "fast locals" and locals in dictionary */
|
| 15 |
+
|
| 16 |
+
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
|
| 17 |
+
|
| 18 |
+
/* -- Caveat emptor --
|
| 19 |
+
* The concept of entry frames is an implementation detail of the CPython
|
| 20 |
+
* interpreter. This API is considered unstable and is provided for the
|
| 21 |
+
* convenience of debuggers, profilers and state-inspecting tools. Notice that
|
| 22 |
+
* this API can be changed in future minor versions if the underlying frame
|
| 23 |
+
* mechanism change or the concept of an 'entry frame' or its semantics becomes
|
| 24 |
+
* obsolete or outdated. */
|
| 25 |
+
|
| 26 |
+
PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame);
|
| 27 |
+
|
| 28 |
+
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
|
| 29 |
+
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
typedef struct {
|
| 33 |
+
PyObject_HEAD
|
| 34 |
+
PyFrameObject* frame;
|
| 35 |
+
} PyFrameLocalsProxyObject;
|
Include/cpython/funcobject.h
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Function object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_LIMITED_API
|
| 4 |
+
#ifndef Py_FUNCOBJECT_H
|
| 5 |
+
#define Py_FUNCOBJECT_H
|
| 6 |
+
#ifdef __cplusplus
|
| 7 |
+
extern "C" {
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
#define _Py_COMMON_FIELDS(PREFIX) \
|
| 12 |
+
PyObject *PREFIX ## globals; \
|
| 13 |
+
PyObject *PREFIX ## builtins; \
|
| 14 |
+
PyObject *PREFIX ## name; \
|
| 15 |
+
PyObject *PREFIX ## qualname; \
|
| 16 |
+
PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \
|
| 17 |
+
PyObject *PREFIX ## defaults; /* NULL or a tuple */ \
|
| 18 |
+
PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \
|
| 19 |
+
PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */
|
| 20 |
+
|
| 21 |
+
typedef struct {
|
| 22 |
+
_Py_COMMON_FIELDS(fc_)
|
| 23 |
+
} PyFrameConstructor;
|
| 24 |
+
|
| 25 |
+
/* Function objects and code objects should not be confused with each other:
|
| 26 |
+
*
|
| 27 |
+
* Function objects are created by the execution of the 'def' statement.
|
| 28 |
+
* They reference a code object in their __code__ attribute, which is a
|
| 29 |
+
* purely syntactic object, i.e. nothing more than a compiled version of some
|
| 30 |
+
* source code lines. There is one code object per source code "fragment",
|
| 31 |
+
* but each code object can be referenced by zero or many function objects
|
| 32 |
+
* depending only on how many times the 'def' statement in the source was
|
| 33 |
+
* executed so far.
|
| 34 |
+
*/
|
| 35 |
+
|
| 36 |
+
typedef struct {
|
| 37 |
+
PyObject_HEAD
|
| 38 |
+
_Py_COMMON_FIELDS(func_)
|
| 39 |
+
PyObject *func_doc; /* The __doc__ attribute, can be anything */
|
| 40 |
+
PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */
|
| 41 |
+
PyObject *func_weakreflist; /* List of weak references */
|
| 42 |
+
PyObject *func_module; /* The __module__ attribute, can be anything */
|
| 43 |
+
PyObject *func_annotations; /* Annotations, a dict or NULL */
|
| 44 |
+
PyObject *func_typeparams; /* Tuple of active type variables or NULL */
|
| 45 |
+
vectorcallfunc vectorcall;
|
| 46 |
+
/* Version number for use by specializer.
|
| 47 |
+
* Can set to non-zero when we want to specialize.
|
| 48 |
+
* Will be set to zero if any of these change:
|
| 49 |
+
* defaults
|
| 50 |
+
* kwdefaults (only if the object changes, not the contents of the dict)
|
| 51 |
+
* code
|
| 52 |
+
* annotations
|
| 53 |
+
* vectorcall function pointer */
|
| 54 |
+
uint32_t func_version;
|
| 55 |
+
|
| 56 |
+
/* Invariant:
|
| 57 |
+
* func_closure contains the bindings for func_code->co_freevars, so
|
| 58 |
+
* PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code)
|
| 59 |
+
* (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0).
|
| 60 |
+
*/
|
| 61 |
+
} PyFunctionObject;
|
| 62 |
+
|
| 63 |
+
#undef _Py_COMMON_FIELDS
|
| 64 |
+
|
| 65 |
+
PyAPI_DATA(PyTypeObject) PyFunction_Type;
|
| 66 |
+
|
| 67 |
+
#define PyFunction_Check(op) Py_IS_TYPE((op), &PyFunction_Type)
|
| 68 |
+
|
| 69 |
+
PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
|
| 70 |
+
PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *);
|
| 71 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);
|
| 72 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
|
| 73 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *);
|
| 74 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *);
|
| 75 |
+
PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *);
|
| 76 |
+
PyAPI_FUNC(void) PyFunction_SetVectorcall(PyFunctionObject *, vectorcallfunc);
|
| 77 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *);
|
| 78 |
+
PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *);
|
| 79 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *);
|
| 80 |
+
PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
|
| 81 |
+
PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *);
|
| 82 |
+
PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *);
|
| 83 |
+
|
| 84 |
+
#define _PyFunction_CAST(func) \
|
| 85 |
+
(assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func))
|
| 86 |
+
|
| 87 |
+
/* Static inline functions for direct access to these values.
|
| 88 |
+
Type checks are *not* done, so use with care. */
|
| 89 |
+
static inline PyObject* PyFunction_GET_CODE(PyObject *func) {
|
| 90 |
+
return _PyFunction_CAST(func)->func_code;
|
| 91 |
+
}
|
| 92 |
+
#define PyFunction_GET_CODE(func) PyFunction_GET_CODE(_PyObject_CAST(func))
|
| 93 |
+
|
| 94 |
+
static inline PyObject* PyFunction_GET_GLOBALS(PyObject *func) {
|
| 95 |
+
return _PyFunction_CAST(func)->func_globals;
|
| 96 |
+
}
|
| 97 |
+
#define PyFunction_GET_GLOBALS(func) PyFunction_GET_GLOBALS(_PyObject_CAST(func))
|
| 98 |
+
|
| 99 |
+
static inline PyObject* PyFunction_GET_MODULE(PyObject *func) {
|
| 100 |
+
return _PyFunction_CAST(func)->func_module;
|
| 101 |
+
}
|
| 102 |
+
#define PyFunction_GET_MODULE(func) PyFunction_GET_MODULE(_PyObject_CAST(func))
|
| 103 |
+
|
| 104 |
+
static inline PyObject* PyFunction_GET_DEFAULTS(PyObject *func) {
|
| 105 |
+
return _PyFunction_CAST(func)->func_defaults;
|
| 106 |
+
}
|
| 107 |
+
#define PyFunction_GET_DEFAULTS(func) PyFunction_GET_DEFAULTS(_PyObject_CAST(func))
|
| 108 |
+
|
| 109 |
+
static inline PyObject* PyFunction_GET_KW_DEFAULTS(PyObject *func) {
|
| 110 |
+
return _PyFunction_CAST(func)->func_kwdefaults;
|
| 111 |
+
}
|
| 112 |
+
#define PyFunction_GET_KW_DEFAULTS(func) PyFunction_GET_KW_DEFAULTS(_PyObject_CAST(func))
|
| 113 |
+
|
| 114 |
+
static inline PyObject* PyFunction_GET_CLOSURE(PyObject *func) {
|
| 115 |
+
return _PyFunction_CAST(func)->func_closure;
|
| 116 |
+
}
|
| 117 |
+
#define PyFunction_GET_CLOSURE(func) PyFunction_GET_CLOSURE(_PyObject_CAST(func))
|
| 118 |
+
|
| 119 |
+
static inline PyObject* PyFunction_GET_ANNOTATIONS(PyObject *func) {
|
| 120 |
+
return _PyFunction_CAST(func)->func_annotations;
|
| 121 |
+
}
|
| 122 |
+
#define PyFunction_GET_ANNOTATIONS(func) PyFunction_GET_ANNOTATIONS(_PyObject_CAST(func))
|
| 123 |
+
|
| 124 |
+
/* The classmethod and staticmethod types lives here, too */
|
| 125 |
+
PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
|
| 126 |
+
PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
|
| 127 |
+
|
| 128 |
+
PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
|
| 129 |
+
PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
|
| 130 |
+
|
| 131 |
+
#define PY_FOREACH_FUNC_EVENT(V) \
|
| 132 |
+
V(CREATE) \
|
| 133 |
+
V(DESTROY) \
|
| 134 |
+
V(MODIFY_CODE) \
|
| 135 |
+
V(MODIFY_DEFAULTS) \
|
| 136 |
+
V(MODIFY_KWDEFAULTS)
|
| 137 |
+
|
| 138 |
+
typedef enum {
|
| 139 |
+
#define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT,
|
| 140 |
+
PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT)
|
| 141 |
+
#undef PY_DEF_EVENT
|
| 142 |
+
} PyFunction_WatchEvent;
|
| 143 |
+
|
| 144 |
+
/*
|
| 145 |
+
* A callback that is invoked for different events in a function's lifecycle.
|
| 146 |
+
*
|
| 147 |
+
* The callback is invoked with a borrowed reference to func, after it is
|
| 148 |
+
* created and before it is modified or destroyed. The callback should not
|
| 149 |
+
* modify func.
|
| 150 |
+
*
|
| 151 |
+
* When a function's code object, defaults, or kwdefaults are modified the
|
| 152 |
+
* callback will be invoked with the respective event and new_value will
|
| 153 |
+
* contain a borrowed reference to the new value that is about to be stored in
|
| 154 |
+
* the function. Otherwise the third argument is NULL.
|
| 155 |
+
*
|
| 156 |
+
* If the callback returns with an exception set, it must return -1. Otherwise
|
| 157 |
+
* it should return 0.
|
| 158 |
+
*/
|
| 159 |
+
typedef int (*PyFunction_WatchCallback)(
|
| 160 |
+
PyFunction_WatchEvent event,
|
| 161 |
+
PyFunctionObject *func,
|
| 162 |
+
PyObject *new_value);
|
| 163 |
+
|
| 164 |
+
/*
|
| 165 |
+
* Register a per-interpreter callback that will be invoked for function lifecycle
|
| 166 |
+
* events.
|
| 167 |
+
*
|
| 168 |
+
* Returns a handle that may be passed to PyFunction_ClearWatcher on success,
|
| 169 |
+
* or -1 and sets an error if no more handles are available.
|
| 170 |
+
*/
|
| 171 |
+
PyAPI_FUNC(int) PyFunction_AddWatcher(PyFunction_WatchCallback callback);
|
| 172 |
+
|
| 173 |
+
/*
|
| 174 |
+
* Clear the watcher associated with the watcher_id handle.
|
| 175 |
+
*
|
| 176 |
+
* Returns 0 on success or -1 if no watcher exists for the supplied id.
|
| 177 |
+
*/
|
| 178 |
+
PyAPI_FUNC(int) PyFunction_ClearWatcher(int watcher_id);
|
| 179 |
+
|
| 180 |
+
#ifdef __cplusplus
|
| 181 |
+
}
|
| 182 |
+
#endif
|
| 183 |
+
#endif /* !Py_FUNCOBJECT_H */
|
| 184 |
+
#endif /* Py_LIMITED_API */
|
Include/cpython/genobject.h
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Generator object interface */
|
| 2 |
+
|
| 3 |
+
#ifndef Py_LIMITED_API
|
| 4 |
+
#ifndef Py_GENOBJECT_H
|
| 5 |
+
#define Py_GENOBJECT_H
|
| 6 |
+
#ifdef __cplusplus
|
| 7 |
+
extern "C" {
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
/* --- Generators --------------------------------------------------------- */
|
| 11 |
+
|
| 12 |
+
/* _PyGenObject_HEAD defines the initial segment of generator
|
| 13 |
+
and coroutine objects. */
|
| 14 |
+
#define _PyGenObject_HEAD(prefix) \
|
| 15 |
+
PyObject_HEAD \
|
| 16 |
+
/* List of weak reference. */ \
|
| 17 |
+
PyObject *prefix##_weakreflist; \
|
| 18 |
+
/* Name of the generator. */ \
|
| 19 |
+
PyObject *prefix##_name; \
|
| 20 |
+
/* Qualified name of the generator. */ \
|
| 21 |
+
PyObject *prefix##_qualname; \
|
| 22 |
+
_PyErr_StackItem prefix##_exc_state; \
|
| 23 |
+
PyObject *prefix##_origin_or_finalizer; \
|
| 24 |
+
char prefix##_hooks_inited; \
|
| 25 |
+
char prefix##_closed; \
|
| 26 |
+
char prefix##_running_async; \
|
| 27 |
+
/* The frame */ \
|
| 28 |
+
int8_t prefix##_frame_state; \
|
| 29 |
+
PyObject *prefix##_iframe[1]; \
|
| 30 |
+
|
| 31 |
+
typedef struct {
|
| 32 |
+
/* The gi_ prefix is intended to remind of generator-iterator. */
|
| 33 |
+
_PyGenObject_HEAD(gi)
|
| 34 |
+
} PyGenObject;
|
| 35 |
+
|
| 36 |
+
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
| 37 |
+
|
| 38 |
+
#define PyGen_Check(op) PyObject_TypeCheck((op), &PyGen_Type)
|
| 39 |
+
#define PyGen_CheckExact(op) Py_IS_TYPE((op), &PyGen_Type)
|
| 40 |
+
|
| 41 |
+
PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *);
|
| 42 |
+
PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *,
|
| 43 |
+
PyObject *name, PyObject *qualname);
|
| 44 |
+
PyAPI_FUNC(PyCodeObject *) PyGen_GetCode(PyGenObject *gen);
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
/* --- PyCoroObject ------------------------------------------------------- */
|
| 48 |
+
|
| 49 |
+
typedef struct {
|
| 50 |
+
_PyGenObject_HEAD(cr)
|
| 51 |
+
} PyCoroObject;
|
| 52 |
+
|
| 53 |
+
PyAPI_DATA(PyTypeObject) PyCoro_Type;
|
| 54 |
+
|
| 55 |
+
#define PyCoro_CheckExact(op) Py_IS_TYPE((op), &PyCoro_Type)
|
| 56 |
+
PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *,
|
| 57 |
+
PyObject *name, PyObject *qualname);
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
/* --- Asynchronous Generators -------------------------------------------- */
|
| 61 |
+
|
| 62 |
+
typedef struct {
|
| 63 |
+
_PyGenObject_HEAD(ag)
|
| 64 |
+
} PyAsyncGenObject;
|
| 65 |
+
|
| 66 |
+
PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
|
| 67 |
+
PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
|
| 68 |
+
|
| 69 |
+
PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *,
|
| 70 |
+
PyObject *name, PyObject *qualname);
|
| 71 |
+
|
| 72 |
+
#define PyAsyncGen_CheckExact(op) Py_IS_TYPE((op), &PyAsyncGen_Type)
|
| 73 |
+
|
| 74 |
+
#define PyAsyncGenASend_CheckExact(op) Py_IS_TYPE((op), &_PyAsyncGenASend_Type)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
#undef _PyGenObject_HEAD
|
| 78 |
+
|
| 79 |
+
#ifdef __cplusplus
|
| 80 |
+
}
|
| 81 |
+
#endif
|
| 82 |
+
#endif /* !Py_GENOBJECT_H */
|
| 83 |
+
#endif /* Py_LIMITED_API */
|
Include/cpython/import.h
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_IMPORT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
PyMODINIT_FUNC PyInit__imp(void);
|
| 6 |
+
|
| 7 |
+
struct _inittab {
|
| 8 |
+
const char *name; /* ASCII encoded string */
|
| 9 |
+
PyObject* (*initfunc)(void);
|
| 10 |
+
};
|
| 11 |
+
// This is not used after Py_Initialize() is called.
|
| 12 |
+
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
|
| 13 |
+
PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
| 14 |
+
|
| 15 |
+
struct _frozen {
|
| 16 |
+
const char *name; /* ASCII encoded string */
|
| 17 |
+
const unsigned char *code;
|
| 18 |
+
int size;
|
| 19 |
+
int is_package;
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
/* Embedding apps may change this pointer to point to their favorite
|
| 23 |
+
collection of frozen modules: */
|
| 24 |
+
|
| 25 |
+
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
|
Include/cpython/initconfig.h
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_PYCORECONFIG_H
|
| 2 |
+
#define Py_PYCORECONFIG_H
|
| 3 |
+
#ifndef Py_LIMITED_API
|
| 4 |
+
#ifdef __cplusplus
|
| 5 |
+
extern "C" {
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
/* --- PyStatus ----------------------------------------------- */
|
| 9 |
+
|
| 10 |
+
typedef struct {
|
| 11 |
+
enum {
|
| 12 |
+
_PyStatus_TYPE_OK=0,
|
| 13 |
+
_PyStatus_TYPE_ERROR=1,
|
| 14 |
+
_PyStatus_TYPE_EXIT=2
|
| 15 |
+
} _type;
|
| 16 |
+
const char *func;
|
| 17 |
+
const char *err_msg;
|
| 18 |
+
int exitcode;
|
| 19 |
+
} PyStatus;
|
| 20 |
+
|
| 21 |
+
PyAPI_FUNC(PyStatus) PyStatus_Ok(void);
|
| 22 |
+
PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg);
|
| 23 |
+
PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void);
|
| 24 |
+
PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
|
| 25 |
+
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
|
| 26 |
+
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
|
| 27 |
+
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
|
| 28 |
+
|
| 29 |
+
/* --- PyWideStringList ------------------------------------------------ */
|
| 30 |
+
|
| 31 |
+
typedef struct {
|
| 32 |
+
/* If length is greater than zero, items must be non-NULL
|
| 33 |
+
and all items strings must be non-NULL */
|
| 34 |
+
Py_ssize_t length;
|
| 35 |
+
wchar_t **items;
|
| 36 |
+
} PyWideStringList;
|
| 37 |
+
|
| 38 |
+
PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
|
| 39 |
+
const wchar_t *item);
|
| 40 |
+
PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list,
|
| 41 |
+
Py_ssize_t index,
|
| 42 |
+
const wchar_t *item);
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
/* --- PyPreConfig ----------------------------------------------- */
|
| 46 |
+
|
| 47 |
+
typedef struct PyPreConfig {
|
| 48 |
+
int _config_init; /* _PyConfigInitEnum value */
|
| 49 |
+
|
| 50 |
+
/* Parse Py_PreInitializeFromBytesArgs() arguments?
|
| 51 |
+
See PyConfig.parse_argv */
|
| 52 |
+
int parse_argv;
|
| 53 |
+
|
| 54 |
+
/* If greater than 0, enable isolated mode: sys.path contains
|
| 55 |
+
neither the script's directory nor the user's site-packages directory.
|
| 56 |
+
|
| 57 |
+
Set to 1 by the -I command line option. If set to -1 (default), inherit
|
| 58 |
+
Py_IsolatedFlag value. */
|
| 59 |
+
int isolated;
|
| 60 |
+
|
| 61 |
+
/* If greater than 0: use environment variables.
|
| 62 |
+
Set to 0 by -E command line option. If set to -1 (default), it is
|
| 63 |
+
set to !Py_IgnoreEnvironmentFlag. */
|
| 64 |
+
int use_environment;
|
| 65 |
+
|
| 66 |
+
/* Set the LC_CTYPE locale to the user preferred locale? If equals to 0,
|
| 67 |
+
set coerce_c_locale and coerce_c_locale_warn to 0. */
|
| 68 |
+
int configure_locale;
|
| 69 |
+
|
| 70 |
+
/* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538)
|
| 71 |
+
|
| 72 |
+
Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1.
|
| 73 |
+
Set to 2 if the user preferred LC_CTYPE locale is "C".
|
| 74 |
+
|
| 75 |
+
If it is equal to 1, LC_CTYPE locale is read to decide if it should be
|
| 76 |
+
coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2
|
| 77 |
+
if the LC_CTYPE locale must be coerced.
|
| 78 |
+
|
| 79 |
+
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
| 80 |
+
should be enabled or not. */
|
| 81 |
+
int coerce_c_locale;
|
| 82 |
+
|
| 83 |
+
/* Emit a warning if the LC_CTYPE locale is coerced?
|
| 84 |
+
|
| 85 |
+
Set to 1 by PYTHONCOERCECLOCALE=warn.
|
| 86 |
+
|
| 87 |
+
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
| 88 |
+
should be enabled or not. */
|
| 89 |
+
int coerce_c_locale_warn;
|
| 90 |
+
|
| 91 |
+
#ifdef MS_WINDOWS
|
| 92 |
+
/* If greater than 1, use the "mbcs" encoding instead of the UTF-8
|
| 93 |
+
encoding for the filesystem encoding.
|
| 94 |
+
|
| 95 |
+
Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is
|
| 96 |
+
set to a non-empty string. If set to -1 (default), inherit
|
| 97 |
+
Py_LegacyWindowsFSEncodingFlag value.
|
| 98 |
+
|
| 99 |
+
See PEP 529 for more details. */
|
| 100 |
+
int legacy_windows_fs_encoding;
|
| 101 |
+
#endif
|
| 102 |
+
|
| 103 |
+
/* Enable UTF-8 mode? (PEP 540)
|
| 104 |
+
|
| 105 |
+
Disabled by default (equals to 0).
|
| 106 |
+
|
| 107 |
+
Set to 1 by "-X utf8" and "-X utf8=1" command line options.
|
| 108 |
+
Set to 1 by PYTHONUTF8=1 environment variable.
|
| 109 |
+
|
| 110 |
+
Set to 0 by "-X utf8=0" and PYTHONUTF8=0.
|
| 111 |
+
|
| 112 |
+
If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or
|
| 113 |
+
"POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */
|
| 114 |
+
int utf8_mode;
|
| 115 |
+
|
| 116 |
+
/* If non-zero, enable the Python Development Mode.
|
| 117 |
+
|
| 118 |
+
Set to 1 by the -X dev command line option. Set by the PYTHONDEVMODE
|
| 119 |
+
environment variable. */
|
| 120 |
+
int dev_mode;
|
| 121 |
+
|
| 122 |
+
/* Memory allocator: PYTHONMALLOC env var.
|
| 123 |
+
See PyMemAllocatorName for valid values. */
|
| 124 |
+
int allocator;
|
| 125 |
+
} PyPreConfig;
|
| 126 |
+
|
| 127 |
+
PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config);
|
| 128 |
+
PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
/* --- PyConfig ---------------------------------------------- */
|
| 132 |
+
|
| 133 |
+
/* This structure is best documented in the Doc/c-api/init_config.rst file. */
|
| 134 |
+
typedef struct PyConfig {
|
| 135 |
+
int _config_init; /* _PyConfigInitEnum value */
|
| 136 |
+
|
| 137 |
+
int isolated;
|
| 138 |
+
int use_environment;
|
| 139 |
+
int dev_mode;
|
| 140 |
+
int install_signal_handlers;
|
| 141 |
+
int use_hash_seed;
|
| 142 |
+
unsigned long hash_seed;
|
| 143 |
+
int faulthandler;
|
| 144 |
+
int tracemalloc;
|
| 145 |
+
int perf_profiling;
|
| 146 |
+
int import_time;
|
| 147 |
+
int code_debug_ranges;
|
| 148 |
+
int show_ref_count;
|
| 149 |
+
int dump_refs;
|
| 150 |
+
wchar_t *dump_refs_file;
|
| 151 |
+
int malloc_stats;
|
| 152 |
+
wchar_t *filesystem_encoding;
|
| 153 |
+
wchar_t *filesystem_errors;
|
| 154 |
+
wchar_t *pycache_prefix;
|
| 155 |
+
int parse_argv;
|
| 156 |
+
PyWideStringList orig_argv;
|
| 157 |
+
PyWideStringList argv;
|
| 158 |
+
PyWideStringList xoptions;
|
| 159 |
+
PyWideStringList warnoptions;
|
| 160 |
+
int site_import;
|
| 161 |
+
int bytes_warning;
|
| 162 |
+
int warn_default_encoding;
|
| 163 |
+
int inspect;
|
| 164 |
+
int interactive;
|
| 165 |
+
int optimization_level;
|
| 166 |
+
int parser_debug;
|
| 167 |
+
int write_bytecode;
|
| 168 |
+
int verbose;
|
| 169 |
+
int quiet;
|
| 170 |
+
int user_site_directory;
|
| 171 |
+
int configure_c_stdio;
|
| 172 |
+
int buffered_stdio;
|
| 173 |
+
wchar_t *stdio_encoding;
|
| 174 |
+
wchar_t *stdio_errors;
|
| 175 |
+
#ifdef MS_WINDOWS
|
| 176 |
+
int legacy_windows_stdio;
|
| 177 |
+
#endif
|
| 178 |
+
wchar_t *check_hash_pycs_mode;
|
| 179 |
+
int use_frozen_modules;
|
| 180 |
+
int safe_path;
|
| 181 |
+
int int_max_str_digits;
|
| 182 |
+
|
| 183 |
+
int cpu_count;
|
| 184 |
+
#ifdef Py_GIL_DISABLED
|
| 185 |
+
int enable_gil;
|
| 186 |
+
#endif
|
| 187 |
+
|
| 188 |
+
/* --- Path configuration inputs ------------ */
|
| 189 |
+
int pathconfig_warnings;
|
| 190 |
+
wchar_t *program_name;
|
| 191 |
+
wchar_t *pythonpath_env;
|
| 192 |
+
wchar_t *home;
|
| 193 |
+
wchar_t *platlibdir;
|
| 194 |
+
|
| 195 |
+
/* --- Path configuration outputs ----------- */
|
| 196 |
+
int module_search_paths_set;
|
| 197 |
+
PyWideStringList module_search_paths;
|
| 198 |
+
wchar_t *stdlib_dir;
|
| 199 |
+
wchar_t *executable;
|
| 200 |
+
wchar_t *base_executable;
|
| 201 |
+
wchar_t *prefix;
|
| 202 |
+
wchar_t *base_prefix;
|
| 203 |
+
wchar_t *exec_prefix;
|
| 204 |
+
wchar_t *base_exec_prefix;
|
| 205 |
+
|
| 206 |
+
/* --- Parameter only used by Py_Main() ---------- */
|
| 207 |
+
int skip_source_first_line;
|
| 208 |
+
wchar_t *run_command;
|
| 209 |
+
wchar_t *run_module;
|
| 210 |
+
wchar_t *run_filename;
|
| 211 |
+
|
| 212 |
+
/* --- Set by Py_Main() -------------------------- */
|
| 213 |
+
wchar_t *sys_path_0;
|
| 214 |
+
|
| 215 |
+
/* --- Private fields ---------------------------- */
|
| 216 |
+
|
| 217 |
+
// Install importlib? If equals to 0, importlib is not initialized at all.
|
| 218 |
+
// Needed by freeze_importlib.
|
| 219 |
+
int _install_importlib;
|
| 220 |
+
|
| 221 |
+
// If equal to 0, stop Python initialization before the "main" phase.
|
| 222 |
+
int _init_main;
|
| 223 |
+
|
| 224 |
+
// If non-zero, we believe we're running from a source tree.
|
| 225 |
+
int _is_python_build;
|
| 226 |
+
|
| 227 |
+
#ifdef Py_STATS
|
| 228 |
+
// If non-zero, turns on statistics gathering.
|
| 229 |
+
int _pystats;
|
| 230 |
+
#endif
|
| 231 |
+
|
| 232 |
+
#ifdef Py_DEBUG
|
| 233 |
+
// If not empty, import a non-__main__ module before site.py is executed.
|
| 234 |
+
// PYTHON_PRESITE=package.module or -X presite=package.module
|
| 235 |
+
wchar_t *run_presite;
|
| 236 |
+
#endif
|
| 237 |
+
} PyConfig;
|
| 238 |
+
|
| 239 |
+
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);
|
| 240 |
+
PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config);
|
| 241 |
+
PyAPI_FUNC(void) PyConfig_Clear(PyConfig *);
|
| 242 |
+
PyAPI_FUNC(PyStatus) PyConfig_SetString(
|
| 243 |
+
PyConfig *config,
|
| 244 |
+
wchar_t **config_str,
|
| 245 |
+
const wchar_t *str);
|
| 246 |
+
PyAPI_FUNC(PyStatus) PyConfig_SetBytesString(
|
| 247 |
+
PyConfig *config,
|
| 248 |
+
wchar_t **config_str,
|
| 249 |
+
const char *str);
|
| 250 |
+
PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config);
|
| 251 |
+
PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
|
| 252 |
+
PyConfig *config,
|
| 253 |
+
Py_ssize_t argc,
|
| 254 |
+
char * const *argv);
|
| 255 |
+
PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
|
| 256 |
+
Py_ssize_t argc,
|
| 257 |
+
wchar_t * const *argv);
|
| 258 |
+
PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
|
| 259 |
+
PyWideStringList *list,
|
| 260 |
+
Py_ssize_t length, wchar_t **items);
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
/* --- Helper functions --------------------------------------- */
|
| 264 |
+
|
| 265 |
+
/* Get the original command line arguments, before Python modified them.
|
| 266 |
+
|
| 267 |
+
See also PyConfig.orig_argv. */
|
| 268 |
+
PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv);
|
| 269 |
+
|
| 270 |
+
#ifdef __cplusplus
|
| 271 |
+
}
|
| 272 |
+
#endif
|
| 273 |
+
#endif /* !Py_LIMITED_API */
|
| 274 |
+
#endif /* !Py_PYCORECONFIG_H */
|
Include/cpython/listobject.h
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_LISTOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
typedef struct {
|
| 6 |
+
PyObject_VAR_HEAD
|
| 7 |
+
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
|
| 8 |
+
PyObject **ob_item;
|
| 9 |
+
|
| 10 |
+
/* ob_item contains space for 'allocated' elements. The number
|
| 11 |
+
* currently in use is ob_size.
|
| 12 |
+
* Invariants:
|
| 13 |
+
* 0 <= ob_size <= allocated
|
| 14 |
+
* len(list) == ob_size
|
| 15 |
+
* ob_item == NULL implies ob_size == allocated == 0
|
| 16 |
+
* list.sort() temporarily sets allocated to -1 to detect mutations.
|
| 17 |
+
*
|
| 18 |
+
* Items must normally not be NULL, except during construction when
|
| 19 |
+
* the list is not yet visible outside the function that builds it.
|
| 20 |
+
*/
|
| 21 |
+
Py_ssize_t allocated;
|
| 22 |
+
} PyListObject;
|
| 23 |
+
|
| 24 |
+
/* Cast argument to PyListObject* type. */
|
| 25 |
+
#define _PyList_CAST(op) \
|
| 26 |
+
(assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op)))
|
| 27 |
+
|
| 28 |
+
// Macros and static inline functions, trading safety for speed
|
| 29 |
+
|
| 30 |
+
static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) {
|
| 31 |
+
PyListObject *list = _PyList_CAST(op);
|
| 32 |
+
#ifdef Py_GIL_DISABLED
|
| 33 |
+
return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(list)->ob_size));
|
| 34 |
+
#else
|
| 35 |
+
return Py_SIZE(list);
|
| 36 |
+
#endif
|
| 37 |
+
}
|
| 38 |
+
#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
|
| 39 |
+
|
| 40 |
+
#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)])
|
| 41 |
+
|
| 42 |
+
static inline void
|
| 43 |
+
PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
|
| 44 |
+
PyListObject *list = _PyList_CAST(op);
|
| 45 |
+
assert(0 <= index);
|
| 46 |
+
assert(index < list->allocated);
|
| 47 |
+
list->ob_item[index] = value;
|
| 48 |
+
}
|
| 49 |
+
#define PyList_SET_ITEM(op, index, value) \
|
| 50 |
+
PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
|
| 51 |
+
|
| 52 |
+
PyAPI_FUNC(int) PyList_Extend(PyObject *self, PyObject *iterable);
|
| 53 |
+
PyAPI_FUNC(int) PyList_Clear(PyObject *self);
|
Include/cpython/lock.h
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_LOCK_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
#define _Py_UNLOCKED 0
|
| 6 |
+
#define _Py_LOCKED 1
|
| 7 |
+
|
| 8 |
+
// A mutex that occupies one byte. The lock can be zero initialized to
|
| 9 |
+
// represent the unlocked state.
|
| 10 |
+
//
|
| 11 |
+
// Typical initialization:
|
| 12 |
+
// PyMutex m = (PyMutex){0};
|
| 13 |
+
//
|
| 14 |
+
// Or initialize as global variables:
|
| 15 |
+
// static PyMutex m;
|
| 16 |
+
//
|
| 17 |
+
// Typical usage:
|
| 18 |
+
// PyMutex_Lock(&m);
|
| 19 |
+
// ...
|
| 20 |
+
// PyMutex_Unlock(&m);
|
| 21 |
+
//
|
| 22 |
+
// The contents of the PyMutex are not part of the public API, but are
|
| 23 |
+
// described to aid in understanding the implementation and debugging. Only
|
| 24 |
+
// the two least significant bits are used. The remaining bits are always zero:
|
| 25 |
+
// 0b00: unlocked
|
| 26 |
+
// 0b01: locked
|
| 27 |
+
// 0b10: unlocked and has parked threads
|
| 28 |
+
// 0b11: locked and has parked threads
|
| 29 |
+
typedef struct PyMutex {
|
| 30 |
+
uint8_t _bits; // (private)
|
| 31 |
+
} PyMutex;
|
| 32 |
+
|
| 33 |
+
// exported function for locking the mutex
|
| 34 |
+
PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m);
|
| 35 |
+
|
| 36 |
+
// exported function for unlocking the mutex
|
| 37 |
+
PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m);
|
| 38 |
+
|
| 39 |
+
// Locks the mutex.
|
| 40 |
+
//
|
| 41 |
+
// If the mutex is currently locked, the calling thread will be parked until
|
| 42 |
+
// the mutex is unlocked. If the current thread holds the GIL, then the GIL
|
| 43 |
+
// will be released while the thread is parked.
|
| 44 |
+
static inline void
|
| 45 |
+
_PyMutex_Lock(PyMutex *m)
|
| 46 |
+
{
|
| 47 |
+
uint8_t expected = _Py_UNLOCKED;
|
| 48 |
+
if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) {
|
| 49 |
+
PyMutex_Lock(m);
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
#define PyMutex_Lock _PyMutex_Lock
|
| 53 |
+
|
| 54 |
+
// Unlocks the mutex.
|
| 55 |
+
static inline void
|
| 56 |
+
_PyMutex_Unlock(PyMutex *m)
|
| 57 |
+
{
|
| 58 |
+
uint8_t expected = _Py_LOCKED;
|
| 59 |
+
if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_UNLOCKED)) {
|
| 60 |
+
PyMutex_Unlock(m);
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
#define PyMutex_Unlock _PyMutex_Unlock
|
Include/cpython/longintrepr.h
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_LIMITED_API
|
| 2 |
+
#ifndef Py_LONGINTREPR_H
|
| 3 |
+
#define Py_LONGINTREPR_H
|
| 4 |
+
#ifdef __cplusplus
|
| 5 |
+
extern "C" {
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
/* This is published for the benefit of "friends" marshal.c and _decimal.c. */
|
| 10 |
+
|
| 11 |
+
/* Parameters of the integer representation. There are two different
|
| 12 |
+
sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit
|
| 13 |
+
integer type, and one set for 15-bit digits with each digit stored in an
|
| 14 |
+
unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at
|
| 15 |
+
configure time or in pyport.h, is used to decide which digit size to use.
|
| 16 |
+
|
| 17 |
+
Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits'
|
| 18 |
+
should be an unsigned integer type able to hold all integers up to
|
| 19 |
+
PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type,
|
| 20 |
+
and that overflow is handled by taking the result modulo 2**N for some N >
|
| 21 |
+
PyLong_SHIFT. The majority of the code doesn't care about the precise
|
| 22 |
+
value of PyLong_SHIFT, but there are some notable exceptions:
|
| 23 |
+
|
| 24 |
+
- PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8
|
| 25 |
+
|
| 26 |
+
- long_hash() requires that PyLong_SHIFT is *strictly* less than the number
|
| 27 |
+
of bits in an unsigned long, as do the PyLong <-> long (or unsigned long)
|
| 28 |
+
conversion functions
|
| 29 |
+
|
| 30 |
+
- the Python int <-> size_t/Py_ssize_t conversion functions expect that
|
| 31 |
+
PyLong_SHIFT is strictly less than the number of bits in a size_t
|
| 32 |
+
|
| 33 |
+
- the marshal code currently expects that PyLong_SHIFT is a multiple of 15
|
| 34 |
+
|
| 35 |
+
- NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single
|
| 36 |
+
digit; with the current values this forces PyLong_SHIFT >= 9
|
| 37 |
+
|
| 38 |
+
The values 15 and 30 should fit all of the above requirements, on any
|
| 39 |
+
platform.
|
| 40 |
+
*/
|
| 41 |
+
|
| 42 |
+
#if PYLONG_BITS_IN_DIGIT == 30
|
| 43 |
+
typedef uint32_t digit;
|
| 44 |
+
typedef int32_t sdigit; /* signed variant of digit */
|
| 45 |
+
typedef uint64_t twodigits;
|
| 46 |
+
typedef int64_t stwodigits; /* signed variant of twodigits */
|
| 47 |
+
#define PyLong_SHIFT 30
|
| 48 |
+
#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */
|
| 49 |
+
#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */
|
| 50 |
+
#elif PYLONG_BITS_IN_DIGIT == 15
|
| 51 |
+
typedef unsigned short digit;
|
| 52 |
+
typedef short sdigit; /* signed variant of digit */
|
| 53 |
+
typedef unsigned long twodigits;
|
| 54 |
+
typedef long stwodigits; /* signed variant of twodigits */
|
| 55 |
+
#define PyLong_SHIFT 15
|
| 56 |
+
#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */
|
| 57 |
+
#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */
|
| 58 |
+
#else
|
| 59 |
+
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
|
| 60 |
+
#endif
|
| 61 |
+
#define PyLong_BASE ((digit)1 << PyLong_SHIFT)
|
| 62 |
+
#define PyLong_MASK ((digit)(PyLong_BASE - 1))
|
| 63 |
+
|
| 64 |
+
/* Long integer representation.
|
| 65 |
+
|
| 66 |
+
Long integers are made up of a number of 30- or 15-bit digits, depending on
|
| 67 |
+
the platform. The number of digits (ndigits) is stored in the high bits of
|
| 68 |
+
the lv_tag field (lvtag >> _PyLong_NON_SIZE_BITS).
|
| 69 |
+
|
| 70 |
+
The absolute value of a number is equal to
|
| 71 |
+
SUM(for i=0 through ndigits-1) ob_digit[i] * 2**(PyLong_SHIFT*i)
|
| 72 |
+
|
| 73 |
+
The sign of the value is stored in the lower 2 bits of lv_tag.
|
| 74 |
+
|
| 75 |
+
- 0: Positive
|
| 76 |
+
- 1: Zero
|
| 77 |
+
- 2: Negative
|
| 78 |
+
|
| 79 |
+
The third lowest bit of lv_tag is reserved for an immortality flag, but is
|
| 80 |
+
not currently used.
|
| 81 |
+
|
| 82 |
+
In a normalized number, ob_digit[ndigits-1] (the most significant
|
| 83 |
+
digit) is never zero. Also, in all cases, for all valid i,
|
| 84 |
+
0 <= ob_digit[i] <= PyLong_MASK.
|
| 85 |
+
|
| 86 |
+
The allocation function takes care of allocating extra memory
|
| 87 |
+
so that ob_digit[0] ... ob_digit[ndigits-1] are actually available.
|
| 88 |
+
We always allocate memory for at least one digit, so accessing ob_digit[0]
|
| 89 |
+
is always safe. However, in the case ndigits == 0, the contents of
|
| 90 |
+
ob_digit[0] may be undefined.
|
| 91 |
+
*/
|
| 92 |
+
|
| 93 |
+
typedef struct _PyLongValue {
|
| 94 |
+
uintptr_t lv_tag; /* Number of digits, sign and flags */
|
| 95 |
+
digit ob_digit[1];
|
| 96 |
+
} _PyLongValue;
|
| 97 |
+
|
| 98 |
+
struct _longobject {
|
| 99 |
+
PyObject_HEAD
|
| 100 |
+
_PyLongValue long_value;
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
|
| 104 |
+
|
| 105 |
+
// Return a copy of src.
|
| 106 |
+
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);
|
| 107 |
+
|
| 108 |
+
PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
|
| 109 |
+
int negative,
|
| 110 |
+
Py_ssize_t digit_count,
|
| 111 |
+
digit *digits);
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
/* Inline some internals for speed. These should be in pycore_long.h
|
| 115 |
+
* if user code didn't need them inlined. */
|
| 116 |
+
|
| 117 |
+
#define _PyLong_SIGN_MASK 3
|
| 118 |
+
#define _PyLong_NON_SIZE_BITS 3
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
static inline int
|
| 122 |
+
_PyLong_IsCompact(const PyLongObject* op) {
|
| 123 |
+
assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS));
|
| 124 |
+
return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS);
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
#define PyUnstable_Long_IsCompact _PyLong_IsCompact
|
| 128 |
+
|
| 129 |
+
static inline Py_ssize_t
|
| 130 |
+
_PyLong_CompactValue(const PyLongObject *op)
|
| 131 |
+
{
|
| 132 |
+
Py_ssize_t sign;
|
| 133 |
+
assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS));
|
| 134 |
+
assert(PyUnstable_Long_IsCompact(op));
|
| 135 |
+
sign = 1 - (op->long_value.lv_tag & _PyLong_SIGN_MASK);
|
| 136 |
+
return sign * (Py_ssize_t)op->long_value.ob_digit[0];
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
#define PyUnstable_Long_CompactValue _PyLong_CompactValue
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
#ifdef __cplusplus
|
| 143 |
+
}
|
| 144 |
+
#endif
|
| 145 |
+
#endif /* !Py_LONGINTREPR_H */
|
| 146 |
+
#endif /* Py_LIMITED_API */
|
Include/cpython/longobject.h
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_LONGOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
|
| 6 |
+
|
| 7 |
+
#define Py_ASNATIVEBYTES_DEFAULTS -1
|
| 8 |
+
#define Py_ASNATIVEBYTES_BIG_ENDIAN 0
|
| 9 |
+
#define Py_ASNATIVEBYTES_LITTLE_ENDIAN 1
|
| 10 |
+
#define Py_ASNATIVEBYTES_NATIVE_ENDIAN 3
|
| 11 |
+
#define Py_ASNATIVEBYTES_UNSIGNED_BUFFER 4
|
| 12 |
+
#define Py_ASNATIVEBYTES_REJECT_NEGATIVE 8
|
| 13 |
+
#define Py_ASNATIVEBYTES_ALLOW_INDEX 16
|
| 14 |
+
|
| 15 |
+
/* PyLong_AsNativeBytes: Copy the integer value to a native variable.
|
| 16 |
+
buffer points to the first byte of the variable.
|
| 17 |
+
n_bytes is the number of bytes available in the buffer. Pass 0 to request
|
| 18 |
+
the required size for the value.
|
| 19 |
+
flags is a bitfield of the following flags:
|
| 20 |
+
* 1 - little endian
|
| 21 |
+
* 2 - native endian
|
| 22 |
+
* 4 - unsigned destination (e.g. don't reject copying 255 into one byte)
|
| 23 |
+
* 8 - raise an exception for negative inputs
|
| 24 |
+
* 16 - call __index__ on non-int types
|
| 25 |
+
If flags is -1 (all bits set), native endian is used, value truncation
|
| 26 |
+
behaves most like C (allows negative inputs and allow MSB set), and non-int
|
| 27 |
+
objects will raise a TypeError.
|
| 28 |
+
Big endian mode will write the most significant byte into the address
|
| 29 |
+
directly referenced by buffer; little endian will write the least significant
|
| 30 |
+
byte into that address.
|
| 31 |
+
|
| 32 |
+
If an exception is raised, returns a negative value.
|
| 33 |
+
Otherwise, returns the number of bytes that are required to store the value.
|
| 34 |
+
To check that the full value is represented, ensure that the return value is
|
| 35 |
+
equal or less than n_bytes.
|
| 36 |
+
All n_bytes are guaranteed to be written (unless an exception occurs), and
|
| 37 |
+
so ignoring a positive return value is the equivalent of a downcast in C.
|
| 38 |
+
In cases where the full value could not be represented, the returned value
|
| 39 |
+
may be larger than necessary - this function is not an accurate way to
|
| 40 |
+
calculate the bit length of an integer object.
|
| 41 |
+
*/
|
| 42 |
+
PyAPI_FUNC(Py_ssize_t) PyLong_AsNativeBytes(PyObject* v, void* buffer,
|
| 43 |
+
Py_ssize_t n_bytes, int flags);
|
| 44 |
+
|
| 45 |
+
/* PyLong_FromNativeBytes: Create an int value from a native integer
|
| 46 |
+
n_bytes is the number of bytes to read from the buffer. Passing 0 will
|
| 47 |
+
always produce the zero int.
|
| 48 |
+
PyLong_FromUnsignedNativeBytes always produces a non-negative int.
|
| 49 |
+
flags is the same as for PyLong_AsNativeBytes, but only supports selecting
|
| 50 |
+
the endianness or forcing an unsigned buffer.
|
| 51 |
+
|
| 52 |
+
Returns the int object, or NULL with an exception set. */
|
| 53 |
+
PyAPI_FUNC(PyObject*) PyLong_FromNativeBytes(const void* buffer, size_t n_bytes,
|
| 54 |
+
int flags);
|
| 55 |
+
PyAPI_FUNC(PyObject*) PyLong_FromUnsignedNativeBytes(const void* buffer,
|
| 56 |
+
size_t n_bytes, int flags);
|
| 57 |
+
|
| 58 |
+
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
|
| 59 |
+
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
|
| 60 |
+
|
| 61 |
+
// _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
|
| 62 |
+
// v must not be NULL, and must be a normalized long.
|
| 63 |
+
// There are no error cases.
|
| 64 |
+
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
|
| 65 |
+
|
| 66 |
+
/* _PyLong_NumBits. Return the number of bits needed to represent the
|
| 67 |
+
absolute value of a long. For example, this returns 1 for 1 and -1, 2
|
| 68 |
+
for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.
|
| 69 |
+
v must not be NULL, and must be a normalized long.
|
| 70 |
+
(size_t)-1 is returned and OverflowError set if the true result doesn't
|
| 71 |
+
fit in a size_t.
|
| 72 |
+
*/
|
| 73 |
+
PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);
|
| 74 |
+
|
| 75 |
+
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
|
| 76 |
+
base 256, and return a Python int with the same numeric value.
|
| 77 |
+
If n is 0, the integer is 0. Else:
|
| 78 |
+
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
|
| 79 |
+
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
|
| 80 |
+
LSB.
|
| 81 |
+
If is_signed is 0/false, view the bytes as a non-negative integer.
|
| 82 |
+
If is_signed is 1/true, view the bytes as a 2's-complement integer,
|
| 83 |
+
non-negative if bit 0x80 of the MSB is clear, negative if set.
|
| 84 |
+
Error returns:
|
| 85 |
+
+ Return NULL with the appropriate exception set if there's not
|
| 86 |
+
enough memory to create the Python int.
|
| 87 |
+
*/
|
| 88 |
+
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
|
| 89 |
+
const unsigned char* bytes, size_t n,
|
| 90 |
+
int little_endian, int is_signed);
|
| 91 |
+
|
| 92 |
+
/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
|
| 93 |
+
v to a base-256 integer, stored in array bytes. Normally return 0,
|
| 94 |
+
return -1 on error.
|
| 95 |
+
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
|
| 96 |
+
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
|
| 97 |
+
the LSB at bytes[n-1].
|
| 98 |
+
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
|
| 99 |
+
are filled and there's nothing special about bit 0x80 of the MSB.
|
| 100 |
+
If is_signed is 1/true, bytes is filled with the 2's-complement
|
| 101 |
+
representation of v's value. Bit 0x80 of the MSB is the sign bit.
|
| 102 |
+
Error returns (-1):
|
| 103 |
+
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
|
| 104 |
+
isn't altered.
|
| 105 |
+
+ n isn't big enough to hold the full mathematical value of v. For
|
| 106 |
+
example, if is_signed is 0 and there are more digits in the v than
|
| 107 |
+
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
|
| 108 |
+
being large enough to hold a sign bit. OverflowError is set in this
|
| 109 |
+
case, but bytes holds the least-significant n bytes of the true value.
|
| 110 |
+
*/
|
| 111 |
+
PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
|
| 112 |
+
unsigned char* bytes, size_t n,
|
| 113 |
+
int little_endian, int is_signed, int with_exceptions);
|
| 114 |
+
|
| 115 |
+
/* For use by the gcd function in mathmodule.c */
|
| 116 |
+
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);
|
Include/cpython/memoryobject.h
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_MEMORYOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
/* The structs are declared here so that macros can work, but they shouldn't
|
| 6 |
+
be considered public. Don't access their fields directly, use the macros
|
| 7 |
+
and functions instead! */
|
| 8 |
+
#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */
|
| 9 |
+
#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */
|
| 10 |
+
|
| 11 |
+
typedef struct {
|
| 12 |
+
PyObject_HEAD
|
| 13 |
+
int flags; /* state flags */
|
| 14 |
+
Py_ssize_t exports; /* number of direct memoryview exports */
|
| 15 |
+
Py_buffer master; /* snapshot buffer obtained from the original exporter */
|
| 16 |
+
} _PyManagedBufferObject;
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
/* memoryview state flags */
|
| 20 |
+
#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */
|
| 21 |
+
#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */
|
| 22 |
+
#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */
|
| 23 |
+
#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */
|
| 24 |
+
#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */
|
| 25 |
+
#define _Py_MEMORYVIEW_RESTRICTED 0x020 /* Disallow new references to the memoryview's buffer */
|
| 26 |
+
|
| 27 |
+
typedef struct {
|
| 28 |
+
PyObject_VAR_HEAD
|
| 29 |
+
_PyManagedBufferObject *mbuf; /* managed buffer */
|
| 30 |
+
Py_hash_t hash; /* hash value for read-only views */
|
| 31 |
+
int flags; /* state flags */
|
| 32 |
+
Py_ssize_t exports; /* number of buffer re-exports */
|
| 33 |
+
Py_buffer view; /* private copy of the exporter's view */
|
| 34 |
+
PyObject *weakreflist;
|
| 35 |
+
Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */
|
| 36 |
+
} PyMemoryViewObject;
|
| 37 |
+
|
| 38 |
+
#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op)
|
| 39 |
+
|
| 40 |
+
/* Get a pointer to the memoryview's private copy of the exporter's buffer. */
|
| 41 |
+
static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) {
|
| 42 |
+
return (&_PyMemoryView_CAST(op)->view);
|
| 43 |
+
}
|
| 44 |
+
#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op))
|
| 45 |
+
|
| 46 |
+
/* Get a pointer to the exporting object (this may be NULL!). */
|
| 47 |
+
static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) {
|
| 48 |
+
return _PyMemoryView_CAST(op)->view.obj;
|
| 49 |
+
}
|
| 50 |
+
#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op))
|
Include/cpython/methodobject.h
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_METHODOBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
// PyCFunctionObject structure
|
| 6 |
+
|
| 7 |
+
typedef struct {
|
| 8 |
+
PyObject_HEAD
|
| 9 |
+
PyMethodDef *m_ml; /* Description of the C function to call */
|
| 10 |
+
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
|
| 11 |
+
PyObject *m_module; /* The __module__ attribute, can be anything */
|
| 12 |
+
PyObject *m_weakreflist; /* List of weak references */
|
| 13 |
+
vectorcallfunc vectorcall;
|
| 14 |
+
} PyCFunctionObject;
|
| 15 |
+
|
| 16 |
+
#define _PyCFunctionObject_CAST(func) \
|
| 17 |
+
(assert(PyCFunction_Check(func)), \
|
| 18 |
+
_Py_CAST(PyCFunctionObject*, (func)))
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
// PyCMethodObject structure
|
| 22 |
+
|
| 23 |
+
typedef struct {
|
| 24 |
+
PyCFunctionObject func;
|
| 25 |
+
PyTypeObject *mm_class; /* Class that defines this method */
|
| 26 |
+
} PyCMethodObject;
|
| 27 |
+
|
| 28 |
+
#define _PyCMethodObject_CAST(func) \
|
| 29 |
+
(assert(PyCMethod_Check(func)), \
|
| 30 |
+
_Py_CAST(PyCMethodObject*, (func)))
|
| 31 |
+
|
| 32 |
+
PyAPI_DATA(PyTypeObject) PyCMethod_Type;
|
| 33 |
+
|
| 34 |
+
#define PyCMethod_CheckExact(op) Py_IS_TYPE((op), &PyCMethod_Type)
|
| 35 |
+
#define PyCMethod_Check(op) PyObject_TypeCheck((op), &PyCMethod_Type)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
/* Static inline functions for direct access to these values.
|
| 39 |
+
Type checks are *not* done, so use with care. */
|
| 40 |
+
static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) {
|
| 41 |
+
return _PyCFunctionObject_CAST(func)->m_ml->ml_meth;
|
| 42 |
+
}
|
| 43 |
+
#define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func))
|
| 44 |
+
|
| 45 |
+
static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) {
|
| 46 |
+
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
|
| 47 |
+
if (func->m_ml->ml_flags & METH_STATIC) {
|
| 48 |
+
return _Py_NULL;
|
| 49 |
+
}
|
| 50 |
+
return func->m_self;
|
| 51 |
+
}
|
| 52 |
+
#define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func))
|
| 53 |
+
|
| 54 |
+
static inline int PyCFunction_GET_FLAGS(PyObject *func) {
|
| 55 |
+
return _PyCFunctionObject_CAST(func)->m_ml->ml_flags;
|
| 56 |
+
}
|
| 57 |
+
#define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func))
|
| 58 |
+
|
| 59 |
+
static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) {
|
| 60 |
+
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
|
| 61 |
+
if (func->m_ml->ml_flags & METH_METHOD) {
|
| 62 |
+
return _PyCMethodObject_CAST(func)->mm_class;
|
| 63 |
+
}
|
| 64 |
+
return _Py_NULL;
|
| 65 |
+
}
|
| 66 |
+
#define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func))
|
Include/cpython/modsupport.h
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_MODSUPPORT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
// A data structure that can be used to run initialization code once in a
|
| 6 |
+
// thread-safe manner. The C++11 equivalent is std::call_once.
|
| 7 |
+
typedef struct {
|
| 8 |
+
uint8_t v;
|
| 9 |
+
} _PyOnceFlag;
|
| 10 |
+
|
| 11 |
+
typedef struct _PyArg_Parser {
|
| 12 |
+
const char *format;
|
| 13 |
+
const char * const *keywords;
|
| 14 |
+
const char *fname;
|
| 15 |
+
const char *custom_msg;
|
| 16 |
+
_PyOnceFlag once; /* atomic one-time initialization flag */
|
| 17 |
+
int is_kwtuple_owned; /* does this parser own the kwtuple object? */
|
| 18 |
+
int pos; /* number of positional-only arguments */
|
| 19 |
+
int min; /* minimal number of arguments */
|
| 20 |
+
int max; /* maximal number of positional arguments */
|
| 21 |
+
PyObject *kwtuple; /* tuple of keyword parameter names */
|
| 22 |
+
struct _PyArg_Parser *next;
|
| 23 |
+
} _PyArg_Parser;
|
| 24 |
+
|
| 25 |
+
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
|
| 26 |
+
struct _PyArg_Parser *, ...);
|
Include/cpython/monitoring.h
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_MONITORING_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
/* Local events.
|
| 6 |
+
* These require bytecode instrumentation */
|
| 7 |
+
|
| 8 |
+
#define PY_MONITORING_EVENT_PY_START 0
|
| 9 |
+
#define PY_MONITORING_EVENT_PY_RESUME 1
|
| 10 |
+
#define PY_MONITORING_EVENT_PY_RETURN 2
|
| 11 |
+
#define PY_MONITORING_EVENT_PY_YIELD 3
|
| 12 |
+
#define PY_MONITORING_EVENT_CALL 4
|
| 13 |
+
#define PY_MONITORING_EVENT_LINE 5
|
| 14 |
+
#define PY_MONITORING_EVENT_INSTRUCTION 6
|
| 15 |
+
#define PY_MONITORING_EVENT_JUMP 7
|
| 16 |
+
#define PY_MONITORING_EVENT_BRANCH 8
|
| 17 |
+
#define PY_MONITORING_EVENT_STOP_ITERATION 9
|
| 18 |
+
|
| 19 |
+
#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \
|
| 20 |
+
((ev) < _PY_MONITORING_LOCAL_EVENTS)
|
| 21 |
+
|
| 22 |
+
/* Other events, mainly exceptions */
|
| 23 |
+
|
| 24 |
+
#define PY_MONITORING_EVENT_RAISE 10
|
| 25 |
+
#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11
|
| 26 |
+
#define PY_MONITORING_EVENT_PY_UNWIND 12
|
| 27 |
+
#define PY_MONITORING_EVENT_PY_THROW 13
|
| 28 |
+
#define PY_MONITORING_EVENT_RERAISE 14
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
/* Ancillary events */
|
| 32 |
+
|
| 33 |
+
#define PY_MONITORING_EVENT_C_RETURN 15
|
| 34 |
+
#define PY_MONITORING_EVENT_C_RAISE 16
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
typedef struct _PyMonitoringState {
|
| 38 |
+
uint8_t active;
|
| 39 |
+
uint8_t opaque;
|
| 40 |
+
} PyMonitoringState;
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
PyAPI_FUNC(int)
|
| 44 |
+
PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version,
|
| 45 |
+
const uint8_t *event_types, Py_ssize_t length);
|
| 46 |
+
|
| 47 |
+
PyAPI_FUNC(int)
|
| 48 |
+
PyMonitoring_ExitScope(void);
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
PyAPI_FUNC(int)
|
| 52 |
+
_PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 53 |
+
|
| 54 |
+
PyAPI_FUNC(int)
|
| 55 |
+
_PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 56 |
+
|
| 57 |
+
PyAPI_FUNC(int)
|
| 58 |
+
_PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 59 |
+
PyObject *retval);
|
| 60 |
+
|
| 61 |
+
PyAPI_FUNC(int)
|
| 62 |
+
_PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 63 |
+
PyObject *retval);
|
| 64 |
+
|
| 65 |
+
PyAPI_FUNC(int)
|
| 66 |
+
_PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 67 |
+
PyObject* callable, PyObject *arg0);
|
| 68 |
+
|
| 69 |
+
PyAPI_FUNC(int)
|
| 70 |
+
_PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 71 |
+
int lineno);
|
| 72 |
+
|
| 73 |
+
PyAPI_FUNC(int)
|
| 74 |
+
_PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 75 |
+
PyObject *target_offset);
|
| 76 |
+
|
| 77 |
+
PyAPI_FUNC(int)
|
| 78 |
+
_PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 79 |
+
PyObject *target_offset);
|
| 80 |
+
|
| 81 |
+
PyAPI_FUNC(int)
|
| 82 |
+
_PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 83 |
+
PyObject *retval);
|
| 84 |
+
|
| 85 |
+
PyAPI_FUNC(int)
|
| 86 |
+
_PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 87 |
+
|
| 88 |
+
PyAPI_FUNC(int)
|
| 89 |
+
_PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 90 |
+
|
| 91 |
+
PyAPI_FUNC(int)
|
| 92 |
+
_PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 93 |
+
|
| 94 |
+
PyAPI_FUNC(int)
|
| 95 |
+
_PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 96 |
+
|
| 97 |
+
PyAPI_FUNC(int)
|
| 98 |
+
_PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 99 |
+
|
| 100 |
+
PyAPI_FUNC(int)
|
| 101 |
+
_PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
|
| 102 |
+
|
| 103 |
+
PyAPI_FUNC(int)
|
| 104 |
+
_PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value);
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
#define _PYMONITORING_IF_ACTIVE(STATE, X) \
|
| 108 |
+
if ((STATE)->active) { \
|
| 109 |
+
return (X); \
|
| 110 |
+
} \
|
| 111 |
+
else { \
|
| 112 |
+
return 0; \
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
static inline int
|
| 116 |
+
PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 117 |
+
{
|
| 118 |
+
_PYMONITORING_IF_ACTIVE(
|
| 119 |
+
state,
|
| 120 |
+
_PyMonitoring_FirePyStartEvent(state, codelike, offset));
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
static inline int
|
| 124 |
+
PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 125 |
+
{
|
| 126 |
+
_PYMONITORING_IF_ACTIVE(
|
| 127 |
+
state,
|
| 128 |
+
_PyMonitoring_FirePyResumeEvent(state, codelike, offset));
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
static inline int
|
| 132 |
+
PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 133 |
+
PyObject *retval)
|
| 134 |
+
{
|
| 135 |
+
_PYMONITORING_IF_ACTIVE(
|
| 136 |
+
state,
|
| 137 |
+
_PyMonitoring_FirePyReturnEvent(state, codelike, offset, retval));
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
static inline int
|
| 141 |
+
PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 142 |
+
PyObject *retval)
|
| 143 |
+
{
|
| 144 |
+
_PYMONITORING_IF_ACTIVE(
|
| 145 |
+
state,
|
| 146 |
+
_PyMonitoring_FirePyYieldEvent(state, codelike, offset, retval));
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
static inline int
|
| 150 |
+
PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 151 |
+
PyObject* callable, PyObject *arg0)
|
| 152 |
+
{
|
| 153 |
+
_PYMONITORING_IF_ACTIVE(
|
| 154 |
+
state,
|
| 155 |
+
_PyMonitoring_FireCallEvent(state, codelike, offset, callable, arg0));
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
static inline int
|
| 159 |
+
PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 160 |
+
int lineno)
|
| 161 |
+
{
|
| 162 |
+
_PYMONITORING_IF_ACTIVE(
|
| 163 |
+
state,
|
| 164 |
+
_PyMonitoring_FireLineEvent(state, codelike, offset, lineno));
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
static inline int
|
| 168 |
+
PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 169 |
+
PyObject *target_offset)
|
| 170 |
+
{
|
| 171 |
+
_PYMONITORING_IF_ACTIVE(
|
| 172 |
+
state,
|
| 173 |
+
_PyMonitoring_FireJumpEvent(state, codelike, offset, target_offset));
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
static inline int
|
| 177 |
+
PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 178 |
+
PyObject *target_offset)
|
| 179 |
+
{
|
| 180 |
+
_PYMONITORING_IF_ACTIVE(
|
| 181 |
+
state,
|
| 182 |
+
_PyMonitoring_FireBranchEvent(state, codelike, offset, target_offset));
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
static inline int
|
| 186 |
+
PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
|
| 187 |
+
PyObject *retval)
|
| 188 |
+
{
|
| 189 |
+
_PYMONITORING_IF_ACTIVE(
|
| 190 |
+
state,
|
| 191 |
+
_PyMonitoring_FireCReturnEvent(state, codelike, offset, retval));
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
static inline int
|
| 195 |
+
PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 196 |
+
{
|
| 197 |
+
_PYMONITORING_IF_ACTIVE(
|
| 198 |
+
state,
|
| 199 |
+
_PyMonitoring_FirePyThrowEvent(state, codelike, offset));
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
static inline int
|
| 203 |
+
PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 204 |
+
{
|
| 205 |
+
_PYMONITORING_IF_ACTIVE(
|
| 206 |
+
state,
|
| 207 |
+
_PyMonitoring_FireRaiseEvent(state, codelike, offset));
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
static inline int
|
| 211 |
+
PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 212 |
+
{
|
| 213 |
+
_PYMONITORING_IF_ACTIVE(
|
| 214 |
+
state,
|
| 215 |
+
_PyMonitoring_FireReraiseEvent(state, codelike, offset));
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
static inline int
|
| 219 |
+
PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 220 |
+
{
|
| 221 |
+
_PYMONITORING_IF_ACTIVE(
|
| 222 |
+
state,
|
| 223 |
+
_PyMonitoring_FireExceptionHandledEvent(state, codelike, offset));
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
static inline int
|
| 227 |
+
PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 228 |
+
{
|
| 229 |
+
_PYMONITORING_IF_ACTIVE(
|
| 230 |
+
state,
|
| 231 |
+
_PyMonitoring_FireCRaiseEvent(state, codelike, offset));
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
static inline int
|
| 235 |
+
PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
|
| 236 |
+
{
|
| 237 |
+
_PYMONITORING_IF_ACTIVE(
|
| 238 |
+
state,
|
| 239 |
+
_PyMonitoring_FirePyUnwindEvent(state, codelike, offset));
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
static inline int
|
| 243 |
+
PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)
|
| 244 |
+
{
|
| 245 |
+
_PYMONITORING_IF_ACTIVE(
|
| 246 |
+
state,
|
| 247 |
+
_PyMonitoring_FireStopIterationEvent(state, codelike, offset, value));
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
#undef _PYMONITORING_IF_ACTIVE
|
Include/cpython/object.h
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_OBJECT_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
|
| 6 |
+
PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
|
| 7 |
+
PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op);
|
| 8 |
+
|
| 9 |
+
#ifdef Py_REF_DEBUG
|
| 10 |
+
/* These are useful as debugging aids when chasing down refleaks. */
|
| 11 |
+
PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void);
|
| 12 |
+
# define _Py_GetRefTotal() _Py_GetGlobalRefTotal()
|
| 13 |
+
PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void);
|
| 14 |
+
PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
|
| 15 |
+
#endif
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
/********************* String Literals ****************************************/
|
| 19 |
+
/* This structure helps managing static strings. The basic usage goes like this:
|
| 20 |
+
Instead of doing
|
| 21 |
+
|
| 22 |
+
r = PyObject_CallMethod(o, "foo", "args", ...);
|
| 23 |
+
|
| 24 |
+
do
|
| 25 |
+
|
| 26 |
+
_Py_IDENTIFIER(foo);
|
| 27 |
+
...
|
| 28 |
+
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
|
| 29 |
+
|
| 30 |
+
PyId_foo is a static variable, either on block level or file level. On first
|
| 31 |
+
usage, the string "foo" is interned, and the structures are linked. On interpreter
|
| 32 |
+
shutdown, all strings are released.
|
| 33 |
+
|
| 34 |
+
Alternatively, _Py_static_string allows choosing the variable name.
|
| 35 |
+
_PyUnicode_FromId returns a borrowed reference to the interned string.
|
| 36 |
+
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
|
| 37 |
+
*/
|
| 38 |
+
typedef struct _Py_Identifier {
|
| 39 |
+
const char* string;
|
| 40 |
+
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
|
| 41 |
+
// unique and must be initialized to -1.
|
| 42 |
+
Py_ssize_t index;
|
| 43 |
+
// Hidden PyMutex struct for non free-threaded build.
|
| 44 |
+
struct {
|
| 45 |
+
uint8_t v;
|
| 46 |
+
} mutex;
|
| 47 |
+
} _Py_Identifier;
|
| 48 |
+
|
| 49 |
+
#ifndef Py_BUILD_CORE
|
| 50 |
+
// For now we are keeping _Py_IDENTIFIER for continued use
|
| 51 |
+
// in non-builtin extensions (and naughty PyPI modules).
|
| 52 |
+
|
| 53 |
+
#define _Py_static_string_init(value) { .string = (value), .index = -1 }
|
| 54 |
+
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
|
| 55 |
+
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
|
| 56 |
+
|
| 57 |
+
#endif /* !Py_BUILD_CORE */
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
typedef struct {
|
| 61 |
+
/* Number implementations must check *both*
|
| 62 |
+
arguments for proper type and implement the necessary conversions
|
| 63 |
+
in the slot functions themselves. */
|
| 64 |
+
|
| 65 |
+
binaryfunc nb_add;
|
| 66 |
+
binaryfunc nb_subtract;
|
| 67 |
+
binaryfunc nb_multiply;
|
| 68 |
+
binaryfunc nb_remainder;
|
| 69 |
+
binaryfunc nb_divmod;
|
| 70 |
+
ternaryfunc nb_power;
|
| 71 |
+
unaryfunc nb_negative;
|
| 72 |
+
unaryfunc nb_positive;
|
| 73 |
+
unaryfunc nb_absolute;
|
| 74 |
+
inquiry nb_bool;
|
| 75 |
+
unaryfunc nb_invert;
|
| 76 |
+
binaryfunc nb_lshift;
|
| 77 |
+
binaryfunc nb_rshift;
|
| 78 |
+
binaryfunc nb_and;
|
| 79 |
+
binaryfunc nb_xor;
|
| 80 |
+
binaryfunc nb_or;
|
| 81 |
+
unaryfunc nb_int;
|
| 82 |
+
void *nb_reserved; /* the slot formerly known as nb_long */
|
| 83 |
+
unaryfunc nb_float;
|
| 84 |
+
|
| 85 |
+
binaryfunc nb_inplace_add;
|
| 86 |
+
binaryfunc nb_inplace_subtract;
|
| 87 |
+
binaryfunc nb_inplace_multiply;
|
| 88 |
+
binaryfunc nb_inplace_remainder;
|
| 89 |
+
ternaryfunc nb_inplace_power;
|
| 90 |
+
binaryfunc nb_inplace_lshift;
|
| 91 |
+
binaryfunc nb_inplace_rshift;
|
| 92 |
+
binaryfunc nb_inplace_and;
|
| 93 |
+
binaryfunc nb_inplace_xor;
|
| 94 |
+
binaryfunc nb_inplace_or;
|
| 95 |
+
|
| 96 |
+
binaryfunc nb_floor_divide;
|
| 97 |
+
binaryfunc nb_true_divide;
|
| 98 |
+
binaryfunc nb_inplace_floor_divide;
|
| 99 |
+
binaryfunc nb_inplace_true_divide;
|
| 100 |
+
|
| 101 |
+
unaryfunc nb_index;
|
| 102 |
+
|
| 103 |
+
binaryfunc nb_matrix_multiply;
|
| 104 |
+
binaryfunc nb_inplace_matrix_multiply;
|
| 105 |
+
} PyNumberMethods;
|
| 106 |
+
|
| 107 |
+
typedef struct {
|
| 108 |
+
lenfunc sq_length;
|
| 109 |
+
binaryfunc sq_concat;
|
| 110 |
+
ssizeargfunc sq_repeat;
|
| 111 |
+
ssizeargfunc sq_item;
|
| 112 |
+
void *was_sq_slice;
|
| 113 |
+
ssizeobjargproc sq_ass_item;
|
| 114 |
+
void *was_sq_ass_slice;
|
| 115 |
+
objobjproc sq_contains;
|
| 116 |
+
|
| 117 |
+
binaryfunc sq_inplace_concat;
|
| 118 |
+
ssizeargfunc sq_inplace_repeat;
|
| 119 |
+
} PySequenceMethods;
|
| 120 |
+
|
| 121 |
+
typedef struct {
|
| 122 |
+
lenfunc mp_length;
|
| 123 |
+
binaryfunc mp_subscript;
|
| 124 |
+
objobjargproc mp_ass_subscript;
|
| 125 |
+
} PyMappingMethods;
|
| 126 |
+
|
| 127 |
+
typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result);
|
| 128 |
+
|
| 129 |
+
typedef struct {
|
| 130 |
+
unaryfunc am_await;
|
| 131 |
+
unaryfunc am_aiter;
|
| 132 |
+
unaryfunc am_anext;
|
| 133 |
+
sendfunc am_send;
|
| 134 |
+
} PyAsyncMethods;
|
| 135 |
+
|
| 136 |
+
typedef struct {
|
| 137 |
+
getbufferproc bf_getbuffer;
|
| 138 |
+
releasebufferproc bf_releasebuffer;
|
| 139 |
+
} PyBufferProcs;
|
| 140 |
+
|
| 141 |
+
/* Allow printfunc in the tp_vectorcall_offset slot for
|
| 142 |
+
* backwards-compatibility */
|
| 143 |
+
typedef Py_ssize_t printfunc;
|
| 144 |
+
|
| 145 |
+
// If this structure is modified, Doc/includes/typestruct.h should be updated
|
| 146 |
+
// as well.
|
| 147 |
+
struct _typeobject {
|
| 148 |
+
PyObject_VAR_HEAD
|
| 149 |
+
const char *tp_name; /* For printing, in format "<module>.<name>" */
|
| 150 |
+
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
|
| 151 |
+
|
| 152 |
+
/* Methods to implement standard operations */
|
| 153 |
+
|
| 154 |
+
destructor tp_dealloc;
|
| 155 |
+
Py_ssize_t tp_vectorcall_offset;
|
| 156 |
+
getattrfunc tp_getattr;
|
| 157 |
+
setattrfunc tp_setattr;
|
| 158 |
+
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
|
| 159 |
+
or tp_reserved (Python 3) */
|
| 160 |
+
reprfunc tp_repr;
|
| 161 |
+
|
| 162 |
+
/* Method suites for standard classes */
|
| 163 |
+
|
| 164 |
+
PyNumberMethods *tp_as_number;
|
| 165 |
+
PySequenceMethods *tp_as_sequence;
|
| 166 |
+
PyMappingMethods *tp_as_mapping;
|
| 167 |
+
|
| 168 |
+
/* More standard operations (here for binary compatibility) */
|
| 169 |
+
|
| 170 |
+
hashfunc tp_hash;
|
| 171 |
+
ternaryfunc tp_call;
|
| 172 |
+
reprfunc tp_str;
|
| 173 |
+
getattrofunc tp_getattro;
|
| 174 |
+
setattrofunc tp_setattro;
|
| 175 |
+
|
| 176 |
+
/* Functions to access object as input/output buffer */
|
| 177 |
+
PyBufferProcs *tp_as_buffer;
|
| 178 |
+
|
| 179 |
+
/* Flags to define presence of optional/expanded features */
|
| 180 |
+
unsigned long tp_flags;
|
| 181 |
+
|
| 182 |
+
const char *tp_doc; /* Documentation string */
|
| 183 |
+
|
| 184 |
+
/* Assigned meaning in release 2.0 */
|
| 185 |
+
/* call function for all accessible objects */
|
| 186 |
+
traverseproc tp_traverse;
|
| 187 |
+
|
| 188 |
+
/* delete references to contained objects */
|
| 189 |
+
inquiry tp_clear;
|
| 190 |
+
|
| 191 |
+
/* Assigned meaning in release 2.1 */
|
| 192 |
+
/* rich comparisons */
|
| 193 |
+
richcmpfunc tp_richcompare;
|
| 194 |
+
|
| 195 |
+
/* weak reference enabler */
|
| 196 |
+
Py_ssize_t tp_weaklistoffset;
|
| 197 |
+
|
| 198 |
+
/* Iterators */
|
| 199 |
+
getiterfunc tp_iter;
|
| 200 |
+
iternextfunc tp_iternext;
|
| 201 |
+
|
| 202 |
+
/* Attribute descriptor and subclassing stuff */
|
| 203 |
+
PyMethodDef *tp_methods;
|
| 204 |
+
PyMemberDef *tp_members;
|
| 205 |
+
PyGetSetDef *tp_getset;
|
| 206 |
+
// Strong reference on a heap type, borrowed reference on a static type
|
| 207 |
+
PyTypeObject *tp_base;
|
| 208 |
+
PyObject *tp_dict;
|
| 209 |
+
descrgetfunc tp_descr_get;
|
| 210 |
+
descrsetfunc tp_descr_set;
|
| 211 |
+
Py_ssize_t tp_dictoffset;
|
| 212 |
+
initproc tp_init;
|
| 213 |
+
allocfunc tp_alloc;
|
| 214 |
+
newfunc tp_new;
|
| 215 |
+
freefunc tp_free; /* Low-level free-memory routine */
|
| 216 |
+
inquiry tp_is_gc; /* For PyObject_IS_GC */
|
| 217 |
+
PyObject *tp_bases;
|
| 218 |
+
PyObject *tp_mro; /* method resolution order */
|
| 219 |
+
PyObject *tp_cache; /* no longer used */
|
| 220 |
+
void *tp_subclasses; /* for static builtin types this is an index */
|
| 221 |
+
PyObject *tp_weaklist; /* not used for static builtin types */
|
| 222 |
+
destructor tp_del;
|
| 223 |
+
|
| 224 |
+
/* Type attribute cache version tag. Added in version 2.6 */
|
| 225 |
+
unsigned int tp_version_tag;
|
| 226 |
+
|
| 227 |
+
destructor tp_finalize;
|
| 228 |
+
vectorcallfunc tp_vectorcall;
|
| 229 |
+
|
| 230 |
+
/* bitset of which type-watchers care about this type */
|
| 231 |
+
unsigned char tp_watched;
|
| 232 |
+
uint16_t tp_versions_used;
|
| 233 |
+
};
|
| 234 |
+
|
| 235 |
+
/* This struct is used by the specializer
|
| 236 |
+
* It should be treated as an opaque blob
|
| 237 |
+
* by code other than the specializer and interpreter. */
|
| 238 |
+
struct _specialization_cache {
|
| 239 |
+
// In order to avoid bloating the bytecode with lots of inline caches, the
|
| 240 |
+
// members of this structure have a somewhat unique contract. They are set
|
| 241 |
+
// by the specialization machinery, and are invalidated by PyType_Modified.
|
| 242 |
+
// The rules for using them are as follows:
|
| 243 |
+
// - If getitem is non-NULL, then it is the same Python function that
|
| 244 |
+
// PyType_Lookup(cls, "__getitem__") would return.
|
| 245 |
+
// - If getitem is NULL, then getitem_version is meaningless.
|
| 246 |
+
// - If getitem->func_version == getitem_version, then getitem can be called
|
| 247 |
+
// with two positional arguments and no keyword arguments, and has neither
|
| 248 |
+
// *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM):
|
| 249 |
+
PyObject *getitem;
|
| 250 |
+
uint32_t getitem_version;
|
| 251 |
+
PyObject *init;
|
| 252 |
+
};
|
| 253 |
+
|
| 254 |
+
/* The *real* layout of a type object when allocated on the heap */
|
| 255 |
+
typedef struct _heaptypeobject {
|
| 256 |
+
/* Note: there's a dependency on the order of these members
|
| 257 |
+
in slotptr() in typeobject.c . */
|
| 258 |
+
PyTypeObject ht_type;
|
| 259 |
+
PyAsyncMethods as_async;
|
| 260 |
+
PyNumberMethods as_number;
|
| 261 |
+
PyMappingMethods as_mapping;
|
| 262 |
+
PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
|
| 263 |
+
so that the mapping wins when both
|
| 264 |
+
the mapping and the sequence define
|
| 265 |
+
a given operator (e.g. __getitem__).
|
| 266 |
+
see add_operators() in typeobject.c . */
|
| 267 |
+
PyBufferProcs as_buffer;
|
| 268 |
+
PyObject *ht_name, *ht_slots, *ht_qualname;
|
| 269 |
+
struct _dictkeysobject *ht_cached_keys;
|
| 270 |
+
PyObject *ht_module;
|
| 271 |
+
char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec
|
| 272 |
+
struct _specialization_cache _spec_cache; // For use by the specializer.
|
| 273 |
+
/* here are optional user slots, followed by the members. */
|
| 274 |
+
} PyHeapTypeObject;
|
| 275 |
+
|
| 276 |
+
PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
|
| 277 |
+
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
|
| 278 |
+
PyAPI_FUNC(PyObject *) _PyType_LookupRef(PyTypeObject *, PyObject *);
|
| 279 |
+
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
|
| 280 |
+
|
| 281 |
+
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
|
| 282 |
+
PyAPI_FUNC(void) _Py_BreakPoint(void);
|
| 283 |
+
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
|
| 284 |
+
|
| 285 |
+
PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
|
| 286 |
+
|
| 287 |
+
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
|
| 288 |
+
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
|
| 289 |
+
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
|
| 290 |
+
|
| 291 |
+
PyAPI_FUNC(void) PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *);
|
| 292 |
+
|
| 293 |
+
/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes
|
| 294 |
+
dict as the last parameter. */
|
| 295 |
+
PyAPI_FUNC(PyObject *)
|
| 296 |
+
_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int);
|
| 297 |
+
PyAPI_FUNC(int)
|
| 298 |
+
_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
| 299 |
+
PyObject *, PyObject *);
|
| 300 |
+
|
| 301 |
+
PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
|
| 302 |
+
|
| 303 |
+
/* Safely decref `dst` and set `dst` to `src`.
|
| 304 |
+
*
|
| 305 |
+
* As in case of Py_CLEAR "the obvious" code can be deadly:
|
| 306 |
+
*
|
| 307 |
+
* Py_DECREF(dst);
|
| 308 |
+
* dst = src;
|
| 309 |
+
*
|
| 310 |
+
* The safe way is:
|
| 311 |
+
*
|
| 312 |
+
* Py_SETREF(dst, src);
|
| 313 |
+
*
|
| 314 |
+
* That arranges to set `dst` to `src` _before_ decref'ing, so that any code
|
| 315 |
+
* triggered as a side-effect of `dst` getting torn down no longer believes
|
| 316 |
+
* `dst` points to a valid object.
|
| 317 |
+
*
|
| 318 |
+
* Temporary variables are used to only evalutate macro arguments once and so
|
| 319 |
+
* avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to
|
| 320 |
+
* avoid a miscompilation caused by type punning. See Py_CLEAR() comment for
|
| 321 |
+
* implementation details about type punning.
|
| 322 |
+
*
|
| 323 |
+
* The memcpy() implementation does not emit a compiler warning if 'src' has
|
| 324 |
+
* not the same type than 'src': any pointer type is accepted for 'src'.
|
| 325 |
+
*/
|
| 326 |
+
#ifdef _Py_TYPEOF
|
| 327 |
+
#define Py_SETREF(dst, src) \
|
| 328 |
+
do { \
|
| 329 |
+
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
|
| 330 |
+
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
|
| 331 |
+
*_tmp_dst_ptr = (src); \
|
| 332 |
+
Py_DECREF(_tmp_old_dst); \
|
| 333 |
+
} while (0)
|
| 334 |
+
#else
|
| 335 |
+
#define Py_SETREF(dst, src) \
|
| 336 |
+
do { \
|
| 337 |
+
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
| 338 |
+
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
|
| 339 |
+
PyObject *_tmp_src = _PyObject_CAST(src); \
|
| 340 |
+
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
|
| 341 |
+
Py_DECREF(_tmp_old_dst); \
|
| 342 |
+
} while (0)
|
| 343 |
+
#endif
|
| 344 |
+
|
| 345 |
+
/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of
|
| 346 |
+
* Py_DECREF().
|
| 347 |
+
*/
|
| 348 |
+
#ifdef _Py_TYPEOF
|
| 349 |
+
#define Py_XSETREF(dst, src) \
|
| 350 |
+
do { \
|
| 351 |
+
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
|
| 352 |
+
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
|
| 353 |
+
*_tmp_dst_ptr = (src); \
|
| 354 |
+
Py_XDECREF(_tmp_old_dst); \
|
| 355 |
+
} while (0)
|
| 356 |
+
#else
|
| 357 |
+
#define Py_XSETREF(dst, src) \
|
| 358 |
+
do { \
|
| 359 |
+
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
|
| 360 |
+
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
|
| 361 |
+
PyObject *_tmp_src = _PyObject_CAST(src); \
|
| 362 |
+
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
|
| 363 |
+
Py_XDECREF(_tmp_old_dst); \
|
| 364 |
+
} while (0)
|
| 365 |
+
#endif
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
/* Define a pair of assertion macros:
|
| 369 |
+
_PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
|
| 370 |
+
|
| 371 |
+
These work like the regular C assert(), in that they will abort the
|
| 372 |
+
process with a message on stderr if the given condition fails to hold,
|
| 373 |
+
but compile away to nothing if NDEBUG is defined.
|
| 374 |
+
|
| 375 |
+
However, before aborting, Python will also try to call _PyObject_Dump() on
|
| 376 |
+
the given object. This may be of use when investigating bugs in which a
|
| 377 |
+
particular object is corrupt (e.g. buggy a tp_visit method in an extension
|
| 378 |
+
module breaking the garbage collector), to help locate the broken objects.
|
| 379 |
+
|
| 380 |
+
The WITH_MSG variant allows you to supply an additional message that Python
|
| 381 |
+
will attempt to print to stderr, after the object dump. */
|
| 382 |
+
#ifdef NDEBUG
|
| 383 |
+
/* No debugging: compile away the assertions: */
|
| 384 |
+
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
| 385 |
+
((void)0)
|
| 386 |
+
#else
|
| 387 |
+
/* With debugging: generate checks: */
|
| 388 |
+
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
| 389 |
+
((expr) \
|
| 390 |
+
? (void)(0) \
|
| 391 |
+
: _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \
|
| 392 |
+
(msg), (filename), (lineno), (func)))
|
| 393 |
+
#endif
|
| 394 |
+
|
| 395 |
+
#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
|
| 396 |
+
_PyObject_ASSERT_FROM((obj), expr, (msg), __FILE__, __LINE__, __func__)
|
| 397 |
+
#define _PyObject_ASSERT(obj, expr) \
|
| 398 |
+
_PyObject_ASSERT_WITH_MSG((obj), expr, NULL)
|
| 399 |
+
|
| 400 |
+
#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \
|
| 401 |
+
_PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__)
|
| 402 |
+
|
| 403 |
+
/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined,
|
| 404 |
+
to avoid causing compiler/linker errors when building extensions without
|
| 405 |
+
NDEBUG against a Python built with NDEBUG defined.
|
| 406 |
+
|
| 407 |
+
msg, expr and function can be NULL. */
|
| 408 |
+
PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed(
|
| 409 |
+
PyObject *obj,
|
| 410 |
+
const char *expr,
|
| 411 |
+
const char *msg,
|
| 412 |
+
const char *file,
|
| 413 |
+
int line,
|
| 414 |
+
const char *function);
|
| 415 |
+
|
| 416 |
+
|
| 417 |
+
/* Trashcan mechanism, thanks to Christian Tismer.
|
| 418 |
+
|
| 419 |
+
When deallocating a container object, it's possible to trigger an unbounded
|
| 420 |
+
chain of deallocations, as each Py_DECREF in turn drops the refcount on "the
|
| 421 |
+
next" object in the chain to 0. This can easily lead to stack overflows,
|
| 422 |
+
especially in threads (which typically have less stack space to work with).
|
| 423 |
+
|
| 424 |
+
A container object can avoid this by bracketing the body of its tp_dealloc
|
| 425 |
+
function with a pair of macros:
|
| 426 |
+
|
| 427 |
+
static void
|
| 428 |
+
mytype_dealloc(mytype *p)
|
| 429 |
+
{
|
| 430 |
+
... declarations go here ...
|
| 431 |
+
|
| 432 |
+
PyObject_GC_UnTrack(p); // must untrack first
|
| 433 |
+
Py_TRASHCAN_BEGIN(p, mytype_dealloc)
|
| 434 |
+
... The body of the deallocator goes here, including all calls ...
|
| 435 |
+
... to Py_DECREF on contained objects. ...
|
| 436 |
+
Py_TRASHCAN_END // there should be no code after this
|
| 437 |
+
}
|
| 438 |
+
|
| 439 |
+
CAUTION: Never return from the middle of the body! If the body needs to
|
| 440 |
+
"get out early", put a label immediately before the Py_TRASHCAN_END
|
| 441 |
+
call, and goto it. Else the call-depth counter (see below) will stay
|
| 442 |
+
above 0 forever, and the trashcan will never get emptied.
|
| 443 |
+
|
| 444 |
+
How it works: The BEGIN macro increments a call-depth counter. So long
|
| 445 |
+
as this counter is small, the body of the deallocator is run directly without
|
| 446 |
+
further ado. But if the counter gets large, it instead adds p to a list of
|
| 447 |
+
objects to be deallocated later, skips the body of the deallocator, and
|
| 448 |
+
resumes execution after the END macro. The tp_dealloc routine then returns
|
| 449 |
+
without deallocating anything (and so unbounded call-stack depth is avoided).
|
| 450 |
+
|
| 451 |
+
When the call stack finishes unwinding again, code generated by the END macro
|
| 452 |
+
notices this, and calls another routine to deallocate all the objects that
|
| 453 |
+
may have been added to the list of deferred deallocations. In effect, a
|
| 454 |
+
chain of N deallocations is broken into (N-1)/(Py_TRASHCAN_HEADROOM-1) pieces,
|
| 455 |
+
with the call stack never exceeding a depth of Py_TRASHCAN_HEADROOM.
|
| 456 |
+
|
| 457 |
+
Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
|
| 458 |
+
class, we need to ensure that the trashcan is only triggered on the tp_dealloc
|
| 459 |
+
of the actual class being deallocated. Otherwise we might end up with a
|
| 460 |
+
partially-deallocated object. To check this, the tp_dealloc function must be
|
| 461 |
+
passed as second argument to Py_TRASHCAN_BEGIN().
|
| 462 |
+
*/
|
| 463 |
+
|
| 464 |
+
/* Python 3.9 private API, invoked by the macros below. */
|
| 465 |
+
PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op);
|
| 466 |
+
PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate);
|
| 467 |
+
|
| 468 |
+
PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op);
|
| 469 |
+
PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate);
|
| 470 |
+
|
| 471 |
+
|
| 472 |
+
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
|
| 473 |
+
|
| 474 |
+
/* To avoid raising recursion errors during dealloc trigger trashcan before we reach
|
| 475 |
+
* recursion limit. To avoid trashing, we don't attempt to empty the trashcan until
|
| 476 |
+
* we have headroom above the trigger limit */
|
| 477 |
+
#define Py_TRASHCAN_HEADROOM 50
|
| 478 |
+
|
| 479 |
+
#define Py_TRASHCAN_BEGIN(op, dealloc) \
|
| 480 |
+
do { \
|
| 481 |
+
PyThreadState *tstate = PyThreadState_Get(); \
|
| 482 |
+
if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
|
| 483 |
+
_PyTrash_thread_deposit_object(tstate, (PyObject *)op); \
|
| 484 |
+
break; \
|
| 485 |
+
} \
|
| 486 |
+
tstate->c_recursion_remaining--;
|
| 487 |
+
/* The body of the deallocator is here. */
|
| 488 |
+
#define Py_TRASHCAN_END \
|
| 489 |
+
tstate->c_recursion_remaining++; \
|
| 490 |
+
if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \
|
| 491 |
+
_PyTrash_thread_destroy_chain(tstate); \
|
| 492 |
+
} \
|
| 493 |
+
} while (0);
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);
|
| 497 |
+
|
| 498 |
+
PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
|
| 499 |
+
PyAPI_FUNC(int) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict);
|
| 500 |
+
PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj);
|
| 501 |
+
|
| 502 |
+
#define TYPE_MAX_WATCHERS 8
|
| 503 |
+
|
| 504 |
+
typedef int(*PyType_WatchCallback)(PyTypeObject *);
|
| 505 |
+
PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback);
|
| 506 |
+
PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id);
|
| 507 |
+
PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type);
|
| 508 |
+
PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type);
|
| 509 |
+
|
| 510 |
+
/* Attempt to assign a version tag to the given type.
|
| 511 |
+
*
|
| 512 |
+
* Returns 1 if the type already had a valid version tag or a new one was
|
| 513 |
+
* assigned, or 0 if a new tag could not be assigned.
|
| 514 |
+
*/
|
| 515 |
+
PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type);
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
typedef enum {
|
| 519 |
+
PyRefTracer_CREATE = 0,
|
| 520 |
+
PyRefTracer_DESTROY = 1,
|
| 521 |
+
} PyRefTracerEvent;
|
| 522 |
+
|
| 523 |
+
typedef int (*PyRefTracer)(PyObject *, PyRefTracerEvent event, void *);
|
| 524 |
+
PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data);
|
| 525 |
+
PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**);
|
Include/cpython/objimpl.h
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_OBJIMPL_H
|
| 2 |
+
# error "this header file must not be included directly"
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
static inline size_t _PyObject_SIZE(PyTypeObject *type) {
|
| 6 |
+
return _Py_STATIC_CAST(size_t, type->tp_basicsize);
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
|
| 10 |
+
vrbl-size object with nitems items, exclusive of gc overhead (if any). The
|
| 11 |
+
value is rounded up to the closest multiple of sizeof(void *), in order to
|
| 12 |
+
ensure that pointer fields at the end of the object are correctly aligned
|
| 13 |
+
for the platform (this is of special importance for subclasses of, e.g.,
|
| 14 |
+
str or int, so that pointers can be stored after the embedded data).
|
| 15 |
+
|
| 16 |
+
Note that there's no memory wastage in doing this, as malloc has to
|
| 17 |
+
return (at worst) pointer-aligned memory anyway.
|
| 18 |
+
*/
|
| 19 |
+
#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
|
| 20 |
+
# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
|
| 21 |
+
#endif
|
| 22 |
+
|
| 23 |
+
static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) {
|
| 24 |
+
size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize);
|
| 25 |
+
size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize);
|
| 26 |
+
return _Py_SIZE_ROUND_UP(size, SIZEOF_VOID_P);
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
/* This example code implements an object constructor with a custom
|
| 31 |
+
allocator, where PyObject_New is inlined, and shows the important
|
| 32 |
+
distinction between two steps (at least):
|
| 33 |
+
1) the actual allocation of the object storage;
|
| 34 |
+
2) the initialization of the Python specific fields
|
| 35 |
+
in this storage with PyObject_{Init, InitVar}.
|
| 36 |
+
|
| 37 |
+
PyObject *
|
| 38 |
+
YourObject_New(...)
|
| 39 |
+
{
|
| 40 |
+
PyObject *op;
|
| 41 |
+
|
| 42 |
+
op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
|
| 43 |
+
if (op == NULL) {
|
| 44 |
+
return PyErr_NoMemory();
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
PyObject_Init(op, &YourTypeStruct);
|
| 48 |
+
|
| 49 |
+
op->ob_field = value;
|
| 50 |
+
...
|
| 51 |
+
return op;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
Note that in C++, the use of the new operator usually implies that
|
| 55 |
+
the 1st step is performed automatically for you, so in a C++ class
|
| 56 |
+
constructor you would start directly with PyObject_Init/InitVar. */
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
typedef struct {
|
| 60 |
+
/* user context passed as the first argument to the 2 functions */
|
| 61 |
+
void *ctx;
|
| 62 |
+
|
| 63 |
+
/* allocate an arena of size bytes */
|
| 64 |
+
void* (*alloc) (void *ctx, size_t size);
|
| 65 |
+
|
| 66 |
+
/* free an arena */
|
| 67 |
+
void (*free) (void *ctx, void *ptr, size_t size);
|
| 68 |
+
} PyObjectArenaAllocator;
|
| 69 |
+
|
| 70 |
+
/* Get the arena allocator. */
|
| 71 |
+
PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
|
| 72 |
+
|
| 73 |
+
/* Set the arena allocator. */
|
| 74 |
+
PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
/* Test if an object implements the garbage collector protocol */
|
| 78 |
+
PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
// Test if a type supports weak references
|
| 82 |
+
PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type);
|
| 83 |
+
|
| 84 |
+
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
|
| 85 |
+
|
| 86 |
+
PyAPI_FUNC(PyObject *) PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *,
|
| 87 |
+
size_t);
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
/* Visit all live GC-capable objects, similar to gc.get_objects(None). The
|
| 91 |
+
* supplied callback is called on every such object with the void* arg set
|
| 92 |
+
* to the supplied arg. Returning 0 from the callback ends iteration, returning
|
| 93 |
+
* 1 allows iteration to continue. Returning any other value may result in
|
| 94 |
+
* undefined behaviour.
|
| 95 |
+
*
|
| 96 |
+
* If new objects are (de)allocated by the callback it is undefined if they
|
| 97 |
+
* will be visited.
|
| 98 |
+
|
| 99 |
+
* Garbage collection is disabled during operation. Explicitly running a
|
| 100 |
+
* collection in the callback may lead to undefined behaviour e.g. visiting the
|
| 101 |
+
* same objects multiple times or not at all.
|
| 102 |
+
*/
|
| 103 |
+
typedef int (*gcvisitobjects_t)(PyObject*, void*);
|
| 104 |
+
PyAPI_FUNC(void) PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void* arg);
|
Include/cpython/odictobject.h
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_ODICTOBJECT_H
|
| 2 |
+
#define Py_ODICTOBJECT_H
|
| 3 |
+
#ifdef __cplusplus
|
| 4 |
+
extern "C" {
|
| 5 |
+
#endif
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
/* OrderedDict */
|
| 9 |
+
/* This API is optional and mostly redundant. */
|
| 10 |
+
|
| 11 |
+
#ifndef Py_LIMITED_API
|
| 12 |
+
|
| 13 |
+
typedef struct _odictobject PyODictObject;
|
| 14 |
+
|
| 15 |
+
PyAPI_DATA(PyTypeObject) PyODict_Type;
|
| 16 |
+
PyAPI_DATA(PyTypeObject) PyODictIter_Type;
|
| 17 |
+
PyAPI_DATA(PyTypeObject) PyODictKeys_Type;
|
| 18 |
+
PyAPI_DATA(PyTypeObject) PyODictItems_Type;
|
| 19 |
+
PyAPI_DATA(PyTypeObject) PyODictValues_Type;
|
| 20 |
+
|
| 21 |
+
#define PyODict_Check(op) PyObject_TypeCheck((op), &PyODict_Type)
|
| 22 |
+
#define PyODict_CheckExact(op) Py_IS_TYPE((op), &PyODict_Type)
|
| 23 |
+
#define PyODict_SIZE(op) PyDict_GET_SIZE((op))
|
| 24 |
+
|
| 25 |
+
PyAPI_FUNC(PyObject *) PyODict_New(void);
|
| 26 |
+
PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
|
| 27 |
+
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
|
| 28 |
+
|
| 29 |
+
/* wrappers around PyDict* functions */
|
| 30 |
+
#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), (key))
|
| 31 |
+
#define PyODict_GetItemWithError(od, key) \
|
| 32 |
+
PyDict_GetItemWithError(_PyObject_CAST(od), (key))
|
| 33 |
+
#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), (key))
|
| 34 |
+
#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od))
|
| 35 |
+
#define PyODict_GetItemString(od, key) \
|
| 36 |
+
PyDict_GetItemString(_PyObject_CAST(od), (key))
|
| 37 |
+
|
| 38 |
+
#endif
|
| 39 |
+
|
| 40 |
+
#ifdef __cplusplus
|
| 41 |
+
}
|
| 42 |
+
#endif
|
| 43 |
+
#endif /* !Py_ODICTOBJECT_H */
|
Include/cpython/picklebufobject.h
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* PickleBuffer object. This is built-in for ease of use from third-party
|
| 2 |
+
* C extensions.
|
| 3 |
+
*/
|
| 4 |
+
|
| 5 |
+
#ifndef Py_PICKLEBUFOBJECT_H
|
| 6 |
+
#define Py_PICKLEBUFOBJECT_H
|
| 7 |
+
#ifdef __cplusplus
|
| 8 |
+
extern "C" {
|
| 9 |
+
#endif
|
| 10 |
+
|
| 11 |
+
#ifndef Py_LIMITED_API
|
| 12 |
+
|
| 13 |
+
PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type;
|
| 14 |
+
|
| 15 |
+
#define PyPickleBuffer_Check(op) Py_IS_TYPE((op), &PyPickleBuffer_Type)
|
| 16 |
+
|
| 17 |
+
/* Create a PickleBuffer redirecting to the given buffer-enabled object */
|
| 18 |
+
PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *);
|
| 19 |
+
/* Get the PickleBuffer's underlying view to the original object
|
| 20 |
+
* (NULL if released)
|
| 21 |
+
*/
|
| 22 |
+
PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *);
|
| 23 |
+
/* Release the PickleBuffer. Returns 0 on success, -1 on error. */
|
| 24 |
+
PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *);
|
| 25 |
+
|
| 26 |
+
#endif /* !Py_LIMITED_API */
|
| 27 |
+
|
| 28 |
+
#ifdef __cplusplus
|
| 29 |
+
}
|
| 30 |
+
#endif
|
| 31 |
+
#endif /* !Py_PICKLEBUFOBJECT_H */
|
Include/cpython/pthread_stubs.h
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef Py_CPYTHON_PTRHEAD_STUBS_H
|
| 2 |
+
#define Py_CPYTHON_PTRHEAD_STUBS_H
|
| 3 |
+
|
| 4 |
+
#if !defined(HAVE_PTHREAD_STUBS)
|
| 5 |
+
# error "this header file requires stubbed pthreads."
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
#ifndef _POSIX_THREADS
|
| 9 |
+
# define _POSIX_THREADS 1
|
| 10 |
+
#endif
|
| 11 |
+
|
| 12 |
+
/* Minimal pthread stubs for CPython.
|
| 13 |
+
*
|
| 14 |
+
* The stubs implement the minimum pthread API for CPython.
|
| 15 |
+
* - pthread_create() fails.
|
| 16 |
+
* - pthread_exit() calls exit(0).
|
| 17 |
+
* - pthread_key_*() functions implement minimal TSS without destructor.
|
| 18 |
+
* - all other functions do nothing and return 0.
|
| 19 |
+
*/
|
| 20 |
+
|
| 21 |
+
#ifdef __wasi__
|
| 22 |
+
// WASI's bits/alltypes.h provides type definitions when __NEED_ is set.
|
| 23 |
+
// The header file can be included multiple times.
|
| 24 |
+
//
|
| 25 |
+
// <sys/types.h> may also define these macros.
|
| 26 |
+
# ifndef __NEED_pthread_cond_t
|
| 27 |
+
# define __NEED_pthread_cond_t 1
|
| 28 |
+
# endif
|
| 29 |
+
# ifndef __NEED_pthread_condattr_t
|
| 30 |
+
# define __NEED_pthread_condattr_t 1
|
| 31 |
+
# endif
|
| 32 |
+
# ifndef __NEED_pthread_mutex_t
|
| 33 |
+
# define __NEED_pthread_mutex_t 1
|
| 34 |
+
# endif
|
| 35 |
+
# ifndef __NEED_pthread_mutexattr_t
|
| 36 |
+
# define __NEED_pthread_mutexattr_t 1
|
| 37 |
+
# endif
|
| 38 |
+
# ifndef __NEED_pthread_key_t
|
| 39 |
+
# define __NEED_pthread_key_t 1
|
| 40 |
+
# endif
|
| 41 |
+
# ifndef __NEED_pthread_t
|
| 42 |
+
# define __NEED_pthread_t 1
|
| 43 |
+
# endif
|
| 44 |
+
# ifndef __NEED_pthread_attr_t
|
| 45 |
+
# define __NEED_pthread_attr_t 1
|
| 46 |
+
# endif
|
| 47 |
+
# include <bits/alltypes.h>
|
| 48 |
+
#else
|
| 49 |
+
typedef struct { void *__x; } pthread_cond_t;
|
| 50 |
+
typedef struct { unsigned __attr; } pthread_condattr_t;
|
| 51 |
+
typedef struct { void *__x; } pthread_mutex_t;
|
| 52 |
+
typedef struct { unsigned __attr; } pthread_mutexattr_t;
|
| 53 |
+
typedef unsigned pthread_key_t;
|
| 54 |
+
typedef unsigned pthread_t;
|
| 55 |
+
typedef struct { unsigned __attr; } pthread_attr_t;
|
| 56 |
+
#endif
|
| 57 |
+
|
| 58 |
+
// mutex
|
| 59 |
+
PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex,
|
| 60 |
+
const pthread_mutexattr_t *restrict attr);
|
| 61 |
+
PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex);
|
| 62 |
+
PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex);
|
| 63 |
+
PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex);
|
| 64 |
+
PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex);
|
| 65 |
+
|
| 66 |
+
// condition
|
| 67 |
+
PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond,
|
| 68 |
+
const pthread_condattr_t *restrict attr);
|
| 69 |
+
PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond);
|
| 70 |
+
PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond,
|
| 71 |
+
pthread_mutex_t *restrict mutex);
|
| 72 |
+
PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond,
|
| 73 |
+
pthread_mutex_t *restrict mutex,
|
| 74 |
+
const struct timespec *restrict abstime);
|
| 75 |
+
PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond);
|
| 76 |
+
PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr);
|
| 77 |
+
PyAPI_FUNC(int) pthread_condattr_setclock(
|
| 78 |
+
pthread_condattr_t *attr, clockid_t clock_id);
|
| 79 |
+
|
| 80 |
+
// pthread
|
| 81 |
+
PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread,
|
| 82 |
+
const pthread_attr_t *restrict attr,
|
| 83 |
+
void *(*start_routine)(void *),
|
| 84 |
+
void *restrict arg);
|
| 85 |
+
PyAPI_FUNC(int) pthread_detach(pthread_t thread);
|
| 86 |
+
PyAPI_FUNC(int) pthread_join(pthread_t thread, void** value_ptr);
|
| 87 |
+
PyAPI_FUNC(pthread_t) pthread_self(void);
|
| 88 |
+
PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__));
|
| 89 |
+
PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr);
|
| 90 |
+
PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
|
| 91 |
+
PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr);
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
// pthread_key
|
| 95 |
+
#ifndef PTHREAD_KEYS_MAX
|
| 96 |
+
# define PTHREAD_KEYS_MAX 128
|
| 97 |
+
#endif
|
| 98 |
+
|
| 99 |
+
PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key,
|
| 100 |
+
void (*destr_function)(void *));
|
| 101 |
+
PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key);
|
| 102 |
+
PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key);
|
| 103 |
+
PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value);
|
| 104 |
+
|
| 105 |
+
#endif // Py_CPYTHON_PTRHEAD_STUBS_H
|
Include/cpython/pyatomic.h
ADDED
|
@@ -0,0 +1,569 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This header provides cross-platform low-level atomic operations
|
| 2 |
+
// similar to C11 atomics.
|
| 3 |
+
//
|
| 4 |
+
// Operations are sequentially consistent unless they have a suffix indicating
|
| 5 |
+
// otherwise. If in doubt, prefer the sequentially consistent operations.
|
| 6 |
+
//
|
| 7 |
+
// The "_relaxed" suffix for load and store operations indicates the "relaxed"
|
| 8 |
+
// memory order. They don't provide synchronization, but (roughly speaking)
|
| 9 |
+
// guarantee somewhat sane behavior for races instead of undefined behavior.
|
| 10 |
+
// In practice, they correspond to "normal" hardware load and store
|
| 11 |
+
// instructions, so they are almost as inexpensive as plain loads and stores
|
| 12 |
+
// in C.
|
| 13 |
+
//
|
| 14 |
+
// Note that atomic read-modify-write operations like _Py_atomic_add_* return
|
| 15 |
+
// the previous value of the atomic variable, not the new value.
|
| 16 |
+
//
|
| 17 |
+
// See https://en.cppreference.com/w/c/atomic for more information on C11
|
| 18 |
+
// atomics.
|
| 19 |
+
// See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf
|
| 20 |
+
// "A Relaxed Guide to memory_order_relaxed" for discussion of and common usage
|
| 21 |
+
// or relaxed atomics.
|
| 22 |
+
//
|
| 23 |
+
// Functions with pseudo Python code:
|
| 24 |
+
//
|
| 25 |
+
// def _Py_atomic_load(obj):
|
| 26 |
+
// return obj # sequential consistency
|
| 27 |
+
//
|
| 28 |
+
// def _Py_atomic_load_relaxed(obj):
|
| 29 |
+
// return obj # relaxed consistency
|
| 30 |
+
//
|
| 31 |
+
// def _Py_atomic_store(obj, value):
|
| 32 |
+
// obj = value # sequential consistency
|
| 33 |
+
//
|
| 34 |
+
// def _Py_atomic_store_relaxed(obj, value):
|
| 35 |
+
// obj = value # relaxed consistency
|
| 36 |
+
//
|
| 37 |
+
// def _Py_atomic_exchange(obj, value):
|
| 38 |
+
// # sequential consistency
|
| 39 |
+
// old_obj = obj
|
| 40 |
+
// obj = value
|
| 41 |
+
// return old_obj
|
| 42 |
+
//
|
| 43 |
+
// def _Py_atomic_compare_exchange(obj, expected, desired):
|
| 44 |
+
// # sequential consistency
|
| 45 |
+
// if obj == expected:
|
| 46 |
+
// obj = desired
|
| 47 |
+
// return True
|
| 48 |
+
// else:
|
| 49 |
+
// expected = obj
|
| 50 |
+
// return False
|
| 51 |
+
//
|
| 52 |
+
// def _Py_atomic_add(obj, value):
|
| 53 |
+
// # sequential consistency
|
| 54 |
+
// old_obj = obj
|
| 55 |
+
// obj += value
|
| 56 |
+
// return old_obj
|
| 57 |
+
//
|
| 58 |
+
// def _Py_atomic_and(obj, value):
|
| 59 |
+
// # sequential consistency
|
| 60 |
+
// old_obj = obj
|
| 61 |
+
// obj &= value
|
| 62 |
+
// return old_obj
|
| 63 |
+
//
|
| 64 |
+
// def _Py_atomic_or(obj, value):
|
| 65 |
+
// # sequential consistency
|
| 66 |
+
// old_obj = obj
|
| 67 |
+
// obj |= value
|
| 68 |
+
// return old_obj
|
| 69 |
+
//
|
| 70 |
+
// Other functions:
|
| 71 |
+
//
|
| 72 |
+
// def _Py_atomic_load_ptr_acquire(obj):
|
| 73 |
+
// return obj # acquire
|
| 74 |
+
//
|
| 75 |
+
// def _Py_atomic_store_ptr_release(obj):
|
| 76 |
+
// return obj # release
|
| 77 |
+
//
|
| 78 |
+
// def _Py_atomic_fence_seq_cst():
|
| 79 |
+
// # sequential consistency
|
| 80 |
+
// ...
|
| 81 |
+
//
|
| 82 |
+
// def _Py_atomic_fence_release():
|
| 83 |
+
// # release
|
| 84 |
+
// ...
|
| 85 |
+
|
| 86 |
+
#ifndef Py_CPYTHON_ATOMIC_H
|
| 87 |
+
# error "this header file must not be included directly"
|
| 88 |
+
#endif
|
| 89 |
+
|
| 90 |
+
// --- _Py_atomic_add --------------------------------------------------------
|
| 91 |
+
// Atomically adds `value` to `obj` and returns the previous value
|
| 92 |
+
|
| 93 |
+
static inline int
|
| 94 |
+
_Py_atomic_add_int(int *obj, int value);
|
| 95 |
+
|
| 96 |
+
static inline int8_t
|
| 97 |
+
_Py_atomic_add_int8(int8_t *obj, int8_t value);
|
| 98 |
+
|
| 99 |
+
static inline int16_t
|
| 100 |
+
_Py_atomic_add_int16(int16_t *obj, int16_t value);
|
| 101 |
+
|
| 102 |
+
static inline int32_t
|
| 103 |
+
_Py_atomic_add_int32(int32_t *obj, int32_t value);
|
| 104 |
+
|
| 105 |
+
static inline int64_t
|
| 106 |
+
_Py_atomic_add_int64(int64_t *obj, int64_t value);
|
| 107 |
+
|
| 108 |
+
static inline intptr_t
|
| 109 |
+
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value);
|
| 110 |
+
|
| 111 |
+
static inline unsigned int
|
| 112 |
+
_Py_atomic_add_uint(unsigned int *obj, unsigned int value);
|
| 113 |
+
|
| 114 |
+
static inline uint8_t
|
| 115 |
+
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value);
|
| 116 |
+
|
| 117 |
+
static inline uint16_t
|
| 118 |
+
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value);
|
| 119 |
+
|
| 120 |
+
static inline uint32_t
|
| 121 |
+
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value);
|
| 122 |
+
|
| 123 |
+
static inline uint64_t
|
| 124 |
+
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value);
|
| 125 |
+
|
| 126 |
+
static inline uintptr_t
|
| 127 |
+
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value);
|
| 128 |
+
|
| 129 |
+
static inline Py_ssize_t
|
| 130 |
+
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value);
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
// --- _Py_atomic_compare_exchange -------------------------------------------
|
| 134 |
+
// Performs an atomic compare-and-exchange.
|
| 135 |
+
//
|
| 136 |
+
// - If `*obj` and `*expected` are equal, store `desired` into `*obj`
|
| 137 |
+
// and return 1 (success).
|
| 138 |
+
// - Otherwise, store the `*obj` current value into `*expected`
|
| 139 |
+
// and return 0 (failure).
|
| 140 |
+
//
|
| 141 |
+
// These correspond to the C11 atomic_compare_exchange_strong() function.
|
| 142 |
+
|
| 143 |
+
static inline int
|
| 144 |
+
_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired);
|
| 145 |
+
|
| 146 |
+
static inline int
|
| 147 |
+
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired);
|
| 148 |
+
|
| 149 |
+
static inline int
|
| 150 |
+
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired);
|
| 151 |
+
|
| 152 |
+
static inline int
|
| 153 |
+
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired);
|
| 154 |
+
|
| 155 |
+
static inline int
|
| 156 |
+
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired);
|
| 157 |
+
|
| 158 |
+
static inline int
|
| 159 |
+
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired);
|
| 160 |
+
|
| 161 |
+
static inline int
|
| 162 |
+
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired);
|
| 163 |
+
|
| 164 |
+
static inline int
|
| 165 |
+
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired);
|
| 166 |
+
|
| 167 |
+
static inline int
|
| 168 |
+
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired);
|
| 169 |
+
|
| 170 |
+
static inline int
|
| 171 |
+
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired);
|
| 172 |
+
|
| 173 |
+
static inline int
|
| 174 |
+
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired);
|
| 175 |
+
|
| 176 |
+
static inline int
|
| 177 |
+
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired);
|
| 178 |
+
|
| 179 |
+
static inline int
|
| 180 |
+
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired);
|
| 181 |
+
|
| 182 |
+
// NOTE: `obj` and `expected` are logically `void**` types, but we use `void*`
|
| 183 |
+
// so that we can pass types like `PyObject**` without a cast.
|
| 184 |
+
static inline int
|
| 185 |
+
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value);
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
// --- _Py_atomic_exchange ---------------------------------------------------
|
| 189 |
+
// Atomically replaces `*obj` with `value` and returns the previous value of `*obj`.
|
| 190 |
+
|
| 191 |
+
static inline int
|
| 192 |
+
_Py_atomic_exchange_int(int *obj, int value);
|
| 193 |
+
|
| 194 |
+
static inline int8_t
|
| 195 |
+
_Py_atomic_exchange_int8(int8_t *obj, int8_t value);
|
| 196 |
+
|
| 197 |
+
static inline int16_t
|
| 198 |
+
_Py_atomic_exchange_int16(int16_t *obj, int16_t value);
|
| 199 |
+
|
| 200 |
+
static inline int32_t
|
| 201 |
+
_Py_atomic_exchange_int32(int32_t *obj, int32_t value);
|
| 202 |
+
|
| 203 |
+
static inline int64_t
|
| 204 |
+
_Py_atomic_exchange_int64(int64_t *obj, int64_t value);
|
| 205 |
+
|
| 206 |
+
static inline intptr_t
|
| 207 |
+
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value);
|
| 208 |
+
|
| 209 |
+
static inline unsigned int
|
| 210 |
+
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value);
|
| 211 |
+
|
| 212 |
+
static inline uint8_t
|
| 213 |
+
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value);
|
| 214 |
+
|
| 215 |
+
static inline uint16_t
|
| 216 |
+
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value);
|
| 217 |
+
|
| 218 |
+
static inline uint32_t
|
| 219 |
+
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value);
|
| 220 |
+
|
| 221 |
+
static inline uint64_t
|
| 222 |
+
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value);
|
| 223 |
+
|
| 224 |
+
static inline uintptr_t
|
| 225 |
+
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value);
|
| 226 |
+
|
| 227 |
+
static inline Py_ssize_t
|
| 228 |
+
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value);
|
| 229 |
+
|
| 230 |
+
static inline void *
|
| 231 |
+
_Py_atomic_exchange_ptr(void *obj, void *value);
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
// --- _Py_atomic_and --------------------------------------------------------
|
| 235 |
+
// Performs `*obj &= value` atomically and returns the previous value of `*obj`.
|
| 236 |
+
|
| 237 |
+
static inline uint8_t
|
| 238 |
+
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value);
|
| 239 |
+
|
| 240 |
+
static inline uint16_t
|
| 241 |
+
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value);
|
| 242 |
+
|
| 243 |
+
static inline uint32_t
|
| 244 |
+
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value);
|
| 245 |
+
|
| 246 |
+
static inline uint64_t
|
| 247 |
+
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value);
|
| 248 |
+
|
| 249 |
+
static inline uintptr_t
|
| 250 |
+
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value);
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
// --- _Py_atomic_or ---------------------------------------------------------
|
| 254 |
+
// Performs `*obj |= value` atomically and returns the previous value of `*obj`.
|
| 255 |
+
|
| 256 |
+
static inline uint8_t
|
| 257 |
+
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value);
|
| 258 |
+
|
| 259 |
+
static inline uint16_t
|
| 260 |
+
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value);
|
| 261 |
+
|
| 262 |
+
static inline uint32_t
|
| 263 |
+
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value);
|
| 264 |
+
|
| 265 |
+
static inline uint64_t
|
| 266 |
+
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value);
|
| 267 |
+
|
| 268 |
+
static inline uintptr_t
|
| 269 |
+
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value);
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
// --- _Py_atomic_load -------------------------------------------------------
|
| 273 |
+
// Atomically loads `*obj` (sequential consistency)
|
| 274 |
+
|
| 275 |
+
static inline int
|
| 276 |
+
_Py_atomic_load_int(const int *obj);
|
| 277 |
+
|
| 278 |
+
static inline int8_t
|
| 279 |
+
_Py_atomic_load_int8(const int8_t *obj);
|
| 280 |
+
|
| 281 |
+
static inline int16_t
|
| 282 |
+
_Py_atomic_load_int16(const int16_t *obj);
|
| 283 |
+
|
| 284 |
+
static inline int32_t
|
| 285 |
+
_Py_atomic_load_int32(const int32_t *obj);
|
| 286 |
+
|
| 287 |
+
static inline int64_t
|
| 288 |
+
_Py_atomic_load_int64(const int64_t *obj);
|
| 289 |
+
|
| 290 |
+
static inline intptr_t
|
| 291 |
+
_Py_atomic_load_intptr(const intptr_t *obj);
|
| 292 |
+
|
| 293 |
+
static inline uint8_t
|
| 294 |
+
_Py_atomic_load_uint8(const uint8_t *obj);
|
| 295 |
+
|
| 296 |
+
static inline uint16_t
|
| 297 |
+
_Py_atomic_load_uint16(const uint16_t *obj);
|
| 298 |
+
|
| 299 |
+
static inline uint32_t
|
| 300 |
+
_Py_atomic_load_uint32(const uint32_t *obj);
|
| 301 |
+
|
| 302 |
+
static inline uint64_t
|
| 303 |
+
_Py_atomic_load_uint64(const uint64_t *obj);
|
| 304 |
+
|
| 305 |
+
static inline uintptr_t
|
| 306 |
+
_Py_atomic_load_uintptr(const uintptr_t *obj);
|
| 307 |
+
|
| 308 |
+
static inline unsigned int
|
| 309 |
+
_Py_atomic_load_uint(const unsigned int *obj);
|
| 310 |
+
|
| 311 |
+
static inline Py_ssize_t
|
| 312 |
+
_Py_atomic_load_ssize(const Py_ssize_t *obj);
|
| 313 |
+
|
| 314 |
+
static inline void *
|
| 315 |
+
_Py_atomic_load_ptr(const void *obj);
|
| 316 |
+
|
| 317 |
+
|
| 318 |
+
// --- _Py_atomic_load_relaxed -----------------------------------------------
|
| 319 |
+
// Loads `*obj` (relaxed consistency, i.e., no ordering)
|
| 320 |
+
|
| 321 |
+
static inline int
|
| 322 |
+
_Py_atomic_load_int_relaxed(const int *obj);
|
| 323 |
+
|
| 324 |
+
static inline int8_t
|
| 325 |
+
_Py_atomic_load_int8_relaxed(const int8_t *obj);
|
| 326 |
+
|
| 327 |
+
static inline int16_t
|
| 328 |
+
_Py_atomic_load_int16_relaxed(const int16_t *obj);
|
| 329 |
+
|
| 330 |
+
static inline int32_t
|
| 331 |
+
_Py_atomic_load_int32_relaxed(const int32_t *obj);
|
| 332 |
+
|
| 333 |
+
static inline int64_t
|
| 334 |
+
_Py_atomic_load_int64_relaxed(const int64_t *obj);
|
| 335 |
+
|
| 336 |
+
static inline intptr_t
|
| 337 |
+
_Py_atomic_load_intptr_relaxed(const intptr_t *obj);
|
| 338 |
+
|
| 339 |
+
static inline uint8_t
|
| 340 |
+
_Py_atomic_load_uint8_relaxed(const uint8_t *obj);
|
| 341 |
+
|
| 342 |
+
static inline uint16_t
|
| 343 |
+
_Py_atomic_load_uint16_relaxed(const uint16_t *obj);
|
| 344 |
+
|
| 345 |
+
static inline uint32_t
|
| 346 |
+
_Py_atomic_load_uint32_relaxed(const uint32_t *obj);
|
| 347 |
+
|
| 348 |
+
static inline uint64_t
|
| 349 |
+
_Py_atomic_load_uint64_relaxed(const uint64_t *obj);
|
| 350 |
+
|
| 351 |
+
static inline uintptr_t
|
| 352 |
+
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj);
|
| 353 |
+
|
| 354 |
+
static inline unsigned int
|
| 355 |
+
_Py_atomic_load_uint_relaxed(const unsigned int *obj);
|
| 356 |
+
|
| 357 |
+
static inline Py_ssize_t
|
| 358 |
+
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj);
|
| 359 |
+
|
| 360 |
+
static inline void *
|
| 361 |
+
_Py_atomic_load_ptr_relaxed(const void *obj);
|
| 362 |
+
|
| 363 |
+
static inline unsigned long long
|
| 364 |
+
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj);
|
| 365 |
+
|
| 366 |
+
// --- _Py_atomic_store ------------------------------------------------------
|
| 367 |
+
// Atomically performs `*obj = value` (sequential consistency)
|
| 368 |
+
|
| 369 |
+
static inline void
|
| 370 |
+
_Py_atomic_store_int(int *obj, int value);
|
| 371 |
+
|
| 372 |
+
static inline void
|
| 373 |
+
_Py_atomic_store_int8(int8_t *obj, int8_t value);
|
| 374 |
+
|
| 375 |
+
static inline void
|
| 376 |
+
_Py_atomic_store_int16(int16_t *obj, int16_t value);
|
| 377 |
+
|
| 378 |
+
static inline void
|
| 379 |
+
_Py_atomic_store_int32(int32_t *obj, int32_t value);
|
| 380 |
+
|
| 381 |
+
static inline void
|
| 382 |
+
_Py_atomic_store_int64(int64_t *obj, int64_t value);
|
| 383 |
+
|
| 384 |
+
static inline void
|
| 385 |
+
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value);
|
| 386 |
+
|
| 387 |
+
static inline void
|
| 388 |
+
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value);
|
| 389 |
+
|
| 390 |
+
static inline void
|
| 391 |
+
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value);
|
| 392 |
+
|
| 393 |
+
static inline void
|
| 394 |
+
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value);
|
| 395 |
+
|
| 396 |
+
static inline void
|
| 397 |
+
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value);
|
| 398 |
+
|
| 399 |
+
static inline void
|
| 400 |
+
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value);
|
| 401 |
+
|
| 402 |
+
static inline void
|
| 403 |
+
_Py_atomic_store_uint(unsigned int *obj, unsigned int value);
|
| 404 |
+
|
| 405 |
+
static inline void
|
| 406 |
+
_Py_atomic_store_ptr(void *obj, void *value);
|
| 407 |
+
|
| 408 |
+
static inline void
|
| 409 |
+
_Py_atomic_store_ssize(Py_ssize_t* obj, Py_ssize_t value);
|
| 410 |
+
|
| 411 |
+
|
| 412 |
+
// --- _Py_atomic_store_relaxed ----------------------------------------------
|
| 413 |
+
// Stores `*obj = value` (relaxed consistency, i.e., no ordering)
|
| 414 |
+
|
| 415 |
+
static inline void
|
| 416 |
+
_Py_atomic_store_int_relaxed(int *obj, int value);
|
| 417 |
+
|
| 418 |
+
static inline void
|
| 419 |
+
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value);
|
| 420 |
+
|
| 421 |
+
static inline void
|
| 422 |
+
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value);
|
| 423 |
+
|
| 424 |
+
static inline void
|
| 425 |
+
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value);
|
| 426 |
+
|
| 427 |
+
static inline void
|
| 428 |
+
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value);
|
| 429 |
+
|
| 430 |
+
static inline void
|
| 431 |
+
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value);
|
| 432 |
+
|
| 433 |
+
static inline void
|
| 434 |
+
_Py_atomic_store_uint8_relaxed(uint8_t* obj, uint8_t value);
|
| 435 |
+
|
| 436 |
+
static inline void
|
| 437 |
+
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value);
|
| 438 |
+
|
| 439 |
+
static inline void
|
| 440 |
+
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value);
|
| 441 |
+
|
| 442 |
+
static inline void
|
| 443 |
+
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value);
|
| 444 |
+
|
| 445 |
+
static inline void
|
| 446 |
+
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value);
|
| 447 |
+
|
| 448 |
+
static inline void
|
| 449 |
+
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value);
|
| 450 |
+
|
| 451 |
+
static inline void
|
| 452 |
+
_Py_atomic_store_ptr_relaxed(void *obj, void *value);
|
| 453 |
+
|
| 454 |
+
static inline void
|
| 455 |
+
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value);
|
| 456 |
+
|
| 457 |
+
static inline void
|
| 458 |
+
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
|
| 459 |
+
unsigned long long value);
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
|
| 463 |
+
|
| 464 |
+
// Loads `*obj` (acquire operation)
|
| 465 |
+
static inline void *
|
| 466 |
+
_Py_atomic_load_ptr_acquire(const void *obj);
|
| 467 |
+
|
| 468 |
+
static inline uintptr_t
|
| 469 |
+
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj);
|
| 470 |
+
|
| 471 |
+
// Stores `*obj = value` (release operation)
|
| 472 |
+
static inline void
|
| 473 |
+
_Py_atomic_store_ptr_release(void *obj, void *value);
|
| 474 |
+
|
| 475 |
+
static inline void
|
| 476 |
+
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value);
|
| 477 |
+
|
| 478 |
+
static inline void
|
| 479 |
+
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value);
|
| 480 |
+
|
| 481 |
+
static inline void
|
| 482 |
+
_Py_atomic_store_int_release(int *obj, int value);
|
| 483 |
+
|
| 484 |
+
static inline int
|
| 485 |
+
_Py_atomic_load_int_acquire(const int *obj);
|
| 486 |
+
|
| 487 |
+
static inline void
|
| 488 |
+
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value);
|
| 489 |
+
|
| 490 |
+
static inline void
|
| 491 |
+
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value);
|
| 492 |
+
|
| 493 |
+
static inline uint64_t
|
| 494 |
+
_Py_atomic_load_uint64_acquire(const uint64_t *obj);
|
| 495 |
+
|
| 496 |
+
static inline uint32_t
|
| 497 |
+
_Py_atomic_load_uint32_acquire(const uint32_t *obj);
|
| 498 |
+
|
| 499 |
+
static inline Py_ssize_t
|
| 500 |
+
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj);
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
|
| 505 |
+
// --- _Py_atomic_fence ------------------------------------------------------
|
| 506 |
+
|
| 507 |
+
// Sequential consistency fence. C11 fences have complex semantics. When
|
| 508 |
+
// possible, use the atomic operations on variables defined above, which
|
| 509 |
+
// generally do not require explicit use of a fence.
|
| 510 |
+
// See https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence
|
| 511 |
+
static inline void _Py_atomic_fence_seq_cst(void);
|
| 512 |
+
|
| 513 |
+
// Acquire fence
|
| 514 |
+
static inline void _Py_atomic_fence_acquire(void);
|
| 515 |
+
|
| 516 |
+
// Release fence
|
| 517 |
+
static inline void _Py_atomic_fence_release(void);
|
| 518 |
+
|
| 519 |
+
|
| 520 |
+
#ifndef _Py_USE_GCC_BUILTIN_ATOMICS
|
| 521 |
+
# if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
| 522 |
+
# define _Py_USE_GCC_BUILTIN_ATOMICS 1
|
| 523 |
+
# elif defined(__clang__)
|
| 524 |
+
# if __has_builtin(__atomic_load)
|
| 525 |
+
# define _Py_USE_GCC_BUILTIN_ATOMICS 1
|
| 526 |
+
# endif
|
| 527 |
+
# endif
|
| 528 |
+
#endif
|
| 529 |
+
|
| 530 |
+
#if _Py_USE_GCC_BUILTIN_ATOMICS
|
| 531 |
+
# define Py_ATOMIC_GCC_H
|
| 532 |
+
# include "pyatomic_gcc.h"
|
| 533 |
+
# undef Py_ATOMIC_GCC_H
|
| 534 |
+
#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
|
| 535 |
+
# define Py_ATOMIC_STD_H
|
| 536 |
+
# include "pyatomic_std.h"
|
| 537 |
+
# undef Py_ATOMIC_STD_H
|
| 538 |
+
#elif defined(_MSC_VER)
|
| 539 |
+
# define Py_ATOMIC_MSC_H
|
| 540 |
+
# include "pyatomic_msc.h"
|
| 541 |
+
# undef Py_ATOMIC_MSC_H
|
| 542 |
+
#else
|
| 543 |
+
# error "no available pyatomic implementation for this platform/compiler"
|
| 544 |
+
#endif
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
// --- aliases ---------------------------------------------------------------
|
| 548 |
+
|
| 549 |
+
#if SIZEOF_LONG == 8
|
| 550 |
+
# define _Py_atomic_load_ulong(p) \
|
| 551 |
+
_Py_atomic_load_uint64((uint64_t *)p)
|
| 552 |
+
# define _Py_atomic_load_ulong_relaxed(p) \
|
| 553 |
+
_Py_atomic_load_uint64_relaxed((uint64_t *)p)
|
| 554 |
+
# define _Py_atomic_store_ulong(p, v) \
|
| 555 |
+
_Py_atomic_store_uint64((uint64_t *)p, v)
|
| 556 |
+
# define _Py_atomic_store_ulong_relaxed(p, v) \
|
| 557 |
+
_Py_atomic_store_uint64_relaxed((uint64_t *)p, v)
|
| 558 |
+
#elif SIZEOF_LONG == 4
|
| 559 |
+
# define _Py_atomic_load_ulong(p) \
|
| 560 |
+
_Py_atomic_load_uint32((uint32_t *)p)
|
| 561 |
+
# define _Py_atomic_load_ulong_relaxed(p) \
|
| 562 |
+
_Py_atomic_load_uint32_relaxed((uint32_t *)p)
|
| 563 |
+
# define _Py_atomic_store_ulong(p, v) \
|
| 564 |
+
_Py_atomic_store_uint32((uint32_t *)p, v)
|
| 565 |
+
# define _Py_atomic_store_ulong_relaxed(p, v) \
|
| 566 |
+
_Py_atomic_store_uint32_relaxed((uint32_t *)p, v)
|
| 567 |
+
#else
|
| 568 |
+
# error "long must be 4 or 8 bytes in size"
|
| 569 |
+
#endif // SIZEOF_LONG
|
Include/cpython/pyatomic_gcc.h
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This is the implementation of Python atomic operations using GCC's built-in
|
| 2 |
+
// functions that match the C+11 memory model. This implementation is preferred
|
| 3 |
+
// for GCC compatible compilers, such as Clang. These functions are available
|
| 4 |
+
// in GCC 4.8+ without needing to compile with --std=c11 or --std=gnu11.
|
| 5 |
+
|
| 6 |
+
#ifndef Py_ATOMIC_GCC_H
|
| 7 |
+
# error "this header file must not be included directly"
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
// --- _Py_atomic_add --------------------------------------------------------
|
| 12 |
+
|
| 13 |
+
static inline int
|
| 14 |
+
_Py_atomic_add_int(int *obj, int value)
|
| 15 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 16 |
+
|
| 17 |
+
static inline int8_t
|
| 18 |
+
_Py_atomic_add_int8(int8_t *obj, int8_t value)
|
| 19 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 20 |
+
|
| 21 |
+
static inline int16_t
|
| 22 |
+
_Py_atomic_add_int16(int16_t *obj, int16_t value)
|
| 23 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 24 |
+
|
| 25 |
+
static inline int32_t
|
| 26 |
+
_Py_atomic_add_int32(int32_t *obj, int32_t value)
|
| 27 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 28 |
+
|
| 29 |
+
static inline int64_t
|
| 30 |
+
_Py_atomic_add_int64(int64_t *obj, int64_t value)
|
| 31 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 32 |
+
|
| 33 |
+
static inline intptr_t
|
| 34 |
+
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
|
| 35 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 36 |
+
|
| 37 |
+
static inline unsigned int
|
| 38 |
+
_Py_atomic_add_uint(unsigned int *obj, unsigned int value)
|
| 39 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 40 |
+
|
| 41 |
+
static inline uint8_t
|
| 42 |
+
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
|
| 43 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 44 |
+
|
| 45 |
+
static inline uint16_t
|
| 46 |
+
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
|
| 47 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 48 |
+
|
| 49 |
+
static inline uint32_t
|
| 50 |
+
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
|
| 51 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 52 |
+
|
| 53 |
+
static inline uint64_t
|
| 54 |
+
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
|
| 55 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 56 |
+
|
| 57 |
+
static inline uintptr_t
|
| 58 |
+
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
|
| 59 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 60 |
+
|
| 61 |
+
static inline Py_ssize_t
|
| 62 |
+
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 63 |
+
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
// --- _Py_atomic_compare_exchange -------------------------------------------
|
| 67 |
+
|
| 68 |
+
static inline int
|
| 69 |
+
_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired)
|
| 70 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 71 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 72 |
+
|
| 73 |
+
static inline int
|
| 74 |
+
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired)
|
| 75 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 76 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 77 |
+
|
| 78 |
+
static inline int
|
| 79 |
+
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired)
|
| 80 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 81 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 82 |
+
|
| 83 |
+
static inline int
|
| 84 |
+
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired)
|
| 85 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 86 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 87 |
+
|
| 88 |
+
static inline int
|
| 89 |
+
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired)
|
| 90 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 91 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 92 |
+
|
| 93 |
+
static inline int
|
| 94 |
+
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
|
| 95 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 96 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 97 |
+
|
| 98 |
+
static inline int
|
| 99 |
+
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired)
|
| 100 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 101 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 102 |
+
|
| 103 |
+
static inline int
|
| 104 |
+
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired)
|
| 105 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 106 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 107 |
+
|
| 108 |
+
static inline int
|
| 109 |
+
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired)
|
| 110 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 111 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 112 |
+
|
| 113 |
+
static inline int
|
| 114 |
+
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired)
|
| 115 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 116 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 117 |
+
|
| 118 |
+
static inline int
|
| 119 |
+
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired)
|
| 120 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 121 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 122 |
+
|
| 123 |
+
static inline int
|
| 124 |
+
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired)
|
| 125 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 126 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 127 |
+
|
| 128 |
+
static inline int
|
| 129 |
+
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired)
|
| 130 |
+
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
|
| 131 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 132 |
+
|
| 133 |
+
static inline int
|
| 134 |
+
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired)
|
| 135 |
+
{ return __atomic_compare_exchange_n((void **)obj, (void **)expected, desired, 0,
|
| 136 |
+
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
// --- _Py_atomic_exchange ---------------------------------------------------
|
| 140 |
+
|
| 141 |
+
static inline int
|
| 142 |
+
_Py_atomic_exchange_int(int *obj, int value)
|
| 143 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 144 |
+
|
| 145 |
+
static inline int8_t
|
| 146 |
+
_Py_atomic_exchange_int8(int8_t *obj, int8_t value)
|
| 147 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 148 |
+
|
| 149 |
+
static inline int16_t
|
| 150 |
+
_Py_atomic_exchange_int16(int16_t *obj, int16_t value)
|
| 151 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 152 |
+
|
| 153 |
+
static inline int32_t
|
| 154 |
+
_Py_atomic_exchange_int32(int32_t *obj, int32_t value)
|
| 155 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 156 |
+
|
| 157 |
+
static inline int64_t
|
| 158 |
+
_Py_atomic_exchange_int64(int64_t *obj, int64_t value)
|
| 159 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 160 |
+
|
| 161 |
+
static inline intptr_t
|
| 162 |
+
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
|
| 163 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 164 |
+
|
| 165 |
+
static inline unsigned int
|
| 166 |
+
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
|
| 167 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 168 |
+
|
| 169 |
+
static inline uint8_t
|
| 170 |
+
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
|
| 171 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 172 |
+
|
| 173 |
+
static inline uint16_t
|
| 174 |
+
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
|
| 175 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 176 |
+
|
| 177 |
+
static inline uint32_t
|
| 178 |
+
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
|
| 179 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 180 |
+
|
| 181 |
+
static inline uint64_t
|
| 182 |
+
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
|
| 183 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 184 |
+
|
| 185 |
+
static inline uintptr_t
|
| 186 |
+
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
|
| 187 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 188 |
+
|
| 189 |
+
static inline Py_ssize_t
|
| 190 |
+
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 191 |
+
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 192 |
+
|
| 193 |
+
static inline void *
|
| 194 |
+
_Py_atomic_exchange_ptr(void *obj, void *value)
|
| 195 |
+
{ return __atomic_exchange_n((void **)obj, value, __ATOMIC_SEQ_CST); }
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
// --- _Py_atomic_and --------------------------------------------------------
|
| 199 |
+
|
| 200 |
+
static inline uint8_t
|
| 201 |
+
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
|
| 202 |
+
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
|
| 203 |
+
|
| 204 |
+
static inline uint16_t
|
| 205 |
+
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
|
| 206 |
+
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
|
| 207 |
+
|
| 208 |
+
static inline uint32_t
|
| 209 |
+
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
|
| 210 |
+
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
|
| 211 |
+
|
| 212 |
+
static inline uint64_t
|
| 213 |
+
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
|
| 214 |
+
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
|
| 215 |
+
|
| 216 |
+
static inline uintptr_t
|
| 217 |
+
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
|
| 218 |
+
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
// --- _Py_atomic_or ---------------------------------------------------------
|
| 222 |
+
|
| 223 |
+
static inline uint8_t
|
| 224 |
+
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
|
| 225 |
+
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
|
| 226 |
+
|
| 227 |
+
static inline uint16_t
|
| 228 |
+
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
|
| 229 |
+
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
|
| 230 |
+
|
| 231 |
+
static inline uint32_t
|
| 232 |
+
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
|
| 233 |
+
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
|
| 234 |
+
|
| 235 |
+
static inline uint64_t
|
| 236 |
+
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
|
| 237 |
+
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
|
| 238 |
+
|
| 239 |
+
static inline uintptr_t
|
| 240 |
+
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
|
| 241 |
+
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
// --- _Py_atomic_load -------------------------------------------------------
|
| 245 |
+
|
| 246 |
+
static inline int
|
| 247 |
+
_Py_atomic_load_int(const int *obj)
|
| 248 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 249 |
+
|
| 250 |
+
static inline int8_t
|
| 251 |
+
_Py_atomic_load_int8(const int8_t *obj)
|
| 252 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 253 |
+
|
| 254 |
+
static inline int16_t
|
| 255 |
+
_Py_atomic_load_int16(const int16_t *obj)
|
| 256 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 257 |
+
|
| 258 |
+
static inline int32_t
|
| 259 |
+
_Py_atomic_load_int32(const int32_t *obj)
|
| 260 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 261 |
+
|
| 262 |
+
static inline int64_t
|
| 263 |
+
_Py_atomic_load_int64(const int64_t *obj)
|
| 264 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 265 |
+
|
| 266 |
+
static inline intptr_t
|
| 267 |
+
_Py_atomic_load_intptr(const intptr_t *obj)
|
| 268 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 269 |
+
|
| 270 |
+
static inline uint8_t
|
| 271 |
+
_Py_atomic_load_uint8(const uint8_t *obj)
|
| 272 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 273 |
+
|
| 274 |
+
static inline uint16_t
|
| 275 |
+
_Py_atomic_load_uint16(const uint16_t *obj)
|
| 276 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 277 |
+
|
| 278 |
+
static inline uint32_t
|
| 279 |
+
_Py_atomic_load_uint32(const uint32_t *obj)
|
| 280 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 281 |
+
|
| 282 |
+
static inline uint64_t
|
| 283 |
+
_Py_atomic_load_uint64(const uint64_t *obj)
|
| 284 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 285 |
+
|
| 286 |
+
static inline uintptr_t
|
| 287 |
+
_Py_atomic_load_uintptr(const uintptr_t *obj)
|
| 288 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 289 |
+
|
| 290 |
+
static inline unsigned int
|
| 291 |
+
_Py_atomic_load_uint(const unsigned int *obj)
|
| 292 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 293 |
+
|
| 294 |
+
static inline Py_ssize_t
|
| 295 |
+
_Py_atomic_load_ssize(const Py_ssize_t *obj)
|
| 296 |
+
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
|
| 297 |
+
|
| 298 |
+
static inline void *
|
| 299 |
+
_Py_atomic_load_ptr(const void *obj)
|
| 300 |
+
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_SEQ_CST); }
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
// --- _Py_atomic_load_relaxed -----------------------------------------------
|
| 304 |
+
|
| 305 |
+
static inline int
|
| 306 |
+
_Py_atomic_load_int_relaxed(const int *obj)
|
| 307 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 308 |
+
|
| 309 |
+
static inline int8_t
|
| 310 |
+
_Py_atomic_load_int8_relaxed(const int8_t *obj)
|
| 311 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 312 |
+
|
| 313 |
+
static inline int16_t
|
| 314 |
+
_Py_atomic_load_int16_relaxed(const int16_t *obj)
|
| 315 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 316 |
+
|
| 317 |
+
static inline int32_t
|
| 318 |
+
_Py_atomic_load_int32_relaxed(const int32_t *obj)
|
| 319 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 320 |
+
|
| 321 |
+
static inline int64_t
|
| 322 |
+
_Py_atomic_load_int64_relaxed(const int64_t *obj)
|
| 323 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 324 |
+
|
| 325 |
+
static inline intptr_t
|
| 326 |
+
_Py_atomic_load_intptr_relaxed(const intptr_t *obj)
|
| 327 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 328 |
+
|
| 329 |
+
static inline uint8_t
|
| 330 |
+
_Py_atomic_load_uint8_relaxed(const uint8_t *obj)
|
| 331 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 332 |
+
|
| 333 |
+
static inline uint16_t
|
| 334 |
+
_Py_atomic_load_uint16_relaxed(const uint16_t *obj)
|
| 335 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 336 |
+
|
| 337 |
+
static inline uint32_t
|
| 338 |
+
_Py_atomic_load_uint32_relaxed(const uint32_t *obj)
|
| 339 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 340 |
+
|
| 341 |
+
static inline uint64_t
|
| 342 |
+
_Py_atomic_load_uint64_relaxed(const uint64_t *obj)
|
| 343 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 344 |
+
|
| 345 |
+
static inline uintptr_t
|
| 346 |
+
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
|
| 347 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 348 |
+
|
| 349 |
+
static inline unsigned int
|
| 350 |
+
_Py_atomic_load_uint_relaxed(const unsigned int *obj)
|
| 351 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 352 |
+
|
| 353 |
+
static inline Py_ssize_t
|
| 354 |
+
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
|
| 355 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 356 |
+
|
| 357 |
+
static inline void *
|
| 358 |
+
_Py_atomic_load_ptr_relaxed(const void *obj)
|
| 359 |
+
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_RELAXED); }
|
| 360 |
+
|
| 361 |
+
static inline unsigned long long
|
| 362 |
+
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
|
| 363 |
+
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
// --- _Py_atomic_store ------------------------------------------------------
|
| 367 |
+
|
| 368 |
+
static inline void
|
| 369 |
+
_Py_atomic_store_int(int *obj, int value)
|
| 370 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 371 |
+
|
| 372 |
+
static inline void
|
| 373 |
+
_Py_atomic_store_int8(int8_t *obj, int8_t value)
|
| 374 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 375 |
+
|
| 376 |
+
static inline void
|
| 377 |
+
_Py_atomic_store_int16(int16_t *obj, int16_t value)
|
| 378 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 379 |
+
|
| 380 |
+
static inline void
|
| 381 |
+
_Py_atomic_store_int32(int32_t *obj, int32_t value)
|
| 382 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 383 |
+
|
| 384 |
+
static inline void
|
| 385 |
+
_Py_atomic_store_int64(int64_t *obj, int64_t value)
|
| 386 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 387 |
+
|
| 388 |
+
static inline void
|
| 389 |
+
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
|
| 390 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 391 |
+
|
| 392 |
+
static inline void
|
| 393 |
+
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
|
| 394 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 395 |
+
|
| 396 |
+
static inline void
|
| 397 |
+
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
|
| 398 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 399 |
+
|
| 400 |
+
static inline void
|
| 401 |
+
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
|
| 402 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 403 |
+
|
| 404 |
+
static inline void
|
| 405 |
+
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
|
| 406 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 407 |
+
|
| 408 |
+
static inline void
|
| 409 |
+
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
|
| 410 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 411 |
+
|
| 412 |
+
static inline void
|
| 413 |
+
_Py_atomic_store_uint(unsigned int *obj, unsigned int value)
|
| 414 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 415 |
+
|
| 416 |
+
static inline void
|
| 417 |
+
_Py_atomic_store_ptr(void *obj, void *value)
|
| 418 |
+
{ __atomic_store_n((void **)obj, value, __ATOMIC_SEQ_CST); }
|
| 419 |
+
|
| 420 |
+
static inline void
|
| 421 |
+
_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 422 |
+
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
// --- _Py_atomic_store_relaxed ----------------------------------------------
|
| 426 |
+
|
| 427 |
+
static inline void
|
| 428 |
+
_Py_atomic_store_int_relaxed(int *obj, int value)
|
| 429 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 430 |
+
|
| 431 |
+
static inline void
|
| 432 |
+
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
|
| 433 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 434 |
+
|
| 435 |
+
static inline void
|
| 436 |
+
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
|
| 437 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 438 |
+
|
| 439 |
+
static inline void
|
| 440 |
+
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
|
| 441 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 442 |
+
|
| 443 |
+
static inline void
|
| 444 |
+
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
|
| 445 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 446 |
+
|
| 447 |
+
static inline void
|
| 448 |
+
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
|
| 449 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 450 |
+
|
| 451 |
+
static inline void
|
| 452 |
+
_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
|
| 453 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 454 |
+
|
| 455 |
+
static inline void
|
| 456 |
+
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
|
| 457 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 458 |
+
|
| 459 |
+
static inline void
|
| 460 |
+
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
|
| 461 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 462 |
+
|
| 463 |
+
static inline void
|
| 464 |
+
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
|
| 465 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 466 |
+
|
| 467 |
+
static inline void
|
| 468 |
+
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
|
| 469 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 470 |
+
|
| 471 |
+
static inline void
|
| 472 |
+
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
|
| 473 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 474 |
+
|
| 475 |
+
static inline void
|
| 476 |
+
_Py_atomic_store_ptr_relaxed(void *obj, void *value)
|
| 477 |
+
{ __atomic_store_n((void **)obj, value, __ATOMIC_RELAXED); }
|
| 478 |
+
|
| 479 |
+
static inline void
|
| 480 |
+
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
|
| 481 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 482 |
+
|
| 483 |
+
static inline void
|
| 484 |
+
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
|
| 485 |
+
unsigned long long value)
|
| 486 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
|
| 490 |
+
|
| 491 |
+
static inline void *
|
| 492 |
+
_Py_atomic_load_ptr_acquire(const void *obj)
|
| 493 |
+
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_ACQUIRE); }
|
| 494 |
+
|
| 495 |
+
static inline uintptr_t
|
| 496 |
+
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
|
| 497 |
+
{ return (uintptr_t)__atomic_load_n(obj, __ATOMIC_ACQUIRE); }
|
| 498 |
+
|
| 499 |
+
static inline void
|
| 500 |
+
_Py_atomic_store_ptr_release(void *obj, void *value)
|
| 501 |
+
{ __atomic_store_n((void **)obj, value, __ATOMIC_RELEASE); }
|
| 502 |
+
|
| 503 |
+
static inline void
|
| 504 |
+
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
|
| 505 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
|
| 506 |
+
|
| 507 |
+
static inline void
|
| 508 |
+
_Py_atomic_store_int_release(int *obj, int value)
|
| 509 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
|
| 510 |
+
|
| 511 |
+
static inline void
|
| 512 |
+
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
|
| 513 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
|
| 514 |
+
|
| 515 |
+
static inline int
|
| 516 |
+
_Py_atomic_load_int_acquire(const int *obj)
|
| 517 |
+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
|
| 518 |
+
|
| 519 |
+
static inline void
|
| 520 |
+
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
|
| 521 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
|
| 522 |
+
|
| 523 |
+
static inline void
|
| 524 |
+
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
|
| 525 |
+
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
|
| 526 |
+
|
| 527 |
+
static inline uint64_t
|
| 528 |
+
_Py_atomic_load_uint64_acquire(const uint64_t *obj)
|
| 529 |
+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
|
| 530 |
+
|
| 531 |
+
static inline uint32_t
|
| 532 |
+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
|
| 533 |
+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
|
| 534 |
+
|
| 535 |
+
static inline Py_ssize_t
|
| 536 |
+
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
|
| 537 |
+
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
|
| 538 |
+
|
| 539 |
+
// --- _Py_atomic_fence ------------------------------------------------------
|
| 540 |
+
|
| 541 |
+
static inline void
|
| 542 |
+
_Py_atomic_fence_seq_cst(void)
|
| 543 |
+
{ __atomic_thread_fence(__ATOMIC_SEQ_CST); }
|
| 544 |
+
|
| 545 |
+
static inline void
|
| 546 |
+
_Py_atomic_fence_acquire(void)
|
| 547 |
+
{ __atomic_thread_fence(__ATOMIC_ACQUIRE); }
|
| 548 |
+
|
| 549 |
+
static inline void
|
| 550 |
+
_Py_atomic_fence_release(void)
|
| 551 |
+
{ __atomic_thread_fence(__ATOMIC_RELEASE); }
|
Include/cpython/pyatomic_msc.h
ADDED
|
@@ -0,0 +1,1095 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This is the implementation of Python atomic operations for MSVC if the
|
| 2 |
+
// compiler does not support C11 or C++11 atomics.
|
| 3 |
+
//
|
| 4 |
+
// MSVC intrinsics are defined on char, short, long, __int64, and pointer
|
| 5 |
+
// types. Note that long and int are both 32-bits even on 64-bit Windows,
|
| 6 |
+
// so operations on int are cast to long.
|
| 7 |
+
//
|
| 8 |
+
// The volatile keyword has additional memory ordering semantics on MSVC. On
|
| 9 |
+
// x86 and x86-64, volatile accesses have acquire-release semantics. On ARM64,
|
| 10 |
+
// volatile accesses behave like C11's memory_order_relaxed.
|
| 11 |
+
|
| 12 |
+
#ifndef Py_ATOMIC_MSC_H
|
| 13 |
+
# error "this header file must not be included directly"
|
| 14 |
+
#endif
|
| 15 |
+
|
| 16 |
+
#include <intrin.h>
|
| 17 |
+
|
| 18 |
+
#define _Py_atomic_ASSERT_ARG_TYPE(TYPE) \
|
| 19 |
+
Py_BUILD_ASSERT(sizeof(*obj) == sizeof(TYPE))
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
// --- _Py_atomic_add --------------------------------------------------------
|
| 23 |
+
|
| 24 |
+
static inline int8_t
|
| 25 |
+
_Py_atomic_add_int8(int8_t *obj, int8_t value)
|
| 26 |
+
{
|
| 27 |
+
_Py_atomic_ASSERT_ARG_TYPE(char);
|
| 28 |
+
return (int8_t)_InterlockedExchangeAdd8((volatile char *)obj, (char)value);
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
static inline int16_t
|
| 32 |
+
_Py_atomic_add_int16(int16_t *obj, int16_t value)
|
| 33 |
+
{
|
| 34 |
+
_Py_atomic_ASSERT_ARG_TYPE(short);
|
| 35 |
+
return (int16_t)_InterlockedExchangeAdd16((volatile short *)obj, (short)value);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
static inline int32_t
|
| 39 |
+
_Py_atomic_add_int32(int32_t *obj, int32_t value)
|
| 40 |
+
{
|
| 41 |
+
_Py_atomic_ASSERT_ARG_TYPE(long);
|
| 42 |
+
return (int32_t)_InterlockedExchangeAdd((volatile long *)obj, (long)value);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
static inline int64_t
|
| 46 |
+
_Py_atomic_add_int64(int64_t *obj, int64_t value)
|
| 47 |
+
{
|
| 48 |
+
#if defined(_M_X64) || defined(_M_ARM64)
|
| 49 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 50 |
+
return (int64_t)_InterlockedExchangeAdd64((volatile __int64 *)obj, (__int64)value);
|
| 51 |
+
#else
|
| 52 |
+
int64_t old_value = _Py_atomic_load_int64_relaxed(obj);
|
| 53 |
+
for (;;) {
|
| 54 |
+
int64_t new_value = old_value + value;
|
| 55 |
+
if (_Py_atomic_compare_exchange_int64(obj, &old_value, new_value)) {
|
| 56 |
+
return old_value;
|
| 57 |
+
}
|
| 58 |
+
}
|
| 59 |
+
#endif
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
static inline uint8_t
|
| 64 |
+
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
|
| 65 |
+
{
|
| 66 |
+
return (uint8_t)_Py_atomic_add_int8((int8_t *)obj, (int8_t)value);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
static inline uint16_t
|
| 70 |
+
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
|
| 71 |
+
{
|
| 72 |
+
return (uint16_t)_Py_atomic_add_int16((int16_t *)obj, (int16_t)value);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
static inline uint32_t
|
| 76 |
+
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
|
| 77 |
+
{
|
| 78 |
+
return (uint32_t)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
static inline int
|
| 82 |
+
_Py_atomic_add_int(int *obj, int value)
|
| 83 |
+
{
|
| 84 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 85 |
+
return (int)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
static inline unsigned int
|
| 89 |
+
_Py_atomic_add_uint(unsigned int *obj, unsigned int value)
|
| 90 |
+
{
|
| 91 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 92 |
+
return (unsigned int)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
static inline uint64_t
|
| 96 |
+
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
|
| 97 |
+
{
|
| 98 |
+
return (uint64_t)_Py_atomic_add_int64((int64_t *)obj, (int64_t)value);
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
static inline intptr_t
|
| 102 |
+
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
|
| 103 |
+
{
|
| 104 |
+
#if SIZEOF_VOID_P == 8
|
| 105 |
+
_Py_atomic_ASSERT_ARG_TYPE(int64_t);
|
| 106 |
+
return (intptr_t)_Py_atomic_add_int64((int64_t *)obj, (int64_t)value);
|
| 107 |
+
#else
|
| 108 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 109 |
+
return (intptr_t)_Py_atomic_add_int32((int32_t *)obj, (int32_t)value);
|
| 110 |
+
#endif
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
static inline uintptr_t
|
| 114 |
+
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
|
| 115 |
+
{
|
| 116 |
+
_Py_atomic_ASSERT_ARG_TYPE(intptr_t);
|
| 117 |
+
return (uintptr_t)_Py_atomic_add_intptr((intptr_t *)obj, (intptr_t)value);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
static inline Py_ssize_t
|
| 121 |
+
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 122 |
+
{
|
| 123 |
+
_Py_atomic_ASSERT_ARG_TYPE(intptr_t);
|
| 124 |
+
return (Py_ssize_t)_Py_atomic_add_intptr((intptr_t *)obj, (intptr_t)value);
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
// --- _Py_atomic_compare_exchange -------------------------------------------
|
| 129 |
+
|
| 130 |
+
static inline int
|
| 131 |
+
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t value)
|
| 132 |
+
{
|
| 133 |
+
_Py_atomic_ASSERT_ARG_TYPE(char);
|
| 134 |
+
int8_t initial = (int8_t)_InterlockedCompareExchange8(
|
| 135 |
+
(volatile char *)obj,
|
| 136 |
+
(char)value,
|
| 137 |
+
(char)*expected);
|
| 138 |
+
if (initial == *expected) {
|
| 139 |
+
return 1;
|
| 140 |
+
}
|
| 141 |
+
*expected = initial;
|
| 142 |
+
return 0;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
static inline int
|
| 146 |
+
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t value)
|
| 147 |
+
{
|
| 148 |
+
_Py_atomic_ASSERT_ARG_TYPE(short);
|
| 149 |
+
int16_t initial = (int16_t)_InterlockedCompareExchange16(
|
| 150 |
+
(volatile short *)obj,
|
| 151 |
+
(short)value,
|
| 152 |
+
(short)*expected);
|
| 153 |
+
if (initial == *expected) {
|
| 154 |
+
return 1;
|
| 155 |
+
}
|
| 156 |
+
*expected = initial;
|
| 157 |
+
return 0;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
static inline int
|
| 161 |
+
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t value)
|
| 162 |
+
{
|
| 163 |
+
_Py_atomic_ASSERT_ARG_TYPE(long);
|
| 164 |
+
int32_t initial = (int32_t)_InterlockedCompareExchange(
|
| 165 |
+
(volatile long *)obj,
|
| 166 |
+
(long)value,
|
| 167 |
+
(long)*expected);
|
| 168 |
+
if (initial == *expected) {
|
| 169 |
+
return 1;
|
| 170 |
+
}
|
| 171 |
+
*expected = initial;
|
| 172 |
+
return 0;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
static inline int
|
| 176 |
+
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t value)
|
| 177 |
+
{
|
| 178 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 179 |
+
int64_t initial = (int64_t)_InterlockedCompareExchange64(
|
| 180 |
+
(volatile __int64 *)obj,
|
| 181 |
+
(__int64)value,
|
| 182 |
+
(__int64)*expected);
|
| 183 |
+
if (initial == *expected) {
|
| 184 |
+
return 1;
|
| 185 |
+
}
|
| 186 |
+
*expected = initial;
|
| 187 |
+
return 0;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
static inline int
|
| 191 |
+
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value)
|
| 192 |
+
{
|
| 193 |
+
void *initial = _InterlockedCompareExchangePointer(
|
| 194 |
+
(void**)obj,
|
| 195 |
+
value,
|
| 196 |
+
*(void**)expected);
|
| 197 |
+
if (initial == *(void**)expected) {
|
| 198 |
+
return 1;
|
| 199 |
+
}
|
| 200 |
+
*(void**)expected = initial;
|
| 201 |
+
return 0;
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
static inline int
|
| 206 |
+
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t value)
|
| 207 |
+
{
|
| 208 |
+
return _Py_atomic_compare_exchange_int8((int8_t *)obj,
|
| 209 |
+
(int8_t *)expected,
|
| 210 |
+
(int8_t)value);
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
static inline int
|
| 214 |
+
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t value)
|
| 215 |
+
{
|
| 216 |
+
return _Py_atomic_compare_exchange_int16((int16_t *)obj,
|
| 217 |
+
(int16_t *)expected,
|
| 218 |
+
(int16_t)value);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
static inline int
|
| 222 |
+
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t value)
|
| 223 |
+
{
|
| 224 |
+
return _Py_atomic_compare_exchange_int32((int32_t *)obj,
|
| 225 |
+
(int32_t *)expected,
|
| 226 |
+
(int32_t)value);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
static inline int
|
| 230 |
+
_Py_atomic_compare_exchange_int(int *obj, int *expected, int value)
|
| 231 |
+
{
|
| 232 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 233 |
+
return _Py_atomic_compare_exchange_int32((int32_t *)obj,
|
| 234 |
+
(int32_t *)expected,
|
| 235 |
+
(int32_t)value);
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
static inline int
|
| 239 |
+
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int value)
|
| 240 |
+
{
|
| 241 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 242 |
+
return _Py_atomic_compare_exchange_int32((int32_t *)obj,
|
| 243 |
+
(int32_t *)expected,
|
| 244 |
+
(int32_t)value);
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
static inline int
|
| 248 |
+
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t value)
|
| 249 |
+
{
|
| 250 |
+
return _Py_atomic_compare_exchange_int64((int64_t *)obj,
|
| 251 |
+
(int64_t *)expected,
|
| 252 |
+
(int64_t)value);
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
static inline int
|
| 256 |
+
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t value)
|
| 257 |
+
{
|
| 258 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 259 |
+
return _Py_atomic_compare_exchange_ptr((void**)obj,
|
| 260 |
+
(void**)expected,
|
| 261 |
+
(void*)value);
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
static inline int
|
| 265 |
+
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t value)
|
| 266 |
+
{
|
| 267 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 268 |
+
return _Py_atomic_compare_exchange_ptr((void**)obj,
|
| 269 |
+
(void**)expected,
|
| 270 |
+
(void*)value);
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
static inline int
|
| 274 |
+
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t value)
|
| 275 |
+
{
|
| 276 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 277 |
+
return _Py_atomic_compare_exchange_ptr((void**)obj,
|
| 278 |
+
(void**)expected,
|
| 279 |
+
(void*)value);
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
// --- _Py_atomic_exchange ---------------------------------------------------
|
| 284 |
+
|
| 285 |
+
static inline int8_t
|
| 286 |
+
_Py_atomic_exchange_int8(int8_t *obj, int8_t value)
|
| 287 |
+
{
|
| 288 |
+
_Py_atomic_ASSERT_ARG_TYPE(char);
|
| 289 |
+
return (int8_t)_InterlockedExchange8((volatile char *)obj, (char)value);
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
static inline int16_t
|
| 293 |
+
_Py_atomic_exchange_int16(int16_t *obj, int16_t value)
|
| 294 |
+
{
|
| 295 |
+
_Py_atomic_ASSERT_ARG_TYPE(short);
|
| 296 |
+
return (int16_t)_InterlockedExchange16((volatile short *)obj, (short)value);
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
static inline int32_t
|
| 300 |
+
_Py_atomic_exchange_int32(int32_t *obj, int32_t value)
|
| 301 |
+
{
|
| 302 |
+
_Py_atomic_ASSERT_ARG_TYPE(long);
|
| 303 |
+
return (int32_t)_InterlockedExchange((volatile long *)obj, (long)value);
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
static inline int64_t
|
| 307 |
+
_Py_atomic_exchange_int64(int64_t *obj, int64_t value)
|
| 308 |
+
{
|
| 309 |
+
#if defined(_M_X64) || defined(_M_ARM64)
|
| 310 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 311 |
+
return (int64_t)_InterlockedExchange64((volatile __int64 *)obj, (__int64)value);
|
| 312 |
+
#else
|
| 313 |
+
int64_t old_value = _Py_atomic_load_int64_relaxed(obj);
|
| 314 |
+
for (;;) {
|
| 315 |
+
if (_Py_atomic_compare_exchange_int64(obj, &old_value, value)) {
|
| 316 |
+
return old_value;
|
| 317 |
+
}
|
| 318 |
+
}
|
| 319 |
+
#endif
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
static inline void*
|
| 323 |
+
_Py_atomic_exchange_ptr(void *obj, void *value)
|
| 324 |
+
{
|
| 325 |
+
return (void*)_InterlockedExchangePointer((void * volatile *)obj, (void *)value);
|
| 326 |
+
}
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
static inline uint8_t
|
| 330 |
+
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
|
| 331 |
+
{
|
| 332 |
+
return (uint8_t)_Py_atomic_exchange_int8((int8_t *)obj,
|
| 333 |
+
(int8_t)value);
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
static inline uint16_t
|
| 337 |
+
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
|
| 338 |
+
{
|
| 339 |
+
return (uint16_t)_Py_atomic_exchange_int16((int16_t *)obj,
|
| 340 |
+
(int16_t)value);
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
static inline uint32_t
|
| 344 |
+
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
|
| 345 |
+
{
|
| 346 |
+
return (uint32_t)_Py_atomic_exchange_int32((int32_t *)obj,
|
| 347 |
+
(int32_t)value);
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
static inline int
|
| 351 |
+
_Py_atomic_exchange_int(int *obj, int value)
|
| 352 |
+
{
|
| 353 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 354 |
+
return (int)_Py_atomic_exchange_int32((int32_t *)obj,
|
| 355 |
+
(int32_t)value);
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
static inline unsigned int
|
| 359 |
+
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
|
| 360 |
+
{
|
| 361 |
+
_Py_atomic_ASSERT_ARG_TYPE(int32_t);
|
| 362 |
+
return (unsigned int)_Py_atomic_exchange_int32((int32_t *)obj,
|
| 363 |
+
(int32_t)value);
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
static inline uint64_t
|
| 367 |
+
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
|
| 368 |
+
{
|
| 369 |
+
return (uint64_t)_Py_atomic_exchange_int64((int64_t *)obj,
|
| 370 |
+
(int64_t)value);
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
static inline intptr_t
|
| 374 |
+
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
|
| 375 |
+
{
|
| 376 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 377 |
+
return (intptr_t)_Py_atomic_exchange_ptr((void**)obj,
|
| 378 |
+
(void*)value);
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
static inline uintptr_t
|
| 382 |
+
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
|
| 383 |
+
{
|
| 384 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 385 |
+
return (uintptr_t)_Py_atomic_exchange_ptr((void**)obj,
|
| 386 |
+
(void*)value);
|
| 387 |
+
}
|
| 388 |
+
|
| 389 |
+
static inline Py_ssize_t
|
| 390 |
+
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 391 |
+
{
|
| 392 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 393 |
+
return (Py_ssize_t)_Py_atomic_exchange_ptr((void**)obj,
|
| 394 |
+
(void*)value);
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
|
| 398 |
+
// --- _Py_atomic_and --------------------------------------------------------
|
| 399 |
+
|
| 400 |
+
static inline uint8_t
|
| 401 |
+
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
|
| 402 |
+
{
|
| 403 |
+
_Py_atomic_ASSERT_ARG_TYPE(char);
|
| 404 |
+
return (uint8_t)_InterlockedAnd8((volatile char *)obj, (char)value);
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
static inline uint16_t
|
| 408 |
+
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
|
| 409 |
+
{
|
| 410 |
+
_Py_atomic_ASSERT_ARG_TYPE(short);
|
| 411 |
+
return (uint16_t)_InterlockedAnd16((volatile short *)obj, (short)value);
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
static inline uint32_t
|
| 415 |
+
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
|
| 416 |
+
{
|
| 417 |
+
_Py_atomic_ASSERT_ARG_TYPE(long);
|
| 418 |
+
return (uint32_t)_InterlockedAnd((volatile long *)obj, (long)value);
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
static inline uint64_t
|
| 422 |
+
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
|
| 423 |
+
{
|
| 424 |
+
#if defined(_M_X64) || defined(_M_ARM64)
|
| 425 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 426 |
+
return (uint64_t)_InterlockedAnd64((volatile __int64 *)obj, (__int64)value);
|
| 427 |
+
#else
|
| 428 |
+
uint64_t old_value = _Py_atomic_load_uint64_relaxed(obj);
|
| 429 |
+
for (;;) {
|
| 430 |
+
uint64_t new_value = old_value & value;
|
| 431 |
+
if (_Py_atomic_compare_exchange_uint64(obj, &old_value, new_value)) {
|
| 432 |
+
return old_value;
|
| 433 |
+
}
|
| 434 |
+
}
|
| 435 |
+
#endif
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
static inline uintptr_t
|
| 439 |
+
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
|
| 440 |
+
{
|
| 441 |
+
#if SIZEOF_VOID_P == 8
|
| 442 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint64_t);
|
| 443 |
+
return (uintptr_t)_Py_atomic_and_uint64((uint64_t *)obj,
|
| 444 |
+
(uint64_t)value);
|
| 445 |
+
#else
|
| 446 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint32_t);
|
| 447 |
+
return (uintptr_t)_Py_atomic_and_uint32((uint32_t *)obj,
|
| 448 |
+
(uint32_t)value);
|
| 449 |
+
#endif
|
| 450 |
+
}
|
| 451 |
+
|
| 452 |
+
|
| 453 |
+
// --- _Py_atomic_or ---------------------------------------------------------
|
| 454 |
+
|
| 455 |
+
static inline uint8_t
|
| 456 |
+
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
|
| 457 |
+
{
|
| 458 |
+
_Py_atomic_ASSERT_ARG_TYPE(char);
|
| 459 |
+
return (uint8_t)_InterlockedOr8((volatile char *)obj, (char)value);
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
static inline uint16_t
|
| 463 |
+
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
|
| 464 |
+
{
|
| 465 |
+
_Py_atomic_ASSERT_ARG_TYPE(short);
|
| 466 |
+
return (uint16_t)_InterlockedOr16((volatile short *)obj, (short)value);
|
| 467 |
+
}
|
| 468 |
+
|
| 469 |
+
static inline uint32_t
|
| 470 |
+
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
|
| 471 |
+
{
|
| 472 |
+
_Py_atomic_ASSERT_ARG_TYPE(long);
|
| 473 |
+
return (uint32_t)_InterlockedOr((volatile long *)obj, (long)value);
|
| 474 |
+
}
|
| 475 |
+
|
| 476 |
+
static inline uint64_t
|
| 477 |
+
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
|
| 478 |
+
{
|
| 479 |
+
#if defined(_M_X64) || defined(_M_ARM64)
|
| 480 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 481 |
+
return (uint64_t)_InterlockedOr64((volatile __int64 *)obj, (__int64)value);
|
| 482 |
+
#else
|
| 483 |
+
uint64_t old_value = _Py_atomic_load_uint64_relaxed(obj);
|
| 484 |
+
for (;;) {
|
| 485 |
+
uint64_t new_value = old_value | value;
|
| 486 |
+
if (_Py_atomic_compare_exchange_uint64(obj, &old_value, new_value)) {
|
| 487 |
+
return old_value;
|
| 488 |
+
}
|
| 489 |
+
}
|
| 490 |
+
#endif
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
|
| 494 |
+
static inline uintptr_t
|
| 495 |
+
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
|
| 496 |
+
{
|
| 497 |
+
#if SIZEOF_VOID_P == 8
|
| 498 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint64_t);
|
| 499 |
+
return (uintptr_t)_Py_atomic_or_uint64((uint64_t *)obj,
|
| 500 |
+
(uint64_t)value);
|
| 501 |
+
#else
|
| 502 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint32_t);
|
| 503 |
+
return (uintptr_t)_Py_atomic_or_uint32((uint32_t *)obj,
|
| 504 |
+
(uint32_t)value);
|
| 505 |
+
#endif
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
|
| 509 |
+
// --- _Py_atomic_load -------------------------------------------------------
|
| 510 |
+
|
| 511 |
+
static inline uint8_t
|
| 512 |
+
_Py_atomic_load_uint8(const uint8_t *obj)
|
| 513 |
+
{
|
| 514 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 515 |
+
return *(volatile uint8_t *)obj;
|
| 516 |
+
#elif defined(_M_ARM64)
|
| 517 |
+
return (uint8_t)__ldar8((unsigned __int8 volatile *)obj);
|
| 518 |
+
#else
|
| 519 |
+
# error "no implementation of _Py_atomic_load_uint8"
|
| 520 |
+
#endif
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
static inline uint16_t
|
| 524 |
+
_Py_atomic_load_uint16(const uint16_t *obj)
|
| 525 |
+
{
|
| 526 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 527 |
+
return *(volatile uint16_t *)obj;
|
| 528 |
+
#elif defined(_M_ARM64)
|
| 529 |
+
return (uint16_t)__ldar16((unsigned __int16 volatile *)obj);
|
| 530 |
+
#else
|
| 531 |
+
# error "no implementation of _Py_atomic_load_uint16"
|
| 532 |
+
#endif
|
| 533 |
+
}
|
| 534 |
+
|
| 535 |
+
static inline uint32_t
|
| 536 |
+
_Py_atomic_load_uint32(const uint32_t *obj)
|
| 537 |
+
{
|
| 538 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 539 |
+
return *(volatile uint32_t *)obj;
|
| 540 |
+
#elif defined(_M_ARM64)
|
| 541 |
+
return (uint32_t)__ldar32((unsigned __int32 volatile *)obj);
|
| 542 |
+
#else
|
| 543 |
+
# error "no implementation of _Py_atomic_load_uint32"
|
| 544 |
+
#endif
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
static inline uint64_t
|
| 548 |
+
_Py_atomic_load_uint64(const uint64_t *obj)
|
| 549 |
+
{
|
| 550 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 551 |
+
return *(volatile uint64_t *)obj;
|
| 552 |
+
#elif defined(_M_ARM64)
|
| 553 |
+
return (uint64_t)__ldar64((unsigned __int64 volatile *)obj);
|
| 554 |
+
#else
|
| 555 |
+
# error "no implementation of _Py_atomic_load_uint64"
|
| 556 |
+
#endif
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
static inline int8_t
|
| 560 |
+
_Py_atomic_load_int8(const int8_t *obj)
|
| 561 |
+
{
|
| 562 |
+
return (int8_t)_Py_atomic_load_uint8((const uint8_t *)obj);
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
+
static inline int16_t
|
| 566 |
+
_Py_atomic_load_int16(const int16_t *obj)
|
| 567 |
+
{
|
| 568 |
+
return (int16_t)_Py_atomic_load_uint16((const uint16_t *)obj);
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
static inline int32_t
|
| 572 |
+
_Py_atomic_load_int32(const int32_t *obj)
|
| 573 |
+
{
|
| 574 |
+
return (int32_t)_Py_atomic_load_uint32((const uint32_t *)obj);
|
| 575 |
+
}
|
| 576 |
+
|
| 577 |
+
static inline int
|
| 578 |
+
_Py_atomic_load_int(const int *obj)
|
| 579 |
+
{
|
| 580 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint32_t);
|
| 581 |
+
return (int)_Py_atomic_load_uint32((uint32_t *)obj);
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
static inline unsigned int
|
| 585 |
+
_Py_atomic_load_uint(const unsigned int *obj)
|
| 586 |
+
{
|
| 587 |
+
_Py_atomic_ASSERT_ARG_TYPE(uint32_t);
|
| 588 |
+
return (unsigned int)_Py_atomic_load_uint32((uint32_t *)obj);
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
static inline int64_t
|
| 592 |
+
_Py_atomic_load_int64(const int64_t *obj)
|
| 593 |
+
{
|
| 594 |
+
return (int64_t)_Py_atomic_load_uint64((const uint64_t *)obj);
|
| 595 |
+
}
|
| 596 |
+
|
| 597 |
+
static inline void*
|
| 598 |
+
_Py_atomic_load_ptr(const void *obj)
|
| 599 |
+
{
|
| 600 |
+
#if SIZEOF_VOID_P == 8
|
| 601 |
+
return (void*)_Py_atomic_load_uint64((const uint64_t *)obj);
|
| 602 |
+
#else
|
| 603 |
+
return (void*)_Py_atomic_load_uint32((const uint32_t *)obj);
|
| 604 |
+
#endif
|
| 605 |
+
}
|
| 606 |
+
|
| 607 |
+
static inline intptr_t
|
| 608 |
+
_Py_atomic_load_intptr(const intptr_t *obj)
|
| 609 |
+
{
|
| 610 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 611 |
+
return (intptr_t)_Py_atomic_load_ptr((void*)obj);
|
| 612 |
+
}
|
| 613 |
+
|
| 614 |
+
static inline uintptr_t
|
| 615 |
+
_Py_atomic_load_uintptr(const uintptr_t *obj)
|
| 616 |
+
{
|
| 617 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 618 |
+
return (uintptr_t)_Py_atomic_load_ptr((void*)obj);
|
| 619 |
+
}
|
| 620 |
+
|
| 621 |
+
static inline Py_ssize_t
|
| 622 |
+
_Py_atomic_load_ssize(const Py_ssize_t *obj)
|
| 623 |
+
{
|
| 624 |
+
_Py_atomic_ASSERT_ARG_TYPE(void*);
|
| 625 |
+
return (Py_ssize_t)_Py_atomic_load_ptr((void*)obj);
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
+
|
| 629 |
+
// --- _Py_atomic_load_relaxed -----------------------------------------------
|
| 630 |
+
|
| 631 |
+
static inline int
|
| 632 |
+
_Py_atomic_load_int_relaxed(const int *obj)
|
| 633 |
+
{
|
| 634 |
+
return *(volatile int *)obj;
|
| 635 |
+
}
|
| 636 |
+
|
| 637 |
+
static inline int8_t
|
| 638 |
+
_Py_atomic_load_int8_relaxed(const int8_t *obj)
|
| 639 |
+
{
|
| 640 |
+
return *(volatile int8_t *)obj;
|
| 641 |
+
}
|
| 642 |
+
|
| 643 |
+
static inline int16_t
|
| 644 |
+
_Py_atomic_load_int16_relaxed(const int16_t *obj)
|
| 645 |
+
{
|
| 646 |
+
return *(volatile int16_t *)obj;
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
+
static inline int32_t
|
| 650 |
+
_Py_atomic_load_int32_relaxed(const int32_t *obj)
|
| 651 |
+
{
|
| 652 |
+
return *(volatile int32_t *)obj;
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
static inline int64_t
|
| 656 |
+
_Py_atomic_load_int64_relaxed(const int64_t *obj)
|
| 657 |
+
{
|
| 658 |
+
return *(volatile int64_t *)obj;
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
static inline intptr_t
|
| 662 |
+
_Py_atomic_load_intptr_relaxed(const intptr_t *obj)
|
| 663 |
+
{
|
| 664 |
+
return *(volatile intptr_t *)obj;
|
| 665 |
+
}
|
| 666 |
+
|
| 667 |
+
static inline uint8_t
|
| 668 |
+
_Py_atomic_load_uint8_relaxed(const uint8_t *obj)
|
| 669 |
+
{
|
| 670 |
+
return *(volatile uint8_t *)obj;
|
| 671 |
+
}
|
| 672 |
+
|
| 673 |
+
static inline uint16_t
|
| 674 |
+
_Py_atomic_load_uint16_relaxed(const uint16_t *obj)
|
| 675 |
+
{
|
| 676 |
+
return *(volatile uint16_t *)obj;
|
| 677 |
+
}
|
| 678 |
+
|
| 679 |
+
static inline uint32_t
|
| 680 |
+
_Py_atomic_load_uint32_relaxed(const uint32_t *obj)
|
| 681 |
+
{
|
| 682 |
+
return *(volatile uint32_t *)obj;
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
+
static inline uint64_t
|
| 686 |
+
_Py_atomic_load_uint64_relaxed(const uint64_t *obj)
|
| 687 |
+
{
|
| 688 |
+
return *(volatile uint64_t *)obj;
|
| 689 |
+
}
|
| 690 |
+
|
| 691 |
+
static inline uintptr_t
|
| 692 |
+
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
|
| 693 |
+
{
|
| 694 |
+
return *(volatile uintptr_t *)obj;
|
| 695 |
+
}
|
| 696 |
+
|
| 697 |
+
static inline unsigned int
|
| 698 |
+
_Py_atomic_load_uint_relaxed(const unsigned int *obj)
|
| 699 |
+
{
|
| 700 |
+
return *(volatile unsigned int *)obj;
|
| 701 |
+
}
|
| 702 |
+
|
| 703 |
+
static inline Py_ssize_t
|
| 704 |
+
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
|
| 705 |
+
{
|
| 706 |
+
return *(volatile Py_ssize_t *)obj;
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
static inline void*
|
| 710 |
+
_Py_atomic_load_ptr_relaxed(const void *obj)
|
| 711 |
+
{
|
| 712 |
+
return *(void * volatile *)obj;
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
static inline unsigned long long
|
| 716 |
+
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
|
| 717 |
+
{
|
| 718 |
+
return *(volatile unsigned long long *)obj;
|
| 719 |
+
}
|
| 720 |
+
|
| 721 |
+
|
| 722 |
+
// --- _Py_atomic_store ------------------------------------------------------
|
| 723 |
+
|
| 724 |
+
static inline void
|
| 725 |
+
_Py_atomic_store_int(int *obj, int value)
|
| 726 |
+
{
|
| 727 |
+
(void)_Py_atomic_exchange_int(obj, value);
|
| 728 |
+
}
|
| 729 |
+
|
| 730 |
+
static inline void
|
| 731 |
+
_Py_atomic_store_int8(int8_t *obj, int8_t value)
|
| 732 |
+
{
|
| 733 |
+
(void)_Py_atomic_exchange_int8(obj, value);
|
| 734 |
+
}
|
| 735 |
+
|
| 736 |
+
static inline void
|
| 737 |
+
_Py_atomic_store_int16(int16_t *obj, int16_t value)
|
| 738 |
+
{
|
| 739 |
+
(void)_Py_atomic_exchange_int16(obj, value);
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
static inline void
|
| 743 |
+
_Py_atomic_store_int32(int32_t *obj, int32_t value)
|
| 744 |
+
{
|
| 745 |
+
(void)_Py_atomic_exchange_int32(obj, value);
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
static inline void
|
| 749 |
+
_Py_atomic_store_int64(int64_t *obj, int64_t value)
|
| 750 |
+
{
|
| 751 |
+
(void)_Py_atomic_exchange_int64(obj, value);
|
| 752 |
+
}
|
| 753 |
+
|
| 754 |
+
static inline void
|
| 755 |
+
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
|
| 756 |
+
{
|
| 757 |
+
(void)_Py_atomic_exchange_intptr(obj, value);
|
| 758 |
+
}
|
| 759 |
+
|
| 760 |
+
static inline void
|
| 761 |
+
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
|
| 762 |
+
{
|
| 763 |
+
(void)_Py_atomic_exchange_uint8(obj, value);
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
static inline void
|
| 767 |
+
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
|
| 768 |
+
{
|
| 769 |
+
(void)_Py_atomic_exchange_uint16(obj, value);
|
| 770 |
+
}
|
| 771 |
+
|
| 772 |
+
static inline void
|
| 773 |
+
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
|
| 774 |
+
{
|
| 775 |
+
(void)_Py_atomic_exchange_uint32(obj, value);
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
static inline void
|
| 779 |
+
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
|
| 780 |
+
{
|
| 781 |
+
(void)_Py_atomic_exchange_uint64(obj, value);
|
| 782 |
+
}
|
| 783 |
+
|
| 784 |
+
static inline void
|
| 785 |
+
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
|
| 786 |
+
{
|
| 787 |
+
(void)_Py_atomic_exchange_uintptr(obj, value);
|
| 788 |
+
}
|
| 789 |
+
|
| 790 |
+
static inline void
|
| 791 |
+
_Py_atomic_store_uint(unsigned int *obj, unsigned int value)
|
| 792 |
+
{
|
| 793 |
+
(void)_Py_atomic_exchange_uint(obj, value);
|
| 794 |
+
}
|
| 795 |
+
|
| 796 |
+
static inline void
|
| 797 |
+
_Py_atomic_store_ptr(void *obj, void *value)
|
| 798 |
+
{
|
| 799 |
+
(void)_Py_atomic_exchange_ptr(obj, value);
|
| 800 |
+
}
|
| 801 |
+
|
| 802 |
+
static inline void
|
| 803 |
+
_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 804 |
+
{
|
| 805 |
+
(void)_Py_atomic_exchange_ssize(obj, value);
|
| 806 |
+
}
|
| 807 |
+
|
| 808 |
+
|
| 809 |
+
// --- _Py_atomic_store_relaxed ----------------------------------------------
|
| 810 |
+
|
| 811 |
+
static inline void
|
| 812 |
+
_Py_atomic_store_int_relaxed(int *obj, int value)
|
| 813 |
+
{
|
| 814 |
+
*(volatile int *)obj = value;
|
| 815 |
+
}
|
| 816 |
+
|
| 817 |
+
static inline void
|
| 818 |
+
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
|
| 819 |
+
{
|
| 820 |
+
*(volatile int8_t *)obj = value;
|
| 821 |
+
}
|
| 822 |
+
|
| 823 |
+
static inline void
|
| 824 |
+
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
|
| 825 |
+
{
|
| 826 |
+
*(volatile int16_t *)obj = value;
|
| 827 |
+
}
|
| 828 |
+
|
| 829 |
+
static inline void
|
| 830 |
+
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
|
| 831 |
+
{
|
| 832 |
+
*(volatile int32_t *)obj = value;
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
+
static inline void
|
| 836 |
+
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
|
| 837 |
+
{
|
| 838 |
+
*(volatile int64_t *)obj = value;
|
| 839 |
+
}
|
| 840 |
+
|
| 841 |
+
static inline void
|
| 842 |
+
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
|
| 843 |
+
{
|
| 844 |
+
*(volatile intptr_t *)obj = value;
|
| 845 |
+
}
|
| 846 |
+
|
| 847 |
+
static inline void
|
| 848 |
+
_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
|
| 849 |
+
{
|
| 850 |
+
*(volatile uint8_t *)obj = value;
|
| 851 |
+
}
|
| 852 |
+
|
| 853 |
+
static inline void
|
| 854 |
+
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
|
| 855 |
+
{
|
| 856 |
+
*(volatile uint16_t *)obj = value;
|
| 857 |
+
}
|
| 858 |
+
|
| 859 |
+
static inline void
|
| 860 |
+
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
|
| 861 |
+
{
|
| 862 |
+
*(volatile uint32_t *)obj = value;
|
| 863 |
+
}
|
| 864 |
+
|
| 865 |
+
static inline void
|
| 866 |
+
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
|
| 867 |
+
{
|
| 868 |
+
*(volatile uint64_t *)obj = value;
|
| 869 |
+
}
|
| 870 |
+
|
| 871 |
+
static inline void
|
| 872 |
+
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
|
| 873 |
+
{
|
| 874 |
+
*(volatile uintptr_t *)obj = value;
|
| 875 |
+
}
|
| 876 |
+
|
| 877 |
+
static inline void
|
| 878 |
+
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
|
| 879 |
+
{
|
| 880 |
+
*(volatile unsigned int *)obj = value;
|
| 881 |
+
}
|
| 882 |
+
|
| 883 |
+
static inline void
|
| 884 |
+
_Py_atomic_store_ptr_relaxed(void *obj, void* value)
|
| 885 |
+
{
|
| 886 |
+
*(void * volatile *)obj = value;
|
| 887 |
+
}
|
| 888 |
+
|
| 889 |
+
static inline void
|
| 890 |
+
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
|
| 891 |
+
{
|
| 892 |
+
*(volatile Py_ssize_t *)obj = value;
|
| 893 |
+
}
|
| 894 |
+
|
| 895 |
+
static inline void
|
| 896 |
+
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
|
| 897 |
+
unsigned long long value)
|
| 898 |
+
{
|
| 899 |
+
*(volatile unsigned long long *)obj = value;
|
| 900 |
+
}
|
| 901 |
+
|
| 902 |
+
|
| 903 |
+
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
|
| 904 |
+
|
| 905 |
+
static inline void *
|
| 906 |
+
_Py_atomic_load_ptr_acquire(const void *obj)
|
| 907 |
+
{
|
| 908 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 909 |
+
return *(void * volatile *)obj;
|
| 910 |
+
#elif defined(_M_ARM64)
|
| 911 |
+
return (void *)__ldar64((unsigned __int64 volatile *)obj);
|
| 912 |
+
#else
|
| 913 |
+
# error "no implementation of _Py_atomic_load_ptr_acquire"
|
| 914 |
+
#endif
|
| 915 |
+
}
|
| 916 |
+
|
| 917 |
+
static inline uintptr_t
|
| 918 |
+
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
|
| 919 |
+
{
|
| 920 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 921 |
+
return *(uintptr_t volatile *)obj;
|
| 922 |
+
#elif defined(_M_ARM64)
|
| 923 |
+
return (uintptr_t)__ldar64((unsigned __int64 volatile *)obj);
|
| 924 |
+
#else
|
| 925 |
+
# error "no implementation of _Py_atomic_load_uintptr_acquire"
|
| 926 |
+
#endif
|
| 927 |
+
}
|
| 928 |
+
|
| 929 |
+
static inline void
|
| 930 |
+
_Py_atomic_store_ptr_release(void *obj, void *value)
|
| 931 |
+
{
|
| 932 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 933 |
+
*(void * volatile *)obj = value;
|
| 934 |
+
#elif defined(_M_ARM64)
|
| 935 |
+
__stlr64((unsigned __int64 volatile *)obj, (uintptr_t)value);
|
| 936 |
+
#else
|
| 937 |
+
# error "no implementation of _Py_atomic_store_ptr_release"
|
| 938 |
+
#endif
|
| 939 |
+
}
|
| 940 |
+
|
| 941 |
+
static inline void
|
| 942 |
+
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
|
| 943 |
+
{
|
| 944 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 945 |
+
*(uintptr_t volatile *)obj = value;
|
| 946 |
+
#elif defined(_M_ARM64)
|
| 947 |
+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int64);
|
| 948 |
+
__stlr64((unsigned __int64 volatile *)obj, (unsigned __int64)value);
|
| 949 |
+
#else
|
| 950 |
+
# error "no implementation of _Py_atomic_store_uintptr_release"
|
| 951 |
+
#endif
|
| 952 |
+
}
|
| 953 |
+
|
| 954 |
+
static inline void
|
| 955 |
+
_Py_atomic_store_int_release(int *obj, int value)
|
| 956 |
+
{
|
| 957 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 958 |
+
*(int volatile *)obj = value;
|
| 959 |
+
#elif defined(_M_ARM64)
|
| 960 |
+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int32);
|
| 961 |
+
__stlr32((unsigned __int32 volatile *)obj, (unsigned __int32)value);
|
| 962 |
+
#else
|
| 963 |
+
# error "no implementation of _Py_atomic_store_int_release"
|
| 964 |
+
#endif
|
| 965 |
+
}
|
| 966 |
+
|
| 967 |
+
static inline void
|
| 968 |
+
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
|
| 969 |
+
{
|
| 970 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 971 |
+
*(Py_ssize_t volatile *)obj = value;
|
| 972 |
+
#elif defined(_M_ARM64)
|
| 973 |
+
__stlr64((unsigned __int64 volatile *)obj, (unsigned __int64)value);
|
| 974 |
+
#else
|
| 975 |
+
# error "no implementation of _Py_atomic_store_ssize_release"
|
| 976 |
+
#endif
|
| 977 |
+
}
|
| 978 |
+
|
| 979 |
+
static inline int
|
| 980 |
+
_Py_atomic_load_int_acquire(const int *obj)
|
| 981 |
+
{
|
| 982 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 983 |
+
return *(int volatile *)obj;
|
| 984 |
+
#elif defined(_M_ARM64)
|
| 985 |
+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int32);
|
| 986 |
+
return (int)__ldar32((unsigned __int32 volatile *)obj);
|
| 987 |
+
#else
|
| 988 |
+
# error "no implementation of _Py_atomic_load_int_acquire"
|
| 989 |
+
#endif
|
| 990 |
+
}
|
| 991 |
+
|
| 992 |
+
static inline void
|
| 993 |
+
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
|
| 994 |
+
{
|
| 995 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 996 |
+
*(uint32_t volatile *)obj = value;
|
| 997 |
+
#elif defined(_M_ARM64)
|
| 998 |
+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int32);
|
| 999 |
+
__stlr32((unsigned __int32 volatile *)obj, (unsigned __int32)value);
|
| 1000 |
+
#else
|
| 1001 |
+
# error "no implementation of _Py_atomic_store_uint32_release"
|
| 1002 |
+
#endif
|
| 1003 |
+
}
|
| 1004 |
+
|
| 1005 |
+
static inline void
|
| 1006 |
+
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
|
| 1007 |
+
{
|
| 1008 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 1009 |
+
*(uint64_t volatile *)obj = value;
|
| 1010 |
+
#elif defined(_M_ARM64)
|
| 1011 |
+
_Py_atomic_ASSERT_ARG_TYPE(unsigned __int64);
|
| 1012 |
+
__stlr64((unsigned __int64 volatile *)obj, (unsigned __int64)value);
|
| 1013 |
+
#else
|
| 1014 |
+
# error "no implementation of _Py_atomic_store_uint64_release"
|
| 1015 |
+
#endif
|
| 1016 |
+
}
|
| 1017 |
+
|
| 1018 |
+
static inline uint64_t
|
| 1019 |
+
_Py_atomic_load_uint64_acquire(const uint64_t *obj)
|
| 1020 |
+
{
|
| 1021 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 1022 |
+
return *(uint64_t volatile *)obj;
|
| 1023 |
+
#elif defined(_M_ARM64)
|
| 1024 |
+
_Py_atomic_ASSERT_ARG_TYPE(__int64);
|
| 1025 |
+
return (uint64_t)__ldar64((unsigned __int64 volatile *)obj);
|
| 1026 |
+
#else
|
| 1027 |
+
# error "no implementation of _Py_atomic_load_uint64_acquire"
|
| 1028 |
+
#endif
|
| 1029 |
+
}
|
| 1030 |
+
|
| 1031 |
+
static inline uint32_t
|
| 1032 |
+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
|
| 1033 |
+
{
|
| 1034 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 1035 |
+
return *(uint32_t volatile *)obj;
|
| 1036 |
+
#elif defined(_M_ARM64)
|
| 1037 |
+
return (uint32_t)__ldar32((uint32_t volatile *)obj);
|
| 1038 |
+
#else
|
| 1039 |
+
# error "no implementation of _Py_atomic_load_uint32_acquire"
|
| 1040 |
+
#endif
|
| 1041 |
+
}
|
| 1042 |
+
|
| 1043 |
+
static inline Py_ssize_t
|
| 1044 |
+
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
|
| 1045 |
+
{
|
| 1046 |
+
#if defined(_M_X64) || defined(_M_IX86)
|
| 1047 |
+
return *(Py_ssize_t volatile *)obj;
|
| 1048 |
+
#elif defined(_M_ARM64)
|
| 1049 |
+
return (Py_ssize_t)__ldar64((unsigned __int64 volatile *)obj);
|
| 1050 |
+
#else
|
| 1051 |
+
# error "no implementation of _Py_atomic_load_ssize_acquire"
|
| 1052 |
+
#endif
|
| 1053 |
+
}
|
| 1054 |
+
|
| 1055 |
+
// --- _Py_atomic_fence ------------------------------------------------------
|
| 1056 |
+
|
| 1057 |
+
static inline void
|
| 1058 |
+
_Py_atomic_fence_seq_cst(void)
|
| 1059 |
+
{
|
| 1060 |
+
#if defined(_M_ARM64)
|
| 1061 |
+
__dmb(_ARM64_BARRIER_ISH);
|
| 1062 |
+
#elif defined(_M_X64)
|
| 1063 |
+
__faststorefence();
|
| 1064 |
+
#elif defined(_M_IX86)
|
| 1065 |
+
_mm_mfence();
|
| 1066 |
+
#else
|
| 1067 |
+
# error "no implementation of _Py_atomic_fence_seq_cst"
|
| 1068 |
+
#endif
|
| 1069 |
+
}
|
| 1070 |
+
|
| 1071 |
+
static inline void
|
| 1072 |
+
_Py_atomic_fence_acquire(void)
|
| 1073 |
+
{
|
| 1074 |
+
#if defined(_M_ARM64)
|
| 1075 |
+
__dmb(_ARM64_BARRIER_ISHLD);
|
| 1076 |
+
#elif defined(_M_X64) || defined(_M_IX86)
|
| 1077 |
+
_ReadBarrier();
|
| 1078 |
+
#else
|
| 1079 |
+
# error "no implementation of _Py_atomic_fence_acquire"
|
| 1080 |
+
#endif
|
| 1081 |
+
}
|
| 1082 |
+
|
| 1083 |
+
static inline void
|
| 1084 |
+
_Py_atomic_fence_release(void)
|
| 1085 |
+
{
|
| 1086 |
+
#if defined(_M_ARM64)
|
| 1087 |
+
__dmb(_ARM64_BARRIER_ISH);
|
| 1088 |
+
#elif defined(_M_X64) || defined(_M_IX86)
|
| 1089 |
+
_ReadWriteBarrier();
|
| 1090 |
+
#else
|
| 1091 |
+
# error "no implementation of _Py_atomic_fence_release"
|
| 1092 |
+
#endif
|
| 1093 |
+
}
|
| 1094 |
+
|
| 1095 |
+
#undef _Py_atomic_ASSERT_ARG_TYPE
|
Include/cpython/pyatomic_std.h
ADDED
|
@@ -0,0 +1,976 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This is the implementation of Python atomic operations using C++11 or C11
|
| 2 |
+
// atomics. Note that the pyatomic_gcc.h implementation is preferred for GCC
|
| 3 |
+
// compatible compilers, even if they support C++11 atomics.
|
| 4 |
+
|
| 5 |
+
#ifndef Py_ATOMIC_STD_H
|
| 6 |
+
# error "this header file must not be included directly"
|
| 7 |
+
#endif
|
| 8 |
+
|
| 9 |
+
#ifdef __cplusplus
|
| 10 |
+
extern "C++" {
|
| 11 |
+
# include <atomic>
|
| 12 |
+
}
|
| 13 |
+
# define _Py_USING_STD using namespace std
|
| 14 |
+
# define _Atomic(tp) atomic<tp>
|
| 15 |
+
#else
|
| 16 |
+
# define _Py_USING_STD
|
| 17 |
+
# include <stdatomic.h>
|
| 18 |
+
#endif
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
// --- _Py_atomic_add --------------------------------------------------------
|
| 22 |
+
|
| 23 |
+
static inline int
|
| 24 |
+
_Py_atomic_add_int(int *obj, int value)
|
| 25 |
+
{
|
| 26 |
+
_Py_USING_STD;
|
| 27 |
+
return atomic_fetch_add((_Atomic(int)*)obj, value);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
static inline int8_t
|
| 31 |
+
_Py_atomic_add_int8(int8_t *obj, int8_t value)
|
| 32 |
+
{
|
| 33 |
+
_Py_USING_STD;
|
| 34 |
+
return atomic_fetch_add((_Atomic(int8_t)*)obj, value);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
static inline int16_t
|
| 38 |
+
_Py_atomic_add_int16(int16_t *obj, int16_t value)
|
| 39 |
+
{
|
| 40 |
+
_Py_USING_STD;
|
| 41 |
+
return atomic_fetch_add((_Atomic(int16_t)*)obj, value);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
static inline int32_t
|
| 45 |
+
_Py_atomic_add_int32(int32_t *obj, int32_t value)
|
| 46 |
+
{
|
| 47 |
+
_Py_USING_STD;
|
| 48 |
+
return atomic_fetch_add((_Atomic(int32_t)*)obj, value);
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
static inline int64_t
|
| 52 |
+
_Py_atomic_add_int64(int64_t *obj, int64_t value)
|
| 53 |
+
{
|
| 54 |
+
_Py_USING_STD;
|
| 55 |
+
return atomic_fetch_add((_Atomic(int64_t)*)obj, value);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
static inline intptr_t
|
| 59 |
+
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
|
| 60 |
+
{
|
| 61 |
+
_Py_USING_STD;
|
| 62 |
+
return atomic_fetch_add((_Atomic(intptr_t)*)obj, value);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
static inline unsigned int
|
| 66 |
+
_Py_atomic_add_uint(unsigned int *obj, unsigned int value)
|
| 67 |
+
{
|
| 68 |
+
_Py_USING_STD;
|
| 69 |
+
return atomic_fetch_add((_Atomic(unsigned int)*)obj, value);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
static inline uint8_t
|
| 73 |
+
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
|
| 74 |
+
{
|
| 75 |
+
_Py_USING_STD;
|
| 76 |
+
return atomic_fetch_add((_Atomic(uint8_t)*)obj, value);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
static inline uint16_t
|
| 80 |
+
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
|
| 81 |
+
{
|
| 82 |
+
_Py_USING_STD;
|
| 83 |
+
return atomic_fetch_add((_Atomic(uint16_t)*)obj, value);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
static inline uint32_t
|
| 87 |
+
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
|
| 88 |
+
{
|
| 89 |
+
_Py_USING_STD;
|
| 90 |
+
return atomic_fetch_add((_Atomic(uint32_t)*)obj, value);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
static inline uint64_t
|
| 94 |
+
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
|
| 95 |
+
{
|
| 96 |
+
_Py_USING_STD;
|
| 97 |
+
return atomic_fetch_add((_Atomic(uint64_t)*)obj, value);
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
static inline uintptr_t
|
| 101 |
+
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
|
| 102 |
+
{
|
| 103 |
+
_Py_USING_STD;
|
| 104 |
+
return atomic_fetch_add((_Atomic(uintptr_t)*)obj, value);
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
static inline Py_ssize_t
|
| 108 |
+
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 109 |
+
{
|
| 110 |
+
_Py_USING_STD;
|
| 111 |
+
return atomic_fetch_add((_Atomic(Py_ssize_t)*)obj, value);
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
// --- _Py_atomic_compare_exchange -------------------------------------------
|
| 116 |
+
|
| 117 |
+
static inline int
|
| 118 |
+
_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired)
|
| 119 |
+
{
|
| 120 |
+
_Py_USING_STD;
|
| 121 |
+
return atomic_compare_exchange_strong((_Atomic(int)*)obj,
|
| 122 |
+
expected, desired);
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
static inline int
|
| 126 |
+
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired)
|
| 127 |
+
{
|
| 128 |
+
_Py_USING_STD;
|
| 129 |
+
return atomic_compare_exchange_strong((_Atomic(int8_t)*)obj,
|
| 130 |
+
expected, desired);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
static inline int
|
| 134 |
+
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired)
|
| 135 |
+
{
|
| 136 |
+
_Py_USING_STD;
|
| 137 |
+
return atomic_compare_exchange_strong((_Atomic(int16_t)*)obj,
|
| 138 |
+
expected, desired);
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
static inline int
|
| 142 |
+
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired)
|
| 143 |
+
{
|
| 144 |
+
_Py_USING_STD;
|
| 145 |
+
return atomic_compare_exchange_strong((_Atomic(int32_t)*)obj,
|
| 146 |
+
expected, desired);
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
static inline int
|
| 150 |
+
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired)
|
| 151 |
+
{
|
| 152 |
+
_Py_USING_STD;
|
| 153 |
+
return atomic_compare_exchange_strong((_Atomic(int64_t)*)obj,
|
| 154 |
+
expected, desired);
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
static inline int
|
| 158 |
+
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
|
| 159 |
+
{
|
| 160 |
+
_Py_USING_STD;
|
| 161 |
+
return atomic_compare_exchange_strong((_Atomic(intptr_t)*)obj,
|
| 162 |
+
expected, desired);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
static inline int
|
| 166 |
+
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired)
|
| 167 |
+
{
|
| 168 |
+
_Py_USING_STD;
|
| 169 |
+
return atomic_compare_exchange_strong((_Atomic(unsigned int)*)obj,
|
| 170 |
+
expected, desired);
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
static inline int
|
| 174 |
+
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired)
|
| 175 |
+
{
|
| 176 |
+
_Py_USING_STD;
|
| 177 |
+
return atomic_compare_exchange_strong((_Atomic(uint8_t)*)obj,
|
| 178 |
+
expected, desired);
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
static inline int
|
| 182 |
+
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired)
|
| 183 |
+
{
|
| 184 |
+
_Py_USING_STD;
|
| 185 |
+
return atomic_compare_exchange_strong((_Atomic(uint16_t)*)obj,
|
| 186 |
+
expected, desired);
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
static inline int
|
| 190 |
+
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired)
|
| 191 |
+
{
|
| 192 |
+
_Py_USING_STD;
|
| 193 |
+
return atomic_compare_exchange_strong((_Atomic(uint32_t)*)obj,
|
| 194 |
+
expected, desired);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
static inline int
|
| 198 |
+
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired)
|
| 199 |
+
{
|
| 200 |
+
_Py_USING_STD;
|
| 201 |
+
return atomic_compare_exchange_strong((_Atomic(uint64_t)*)obj,
|
| 202 |
+
expected, desired);
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
static inline int
|
| 206 |
+
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired)
|
| 207 |
+
{
|
| 208 |
+
_Py_USING_STD;
|
| 209 |
+
return atomic_compare_exchange_strong((_Atomic(uintptr_t)*)obj,
|
| 210 |
+
expected, desired);
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
static inline int
|
| 214 |
+
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired)
|
| 215 |
+
{
|
| 216 |
+
_Py_USING_STD;
|
| 217 |
+
return atomic_compare_exchange_strong((_Atomic(Py_ssize_t)*)obj,
|
| 218 |
+
expected, desired);
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
static inline int
|
| 222 |
+
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired)
|
| 223 |
+
{
|
| 224 |
+
_Py_USING_STD;
|
| 225 |
+
return atomic_compare_exchange_strong((_Atomic(void *)*)obj,
|
| 226 |
+
(void **)expected, desired);
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
// --- _Py_atomic_exchange ---------------------------------------------------
|
| 231 |
+
|
| 232 |
+
static inline int
|
| 233 |
+
_Py_atomic_exchange_int(int *obj, int value)
|
| 234 |
+
{
|
| 235 |
+
_Py_USING_STD;
|
| 236 |
+
return atomic_exchange((_Atomic(int)*)obj, value);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
static inline int8_t
|
| 240 |
+
_Py_atomic_exchange_int8(int8_t *obj, int8_t value)
|
| 241 |
+
{
|
| 242 |
+
_Py_USING_STD;
|
| 243 |
+
return atomic_exchange((_Atomic(int8_t)*)obj, value);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
static inline int16_t
|
| 247 |
+
_Py_atomic_exchange_int16(int16_t *obj, int16_t value)
|
| 248 |
+
{
|
| 249 |
+
_Py_USING_STD;
|
| 250 |
+
return atomic_exchange((_Atomic(int16_t)*)obj, value);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
static inline int32_t
|
| 254 |
+
_Py_atomic_exchange_int32(int32_t *obj, int32_t value)
|
| 255 |
+
{
|
| 256 |
+
_Py_USING_STD;
|
| 257 |
+
return atomic_exchange((_Atomic(int32_t)*)obj, value);
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
static inline int64_t
|
| 261 |
+
_Py_atomic_exchange_int64(int64_t *obj, int64_t value)
|
| 262 |
+
{
|
| 263 |
+
_Py_USING_STD;
|
| 264 |
+
return atomic_exchange((_Atomic(int64_t)*)obj, value);
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
static inline intptr_t
|
| 268 |
+
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
|
| 269 |
+
{
|
| 270 |
+
_Py_USING_STD;
|
| 271 |
+
return atomic_exchange((_Atomic(intptr_t)*)obj, value);
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
static inline unsigned int
|
| 275 |
+
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
|
| 276 |
+
{
|
| 277 |
+
_Py_USING_STD;
|
| 278 |
+
return atomic_exchange((_Atomic(unsigned int)*)obj, value);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
static inline uint8_t
|
| 282 |
+
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
|
| 283 |
+
{
|
| 284 |
+
_Py_USING_STD;
|
| 285 |
+
return atomic_exchange((_Atomic(uint8_t)*)obj, value);
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
static inline uint16_t
|
| 289 |
+
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
|
| 290 |
+
{
|
| 291 |
+
_Py_USING_STD;
|
| 292 |
+
return atomic_exchange((_Atomic(uint16_t)*)obj, value);
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
static inline uint32_t
|
| 296 |
+
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
|
| 297 |
+
{
|
| 298 |
+
_Py_USING_STD;
|
| 299 |
+
return atomic_exchange((_Atomic(uint32_t)*)obj, value);
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
static inline uint64_t
|
| 303 |
+
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
|
| 304 |
+
{
|
| 305 |
+
_Py_USING_STD;
|
| 306 |
+
return atomic_exchange((_Atomic(uint64_t)*)obj, value);
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
static inline uintptr_t
|
| 310 |
+
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
|
| 311 |
+
{
|
| 312 |
+
_Py_USING_STD;
|
| 313 |
+
return atomic_exchange((_Atomic(uintptr_t)*)obj, value);
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
static inline Py_ssize_t
|
| 317 |
+
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 318 |
+
{
|
| 319 |
+
_Py_USING_STD;
|
| 320 |
+
return atomic_exchange((_Atomic(Py_ssize_t)*)obj, value);
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
static inline void*
|
| 324 |
+
_Py_atomic_exchange_ptr(void *obj, void *value)
|
| 325 |
+
{
|
| 326 |
+
_Py_USING_STD;
|
| 327 |
+
return atomic_exchange((_Atomic(void *)*)obj, value);
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
// --- _Py_atomic_and --------------------------------------------------------
|
| 332 |
+
|
| 333 |
+
static inline uint8_t
|
| 334 |
+
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
|
| 335 |
+
{
|
| 336 |
+
_Py_USING_STD;
|
| 337 |
+
return atomic_fetch_and((_Atomic(uint8_t)*)obj, value);
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
static inline uint16_t
|
| 341 |
+
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
|
| 342 |
+
{
|
| 343 |
+
_Py_USING_STD;
|
| 344 |
+
return atomic_fetch_and((_Atomic(uint16_t)*)obj, value);
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
static inline uint32_t
|
| 348 |
+
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
|
| 349 |
+
{
|
| 350 |
+
_Py_USING_STD;
|
| 351 |
+
return atomic_fetch_and((_Atomic(uint32_t)*)obj, value);
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
static inline uint64_t
|
| 355 |
+
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
|
| 356 |
+
{
|
| 357 |
+
_Py_USING_STD;
|
| 358 |
+
return atomic_fetch_and((_Atomic(uint64_t)*)obj, value);
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
static inline uintptr_t
|
| 362 |
+
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
|
| 363 |
+
{
|
| 364 |
+
_Py_USING_STD;
|
| 365 |
+
return atomic_fetch_and((_Atomic(uintptr_t)*)obj, value);
|
| 366 |
+
}
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
// --- _Py_atomic_or ---------------------------------------------------------
|
| 370 |
+
|
| 371 |
+
static inline uint8_t
|
| 372 |
+
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
|
| 373 |
+
{
|
| 374 |
+
_Py_USING_STD;
|
| 375 |
+
return atomic_fetch_or((_Atomic(uint8_t)*)obj, value);
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
static inline uint16_t
|
| 379 |
+
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
|
| 380 |
+
{
|
| 381 |
+
_Py_USING_STD;
|
| 382 |
+
return atomic_fetch_or((_Atomic(uint16_t)*)obj, value);
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
static inline uint32_t
|
| 386 |
+
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
|
| 387 |
+
{
|
| 388 |
+
_Py_USING_STD;
|
| 389 |
+
return atomic_fetch_or((_Atomic(uint32_t)*)obj, value);
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
static inline uint64_t
|
| 393 |
+
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
|
| 394 |
+
{
|
| 395 |
+
_Py_USING_STD;
|
| 396 |
+
return atomic_fetch_or((_Atomic(uint64_t)*)obj, value);
|
| 397 |
+
}
|
| 398 |
+
|
| 399 |
+
static inline uintptr_t
|
| 400 |
+
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
|
| 401 |
+
{
|
| 402 |
+
_Py_USING_STD;
|
| 403 |
+
return atomic_fetch_or((_Atomic(uintptr_t)*)obj, value);
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
|
| 407 |
+
// --- _Py_atomic_load -------------------------------------------------------
|
| 408 |
+
|
| 409 |
+
static inline int
|
| 410 |
+
_Py_atomic_load_int(const int *obj)
|
| 411 |
+
{
|
| 412 |
+
_Py_USING_STD;
|
| 413 |
+
return atomic_load((const _Atomic(int)*)obj);
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
static inline int8_t
|
| 417 |
+
_Py_atomic_load_int8(const int8_t *obj)
|
| 418 |
+
{
|
| 419 |
+
_Py_USING_STD;
|
| 420 |
+
return atomic_load((const _Atomic(int8_t)*)obj);
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
static inline int16_t
|
| 424 |
+
_Py_atomic_load_int16(const int16_t *obj)
|
| 425 |
+
{
|
| 426 |
+
_Py_USING_STD;
|
| 427 |
+
return atomic_load((const _Atomic(int16_t)*)obj);
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
static inline int32_t
|
| 431 |
+
_Py_atomic_load_int32(const int32_t *obj)
|
| 432 |
+
{
|
| 433 |
+
_Py_USING_STD;
|
| 434 |
+
return atomic_load((const _Atomic(int32_t)*)obj);
|
| 435 |
+
}
|
| 436 |
+
|
| 437 |
+
static inline int64_t
|
| 438 |
+
_Py_atomic_load_int64(const int64_t *obj)
|
| 439 |
+
{
|
| 440 |
+
_Py_USING_STD;
|
| 441 |
+
return atomic_load((const _Atomic(int64_t)*)obj);
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
+
static inline intptr_t
|
| 445 |
+
_Py_atomic_load_intptr(const intptr_t *obj)
|
| 446 |
+
{
|
| 447 |
+
_Py_USING_STD;
|
| 448 |
+
return atomic_load((const _Atomic(intptr_t)*)obj);
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
static inline uint8_t
|
| 452 |
+
_Py_atomic_load_uint8(const uint8_t *obj)
|
| 453 |
+
{
|
| 454 |
+
_Py_USING_STD;
|
| 455 |
+
return atomic_load((const _Atomic(uint8_t)*)obj);
|
| 456 |
+
}
|
| 457 |
+
|
| 458 |
+
static inline uint16_t
|
| 459 |
+
_Py_atomic_load_uint16(const uint16_t *obj)
|
| 460 |
+
{
|
| 461 |
+
_Py_USING_STD;
|
| 462 |
+
return atomic_load((const _Atomic(uint32_t)*)obj);
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
static inline uint32_t
|
| 466 |
+
_Py_atomic_load_uint32(const uint32_t *obj)
|
| 467 |
+
{
|
| 468 |
+
_Py_USING_STD;
|
| 469 |
+
return atomic_load((const _Atomic(uint32_t)*)obj);
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
static inline uint64_t
|
| 473 |
+
_Py_atomic_load_uint64(const uint64_t *obj)
|
| 474 |
+
{
|
| 475 |
+
_Py_USING_STD;
|
| 476 |
+
return atomic_load((const _Atomic(uint64_t)*)obj);
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
static inline uintptr_t
|
| 480 |
+
_Py_atomic_load_uintptr(const uintptr_t *obj)
|
| 481 |
+
{
|
| 482 |
+
_Py_USING_STD;
|
| 483 |
+
return atomic_load((const _Atomic(uintptr_t)*)obj);
|
| 484 |
+
}
|
| 485 |
+
|
| 486 |
+
static inline unsigned int
|
| 487 |
+
_Py_atomic_load_uint(const unsigned int *obj)
|
| 488 |
+
{
|
| 489 |
+
_Py_USING_STD;
|
| 490 |
+
return atomic_load((const _Atomic(unsigned int)*)obj);
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
static inline Py_ssize_t
|
| 494 |
+
_Py_atomic_load_ssize(const Py_ssize_t *obj)
|
| 495 |
+
{
|
| 496 |
+
_Py_USING_STD;
|
| 497 |
+
return atomic_load((const _Atomic(Py_ssize_t)*)obj);
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
static inline void*
|
| 501 |
+
_Py_atomic_load_ptr(const void *obj)
|
| 502 |
+
{
|
| 503 |
+
_Py_USING_STD;
|
| 504 |
+
return atomic_load((const _Atomic(void*)*)obj);
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
// --- _Py_atomic_load_relaxed -----------------------------------------------
|
| 509 |
+
|
| 510 |
+
static inline int
|
| 511 |
+
_Py_atomic_load_int_relaxed(const int *obj)
|
| 512 |
+
{
|
| 513 |
+
_Py_USING_STD;
|
| 514 |
+
return atomic_load_explicit((const _Atomic(int)*)obj,
|
| 515 |
+
memory_order_relaxed);
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
static inline int8_t
|
| 519 |
+
_Py_atomic_load_int8_relaxed(const int8_t *obj)
|
| 520 |
+
{
|
| 521 |
+
_Py_USING_STD;
|
| 522 |
+
return atomic_load_explicit((const _Atomic(int8_t)*)obj,
|
| 523 |
+
memory_order_relaxed);
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
+
static inline int16_t
|
| 527 |
+
_Py_atomic_load_int16_relaxed(const int16_t *obj)
|
| 528 |
+
{
|
| 529 |
+
_Py_USING_STD;
|
| 530 |
+
return atomic_load_explicit((const _Atomic(int16_t)*)obj,
|
| 531 |
+
memory_order_relaxed);
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
static inline int32_t
|
| 535 |
+
_Py_atomic_load_int32_relaxed(const int32_t *obj)
|
| 536 |
+
{
|
| 537 |
+
_Py_USING_STD;
|
| 538 |
+
return atomic_load_explicit((const _Atomic(int32_t)*)obj,
|
| 539 |
+
memory_order_relaxed);
|
| 540 |
+
}
|
| 541 |
+
|
| 542 |
+
static inline int64_t
|
| 543 |
+
_Py_atomic_load_int64_relaxed(const int64_t *obj)
|
| 544 |
+
{
|
| 545 |
+
_Py_USING_STD;
|
| 546 |
+
return atomic_load_explicit((const _Atomic(int64_t)*)obj,
|
| 547 |
+
memory_order_relaxed);
|
| 548 |
+
}
|
| 549 |
+
|
| 550 |
+
static inline intptr_t
|
| 551 |
+
_Py_atomic_load_intptr_relaxed(const intptr_t *obj)
|
| 552 |
+
{
|
| 553 |
+
_Py_USING_STD;
|
| 554 |
+
return atomic_load_explicit((const _Atomic(intptr_t)*)obj,
|
| 555 |
+
memory_order_relaxed);
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
static inline uint8_t
|
| 559 |
+
_Py_atomic_load_uint8_relaxed(const uint8_t *obj)
|
| 560 |
+
{
|
| 561 |
+
_Py_USING_STD;
|
| 562 |
+
return atomic_load_explicit((const _Atomic(uint8_t)*)obj,
|
| 563 |
+
memory_order_relaxed);
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
+
static inline uint16_t
|
| 567 |
+
_Py_atomic_load_uint16_relaxed(const uint16_t *obj)
|
| 568 |
+
{
|
| 569 |
+
_Py_USING_STD;
|
| 570 |
+
return atomic_load_explicit((const _Atomic(uint16_t)*)obj,
|
| 571 |
+
memory_order_relaxed);
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
static inline uint32_t
|
| 575 |
+
_Py_atomic_load_uint32_relaxed(const uint32_t *obj)
|
| 576 |
+
{
|
| 577 |
+
_Py_USING_STD;
|
| 578 |
+
return atomic_load_explicit((const _Atomic(uint32_t)*)obj,
|
| 579 |
+
memory_order_relaxed);
|
| 580 |
+
}
|
| 581 |
+
|
| 582 |
+
static inline uint64_t
|
| 583 |
+
_Py_atomic_load_uint64_relaxed(const uint64_t *obj)
|
| 584 |
+
{
|
| 585 |
+
_Py_USING_STD;
|
| 586 |
+
return atomic_load_explicit((const _Atomic(uint64_t)*)obj,
|
| 587 |
+
memory_order_relaxed);
|
| 588 |
+
}
|
| 589 |
+
|
| 590 |
+
static inline uintptr_t
|
| 591 |
+
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
|
| 592 |
+
{
|
| 593 |
+
_Py_USING_STD;
|
| 594 |
+
return atomic_load_explicit((const _Atomic(uintptr_t)*)obj,
|
| 595 |
+
memory_order_relaxed);
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
static inline unsigned int
|
| 599 |
+
_Py_atomic_load_uint_relaxed(const unsigned int *obj)
|
| 600 |
+
{
|
| 601 |
+
_Py_USING_STD;
|
| 602 |
+
return atomic_load_explicit((const _Atomic(unsigned int)*)obj,
|
| 603 |
+
memory_order_relaxed);
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
static inline Py_ssize_t
|
| 607 |
+
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
|
| 608 |
+
{
|
| 609 |
+
_Py_USING_STD;
|
| 610 |
+
return atomic_load_explicit((const _Atomic(Py_ssize_t)*)obj,
|
| 611 |
+
memory_order_relaxed);
|
| 612 |
+
}
|
| 613 |
+
|
| 614 |
+
static inline void*
|
| 615 |
+
_Py_atomic_load_ptr_relaxed(const void *obj)
|
| 616 |
+
{
|
| 617 |
+
_Py_USING_STD;
|
| 618 |
+
return atomic_load_explicit((const _Atomic(void*)*)obj,
|
| 619 |
+
memory_order_relaxed);
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
static inline unsigned long long
|
| 623 |
+
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
|
| 624 |
+
{
|
| 625 |
+
_Py_USING_STD;
|
| 626 |
+
return atomic_load_explicit((const _Atomic(unsigned long long)*)obj,
|
| 627 |
+
memory_order_relaxed);
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
+
|
| 631 |
+
// --- _Py_atomic_store ------------------------------------------------------
|
| 632 |
+
|
| 633 |
+
static inline void
|
| 634 |
+
_Py_atomic_store_int(int *obj, int value)
|
| 635 |
+
{
|
| 636 |
+
_Py_USING_STD;
|
| 637 |
+
atomic_store((_Atomic(int)*)obj, value);
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
static inline void
|
| 641 |
+
_Py_atomic_store_int8(int8_t *obj, int8_t value)
|
| 642 |
+
{
|
| 643 |
+
_Py_USING_STD;
|
| 644 |
+
atomic_store((_Atomic(int8_t)*)obj, value);
|
| 645 |
+
}
|
| 646 |
+
|
| 647 |
+
static inline void
|
| 648 |
+
_Py_atomic_store_int16(int16_t *obj, int16_t value)
|
| 649 |
+
{
|
| 650 |
+
_Py_USING_STD;
|
| 651 |
+
atomic_store((_Atomic(int16_t)*)obj, value);
|
| 652 |
+
}
|
| 653 |
+
|
| 654 |
+
static inline void
|
| 655 |
+
_Py_atomic_store_int32(int32_t *obj, int32_t value)
|
| 656 |
+
{
|
| 657 |
+
_Py_USING_STD;
|
| 658 |
+
atomic_store((_Atomic(int32_t)*)obj, value);
|
| 659 |
+
}
|
| 660 |
+
|
| 661 |
+
static inline void
|
| 662 |
+
_Py_atomic_store_int64(int64_t *obj, int64_t value)
|
| 663 |
+
{
|
| 664 |
+
_Py_USING_STD;
|
| 665 |
+
atomic_store((_Atomic(int64_t)*)obj, value);
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
static inline void
|
| 669 |
+
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
|
| 670 |
+
{
|
| 671 |
+
_Py_USING_STD;
|
| 672 |
+
atomic_store((_Atomic(intptr_t)*)obj, value);
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
static inline void
|
| 676 |
+
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
|
| 677 |
+
{
|
| 678 |
+
_Py_USING_STD;
|
| 679 |
+
atomic_store((_Atomic(uint8_t)*)obj, value);
|
| 680 |
+
}
|
| 681 |
+
|
| 682 |
+
static inline void
|
| 683 |
+
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
|
| 684 |
+
{
|
| 685 |
+
_Py_USING_STD;
|
| 686 |
+
atomic_store((_Atomic(uint16_t)*)obj, value);
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
static inline void
|
| 690 |
+
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
|
| 691 |
+
{
|
| 692 |
+
_Py_USING_STD;
|
| 693 |
+
atomic_store((_Atomic(uint32_t)*)obj, value);
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
+
static inline void
|
| 697 |
+
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
|
| 698 |
+
{
|
| 699 |
+
_Py_USING_STD;
|
| 700 |
+
atomic_store((_Atomic(uint64_t)*)obj, value);
|
| 701 |
+
}
|
| 702 |
+
|
| 703 |
+
static inline void
|
| 704 |
+
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
|
| 705 |
+
{
|
| 706 |
+
_Py_USING_STD;
|
| 707 |
+
atomic_store((_Atomic(uintptr_t)*)obj, value);
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
static inline void
|
| 711 |
+
_Py_atomic_store_uint(unsigned int *obj, unsigned int value)
|
| 712 |
+
{
|
| 713 |
+
_Py_USING_STD;
|
| 714 |
+
atomic_store((_Atomic(unsigned int)*)obj, value);
|
| 715 |
+
}
|
| 716 |
+
|
| 717 |
+
static inline void
|
| 718 |
+
_Py_atomic_store_ptr(void *obj, void *value)
|
| 719 |
+
{
|
| 720 |
+
_Py_USING_STD;
|
| 721 |
+
atomic_store((_Atomic(void*)*)obj, value);
|
| 722 |
+
}
|
| 723 |
+
|
| 724 |
+
static inline void
|
| 725 |
+
_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
|
| 726 |
+
{
|
| 727 |
+
_Py_USING_STD;
|
| 728 |
+
atomic_store((_Atomic(Py_ssize_t)*)obj, value);
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
|
| 732 |
+
// --- _Py_atomic_store_relaxed ----------------------------------------------
|
| 733 |
+
|
| 734 |
+
static inline void
|
| 735 |
+
_Py_atomic_store_int_relaxed(int *obj, int value)
|
| 736 |
+
{
|
| 737 |
+
_Py_USING_STD;
|
| 738 |
+
atomic_store_explicit((_Atomic(int)*)obj, value,
|
| 739 |
+
memory_order_relaxed);
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
static inline void
|
| 743 |
+
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
|
| 744 |
+
{
|
| 745 |
+
_Py_USING_STD;
|
| 746 |
+
atomic_store_explicit((_Atomic(int8_t)*)obj, value,
|
| 747 |
+
memory_order_relaxed);
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
static inline void
|
| 751 |
+
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
|
| 752 |
+
{
|
| 753 |
+
_Py_USING_STD;
|
| 754 |
+
atomic_store_explicit((_Atomic(int16_t)*)obj, value,
|
| 755 |
+
memory_order_relaxed);
|
| 756 |
+
}
|
| 757 |
+
|
| 758 |
+
static inline void
|
| 759 |
+
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
|
| 760 |
+
{
|
| 761 |
+
_Py_USING_STD;
|
| 762 |
+
atomic_store_explicit((_Atomic(int32_t)*)obj, value,
|
| 763 |
+
memory_order_relaxed);
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
static inline void
|
| 767 |
+
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
|
| 768 |
+
{
|
| 769 |
+
_Py_USING_STD;
|
| 770 |
+
atomic_store_explicit((_Atomic(int64_t)*)obj, value,
|
| 771 |
+
memory_order_relaxed);
|
| 772 |
+
}
|
| 773 |
+
|
| 774 |
+
static inline void
|
| 775 |
+
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
|
| 776 |
+
{
|
| 777 |
+
_Py_USING_STD;
|
| 778 |
+
atomic_store_explicit((_Atomic(intptr_t)*)obj, value,
|
| 779 |
+
memory_order_relaxed);
|
| 780 |
+
}
|
| 781 |
+
|
| 782 |
+
static inline void
|
| 783 |
+
_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
|
| 784 |
+
{
|
| 785 |
+
_Py_USING_STD;
|
| 786 |
+
atomic_store_explicit((_Atomic(uint8_t)*)obj, value,
|
| 787 |
+
memory_order_relaxed);
|
| 788 |
+
}
|
| 789 |
+
|
| 790 |
+
static inline void
|
| 791 |
+
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
|
| 792 |
+
{
|
| 793 |
+
_Py_USING_STD;
|
| 794 |
+
atomic_store_explicit((_Atomic(uint16_t)*)obj, value,
|
| 795 |
+
memory_order_relaxed);
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
static inline void
|
| 799 |
+
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
|
| 800 |
+
{
|
| 801 |
+
_Py_USING_STD;
|
| 802 |
+
atomic_store_explicit((_Atomic(uint32_t)*)obj, value,
|
| 803 |
+
memory_order_relaxed);
|
| 804 |
+
}
|
| 805 |
+
|
| 806 |
+
static inline void
|
| 807 |
+
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
|
| 808 |
+
{
|
| 809 |
+
_Py_USING_STD;
|
| 810 |
+
atomic_store_explicit((_Atomic(uint64_t)*)obj, value,
|
| 811 |
+
memory_order_relaxed);
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
static inline void
|
| 815 |
+
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
|
| 816 |
+
{
|
| 817 |
+
_Py_USING_STD;
|
| 818 |
+
atomic_store_explicit((_Atomic(uintptr_t)*)obj, value,
|
| 819 |
+
memory_order_relaxed);
|
| 820 |
+
}
|
| 821 |
+
|
| 822 |
+
static inline void
|
| 823 |
+
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
|
| 824 |
+
{
|
| 825 |
+
_Py_USING_STD;
|
| 826 |
+
atomic_store_explicit((_Atomic(unsigned int)*)obj, value,
|
| 827 |
+
memory_order_relaxed);
|
| 828 |
+
}
|
| 829 |
+
|
| 830 |
+
static inline void
|
| 831 |
+
_Py_atomic_store_ptr_relaxed(void *obj, void *value)
|
| 832 |
+
{
|
| 833 |
+
_Py_USING_STD;
|
| 834 |
+
atomic_store_explicit((_Atomic(void*)*)obj, value,
|
| 835 |
+
memory_order_relaxed);
|
| 836 |
+
}
|
| 837 |
+
|
| 838 |
+
static inline void
|
| 839 |
+
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
|
| 840 |
+
{
|
| 841 |
+
_Py_USING_STD;
|
| 842 |
+
atomic_store_explicit((_Atomic(Py_ssize_t)*)obj, value,
|
| 843 |
+
memory_order_relaxed);
|
| 844 |
+
}
|
| 845 |
+
|
| 846 |
+
static inline void
|
| 847 |
+
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
|
| 848 |
+
unsigned long long value)
|
| 849 |
+
{
|
| 850 |
+
_Py_USING_STD;
|
| 851 |
+
atomic_store_explicit((_Atomic(unsigned long long)*)obj, value,
|
| 852 |
+
memory_order_relaxed);
|
| 853 |
+
}
|
| 854 |
+
|
| 855 |
+
|
| 856 |
+
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
|
| 857 |
+
|
| 858 |
+
static inline void *
|
| 859 |
+
_Py_atomic_load_ptr_acquire(const void *obj)
|
| 860 |
+
{
|
| 861 |
+
_Py_USING_STD;
|
| 862 |
+
return atomic_load_explicit((const _Atomic(void*)*)obj,
|
| 863 |
+
memory_order_acquire);
|
| 864 |
+
}
|
| 865 |
+
|
| 866 |
+
static inline uintptr_t
|
| 867 |
+
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
|
| 868 |
+
{
|
| 869 |
+
_Py_USING_STD;
|
| 870 |
+
return atomic_load_explicit((const _Atomic(uintptr_t)*)obj,
|
| 871 |
+
memory_order_acquire);
|
| 872 |
+
}
|
| 873 |
+
|
| 874 |
+
static inline void
|
| 875 |
+
_Py_atomic_store_ptr_release(void *obj, void *value)
|
| 876 |
+
{
|
| 877 |
+
_Py_USING_STD;
|
| 878 |
+
atomic_store_explicit((_Atomic(void*)*)obj, value,
|
| 879 |
+
memory_order_release);
|
| 880 |
+
}
|
| 881 |
+
|
| 882 |
+
static inline void
|
| 883 |
+
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
|
| 884 |
+
{
|
| 885 |
+
_Py_USING_STD;
|
| 886 |
+
atomic_store_explicit((_Atomic(uintptr_t)*)obj, value,
|
| 887 |
+
memory_order_release);
|
| 888 |
+
}
|
| 889 |
+
|
| 890 |
+
static inline void
|
| 891 |
+
_Py_atomic_store_int_release(int *obj, int value)
|
| 892 |
+
{
|
| 893 |
+
_Py_USING_STD;
|
| 894 |
+
atomic_store_explicit((_Atomic(int)*)obj, value,
|
| 895 |
+
memory_order_release);
|
| 896 |
+
}
|
| 897 |
+
|
| 898 |
+
static inline void
|
| 899 |
+
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
|
| 900 |
+
{
|
| 901 |
+
_Py_USING_STD;
|
| 902 |
+
atomic_store_explicit((_Atomic(Py_ssize_t)*)obj, value,
|
| 903 |
+
memory_order_release);
|
| 904 |
+
}
|
| 905 |
+
|
| 906 |
+
static inline int
|
| 907 |
+
_Py_atomic_load_int_acquire(const int *obj)
|
| 908 |
+
{
|
| 909 |
+
_Py_USING_STD;
|
| 910 |
+
return atomic_load_explicit((const _Atomic(int)*)obj,
|
| 911 |
+
memory_order_acquire);
|
| 912 |
+
}
|
| 913 |
+
|
| 914 |
+
static inline void
|
| 915 |
+
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
|
| 916 |
+
{
|
| 917 |
+
_Py_USING_STD;
|
| 918 |
+
atomic_store_explicit((_Atomic(uint32_t)*)obj, value,
|
| 919 |
+
memory_order_release);
|
| 920 |
+
}
|
| 921 |
+
|
| 922 |
+
static inline void
|
| 923 |
+
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
|
| 924 |
+
{
|
| 925 |
+
_Py_USING_STD;
|
| 926 |
+
atomic_store_explicit((_Atomic(uint64_t)*)obj, value,
|
| 927 |
+
memory_order_release);
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
static inline uint64_t
|
| 931 |
+
_Py_atomic_load_uint64_acquire(const uint64_t *obj)
|
| 932 |
+
{
|
| 933 |
+
_Py_USING_STD;
|
| 934 |
+
return atomic_load_explicit((const _Atomic(uint64_t)*)obj,
|
| 935 |
+
memory_order_acquire);
|
| 936 |
+
}
|
| 937 |
+
|
| 938 |
+
static inline uint32_t
|
| 939 |
+
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
|
| 940 |
+
{
|
| 941 |
+
_Py_USING_STD;
|
| 942 |
+
return atomic_load_explicit((const _Atomic(uint32_t)*)obj,
|
| 943 |
+
memory_order_acquire);
|
| 944 |
+
}
|
| 945 |
+
|
| 946 |
+
static inline Py_ssize_t
|
| 947 |
+
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
|
| 948 |
+
{
|
| 949 |
+
_Py_USING_STD;
|
| 950 |
+
return atomic_load_explicit((const _Atomic(Py_ssize_t)*)obj,
|
| 951 |
+
memory_order_acquire);
|
| 952 |
+
}
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
// --- _Py_atomic_fence ------------------------------------------------------
|
| 956 |
+
|
| 957 |
+
static inline void
|
| 958 |
+
_Py_atomic_fence_seq_cst(void)
|
| 959 |
+
{
|
| 960 |
+
_Py_USING_STD;
|
| 961 |
+
atomic_thread_fence(memory_order_seq_cst);
|
| 962 |
+
}
|
| 963 |
+
|
| 964 |
+
static inline void
|
| 965 |
+
_Py_atomic_fence_acquire(void)
|
| 966 |
+
{
|
| 967 |
+
_Py_USING_STD;
|
| 968 |
+
atomic_thread_fence(memory_order_acquire);
|
| 969 |
+
}
|
| 970 |
+
|
| 971 |
+
static inline void
|
| 972 |
+
_Py_atomic_fence_release(void)
|
| 973 |
+
{
|
| 974 |
+
_Py_USING_STD;
|
| 975 |
+
atomic_thread_fence(memory_order_release);
|
| 976 |
+
}
|