Compare commits
33 Commits
engjam_uic
...
master
Author | SHA1 | Date |
---|---|---|
John McCardle | 232105a893 | |
John McCardle | c2de9b08d6 | |
John McCardle | a465a9861d | |
John McCardle | ac7f7052cd | |
John McCardle | 1a7186f745 | |
John McCardle | fbf263a038 | |
John McCardle | f82508b753 | |
John McCardle | 4ffe438d1b | |
John McCardle | cdaf309272 | |
John McCardle | 2c3c1449ee | |
John McCardle | 8739da8463 | |
John McCardle | 45f07b7226 | |
John McCardle | 9eb9562b9f | |
John McCardle | 5ada446360 | |
John McCardle | 8e1552eec5 | |
John McCardle | aa7f2ba605 | |
John McCardle | e8240cb380 | |
John McCardle | db548c9183 | |
John McCardle | 4b31864b2f | |
John McCardle | 343669df1e | |
John McCardle | d417bdc8a3 | |
John McCardle | ccd79fc551 | |
John McCardle | 9d728ee902 | |
John McCardle | 9587218b28 | |
John McCardle | 6a1edfe182 | |
John McCardle | 145012074c | |
John McCardle | 30cfa5ca71 | |
John McCardle | 6de3f0e8cf | |
John McCardle | 08772111de | |
John McCardle | 4dd4f74120 | |
John McCardle | 197211fa76 | |
John McCardle | 198ed337e3 | |
John McCardle | 07b597d6f2 |
|
@ -6,4 +6,7 @@ bin
|
||||||
PCbuild
|
PCbuild
|
||||||
.vs
|
.vs
|
||||||
obj
|
obj
|
||||||
|
build
|
||||||
|
lib
|
||||||
|
obj
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
[submodule "modules/imgui"]
|
||||||
|
path = modules/imgui
|
||||||
|
url = git@github.com:SFML/imgui-sfml.git
|
||||||
|
[submodule "modules/imgui-sfml"]
|
||||||
|
path = modules/imgui-sfml
|
||||||
|
url = git@github.com:SFML/imgui-sfml.git
|
||||||
|
[submodule "modules/cpython"]
|
||||||
|
path = modules/cpython
|
||||||
|
url = git@github.com:python/cpython.git
|
||||||
|
[submodule "modules/SFML"]
|
||||||
|
path = modules/SFML
|
||||||
|
url = git@github.com:SFML/SFML.git
|
||||||
|
[submodule "modules/libtcod"]
|
||||||
|
path = modules/libtcod
|
||||||
|
url = git@github.com:libtcod/libtcod.git
|
|
@ -0,0 +1,75 @@
|
||||||
|
# Minimum version of CMake required
|
||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
# Project name
|
||||||
|
project(McRogueFace)
|
||||||
|
|
||||||
|
# Specify the C++ standard
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
|
# Add include directories
|
||||||
|
#include_directories(${CMAKE_SOURCE_DIR}/deps_linux)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps)
|
||||||
|
#include_directories(${CMAKE_SOURCE_DIR}/deps_linux/Python-3.11.1)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps/libtcod)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps/cpython)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps/Python)
|
||||||
|
|
||||||
|
# Collect all the source files
|
||||||
|
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
|
|
||||||
|
# Create a list of libraries to link against
|
||||||
|
set(LINK_LIBS
|
||||||
|
m
|
||||||
|
dl
|
||||||
|
util
|
||||||
|
pthread
|
||||||
|
python3.12
|
||||||
|
sfml-graphics
|
||||||
|
sfml-window
|
||||||
|
sfml-system
|
||||||
|
sfml-audio
|
||||||
|
tcod)
|
||||||
|
|
||||||
|
# On Windows, add any additional libs and include directories
|
||||||
|
if(WIN32)
|
||||||
|
# Add the necessary Windows-specific libraries and include directories
|
||||||
|
# include_directories(path_to_additional_includes)
|
||||||
|
# link_directories(path_to_additional_libs)
|
||||||
|
# list(APPEND LINK_LIBS additional_windows_libs)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/windows)
|
||||||
|
else()
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/linux)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add the directory where the linker should look for the libraries
|
||||||
|
#link_directories(${CMAKE_SOURCE_DIR}/deps_linux)
|
||||||
|
link_directories(${CMAKE_SOURCE_DIR}/lib)
|
||||||
|
|
||||||
|
# Define the executable target before linking libraries
|
||||||
|
add_executable(mcrogueface ${SOURCES})
|
||||||
|
|
||||||
|
# Now the linker will find the libraries in the specified directory
|
||||||
|
target_link_libraries(mcrogueface ${LINK_LIBS})
|
||||||
|
|
||||||
|
# Copy assets to build directory post-build
|
||||||
|
add_custom_command(TARGET mcrogueface POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/assets $<TARGET_FILE_DIR:mcrogueface>/assets)
|
||||||
|
|
||||||
|
# Copy Python scripts to build directory post-build
|
||||||
|
add_custom_command(TARGET mcrogueface POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/src/scripts $<TARGET_FILE_DIR:mcrogueface>/scripts)
|
||||||
|
|
||||||
|
# Copy Python standard library to build directory
|
||||||
|
add_custom_command(TARGET mcrogueface POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/lib $<TARGET_FILE_DIR:mcrogueface>/lib)
|
||||||
|
|
||||||
|
# rpath for including shared libraries
|
||||||
|
set_target_properties(mcrogueface PROPERTIES
|
||||||
|
INSTALL_RPATH "./lib")
|
||||||
|
|
101
JANKFILE.md
101
JANKFILE.md
|
@ -1,101 +0,0 @@
|
||||||
```
|
|
||||||
* python API overhaul
|
|
||||||
* At the very least, a function to turn a color tuple to sf::Color would be good.
|
|
||||||
All the sf::Color objects going into / out of Python need to support transparency (4th value of Alpha) - Python would tolerate it, C++ needs to allow it (parse "iii|i", default alpha of 0 for fully nontransparent)
|
|
||||||
* The entire method of reading properties to re-ingest Grids/Menus is stupid.
|
|
||||||
C++ classes should be exposed more directly, or have clean methods to accept the changes from Python code.
|
|
||||||
* return actual exceptions instead of std::cout and NULL
|
|
||||||
* smart pointers (`std::shared_ptr<PyObject>`) to C++-ify Python object passing? Can this be made to work with reference counting?
|
|
||||||
* Raise Exceptions - see *janknote* in the Animation API method
|
|
||||||
* C++ hygene: Make data members private, call getter/setter methods
|
|
||||||
* std::shared_ptr, not bare pointers. The grid/entity/component connections suffer from this
|
|
||||||
* SFML: "widget" hierarchy. Keep all sizes/positions in the RectangleShape objects. Make Grid and UIMenu subclasses of the same base, and keep a single map of drawable widgets.
|
|
||||||
* UIMenu should become a "frame", and draw any objects of the "Widget" class relatively to its own positions
|
|
||||||
* "Widget" as an abstract class should set the template for going to/from Python; don't copy to and from Python, the C++ object *is* the Python object.
|
|
||||||
* ==Buttons don't know their parent...?== So there's arithmetic happening in the event loop to determine it's actual positions. Fix this with the widgets-on-widgets system (so we can go deeper, and just ask the widgets if they or their children were clicked)
|
|
||||||
* Keep aspect ratio correct (and hopefully unbork any mouse issues) when maximizing / full screening the game
|
|
||||||
```
|
|
||||||
|
|
||||||
# r/RoguelikeDev Does the Complete Roguelike Tutorial - July 2023
|
|
||||||
|
|
||||||
## Planning
|
|
||||||
|
|
||||||
Event ends roughly 26 August (last post will be 22 August)
|
|
||||||
|
|
||||||
* Add and remove keystroke registration from Python scripts
|
|
||||||
* Error checking: raise Python exceptions instead of null reference segfault in C++
|
|
||||||
* Proper exception handling: figure out the "any code at REPL shows the unhandled exception" bug thingy
|
|
||||||
* Extra clarity: display more status info about what Python stuff is being done
|
|
||||||
- load all files in directory at first
|
|
||||||
- list modules / classes found
|
|
||||||
- list Scenes that were found
|
|
||||||
- Read all Python modules, then call objects & methods at C++-managed events (Engine provided decorators, perhaps??)
|
|
||||||
* PythonScene version of MenuScene
|
|
||||||
- instantiate PythonScenes
|
|
||||||
* Switch Scenes from Python (edge of board / stairs / teleportation feature)
|
|
||||||
* Update the visible map from Python (fix "map blank until you move" bug)
|
|
||||||
- update "camera state" and "Recenter camera" buttons' API info as well without a whole Turn
|
|
||||||
* C++/TCOD Entity pathfinding without calling Python every Turn
|
|
||||||
* Replace jank .py files that define engine-required objects with C++ definitions inside of `mcrfpy` module
|
|
||||||
|
|
||||||
This actually a pretty big list, but there's about 7 weeks left, so it's just over one item per week.
|
|
||||||
|
|
||||||
I have no bad feelings if these items leak over to EngJam or beyond.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Notes 12 July
|
|
||||||
|
|
||||||
Some changes to make in McRFPy_API.cpp:
|
|
||||||
* create a parallel to _registerPyAction which will register a keystroke to a Python label in the current scene.
|
|
||||||
|
|
||||||
## Notes 13 July
|
|
||||||
|
|
||||||
- working on API endpoint `_registerInputAction`.
|
|
||||||
|
|
||||||
it will add "_py" as a suffix to the action string and register it along with other scene actions.
|
|
||||||
|
|
||||||
- Adding public Scene methods. These are on the base class with default of return `false`.
|
|
||||||
|
|
||||||
`bool Scene::registerActionInjected(int code, std::string name)` and `unregisterActionInjected`
|
|
||||||
|
|
||||||
the PythonScene (and other scenes that support injected user input) can override this method, check existing registrations, and return `true` when succeeding.
|
|
||||||
|
|
||||||
- then remove `McRFPy_API::player_input`
|
|
||||||
|
|
||||||
This behavior can be more flexibly implemented in Python using keyboard registration. There's some deduplication as well, since I have a Python implementation of collision detection anyway (for items, doors, and NPCs).
|
|
||||||
|
|
||||||
Also, upgraded to C++20 (g++ `c++2a`), mostly because I want to use map::contains.
|
|
||||||
|
|
||||||
More ideas:
|
|
||||||
|
|
||||||
* Need to make "pan" and "zoom" optional on each grid (for minimap type use cases)
|
|
||||||
* clicks are handled by C++ and only used on buttons. Grids could have a Python click function (with pixel & grid coords available)
|
|
||||||
* pixel-on-menu Python click function should be possible too
|
|
||||||
* Need to call a Python update function when C++ events cause camera following to change: UI is only updating after player input
|
|
||||||
|
|
||||||
|
|
||||||
Continue with:
|
|
||||||
|
|
||||||
* implement checks in PythonScene::registerActionInjected - Save injected actions, don't let regular actions be overwritten, return success
|
|
||||||
* Remove PythonScene key definitions and McRFPy_API::player_input
|
|
||||||
* re-implement walking via keyboard input in Python
|
|
||||||
* Find a good spot for camera following to update Python immediately
|
|
||||||
* Find a good spot for grid updates to redraw TCOD line of sight immediately
|
|
||||||
|
|
||||||
## Notes 16 July
|
|
||||||
|
|
||||||
Main problem that came up today: all Python code is executed at the moment the GameEngine instantiates the PythonScene, which is actually when the game starts up. The active scene at that point is the MenuScene, so the Python code registers events against that scene (which rejects injected event binding and has no API functionality).
|
|
||||||
|
|
||||||
Workaround: There's a clickable button that performs the input registration. This is good for working out the behavior, but doesn't really allow Python scripts to properly control and set up their own environment.
|
|
||||||
|
|
||||||
The module name is passed to the PythonScene constructor, and the `start()` method is called to set up class objects. Can I add more methods that are called on this module to swap scenes?
|
|
||||||
|
|
||||||
## Notes 17 July
|
|
||||||
|
|
||||||
The player entity is moving around via Python now!
|
|
||||||
|
|
||||||
Unfortunately, the "actiononce" macro I use in C++ is not the behavior passed on to the Python key events. Key release events are being passed to Python just the way that keypresses are.
|
|
||||||
|
|
||||||
I'll need to expose more of the input event properties down to Python. I also don't like how keycodes are being passed from python to C++, which currently limits user input to key strokes. Mouse buttons and mouse wheel should be possible too (just as they are under the SFML event binding).
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.0 MiB |
|
@ -1,75 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#rm -R bin/linux
|
|
||||||
mkdir -p bin/linux/lib
|
|
||||||
mkdir -p obj
|
|
||||||
rm obj/*
|
|
||||||
|
|
||||||
# copy shared objects, squish "linux" subdirectory in bin/linux/lib
|
|
||||||
#cp -R lib/linux/* bin/linux/lib
|
|
||||||
|
|
||||||
# copy assets directory (font, sprites, etc)
|
|
||||||
cp -R assets bin/linux
|
|
||||||
|
|
||||||
# copy Python code
|
|
||||||
cp -R src/scripts bin/linux/scripts
|
|
||||||
|
|
||||||
# work from output directory and change every g++ path to relative D:<
|
|
||||||
cd bin/linux
|
|
||||||
|
|
||||||
# prepare object files of engine classes
|
|
||||||
abort_compile()
|
|
||||||
{
|
|
||||||
echo "Compilation failed on $fn.cpp"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Precompile engine classes. Get errors in their file, not where they're included
|
|
||||||
for fn in $(ls ../../src/*.cpp -1 | cut -d/ -f4 | cut -d. -f1)
|
|
||||||
do
|
|
||||||
# Skip combined_poc.cpp, it has a duplicate main
|
|
||||||
if [ "$fn" = "combined_poc" ]; then continue; fi
|
|
||||||
|
|
||||||
echo "Compile $fn.cpp"
|
|
||||||
g++ \
|
|
||||||
-I../../deps_linux \
|
|
||||||
-I../../deps_linux/Python-3.11.1 \
|
|
||||||
-I../../platform/linux \
|
|
||||||
--std=c++2a \
|
|
||||||
-c ../../src/$fn.cpp \
|
|
||||||
-o ../../obj/$fn.o \
|
|
||||||
-lm \
|
|
||||||
-ldl \
|
|
||||||
-lutil \
|
|
||||||
-lpthread \
|
|
||||||
-lpython3.11 \
|
|
||||||
-lsfml-graphics \
|
|
||||||
-lsfml-window \
|
|
||||||
-lsfml-system \
|
|
||||||
-lsfml-audio \
|
|
||||||
-ltcod \
|
|
||||||
|| abort_compile $fn
|
|
||||||
done
|
|
||||||
|
|
||||||
# Final executable
|
|
||||||
# --std= : c++2a vs c++17
|
|
||||||
g++ \
|
|
||||||
--std=c++2a \
|
|
||||||
-I../../deps_linux \
|
|
||||||
-I../../deps_linux/Python-3.11.1 \
|
|
||||||
-I../../platform/linux \
|
|
||||||
../../obj/*.o \
|
|
||||||
-o mcrogueface \
|
|
||||||
-Wl,-rpath lib \
|
|
||||||
-L../../deps_linux \
|
|
||||||
-lm \
|
|
||||||
-ldl \
|
|
||||||
-lutil \
|
|
||||||
-lpthread \
|
|
||||||
-lpython3.11 \
|
|
||||||
-lsfml-graphics \
|
|
||||||
-lsfml-window \
|
|
||||||
-lsfml-system \
|
|
||||||
-lsfml-audio \
|
|
||||||
-ltcod \
|
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
aqua #00FFFF
|
||||||
|
black #000000
|
||||||
|
blue #0000FF
|
||||||
|
fuchsia #FF00FF
|
||||||
|
gray #808080
|
||||||
|
green #008000
|
||||||
|
lime #00FF00
|
||||||
|
maroon #800000
|
||||||
|
navy #000080
|
||||||
|
olive #808000
|
||||||
|
purple #800080
|
||||||
|
red #FF0000
|
||||||
|
silver #C0C0C0
|
||||||
|
teal #008080
|
||||||
|
white #FFFFFF
|
||||||
|
yellow #FFFF00
|
||||||
|
aliceblue #F0F8FF
|
||||||
|
antiquewhite #FAEBD7
|
||||||
|
aqua #00FFFF
|
||||||
|
aquamarine #7FFFD4
|
||||||
|
azure #F0FFFF
|
||||||
|
beige #F5F5DC
|
||||||
|
bisque #FFE4C4
|
||||||
|
black #000000
|
||||||
|
blanchedalmond #FFEBCD
|
||||||
|
blue #0000FF
|
||||||
|
blueviolet #8A2BE2
|
||||||
|
brown #A52A2A
|
||||||
|
burlywood #DEB887
|
||||||
|
cadetblue #5F9EA0
|
||||||
|
chartreuse #7FFF00
|
||||||
|
chocolate #D2691E
|
||||||
|
coral #FF7F50
|
||||||
|
cornflowerblue #6495ED
|
||||||
|
cornsilk #FFF8DC
|
||||||
|
crimson #DC143C
|
||||||
|
cyan #00FFFF
|
||||||
|
darkblue #00008B
|
||||||
|
darkcyan #008B8B
|
||||||
|
darkgoldenrod #B8860B
|
||||||
|
darkgray #A9A9A9
|
||||||
|
darkgreen #006400
|
||||||
|
darkkhaki #BDB76B
|
||||||
|
darkmagenta #8B008B
|
||||||
|
darkolivegreen #556B2F
|
||||||
|
darkorange #FF8C00
|
||||||
|
darkorchid #9932CC
|
||||||
|
darkred #8B0000
|
||||||
|
darksalmon #E9967A
|
||||||
|
darkseagreen #8FBC8F
|
||||||
|
darkslateblue #483D8B
|
||||||
|
darkslategray #2F4F4F
|
||||||
|
darkturquoise #00CED1
|
||||||
|
darkviolet #9400D3
|
||||||
|
deeppink #FF1493
|
||||||
|
deepskyblue #00BFFF
|
||||||
|
dimgray #696969
|
||||||
|
dodgerblue #1E90FF
|
||||||
|
firebrick #B22222
|
||||||
|
floralwhite #FFFAF0
|
||||||
|
forestgreen #228B22
|
||||||
|
fuchsia #FF00FF
|
||||||
|
gainsboro #DCDCDC
|
||||||
|
ghostwhite #F8F8FF
|
||||||
|
gold #FFD700
|
||||||
|
goldenrod #DAA520
|
||||||
|
gray #7F7F7F
|
||||||
|
green #008000
|
||||||
|
greenyellow #ADFF2F
|
||||||
|
honeydew #F0FFF0
|
||||||
|
hotpink #FF69B4
|
||||||
|
indianred #CD5C5C
|
||||||
|
indigo #4B0082
|
||||||
|
ivory #FFFFF0
|
||||||
|
khaki #F0E68C
|
||||||
|
lavender #E6E6FA
|
||||||
|
lavenderblush #FFF0F5
|
||||||
|
lawngreen #7CFC00
|
||||||
|
lemonchiffon #FFFACD
|
||||||
|
lightblue #ADD8E6
|
||||||
|
lightcoral #F08080
|
||||||
|
lightcyan #E0FFFF
|
||||||
|
lightgoldenrodyellow #FAFAD2
|
||||||
|
lightgreen #90EE90
|
||||||
|
lightgrey #D3D3D3
|
||||||
|
lightpink #FFB6C1
|
||||||
|
lightsalmon #FFA07A
|
||||||
|
lightseagreen #20B2AA
|
||||||
|
lightskyblue #87CEFA
|
||||||
|
lightslategray #778899
|
||||||
|
lightsteelblue #B0C4DE
|
||||||
|
lightyellow #FFFFE0
|
||||||
|
lime #00FF00
|
||||||
|
limegreen #32CD32
|
||||||
|
linen #FAF0E6
|
||||||
|
magenta #FF00FF
|
||||||
|
maroon #800000
|
||||||
|
mediumaquamarine #66CDAA
|
||||||
|
mediumblue #0000CD
|
||||||
|
mediumorchid #BA55D3
|
||||||
|
mediumpurple #9370DB
|
||||||
|
mediumseagreen #3CB371
|
||||||
|
mediumslateblue #7B68EE
|
||||||
|
mediumspringgreen #00FA9A
|
||||||
|
mediumturquoise #48D1CC
|
||||||
|
mediumvioletred #C71585
|
||||||
|
midnightblue #191970
|
||||||
|
mintcream #F5FFFA
|
||||||
|
mistyrose #FFE4E1
|
||||||
|
moccasin #FFE4B5
|
||||||
|
navajowhite #FFDEAD
|
||||||
|
navy #000080
|
||||||
|
navyblue #9FAFDF
|
||||||
|
oldlace #FDF5E6
|
||||||
|
olive #808000
|
||||||
|
olivedrab #6B8E23
|
||||||
|
orange #FFA500
|
||||||
|
orangered #FF4500
|
||||||
|
orchid #DA70D6
|
||||||
|
palegoldenrod #EEE8AA
|
||||||
|
palegreen #98FB98
|
||||||
|
paleturquoise #AFEEEE
|
||||||
|
palevioletred #DB7093
|
||||||
|
papayawhip #FFEFD5
|
||||||
|
peachpuff #FFDAB9
|
||||||
|
peru #CD853F
|
||||||
|
pink #FFC0CB
|
||||||
|
plum #DDA0DD
|
||||||
|
powderblue #B0E0E6
|
||||||
|
purple #800080
|
||||||
|
red #FF0000
|
||||||
|
rosybrown #BC8F8F
|
||||||
|
royalblue #4169E1
|
||||||
|
saddlebrown #8B4513
|
||||||
|
salmon #FA8072
|
||||||
|
sandybrown #FA8072
|
||||||
|
seagreen #2E8B57
|
||||||
|
seashell #FFF5EE
|
||||||
|
sienna #A0522D
|
||||||
|
silver #C0C0C0
|
||||||
|
skyblue #87CEEB
|
||||||
|
slateblue #6A5ACD
|
||||||
|
slategray #708090
|
||||||
|
snow #FFFAFA
|
||||||
|
springgreen #00FF7F
|
||||||
|
steelblue #4682B4
|
||||||
|
tan #D2B48C
|
||||||
|
teal #008080
|
||||||
|
thistle #D8BFD8
|
||||||
|
tomato #FF6347
|
||||||
|
turquoise #40E0D0
|
||||||
|
violet #EE82EE
|
||||||
|
wheat #F5DEB3
|
||||||
|
white #FFFFFF
|
||||||
|
whitesmoke #F5F5F5
|
||||||
|
yellow #FFFF00
|
||||||
|
yellowgreen #9ACD32
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
cp src/scripts/*.py bin/linux/scripts/
|
|
||||||
cd bin/linux
|
|
||||||
gdb ./mcrogueface
|
|
|
@ -1,109 +0,0 @@
|
||||||
// Entry point of the Python C API.
|
|
||||||
// C extensions should only #include <Python.h>, and not include directly
|
|
||||||
// the other Python header files included by <Python.h>.
|
|
||||||
|
|
||||||
#ifndef Py_PYTHON_H
|
|
||||||
#define Py_PYTHON_H
|
|
||||||
|
|
||||||
// Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" {
|
|
||||||
|
|
||||||
// Include Python header files
|
|
||||||
#include "patchlevel.h"
|
|
||||||
#include "pyconfig.h"
|
|
||||||
#include "pymacconfig.h"
|
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
|
|
||||||
# define _SGI_MP_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// stdlib.h, stdio.h, errno.h and string.h headers are not used by Python
|
|
||||||
// headers, but kept for backward compatibility. They are excluded from the
|
|
||||||
// limited C API of Python 3.11.
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <stdio.h> // FILE*
|
|
||||||
# include <errno.h> // errno
|
|
||||||
# include <string.h> // memcpy()
|
|
||||||
#endif
|
|
||||||
#ifndef MS_WINDOWS
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_STDDEF_H
|
|
||||||
# include <stddef.h> // size_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h> // assert()
|
|
||||||
#include <wchar.h> // wchar_t
|
|
||||||
|
|
||||||
#include "pyport.h"
|
|
||||||
#include "pymacro.h"
|
|
||||||
#include "pymath.h"
|
|
||||||
#include "pymem.h"
|
|
||||||
#include "pytypedefs.h"
|
|
||||||
#include "pybuffer.h"
|
|
||||||
#include "object.h"
|
|
||||||
#include "objimpl.h"
|
|
||||||
#include "typeslots.h"
|
|
||||||
#include "pyhash.h"
|
|
||||||
#include "cpython/pydebug.h"
|
|
||||||
#include "bytearrayobject.h"
|
|
||||||
#include "bytesobject.h"
|
|
||||||
#include "unicodeobject.h"
|
|
||||||
#include "longobject.h"
|
|
||||||
#include "cpython/longintrepr.h"
|
|
||||||
#include "boolobject.h"
|
|
||||||
#include "floatobject.h"
|
|
||||||
#include "complexobject.h"
|
|
||||||
#include "rangeobject.h"
|
|
||||||
#include "memoryobject.h"
|
|
||||||
#include "tupleobject.h"
|
|
||||||
#include "listobject.h"
|
|
||||||
#include "dictobject.h"
|
|
||||||
#include "cpython/odictobject.h"
|
|
||||||
#include "enumobject.h"
|
|
||||||
#include "setobject.h"
|
|
||||||
#include "methodobject.h"
|
|
||||||
#include "moduleobject.h"
|
|
||||||
#include "cpython/funcobject.h"
|
|
||||||
#include "cpython/classobject.h"
|
|
||||||
#include "fileobject.h"
|
|
||||||
#include "pycapsule.h"
|
|
||||||
#include "cpython/code.h"
|
|
||||||
#include "pyframe.h"
|
|
||||||
#include "traceback.h"
|
|
||||||
#include "sliceobject.h"
|
|
||||||
#include "cpython/cellobject.h"
|
|
||||||
#include "iterobject.h"
|
|
||||||
#include "cpython/initconfig.h"
|
|
||||||
#include "pystate.h"
|
|
||||||
#include "cpython/genobject.h"
|
|
||||||
#include "descrobject.h"
|
|
||||||
#include "genericaliasobject.h"
|
|
||||||
#include "warnings.h"
|
|
||||||
#include "weakrefobject.h"
|
|
||||||
#include "structseq.h"
|
|
||||||
#include "cpython/picklebufobject.h"
|
|
||||||
#include "cpython/pytime.h"
|
|
||||||
#include "codecs.h"
|
|
||||||
#include "pyerrors.h"
|
|
||||||
#include "pythread.h"
|
|
||||||
#include "cpython/context.h"
|
|
||||||
#include "modsupport.h"
|
|
||||||
#include "compile.h"
|
|
||||||
#include "pythonrun.h"
|
|
||||||
#include "pylifecycle.h"
|
|
||||||
#include "ceval.h"
|
|
||||||
#include "sysmodule.h"
|
|
||||||
#include "osmodule.h"
|
|
||||||
#include "intrcheck.h"
|
|
||||||
#include "import.h"
|
|
||||||
#include "abstract.h"
|
|
||||||
#include "bltinmodule.h"
|
|
||||||
#include "cpython/pyctype.h"
|
|
||||||
#include "pystrtod.h"
|
|
||||||
#include "pystrcmp.h"
|
|
||||||
#include "fileutils.h"
|
|
||||||
#include "cpython/pyfpe.h"
|
|
||||||
#include "tracemalloc.h"
|
|
||||||
|
|
||||||
#endif /* !Py_PYTHON_H */
|
|
|
@ -1,12 +0,0 @@
|
||||||
The Python C API
|
|
||||||
================
|
|
||||||
|
|
||||||
The C API is divided into three sections:
|
|
||||||
|
|
||||||
1. ``Include/``: Limited API
|
|
||||||
2. ``Include/cpython/``: CPython implementation details
|
|
||||||
3. ``Include/internal/``: The internal API
|
|
||||||
|
|
||||||
Information on changing the C API is available `in the developer guide`_
|
|
||||||
|
|
||||||
.. _in the developer guide: https://devguide.python.org/c-api/
|
|
|
@ -1,873 +0,0 @@
|
||||||
/* Abstract Object Interface (many thanks to Jim Fulton) */
|
|
||||||
|
|
||||||
#ifndef Py_ABSTRACTOBJECT_H
|
|
||||||
#define Py_ABSTRACTOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* === Object Protocol ================================================== */
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_Print(PyObject *o, FILE *fp, int flags);
|
|
||||||
|
|
||||||
Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument
|
|
||||||
is used to enable certain printing options. The only option currently
|
|
||||||
supported is Py_Print_RAW.
|
|
||||||
|
|
||||||
(What should be said about Py_Print_RAW?). */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_HasAttrString(PyObject *o, const char *attr_name);
|
|
||||||
|
|
||||||
Returns 1 if object 'o' has the attribute attr_name, and 0 otherwise.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: hasattr(o,attr_name).
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name);
|
|
||||||
|
|
||||||
Retrieve an attributed named attr_name form object o.
|
|
||||||
Returns the attribute value on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o.attr_name. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_HasAttr(PyObject *o, PyObject *attr_name);
|
|
||||||
|
|
||||||
Returns 1 if o has the attribute attr_name, and 0 otherwise.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: hasattr(o,attr_name).
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name);
|
|
||||||
|
|
||||||
Retrieve an attributed named 'attr_name' form object 'o'.
|
|
||||||
Returns the attribute value on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o.attr_name. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v);
|
|
||||||
|
|
||||||
Set the value of the attribute named attr_name, for object 'o',
|
|
||||||
to the value 'v'. Raise an exception and return -1 on failure; return 0 on
|
|
||||||
success.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement o.attr_name=v. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v);
|
|
||||||
|
|
||||||
Set the value of the attribute named attr_name, for object 'o', to the value
|
|
||||||
'v'. an exception and return -1 on failure; return 0 on success.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement o.attr_name=v. */
|
|
||||||
|
|
||||||
/* Implemented as a macro:
|
|
||||||
|
|
||||||
int PyObject_DelAttrString(PyObject *o, const char *attr_name);
|
|
||||||
|
|
||||||
Delete attribute named attr_name, for object o. Returns
|
|
||||||
-1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: del o.attr_name. */
|
|
||||||
#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL)
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented as a macro:
|
|
||||||
|
|
||||||
int PyObject_DelAttr(PyObject *o, PyObject *attr_name);
|
|
||||||
|
|
||||||
Delete attribute named attr_name, for object o. Returns -1
|
|
||||||
on failure. This is the equivalent of the Python
|
|
||||||
statement: del o.attr_name. */
|
|
||||||
#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL)
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
PyObject *PyObject_Repr(PyObject *o);
|
|
||||||
|
|
||||||
Compute the string representation of object 'o'. Returns the
|
|
||||||
string representation on success, NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: repr(o).
|
|
||||||
|
|
||||||
Called by the repr() built-in function. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
PyObject *PyObject_Str(PyObject *o);
|
|
||||||
|
|
||||||
Compute the string representation of object, o. Returns the
|
|
||||||
string representation on success, NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: str(o).
|
|
||||||
|
|
||||||
Called by the str() and print() built-in functions. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Declared elsewhere
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyCallable_Check(PyObject *o);
|
|
||||||
|
|
||||||
Determine if the object, o, is callable. Return 1 if the object is callable
|
|
||||||
and 0 otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PY_SSIZE_T_CLEAN
|
|
||||||
# define PyObject_CallFunction _PyObject_CallFunction_SizeT
|
|
||||||
# define PyObject_CallMethod _PyObject_CallMethod_SizeT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
|
|
||||||
/* Call a callable Python object without any arguments */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Call a callable Python object 'callable' with arguments given by the
|
|
||||||
tuple 'args' and keywords arguments given by the dictionary 'kwargs'.
|
|
||||||
|
|
||||||
'args' must not be NULL, use an empty tuple if no arguments are
|
|
||||||
needed. If no named arguments are needed, 'kwargs' can be NULL.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression:
|
|
||||||
callable(*args, **kwargs). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable,
|
|
||||||
PyObject *args, PyObject *kwargs);
|
|
||||||
|
|
||||||
|
|
||||||
/* Call a callable Python object 'callable', with arguments given by the
|
|
||||||
tuple 'args'. If no arguments are needed, then 'args' can be NULL.
|
|
||||||
|
|
||||||
Returns the result of the call on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression:
|
|
||||||
callable(*args). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable,
|
|
||||||
PyObject *args);
|
|
||||||
|
|
||||||
/* Call a callable Python object, callable, with a variable number of C
|
|
||||||
arguments. The C arguments are described using a mkvalue-style format
|
|
||||||
string.
|
|
||||||
|
|
||||||
The format may be NULL, indicating that no arguments are provided.
|
|
||||||
|
|
||||||
Returns the result of the call on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression:
|
|
||||||
callable(arg1, arg2, ...). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable,
|
|
||||||
const char *format, ...);
|
|
||||||
|
|
||||||
/* Call the method named 'name' of object 'obj' with a variable number of
|
|
||||||
C arguments. The C arguments are described by a mkvalue format string.
|
|
||||||
|
|
||||||
The format can be NULL, indicating that no arguments are provided.
|
|
||||||
|
|
||||||
Returns the result of the call on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression:
|
|
||||||
obj.name(arg1, arg2, ...). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *obj,
|
|
||||||
const char *name,
|
|
||||||
const char *format, ...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable,
|
|
||||||
const char *format,
|
|
||||||
...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *obj,
|
|
||||||
const char *name,
|
|
||||||
const char *format,
|
|
||||||
...);
|
|
||||||
|
|
||||||
/* Call a callable Python object 'callable' with a variable number of C
|
|
||||||
arguments. The C arguments are provided as PyObject* values, terminated
|
|
||||||
by a NULL.
|
|
||||||
|
|
||||||
Returns the result of the call on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression:
|
|
||||||
callable(arg1, arg2, ...). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable,
|
|
||||||
...);
|
|
||||||
|
|
||||||
/* Call the method named 'name' of object 'obj' with a variable number of
|
|
||||||
C arguments. The C arguments are provided as PyObject* values, terminated
|
|
||||||
by NULL.
|
|
||||||
|
|
||||||
Returns the result of the call on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: obj.name(*args). */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(
|
|
||||||
PyObject *obj,
|
|
||||||
PyObject *name,
|
|
||||||
...);
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
Py_hash_t PyObject_Hash(PyObject *o);
|
|
||||||
|
|
||||||
Compute and return the hash, hash_value, of an object, o. On
|
|
||||||
failure, return -1.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: hash(o). */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_IsTrue(PyObject *o);
|
|
||||||
|
|
||||||
Returns 1 if the object, o, is considered to be true, 0 if o is
|
|
||||||
considered to be false and -1 on failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: not not o. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented elsewhere:
|
|
||||||
|
|
||||||
int PyObject_Not(PyObject *o);
|
|
||||||
|
|
||||||
Returns 0 if the object, o, is considered to be true, 1 if o is
|
|
||||||
considered to be false and -1 on failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: not o. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Get the type of an object.
|
|
||||||
|
|
||||||
On success, returns a type object corresponding to the object type of object
|
|
||||||
'o'. On failure, returns NULL.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: type(o) */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o);
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the size of object 'o'. If the object 'o' provides both sequence and
|
|
||||||
mapping protocols, the sequence size is returned.
|
|
||||||
|
|
||||||
On error, -1 is returned.
|
|
||||||
|
|
||||||
This is the equivalent to the Python expression: len(o) */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o);
|
|
||||||
|
|
||||||
|
|
||||||
/* For DLL compatibility */
|
|
||||||
#undef PyObject_Length
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
|
|
||||||
#define PyObject_Length PyObject_Size
|
|
||||||
|
|
||||||
/* Return element of 'o' corresponding to the object 'key'. Return NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o[key] */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
|
|
||||||
|
|
||||||
|
|
||||||
/* Map the object 'key' to the value 'v' into 'o'.
|
|
||||||
|
|
||||||
Raise an exception and return -1 on failure; return 0 on success.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: o[key]=v. */
|
|
||||||
PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v);
|
|
||||||
|
|
||||||
/* Remove the mapping for the string 'key' from the object 'o'.
|
|
||||||
Returns -1 on failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python statement: del o[key]. */
|
|
||||||
PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, const char *key);
|
|
||||||
|
|
||||||
/* Delete the mapping for the object 'key' from the object 'o'.
|
|
||||||
Returns -1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: del o[key]. */
|
|
||||||
PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key);
|
|
||||||
|
|
||||||
|
|
||||||
/* === Old Buffer API ============================================ */
|
|
||||||
|
|
||||||
/* FIXME: usage of these should all be replaced in Python itself
|
|
||||||
but for backwards compatibility we will implement them.
|
|
||||||
Their usage without a corresponding "unlock" mechanism
|
|
||||||
may create issues (but they would already be there). */
|
|
||||||
|
|
||||||
/* Takes an arbitrary object which must support the (character, single segment)
|
|
||||||
buffer interface and returns a pointer to a read-only memory location
|
|
||||||
usable as character based input for subsequent processing.
|
|
||||||
|
|
||||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
|
||||||
occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
|
|
||||||
const char **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
/* Checks whether an arbitrary object supports the (character, single segment)
|
|
||||||
buffer interface.
|
|
||||||
|
|
||||||
Returns 1 on success, 0 on failure. */
|
|
||||||
Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj);
|
|
||||||
|
|
||||||
/* Same as PyObject_AsCharBuffer() except that this API expects (readable,
|
|
||||||
single segment) buffer interface and returns a pointer to a read-only memory
|
|
||||||
location which can contain arbitrary data.
|
|
||||||
|
|
||||||
0 is returned on success. buffer and buffer_len are only set in case no
|
|
||||||
error occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj,
|
|
||||||
const void **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
/* Takes an arbitrary object which must support the (writable, single segment)
|
|
||||||
buffer interface and returns a pointer to a writable memory location in
|
|
||||||
buffer of size 'buffer_len'.
|
|
||||||
|
|
||||||
Return 0 on success. buffer and buffer_len are only set in case no error
|
|
||||||
occurs. Otherwise, -1 is returned and an exception set. */
|
|
||||||
Py_DEPRECATED(3.0)
|
|
||||||
PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
|
|
||||||
void **buffer,
|
|
||||||
Py_ssize_t *buffer_len);
|
|
||||||
|
|
||||||
|
|
||||||
/* === New Buffer API ============================================ */
|
|
||||||
|
|
||||||
/* Takes an arbitrary object and returns the result of calling
|
|
||||||
obj.__format__(format_spec). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_Format(PyObject *obj,
|
|
||||||
PyObject *format_spec);
|
|
||||||
|
|
||||||
|
|
||||||
/* ==== Iterators ================================================ */
|
|
||||||
|
|
||||||
/* Takes an object and returns an iterator for it.
|
|
||||||
This is typically a new iterator but if the argument is an iterator, this
|
|
||||||
returns itself. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
|
|
||||||
|
|
||||||
/* Takes an AsyncIterable object and returns an AsyncIterator for it.
|
|
||||||
This is typically a new iterator but if the argument is an AsyncIterator,
|
|
||||||
this returns itself. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_GetAIter(PyObject *);
|
|
||||||
|
|
||||||
/* Returns non-zero if the object 'obj' provides iterator protocols, and 0 otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyIter_Check(PyObject *);
|
|
||||||
|
|
||||||
/* Returns non-zero if the object 'obj' provides AsyncIterator protocols, and 0 otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyAIter_Check(PyObject *);
|
|
||||||
|
|
||||||
/* Takes an iterator object and calls its tp_iternext slot,
|
|
||||||
returning the next value.
|
|
||||||
|
|
||||||
If the iterator is exhausted, this returns NULL without setting an
|
|
||||||
exception.
|
|
||||||
|
|
||||||
NULL with an exception means an error occurred. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
|
||||||
|
|
||||||
/* Takes generator, coroutine or iterator object and sends the value into it.
|
|
||||||
Returns:
|
|
||||||
- PYGEN_RETURN (0) if generator has returned.
|
|
||||||
'result' parameter is filled with return value
|
|
||||||
- PYGEN_ERROR (-1) if exception was raised.
|
|
||||||
'result' parameter is NULL
|
|
||||||
- PYGEN_NEXT (1) if generator has yielded.
|
|
||||||
'result' parameter is filled with yielded value. */
|
|
||||||
PyAPI_FUNC(PySendResult) PyIter_Send(PyObject *, PyObject *, PyObject **);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* === Number Protocol ================================================== */
|
|
||||||
|
|
||||||
/* Returns 1 if the object 'o' provides numeric protocols, and 0 otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyNumber_Check(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the result of adding o1 and o2, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 + o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of subtracting o2 from o1, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 - o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of multiplying o1 and o2, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 * o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
|
||||||
/* This is the equivalent of the Python expression: o1 @ o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Returns the result of dividing o1 by o2 giving an integral result,
|
|
||||||
or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 // o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of dividing o1 by o2 giving a float result, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 / o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the remainder of dividing o1 by o2, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 % o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* See the built-in function divmod.
|
|
||||||
|
|
||||||
Returns NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: divmod(o1, o2). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* See the built-in function pow. Returns NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: pow(o1, o2, o3),
|
|
||||||
where o3 is optional. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2,
|
|
||||||
PyObject *o3);
|
|
||||||
|
|
||||||
/* Returns the negation of o on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: -o. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the positive of o on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: +o. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the absolute value of 'o', or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: abs(o). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the bitwise negation of 'o' on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: ~o. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the result of left shifting o1 by o2 on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 << o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of right shifting o1 by o2 on success, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 >> o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of bitwise and of o1 and o2 on success, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 & o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the bitwise exclusive or of o1 by o2 on success, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 ^ o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of bitwise or on o1 and o2 on success, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 | o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns 1 if obj is an index integer (has the nb_index slot of the
|
|
||||||
tp_as_number structure filled in), and 0 otherwise. */
|
|
||||||
PyAPI_FUNC(int) PyIndex_Check(PyObject *);
|
|
||||||
|
|
||||||
/* Returns the object 'o' converted to a Python int, or NULL with an exception
|
|
||||||
raised on failure. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the object 'o' converted to Py_ssize_t by going through
|
|
||||||
PyNumber_Index() first.
|
|
||||||
|
|
||||||
If an overflow error occurs while converting the int to Py_ssize_t, then the
|
|
||||||
second argument 'exc' is the error-type to return. If it is NULL, then the
|
|
||||||
overflow error is cleared and the value is clipped. */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc);
|
|
||||||
|
|
||||||
/* Returns the object 'o' converted to an integer object on success, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: int(o). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the object 'o' converted to a float object on success, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: float(o). */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- In-place variants of (some of) the above number protocol functions -- */
|
|
||||||
|
|
||||||
/* Returns the result of adding o2 to o1, possibly in-place, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 += o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of subtracting o2 from o1, possibly in-place or
|
|
||||||
NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 -= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of multiplying o1 by o2, possibly in-place, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 *= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
|
||||||
/* This is the equivalent of the Python expression: o1 @= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Returns the result of dividing o1 by o2 giving an integral result, possibly
|
|
||||||
in-place, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 /= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1,
|
|
||||||
PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of dividing o1 by o2 giving a float result, possibly
|
|
||||||
in-place, or null on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 /= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1,
|
|
||||||
PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the remainder of dividing o1 by o2, possibly in-place, or NULL on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 %= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of raising o1 to the power of o2, possibly in-place,
|
|
||||||
or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 **= o2,
|
|
||||||
or o1 = pow(o1, o2, o3) if o3 is present. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2,
|
|
||||||
PyObject *o3);
|
|
||||||
|
|
||||||
/* Returns the result of left shifting o1 by o2, possibly in-place, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 <<= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of right shifting o1 by o2, possibly in-place or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 >>= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of bitwise and of o1 and o2, possibly in-place, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 &= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the bitwise exclusive or of o1 by o2, possibly in-place, or NULL
|
|
||||||
on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 ^= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the result of bitwise or of o1 and o2, possibly in-place,
|
|
||||||
or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 |= o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Returns the integer n converted to a string with a base, with a base
|
|
||||||
marker of 0b, 0o or 0x prefixed if applicable.
|
|
||||||
|
|
||||||
If n is not an int object, it is converted with PyNumber_Index first. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base);
|
|
||||||
|
|
||||||
|
|
||||||
/* === Sequence protocol ================================================ */
|
|
||||||
|
|
||||||
/* Return 1 if the object provides sequence protocol, and zero
|
|
||||||
otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PySequence_Check(PyObject *o);
|
|
||||||
|
|
||||||
/* Return the size of sequence object o, or -1 on failure. */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o);
|
|
||||||
|
|
||||||
/* For DLL compatibility */
|
|
||||||
#undef PySequence_Length
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o);
|
|
||||||
#define PySequence_Length PySequence_Size
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the concatenation of o1 and o2 on success, and NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 + o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Return the result of repeating sequence object 'o' 'count' times,
|
|
||||||
or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o * count. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count);
|
|
||||||
|
|
||||||
/* Return the ith element of o, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o[i]. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i);
|
|
||||||
|
|
||||||
/* Return the slice of sequence object o between i1 and i2, or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o[i1:i2]. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
|
||||||
|
|
||||||
/* Assign object 'v' to the ith element of the sequence 'o'. Raise an exception
|
|
||||||
and return -1 on failure; return 0 on success.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement o[i] = v. */
|
|
||||||
PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v);
|
|
||||||
|
|
||||||
/* Delete the 'i'-th element of the sequence 'v'. Returns -1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: del o[i]. */
|
|
||||||
PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i);
|
|
||||||
|
|
||||||
/* Assign the sequence object 'v' to the slice in sequence object 'o',
|
|
||||||
from 'i1' to 'i2'. Returns -1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: o[i1:i2] = v. */
|
|
||||||
PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2,
|
|
||||||
PyObject *v);
|
|
||||||
|
|
||||||
/* Delete the slice in sequence object 'o' from 'i1' to 'i2'.
|
|
||||||
Returns -1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: del o[i1:i2]. */
|
|
||||||
PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2);
|
|
||||||
|
|
||||||
/* Returns the sequence 'o' as a tuple on success, and NULL on failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: tuple(o). */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the sequence 'o' as a list on success, and NULL on failure.
|
|
||||||
This is equivalent to the Python expression: list(o) */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o);
|
|
||||||
|
|
||||||
/* Return the sequence 'o' as a list, unless it's already a tuple or list.
|
|
||||||
|
|
||||||
Use PySequence_Fast_GET_ITEM to access the members of this list, and
|
|
||||||
PySequence_Fast_GET_SIZE to get its length.
|
|
||||||
|
|
||||||
Returns NULL on failure. If the object does not support iteration, raises a
|
|
||||||
TypeError exception with 'm' as the message text. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m);
|
|
||||||
|
|
||||||
/* Return the size of the sequence 'o', assuming that 'o' was returned by
|
|
||||||
PySequence_Fast and is not NULL. */
|
|
||||||
#define PySequence_Fast_GET_SIZE(o) \
|
|
||||||
(PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
|
|
||||||
|
|
||||||
/* Return the 'i'-th element of the sequence 'o', assuming that o was returned
|
|
||||||
by PySequence_Fast, and that i is within bounds. */
|
|
||||||
#define PySequence_Fast_GET_ITEM(o, i)\
|
|
||||||
(PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))
|
|
||||||
|
|
||||||
/* Return a pointer to the underlying item array for
|
|
||||||
an object returned by PySequence_Fast */
|
|
||||||
#define PySequence_Fast_ITEMS(sf) \
|
|
||||||
(PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \
|
|
||||||
: ((PyTupleObject *)(sf))->ob_item)
|
|
||||||
|
|
||||||
/* Return the number of occurrences on value on 'o', that is, return
|
|
||||||
the number of keys for which o[key] == value.
|
|
||||||
|
|
||||||
On failure, return -1. This is equivalent to the Python expression:
|
|
||||||
o.count(value). */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value);
|
|
||||||
|
|
||||||
/* Return 1 if 'ob' is in the sequence 'seq'; 0 if 'ob' is not in the sequence
|
|
||||||
'seq'; -1 on error.
|
|
||||||
|
|
||||||
Use __contains__ if possible, else _PySequence_IterSearch(). */
|
|
||||||
PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob);
|
|
||||||
|
|
||||||
/* For DLL-level backwards compatibility */
|
|
||||||
#undef PySequence_In
|
|
||||||
/* Determine if the sequence 'o' contains 'value'. If an item in 'o' is equal
|
|
||||||
to 'value', return 1, otherwise return 0. On error, return -1.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: value in o. */
|
|
||||||
PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value);
|
|
||||||
|
|
||||||
/* For source-level backwards compatibility */
|
|
||||||
#define PySequence_In PySequence_Contains
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the first index for which o[i] == value.
|
|
||||||
On error, return -1.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: o.index(value). */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- In-place versions of some of the above Sequence functions --- */
|
|
||||||
|
|
||||||
/* Append sequence 'o2' to sequence 'o1', in-place when possible. Return the
|
|
||||||
resulting object, which could be 'o1', or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 += o2. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2);
|
|
||||||
|
|
||||||
/* Repeat sequence 'o' by 'count', in-place when possible. Return the resulting
|
|
||||||
object, which could be 'o', or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o1 *= count. */
|
|
||||||
PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count);
|
|
||||||
|
|
||||||
|
|
||||||
/* === Mapping protocol ================================================= */
|
|
||||||
|
|
||||||
/* Return 1 if the object provides mapping protocol, and 0 otherwise.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyMapping_Check(PyObject *o);
|
|
||||||
|
|
||||||
/* Returns the number of keys in mapping object 'o' on success, and -1 on
|
|
||||||
failure. This is equivalent to the Python expression: len(o). */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o);
|
|
||||||
|
|
||||||
/* For DLL compatibility */
|
|
||||||
#undef PyMapping_Length
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o);
|
|
||||||
#define PyMapping_Length PyMapping_Size
|
|
||||||
|
|
||||||
|
|
||||||
/* Implemented as a macro:
|
|
||||||
|
|
||||||
int PyMapping_DelItemString(PyObject *o, const char *key);
|
|
||||||
|
|
||||||
Remove the mapping for the string 'key' from the mapping 'o'. Returns -1 on
|
|
||||||
failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python statement: del o[key]. */
|
|
||||||
#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K))
|
|
||||||
|
|
||||||
/* Implemented as a macro:
|
|
||||||
|
|
||||||
int PyMapping_DelItem(PyObject *o, PyObject *key);
|
|
||||||
|
|
||||||
Remove the mapping for the object 'key' from the mapping object 'o'.
|
|
||||||
Returns -1 on failure.
|
|
||||||
|
|
||||||
This is equivalent to the Python statement: del o[key]. */
|
|
||||||
#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K))
|
|
||||||
|
|
||||||
/* On success, return 1 if the mapping object 'o' has the key 'key',
|
|
||||||
and 0 otherwise.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: key in o.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, const char *key);
|
|
||||||
|
|
||||||
/* Return 1 if the mapping object has the key 'key', and 0 otherwise.
|
|
||||||
|
|
||||||
This is equivalent to the Python expression: key in o.
|
|
||||||
|
|
||||||
This function always succeeds. */
|
|
||||||
PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key);
|
|
||||||
|
|
||||||
/* On success, return a list or tuple of the keys in mapping object 'o'.
|
|
||||||
On failure, return NULL. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyMapping_Keys(PyObject *o);
|
|
||||||
|
|
||||||
/* On success, return a list or tuple of the values in mapping object 'o'.
|
|
||||||
On failure, return NULL. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyMapping_Values(PyObject *o);
|
|
||||||
|
|
||||||
/* On success, return a list or tuple of the items in mapping object 'o',
|
|
||||||
where each item is a tuple containing a key-value pair. On failure, return
|
|
||||||
NULL. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyMapping_Items(PyObject *o);
|
|
||||||
|
|
||||||
/* Return element of 'o' corresponding to the string 'key' or NULL on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python expression: o[key]. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o,
|
|
||||||
const char *key);
|
|
||||||
|
|
||||||
/* Map the string 'key' to the value 'v' in the mapping 'o'.
|
|
||||||
Returns -1 on failure.
|
|
||||||
|
|
||||||
This is the equivalent of the Python statement: o[key]=v. */
|
|
||||||
PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, const char *key,
|
|
||||||
PyObject *value);
|
|
||||||
|
|
||||||
/* isinstance(object, typeorclass) */
|
|
||||||
PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass);
|
|
||||||
|
|
||||||
/* issubclass(object, typeorclass) */
|
|
||||||
PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_ABSTRACTOBJECT_H
|
|
||||||
# include "cpython/abstract.h"
|
|
||||||
# undef Py_CPYTHON_ABSTRACTOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* Py_ABSTRACTOBJECT_H */
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef Py_BLTINMODULE_H
|
|
||||||
#define Py_BLTINMODULE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyFilter_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyMap_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyZip_Type;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_BLTINMODULE_H */
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* Boolean object interface */
|
|
||||||
|
|
||||||
#ifndef Py_BOOLOBJECT_H
|
|
||||||
#define Py_BOOLOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyBool_Type;
|
|
||||||
|
|
||||||
#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type)
|
|
||||||
|
|
||||||
/* Py_False and Py_True are the only two bools in existence.
|
|
||||||
Don't forget to apply Py_INCREF() when returning either!!! */
|
|
||||||
|
|
||||||
/* Don't use these directly */
|
|
||||||
PyAPI_DATA(PyLongObject) _Py_FalseStruct;
|
|
||||||
PyAPI_DATA(PyLongObject) _Py_TrueStruct;
|
|
||||||
|
|
||||||
/* Use these macros */
|
|
||||||
#define Py_False ((PyObject *) &_Py_FalseStruct)
|
|
||||||
#define Py_True ((PyObject *) &_Py_TrueStruct)
|
|
||||||
|
|
||||||
// Test if an object is the True singleton, the same as "x is True" in Python.
|
|
||||||
PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
|
|
||||||
#define Py_IsTrue(x) Py_Is((x), Py_True)
|
|
||||||
|
|
||||||
// Test if an object is the False singleton, the same as "x is False" in Python.
|
|
||||||
PyAPI_FUNC(int) Py_IsFalse(PyObject *x);
|
|
||||||
#define Py_IsFalse(x) Py_Is((x), Py_False)
|
|
||||||
|
|
||||||
/* Macros for returning Py_True or Py_False, respectively */
|
|
||||||
#define Py_RETURN_TRUE return Py_NewRef(Py_True)
|
|
||||||
#define Py_RETURN_FALSE return Py_NewRef(Py_False)
|
|
||||||
|
|
||||||
/* Function to return a bool from a C long */
|
|
||||||
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_BOOLOBJECT_H */
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* ByteArray object interface */
|
|
||||||
|
|
||||||
#ifndef Py_BYTEARRAYOBJECT_H
|
|
||||||
#define Py_BYTEARRAYOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Type PyByteArrayObject represents a mutable array of bytes.
|
|
||||||
* The Python API is that of a sequence;
|
|
||||||
* the bytes are mapped to ints in [0, 256).
|
|
||||||
* Bytes are not characters; they may be used to encode characters.
|
|
||||||
* The only way to go between bytes and str/unicode is via encoding
|
|
||||||
* and decoding.
|
|
||||||
* For the convenience of C programmers, the bytes type is considered
|
|
||||||
* to contain a char pointer, not an unsigned char pointer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Type object */
|
|
||||||
PyAPI_DATA(PyTypeObject) PyByteArray_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type;
|
|
||||||
|
|
||||||
/* Type check macros */
|
|
||||||
#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type)
|
|
||||||
#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type)
|
|
||||||
|
|
||||||
/* Direct API functions */
|
|
||||||
PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t);
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *);
|
|
||||||
PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_BYTEARRAYOBJECT_H
|
|
||||||
# include "cpython/bytearrayobject.h"
|
|
||||||
# undef Py_CPYTHON_BYTEARRAYOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_BYTEARRAYOBJECT_H */
|
|
|
@ -1,69 +0,0 @@
|
||||||
|
|
||||||
/* Bytes object interface */
|
|
||||||
|
|
||||||
#ifndef Py_BYTESOBJECT_H
|
|
||||||
#define Py_BYTESOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdarg.h> // va_list
|
|
||||||
|
|
||||||
/*
|
|
||||||
Type PyBytesObject represents a byte string. An extra zero byte is
|
|
||||||
reserved at the end to ensure it is zero-terminated, but a size is
|
|
||||||
present so strings with null bytes in them can be represented. This
|
|
||||||
is an immutable object type.
|
|
||||||
|
|
||||||
There are functions to create new bytes objects, to test
|
|
||||||
an object for bytes-ness, and to get the
|
|
||||||
byte string value. The latter function returns a null pointer
|
|
||||||
if the object is not of the proper type.
|
|
||||||
There is a variant that takes an explicit size as well as a
|
|
||||||
variant that assumes a zero-terminated string. Note that none of the
|
|
||||||
functions should be applied to NULL pointer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyBytes_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyBytesIter_Type;
|
|
||||||
|
|
||||||
#define PyBytes_Check(op) \
|
|
||||||
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS)
|
|
||||||
#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t);
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list)
|
|
||||||
Py_GCC_ATTRIBUTE((format(printf, 1, 0)));
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...)
|
|
||||||
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *);
|
|
||||||
PyAPI_FUNC(char *) PyBytes_AsString(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int);
|
|
||||||
PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *);
|
|
||||||
PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t,
|
|
||||||
const char *, Py_ssize_t,
|
|
||||||
const char *);
|
|
||||||
|
|
||||||
/* Provides access to the internal data buffer and size of a bytes object.
|
|
||||||
Passing NULL as len parameter will force the string buffer to be
|
|
||||||
0-terminated (passing a string with embedded NUL characters will
|
|
||||||
cause an exception). */
|
|
||||||
PyAPI_FUNC(int) PyBytes_AsStringAndSize(
|
|
||||||
PyObject *obj, /* bytes object */
|
|
||||||
char **s, /* pointer to buffer variable */
|
|
||||||
Py_ssize_t *len /* pointer to length variable or NULL */
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_BYTESOBJECT_H
|
|
||||||
# include "cpython/bytesobject.h"
|
|
||||||
# undef Py_CPYTHON_BYTESOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_BYTESOBJECT_H */
|
|
|
@ -1,168 +0,0 @@
|
||||||
/* Interface to random parts in ceval.c */
|
|
||||||
|
|
||||||
#ifndef Py_CEVAL_H
|
|
||||||
#define Py_CEVAL_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co,
|
|
||||||
PyObject *globals,
|
|
||||||
PyObject *locals,
|
|
||||||
PyObject *const *args, int argc,
|
|
||||||
PyObject *const *kwds, int kwdc,
|
|
||||||
PyObject *const *defs, int defc,
|
|
||||||
PyObject *kwdefs, PyObject *closure);
|
|
||||||
|
|
||||||
/* PyEval_CallObjectWithKeywords(), PyEval_CallObject(), PyEval_CallFunction
|
|
||||||
* and PyEval_CallMethod are deprecated. Since they are officially part of the
|
|
||||||
* stable ABI (PEP 384), they must be kept for backward compatibility.
|
|
||||||
* PyObject_Call(), PyObject_CallFunction() and PyObject_CallMethod() are
|
|
||||||
* recommended to call a callable object.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords(
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *args,
|
|
||||||
PyObject *kwargs);
|
|
||||||
|
|
||||||
/* Deprecated since PyEval_CallObjectWithKeywords is deprecated */
|
|
||||||
#define PyEval_CallObject(callable, arg) \
|
|
||||||
PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL)
|
|
||||||
|
|
||||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction(
|
|
||||||
PyObject *callable, const char *format, ...);
|
|
||||||
Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallMethod(
|
|
||||||
PyObject *obj, const char *name, const char *format, ...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void);
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
|
|
||||||
PyAPI_FUNC(PyFrameObject *) PyEval_GetFrame(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
|
|
||||||
PyAPI_FUNC(int) Py_MakePendingCalls(void);
|
|
||||||
|
|
||||||
/* Protection against deeply nested recursive calls
|
|
||||||
|
|
||||||
In Python 3.0, this protection has two levels:
|
|
||||||
* normal anti-recursion protection is triggered when the recursion level
|
|
||||||
exceeds the current recursion limit. It raises a RecursionError, and sets
|
|
||||||
the "overflowed" flag in the thread state structure. This flag
|
|
||||||
temporarily *disables* the normal protection; this allows cleanup code
|
|
||||||
to potentially outgrow the recursion limit while processing the
|
|
||||||
RecursionError.
|
|
||||||
* "last chance" anti-recursion protection is triggered when the recursion
|
|
||||||
level exceeds "current recursion limit + 50". By construction, this
|
|
||||||
protection can only be triggered when the "overflowed" flag is set. It
|
|
||||||
means the cleanup code has itself gone into an infinite loop, or the
|
|
||||||
RecursionError has been mistakingly ignored. When this protection is
|
|
||||||
triggered, the interpreter aborts with a Fatal Error.
|
|
||||||
|
|
||||||
In addition, the "overflowed" flag is automatically reset when the
|
|
||||||
recursion level drops below "current recursion limit - 50". This heuristic
|
|
||||||
is meant to ensure that the normal anti-recursion protection doesn't get
|
|
||||||
disabled too long.
|
|
||||||
|
|
||||||
Please note: this scheme has its own limitations. See:
|
|
||||||
http://mail.python.org/pipermail/python-dev/2008-August/082106.html
|
|
||||||
for some observations.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(void) Py_SetRecursionLimit(int);
|
|
||||||
PyAPI_FUNC(int) Py_GetRecursionLimit(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where);
|
|
||||||
PyAPI_FUNC(void) Py_LeaveRecursiveCall(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
|
|
||||||
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(PyFrameObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
|
|
||||||
|
|
||||||
/* Interface for threads.
|
|
||||||
|
|
||||||
A module that plans to do a blocking system call (or something else
|
|
||||||
that lasts a long time and doesn't touch Python data) can allow other
|
|
||||||
threads to run as follows:
|
|
||||||
|
|
||||||
...preparations here...
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
...blocking system call here...
|
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
...interpret result here...
|
|
||||||
|
|
||||||
The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a
|
|
||||||
{}-surrounded block.
|
|
||||||
To leave the block in the middle (e.g., with return), you must insert
|
|
||||||
a line containing Py_BLOCK_THREADS before the return, e.g.
|
|
||||||
|
|
||||||
if (...premature_exit...) {
|
|
||||||
Py_BLOCK_THREADS
|
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
An alternative is:
|
|
||||||
|
|
||||||
Py_BLOCK_THREADS
|
|
||||||
if (...premature_exit...) {
|
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Py_UNBLOCK_THREADS
|
|
||||||
|
|
||||||
For convenience, that the value of 'errno' is restored across
|
|
||||||
Py_END_ALLOW_THREADS and Py_BLOCK_THREADS.
|
|
||||||
|
|
||||||
WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
|
|
||||||
Py_END_ALLOW_THREADS!!!
|
|
||||||
|
|
||||||
Note that not yet all candidates have been converted to use this
|
|
||||||
mechanism!
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
|
|
||||||
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
|
||||||
|
|
||||||
Py_DEPRECATED(3.9) PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
|
||||||
Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
|
|
||||||
/* PyEval_AcquireLock() and PyEval_ReleaseLock() are part of stable ABI.
|
|
||||||
* They will be removed from this header file in the future version.
|
|
||||||
* But they will be remained in ABI until Python 4.0.
|
|
||||||
*/
|
|
||||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void);
|
|
||||||
Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_ReleaseLock(void);
|
|
||||||
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
|
|
||||||
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
|
|
||||||
|
|
||||||
#define Py_BEGIN_ALLOW_THREADS { \
|
|
||||||
PyThreadState *_save; \
|
|
||||||
_save = PyEval_SaveThread();
|
|
||||||
#define Py_BLOCK_THREADS PyEval_RestoreThread(_save);
|
|
||||||
#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread();
|
|
||||||
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Masks and values used by FORMAT_VALUE opcode. */
|
|
||||||
#define FVC_MASK 0x3
|
|
||||||
#define FVC_NONE 0x0
|
|
||||||
#define FVC_STR 0x1
|
|
||||||
#define FVC_REPR 0x2
|
|
||||||
#define FVC_ASCII 0x3
|
|
||||||
#define FVS_MASK 0x4
|
|
||||||
#define FVS_HAVE_SPEC 0x4
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_CEVAL_H
|
|
||||||
# include "cpython/ceval.h"
|
|
||||||
# undef Py_CPYTHON_CEVAL_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_CEVAL_H */
|
|
|
@ -1,248 +0,0 @@
|
||||||
#ifndef Py_CODECREGISTRY_H
|
|
||||||
#define Py_CODECREGISTRY_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Python Codec Registry and support functions
|
|
||||||
|
|
||||||
|
|
||||||
Written by Marc-Andre Lemburg (mal@lemburg.com).
|
|
||||||
|
|
||||||
Copyright (c) Corporation for National Research Initiatives.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/* Register a new codec search function.
|
|
||||||
|
|
||||||
As side effect, this tries to load the encodings package, if not
|
|
||||||
yet done, to make sure that it is always first in the list of
|
|
||||||
search functions.
|
|
||||||
|
|
||||||
The search_function's refcount is incremented by this function. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyCodec_Register(
|
|
||||||
PyObject *search_function
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Unregister a codec search function and clear the registry's cache.
|
|
||||||
If the search function is not registered, do nothing.
|
|
||||||
Return 0 on success. Raise an exception and return -1 on error. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyCodec_Unregister(
|
|
||||||
PyObject *search_function
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Codec registry lookup API.
|
|
||||||
|
|
||||||
Looks up the given encoding and returns a CodecInfo object with
|
|
||||||
function attributes which implement the different aspects of
|
|
||||||
processing the encoding.
|
|
||||||
|
|
||||||
The encoding string is looked up converted to all lower-case
|
|
||||||
characters. This makes encodings looked up through this mechanism
|
|
||||||
effectively case-insensitive.
|
|
||||||
|
|
||||||
If no codec is found, a KeyError is set and NULL returned.
|
|
||||||
|
|
||||||
As side effect, this tries to load the encodings package, if not
|
|
||||||
yet done. This is part of the lazy load strategy for the encodings
|
|
||||||
package.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
|
|
||||||
const char *encoding
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyCodec_Forget(
|
|
||||||
const char *encoding
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Codec registry encoding check API.
|
|
||||||
|
|
||||||
Returns 1/0 depending on whether there is a registered codec for
|
|
||||||
the given encoding.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyCodec_KnownEncoding(
|
|
||||||
const char *encoding
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Generic codec based encoding API.
|
|
||||||
|
|
||||||
object is passed through the encoder function found for the given
|
|
||||||
encoding using the error handling method defined by errors. errors
|
|
||||||
may be NULL to use the default method defined for the codec.
|
|
||||||
|
|
||||||
Raises a LookupError in case no encoder can be found.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_Encode(
|
|
||||||
PyObject *object,
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Generic codec based decoding API.
|
|
||||||
|
|
||||||
object is passed through the decoder function found for the given
|
|
||||||
encoding using the error handling method defined by errors. errors
|
|
||||||
may be NULL to use the default method defined for the codec.
|
|
||||||
|
|
||||||
Raises a LookupError in case no encoder can be found.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_Decode(
|
|
||||||
PyObject *object,
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
/* Text codec specific encoding and decoding API.
|
|
||||||
|
|
||||||
Checks the encoding against a list of codecs which do not
|
|
||||||
implement a str<->bytes encoding before attempting the
|
|
||||||
operation.
|
|
||||||
|
|
||||||
Please note that these APIs are internal and should not
|
|
||||||
be used in Python C extensions.
|
|
||||||
|
|
||||||
XXX (ncoghlan): should we make these, or something like them, public
|
|
||||||
in Python 3.5+?
|
|
||||||
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding(
|
|
||||||
const char *encoding,
|
|
||||||
const char *alternate_command
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodec_EncodeText(
|
|
||||||
PyObject *object,
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodec_DecodeText(
|
|
||||||
PyObject *object,
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* These two aren't actually text encoding specific, but _io.TextIOWrapper
|
|
||||||
* is the only current API consumer.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder(
|
|
||||||
PyObject *codec_info,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder(
|
|
||||||
PyObject *codec_info,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* --- Codec Lookup APIs --------------------------------------------------
|
|
||||||
|
|
||||||
All APIs return a codec object with incremented refcount and are
|
|
||||||
based on _PyCodec_Lookup(). The same comments w/r to the encoding
|
|
||||||
name also apply to these APIs.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Get an encoder function for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_Encoder(
|
|
||||||
const char *encoding
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Get a decoder function for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_Decoder(
|
|
||||||
const char *encoding
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Get an IncrementalEncoder object for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Get an IncrementalDecoder object function for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Get a StreamReader factory function for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
|
|
||||||
const char *encoding,
|
|
||||||
PyObject *stream,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Get a StreamWriter factory function for the given encoding. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_StreamWriter(
|
|
||||||
const char *encoding,
|
|
||||||
PyObject *stream,
|
|
||||||
const char *errors
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Unicode encoding error handling callback registry API */
|
|
||||||
|
|
||||||
/* Register the error handling callback function error under the given
|
|
||||||
name. This function will be called by the codec when it encounters
|
|
||||||
unencodable characters/undecodable bytes and doesn't know the
|
|
||||||
callback name, when name is specified as the error parameter
|
|
||||||
in the call to the encode/decode function.
|
|
||||||
Return 0 on success, -1 on error */
|
|
||||||
PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error);
|
|
||||||
|
|
||||||
/* Lookup the error handling callback function registered under the given
|
|
||||||
name. As a special case NULL can be passed, in which case
|
|
||||||
the error handling callback for "strict" will be returned. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name);
|
|
||||||
|
|
||||||
/* raise exc as an exception */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc);
|
|
||||||
|
|
||||||
/* ignore the unicode error, skipping the faulty input */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc);
|
|
||||||
|
|
||||||
/* replace the unicode encode error with ? or U+FFFD */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc);
|
|
||||||
|
|
||||||
/* replace the unicode encode error with XML character references */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc);
|
|
||||||
|
|
||||||
/* replace the unicode encode error with backslash escapes (\x, \u and \U) */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc);
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
|
||||||
/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
PyAPI_DATA(const char *) Py_hexdigits;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_CODECREGISTRY_H */
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef Py_COMPILE_H
|
|
||||||
#define Py_COMPILE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These definitions must match corresponding definitions in graminit.h. */
|
|
||||||
#define Py_single_input 256
|
|
||||||
#define Py_file_input 257
|
|
||||||
#define Py_eval_input 258
|
|
||||||
#define Py_func_type_input 345
|
|
||||||
|
|
||||||
/* This doesn't need to match anything */
|
|
||||||
#define Py_fstring_input 800
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_COMPILE_H
|
|
||||||
# include "cpython/compile.h"
|
|
||||||
# undef Py_CPYTHON_COMPILE_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_COMPILE_H */
|
|
|
@ -1,30 +0,0 @@
|
||||||
/* Complex number structure */
|
|
||||||
|
|
||||||
#ifndef Py_COMPLEXOBJECT_H
|
|
||||||
#define Py_COMPLEXOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Complex object interface */
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyComplex_Type;
|
|
||||||
|
|
||||||
#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type)
|
|
||||||
#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
|
|
||||||
|
|
||||||
PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
|
|
||||||
PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_COMPLEXOBJECT_H
|
|
||||||
# include "cpython/complexobject.h"
|
|
||||||
# undef Py_CPYTHON_COMPLEXOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_COMPLEXOBJECT_H */
|
|
|
@ -1,219 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* === Object Protocol ================================================== */
|
|
||||||
|
|
||||||
#ifdef PY_SSIZE_T_CLEAN
|
|
||||||
# define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
|
|
||||||
format to a Python dictionary ("kwargs" dict).
|
|
||||||
|
|
||||||
The type of kwnames keys is not checked. The final function getting
|
|
||||||
arguments is responsible to check if all keys are strings, for example using
|
|
||||||
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
|
|
||||||
|
|
||||||
Duplicate keys are merged using the last value. If duplicate keys must raise
|
|
||||||
an exception, the caller is responsible to implement an explicit keys on
|
|
||||||
kwnames. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
|
||||||
PyObject *const *values,
|
|
||||||
PyObject *kwnames);
|
|
||||||
|
|
||||||
/* Suggested size (number of positional arguments) for arrays of PyObject*
|
|
||||||
allocated on a C stack to avoid allocating memory on the heap memory. Such
|
|
||||||
array is used to pass positional arguments to call functions of the
|
|
||||||
PyObject_Vectorcall() family.
|
|
||||||
|
|
||||||
The size is chosen to not abuse the C stack and so limit the risk of stack
|
|
||||||
overflow. The size is also chosen to allow using the small stack for most
|
|
||||||
function calls of the Python standard library. On 64-bit CPU, it allocates
|
|
||||||
40 bytes on the stack. */
|
|
||||||
#define _PY_FASTCALL_SMALL_STACK 5
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *result,
|
|
||||||
const char *where);
|
|
||||||
|
|
||||||
/* === Vectorcall protocol (PEP 590) ============================= */
|
|
||||||
|
|
||||||
/* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
|
|
||||||
or PyObject_FastCallDict() (both forms are supported),
|
|
||||||
except that nargs is plainly the number of arguments without flags. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *const *args, Py_ssize_t nargs,
|
|
||||||
PyObject *keywords);
|
|
||||||
|
|
||||||
#define PY_VECTORCALL_ARGUMENTS_OFFSET \
|
|
||||||
(_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1))
|
|
||||||
|
|
||||||
static inline Py_ssize_t
|
|
||||||
PyVectorcall_NARGS(size_t n)
|
|
||||||
{
|
|
||||||
return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_Vectorcall(
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *const *args,
|
|
||||||
size_t nargsf,
|
|
||||||
PyObject *kwnames);
|
|
||||||
|
|
||||||
// Backwards compatibility aliases for API that was provisional in Python 3.8
|
|
||||||
#define _PyObject_Vectorcall PyObject_Vectorcall
|
|
||||||
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
|
|
||||||
#define _PyObject_FastCallDict PyObject_VectorcallDict
|
|
||||||
#define _PyVectorcall_Function PyVectorcall_Function
|
|
||||||
#define _PyObject_CallOneArg PyObject_CallOneArg
|
|
||||||
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
|
|
||||||
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
|
|
||||||
|
|
||||||
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
|
|
||||||
dict, which may be NULL if there are no keyword arguments. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *const *args,
|
|
||||||
size_t nargsf,
|
|
||||||
PyObject *kwargs);
|
|
||||||
|
|
||||||
/* Call "callable" (which must support vectorcall) with positional arguments
|
|
||||||
"tuple" and keyword arguments "dict". "dict" may also be NULL */
|
|
||||||
PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
|
|
||||||
|
|
||||||
// Same as PyObject_Vectorcall(), except without keyword arguments
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_FastCall(
|
|
||||||
PyObject *func,
|
|
||||||
PyObject *const *args,
|
|
||||||
Py_ssize_t nargs);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
|
|
||||||
PyObject *name, PyObject *const *args,
|
|
||||||
size_t nargsf, PyObject *kwnames);
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
|
|
||||||
{
|
|
||||||
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
|
||||||
return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
|
||||||
{
|
|
||||||
PyObject *args[2] = {self, arg};
|
|
||||||
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
|
||||||
assert(arg != NULL);
|
|
||||||
return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
|
|
||||||
PyObject *name,
|
|
||||||
const char *format, ...);
|
|
||||||
|
|
||||||
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
|
|
||||||
as the method name. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
|
|
||||||
_Py_Identifier *name,
|
|
||||||
const char *format, ...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj,
|
|
||||||
_Py_Identifier *name,
|
|
||||||
const char *format,
|
|
||||||
...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
|
|
||||||
PyObject *obj,
|
|
||||||
_Py_Identifier *name,
|
|
||||||
...);
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_VectorcallMethodId(
|
|
||||||
_Py_Identifier *name, PyObject *const *args,
|
|
||||||
size_t nargsf, PyObject *kwnames)
|
|
||||||
{
|
|
||||||
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
|
|
||||||
if (!oname) {
|
|
||||||
return _Py_NULL;
|
|
||||||
}
|
|
||||||
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
|
|
||||||
{
|
|
||||||
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
|
||||||
return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
|
|
||||||
{
|
|
||||||
PyObject *args[2] = {self, arg};
|
|
||||||
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
|
||||||
assert(arg != NULL);
|
|
||||||
return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
|
|
||||||
|
|
||||||
/* Guess the size of object 'o' using len(o) or o.__length_hint__().
|
|
||||||
If neither of those return a non-negative value, then return the default
|
|
||||||
value. If one of the calls fails, this function returns -1. */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
|
|
||||||
|
|
||||||
/* === Sequence protocol ================================================ */
|
|
||||||
|
|
||||||
/* Assume tp_as_sequence and sq_item exist and that 'i' does not
|
|
||||||
need to be corrected for a negative index. */
|
|
||||||
#define PySequence_ITEM(o, i)\
|
|
||||||
( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) )
|
|
||||||
|
|
||||||
#define PY_ITERSEARCH_COUNT 1
|
|
||||||
#define PY_ITERSEARCH_INDEX 2
|
|
||||||
#define PY_ITERSEARCH_CONTAINS 3
|
|
||||||
|
|
||||||
/* Iterate over seq.
|
|
||||||
|
|
||||||
Result depends on the operation:
|
|
||||||
|
|
||||||
PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if
|
|
||||||
error.
|
|
||||||
PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of
|
|
||||||
obj in seq; set ValueError and return -1 if none found;
|
|
||||||
also return -1 on error.
|
|
||||||
PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on
|
|
||||||
error. */
|
|
||||||
PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq,
|
|
||||||
PyObject *obj, int operation);
|
|
||||||
|
|
||||||
/* === Mapping protocol ================================================= */
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
|
|
||||||
|
|
||||||
PyAPI_FUNC(char *const *) _PySequence_BytesToCharpArray(PyObject* self);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
|
|
||||||
|
|
||||||
/* For internal use by buffer API functions */
|
|
||||||
PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
|
|
||||||
const Py_ssize_t *shape);
|
|
||||||
PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
|
|
||||||
const Py_ssize_t *shape);
|
|
||||||
|
|
||||||
/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
|
|
||||||
PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
|
|
||||||
|
|
||||||
/* Same as PyNumber_Index but can return an instance of a subclass of int. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o);
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Object layout */
|
|
||||||
typedef struct {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */
|
|
||||||
char *ob_bytes; /* Physical backing buffer */
|
|
||||||
char *ob_start; /* Logical start inside ob_bytes */
|
|
||||||
Py_ssize_t ob_exports; /* How many buffer exports */
|
|
||||||
} PyByteArrayObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(char) _PyByteArray_empty_string[];
|
|
||||||
|
|
||||||
/* Macros and static inline functions, trading safety for speed */
|
|
||||||
#define _PyByteArray_CAST(op) \
|
|
||||||
(assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op))
|
|
||||||
|
|
||||||
static inline char* PyByteArray_AS_STRING(PyObject *op)
|
|
||||||
{
|
|
||||||
PyByteArrayObject *self = _PyByteArray_CAST(op);
|
|
||||||
if (Py_SIZE(self)) {
|
|
||||||
return self->ob_start;
|
|
||||||
}
|
|
||||||
return _PyByteArray_empty_string;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
|
|
||||||
PyByteArrayObject *self = _PyByteArray_CAST(op);
|
|
||||||
return Py_SIZE(self);
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))
|
|
||||||
#endif
|
|
|
@ -1,133 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_BYTESOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
|
|
||||||
char ob_sval[1];
|
|
||||||
|
|
||||||
/* Invariants:
|
|
||||||
* ob_sval contains space for 'ob_size+1' elements.
|
|
||||||
* ob_sval[ob_size] == 0.
|
|
||||||
* ob_shash is the hash of the byte string or -1 if not computed yet.
|
|
||||||
*/
|
|
||||||
} PyBytesObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t);
|
|
||||||
PyAPI_FUNC(PyObject*) _PyBytes_FormatEx(
|
|
||||||
const char *format,
|
|
||||||
Py_ssize_t format_len,
|
|
||||||
PyObject *args,
|
|
||||||
int use_bytearray);
|
|
||||||
PyAPI_FUNC(PyObject*) _PyBytes_FromHex(
|
|
||||||
PyObject *string,
|
|
||||||
int use_bytearray);
|
|
||||||
|
|
||||||
/* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
|
|
||||||
const char *, const char **);
|
|
||||||
|
|
||||||
/* Macros and static inline functions, trading safety for speed */
|
|
||||||
#define _PyBytes_CAST(op) \
|
|
||||||
(assert(PyBytes_Check(op)), _Py_CAST(PyBytesObject*, op))
|
|
||||||
|
|
||||||
static inline char* PyBytes_AS_STRING(PyObject *op)
|
|
||||||
{
|
|
||||||
return _PyBytes_CAST(op)->ob_sval;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) {
|
|
||||||
PyBytesObject *self = _PyBytes_CAST(op);
|
|
||||||
return Py_SIZE(self);
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*,
|
|
||||||
x must be an iterable object. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyBytes_Join(PyObject *sep, PyObject *x);
|
|
||||||
|
|
||||||
|
|
||||||
/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer".
|
|
||||||
A _PyBytesWriter variable must be declared at the end of variables in a
|
|
||||||
function to optimize the memory allocation on the stack. */
|
|
||||||
typedef struct {
|
|
||||||
/* bytes, bytearray or NULL (when the small buffer is used) */
|
|
||||||
PyObject *buffer;
|
|
||||||
|
|
||||||
/* Number of allocated size. */
|
|
||||||
Py_ssize_t allocated;
|
|
||||||
|
|
||||||
/* Minimum number of allocated bytes,
|
|
||||||
incremented by _PyBytesWriter_Prepare() */
|
|
||||||
Py_ssize_t min_size;
|
|
||||||
|
|
||||||
/* If non-zero, use a bytearray instead of a bytes object for buffer. */
|
|
||||||
int use_bytearray;
|
|
||||||
|
|
||||||
/* If non-zero, overallocate the buffer (default: 0).
|
|
||||||
This flag must be zero if use_bytearray is non-zero. */
|
|
||||||
int overallocate;
|
|
||||||
|
|
||||||
/* Stack buffer */
|
|
||||||
int use_small_buffer;
|
|
||||||
char small_buffer[512];
|
|
||||||
} _PyBytesWriter;
|
|
||||||
|
|
||||||
/* Initialize a bytes writer
|
|
||||||
|
|
||||||
By default, the overallocation is disabled. Set the overallocate attribute
|
|
||||||
to control the allocation of the buffer. */
|
|
||||||
PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer);
|
|
||||||
|
|
||||||
/* Get the buffer content and reset the writer.
|
|
||||||
Return a bytes object, or a bytearray object if use_bytearray is non-zero.
|
|
||||||
Raise an exception and return NULL on error. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer,
|
|
||||||
void *str);
|
|
||||||
|
|
||||||
/* Deallocate memory of a writer (clear its internal buffer). */
|
|
||||||
PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer);
|
|
||||||
|
|
||||||
/* Allocate the buffer to write size bytes.
|
|
||||||
Return the pointer to the beginning of buffer data.
|
|
||||||
Raise an exception and return NULL on error. */
|
|
||||||
PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer,
|
|
||||||
Py_ssize_t size);
|
|
||||||
|
|
||||||
/* Ensure that the buffer is large enough to write *size* bytes.
|
|
||||||
Add size to the writer minimum size (min_size attribute).
|
|
||||||
|
|
||||||
str is the current pointer inside the buffer.
|
|
||||||
Return the updated current pointer inside the buffer.
|
|
||||||
Raise an exception and return NULL on error. */
|
|
||||||
PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer,
|
|
||||||
void *str,
|
|
||||||
Py_ssize_t size);
|
|
||||||
|
|
||||||
/* Resize the buffer to make it larger.
|
|
||||||
The new buffer may be larger than size bytes because of overallocation.
|
|
||||||
Return the updated current pointer inside the buffer.
|
|
||||||
Raise an exception and return NULL on error.
|
|
||||||
|
|
||||||
Note: size must be greater than the number of allocated bytes in the writer.
|
|
||||||
|
|
||||||
This function doesn't use the writer minimum size (min_size attribute).
|
|
||||||
|
|
||||||
See also _PyBytesWriter_Prepare().
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer,
|
|
||||||
void *str,
|
|
||||||
Py_ssize_t size);
|
|
||||||
|
|
||||||
/* Write bytes.
|
|
||||||
Raise an exception and return NULL on error. */
|
|
||||||
PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,
|
|
||||||
void *str,
|
|
||||||
const void *bytes,
|
|
||||||
Py_ssize_t size);
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* Cell object interface */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_CELLOBJECT_H
|
|
||||||
#define Py_CELLOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
/* Content of the cell or NULL when empty */
|
|
||||||
PyObject *ob_ref;
|
|
||||||
} PyCellObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyCell_Type;
|
|
||||||
|
|
||||||
#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyCell_New(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref)
|
|
||||||
#define PyCell_SET(op, v) _Py_RVALUE(((PyCellObject *)(op))->ob_ref = (v))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_TUPLEOBJECT_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_CEVAL_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
|
|
||||||
PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
|
|
||||||
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
|
|
||||||
PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
|
|
||||||
|
|
||||||
/* Helper to look up a builtin object */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *);
|
|
||||||
/* Look at the current frame's (if any) code's co_flags, and turn on
|
|
||||||
the corresponding compiler flags in cf->cf_flags. Return 1 if any
|
|
||||||
flag was set, else return 0. */
|
|
||||||
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
|
|
||||||
PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
|
||||||
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
|
|
@ -1,57 +0,0 @@
|
||||||
/* Former class object interface -- now only bound methods are here */
|
|
||||||
|
|
||||||
/* Revealing some structures (not for general use) */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_CLASSOBJECT_H
|
|
||||||
#define Py_CLASSOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyObject *im_func; /* The callable object implementing the method */
|
|
||||||
PyObject *im_self; /* The instance it is bound to */
|
|
||||||
PyObject *im_weakreflist; /* List of weak references */
|
|
||||||
vectorcallfunc vectorcall;
|
|
||||||
} PyMethodObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyMethod_Type;
|
|
||||||
|
|
||||||
#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
|
|
||||||
|
|
||||||
/* Macros for direct access to these values. Type checks are *not*
|
|
||||||
done, so use with care. */
|
|
||||||
#define PyMethod_GET_FUNCTION(meth) \
|
|
||||||
(((PyMethodObject *)meth) -> im_func)
|
|
||||||
#define PyMethod_GET_SELF(meth) \
|
|
||||||
(((PyMethodObject *)meth) -> im_self)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyObject *func;
|
|
||||||
} PyInstanceMethodObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type;
|
|
||||||
|
|
||||||
#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *);
|
|
||||||
|
|
||||||
/* Macros for direct access to these values. Type checks are *not*
|
|
||||||
done, so use with care. */
|
|
||||||
#define PyInstanceMethod_GET_FUNCTION(meth) \
|
|
||||||
(((PyInstanceMethodObject *)meth) -> func)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // !Py_CLASSOBJECT_H
|
|
||||||
#endif // !Py_LIMITED_API
|
|
|
@ -1,236 +0,0 @@
|
||||||
/* Definitions for bytecode */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_CODE_H
|
|
||||||
#define Py_CODE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Each instruction in a code object is a fixed-width value,
|
|
||||||
* currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG
|
|
||||||
* opcode allows for larger values but the current limit is 3 uses
|
|
||||||
* of EXTENDED_ARG (see Python/compile.c), for a maximum
|
|
||||||
* 32-bit value. This aligns with the note in Python/compile.c
|
|
||||||
* (compiler_addop_i_line) indicating that the max oparg value is
|
|
||||||
* 2**32 - 1, rather than INT_MAX.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef uint16_t _Py_CODEUNIT;
|
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
# define _Py_OPCODE(word) ((word) >> 8)
|
|
||||||
# define _Py_OPARG(word) ((word) & 255)
|
|
||||||
# define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg))
|
|
||||||
#else
|
|
||||||
# define _Py_OPCODE(word) ((word) & 255)
|
|
||||||
# define _Py_OPARG(word) ((word) >> 8)
|
|
||||||
# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing:
|
|
||||||
#define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode))
|
|
||||||
|
|
||||||
// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are
|
|
||||||
// defined in this macro:
|
|
||||||
#define _PyCode_DEF(SIZE) { \
|
|
||||||
PyObject_VAR_HEAD \
|
|
||||||
\
|
|
||||||
/* Note only the following fields are used in hash and/or comparisons \
|
|
||||||
* \
|
|
||||||
* - co_name \
|
|
||||||
* - co_argcount \
|
|
||||||
* - co_posonlyargcount \
|
|
||||||
* - co_kwonlyargcount \
|
|
||||||
* - co_nlocals \
|
|
||||||
* - co_stacksize \
|
|
||||||
* - co_flags \
|
|
||||||
* - co_firstlineno \
|
|
||||||
* - co_consts \
|
|
||||||
* - co_names \
|
|
||||||
* - co_localsplusnames \
|
|
||||||
* This is done to preserve the name and line number for tracebacks \
|
|
||||||
* and debuggers; otherwise, constant de-duplication would collapse \
|
|
||||||
* identical functions/lambdas defined on different lines. \
|
|
||||||
*/ \
|
|
||||||
\
|
|
||||||
/* These fields are set with provided values on new code objects. */ \
|
|
||||||
\
|
|
||||||
/* The hottest fields (in the eval loop) are grouped here at the top. */ \
|
|
||||||
PyObject *co_consts; /* list (constants used) */ \
|
|
||||||
PyObject *co_names; /* list of strings (names used) */ \
|
|
||||||
PyObject *co_exceptiontable; /* Byte string encoding exception handling \
|
|
||||||
table */ \
|
|
||||||
int co_flags; /* CO_..., see below */ \
|
|
||||||
short co_warmup; /* Warmup counter for quickening */ \
|
|
||||||
short _co_linearray_entry_size; /* Size of each entry in _co_linearray */ \
|
|
||||||
\
|
|
||||||
/* The rest are not so impactful on performance. */ \
|
|
||||||
int co_argcount; /* #arguments, except *args */ \
|
|
||||||
int co_posonlyargcount; /* #positional only arguments */ \
|
|
||||||
int co_kwonlyargcount; /* #keyword only arguments */ \
|
|
||||||
int co_stacksize; /* #entries needed for evaluation stack */ \
|
|
||||||
int co_firstlineno; /* first source line number */ \
|
|
||||||
\
|
|
||||||
/* redundant values (derived from co_localsplusnames and \
|
|
||||||
co_localspluskinds) */ \
|
|
||||||
int co_nlocalsplus; /* number of local + cell + free variables \
|
|
||||||
*/ \
|
|
||||||
int co_nlocals; /* number of local variables */ \
|
|
||||||
int co_nplaincellvars; /* number of non-arg cell variables */ \
|
|
||||||
int co_ncellvars; /* total number of cell variables */ \
|
|
||||||
int co_nfreevars; /* number of free variables */ \
|
|
||||||
\
|
|
||||||
PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \
|
|
||||||
PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \
|
|
||||||
per variable) */ \
|
|
||||||
PyObject *co_filename; /* unicode (where it was loaded from) */ \
|
|
||||||
PyObject *co_name; /* unicode (name, for reference) */ \
|
|
||||||
PyObject *co_qualname; /* unicode (qualname, for reference) */ \
|
|
||||||
PyObject *co_linetable; /* bytes object that holds location info */ \
|
|
||||||
PyObject *co_weakreflist; /* to support weakrefs to code objects */ \
|
|
||||||
PyObject *_co_code; /* cached co_code object/attribute */ \
|
|
||||||
char *_co_linearray; /* array of line offsets */ \
|
|
||||||
int _co_firsttraceable; /* index of first traceable instruction */ \
|
|
||||||
/* Scratch space for extra data relating to the code object. \
|
|
||||||
Type is a void* to keep the format private in codeobject.c to force \
|
|
||||||
people to go through the proper APIs. */ \
|
|
||||||
void *co_extra; \
|
|
||||||
char co_code_adaptive[(SIZE)]; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bytecode object */
|
|
||||||
struct PyCodeObject _PyCode_DEF(1);
|
|
||||||
|
|
||||||
/* Masks for co_flags above */
|
|
||||||
#define CO_OPTIMIZED 0x0001
|
|
||||||
#define CO_NEWLOCALS 0x0002
|
|
||||||
#define CO_VARARGS 0x0004
|
|
||||||
#define CO_VARKEYWORDS 0x0008
|
|
||||||
#define CO_NESTED 0x0010
|
|
||||||
#define CO_GENERATOR 0x0020
|
|
||||||
|
|
||||||
/* The CO_COROUTINE flag is set for coroutine functions (defined with
|
|
||||||
``async def`` keywords) */
|
|
||||||
#define CO_COROUTINE 0x0080
|
|
||||||
#define CO_ITERABLE_COROUTINE 0x0100
|
|
||||||
#define CO_ASYNC_GENERATOR 0x0200
|
|
||||||
|
|
||||||
/* bpo-39562: These constant values are changed in Python 3.9
|
|
||||||
to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
|
|
||||||
constants must be kept unique. PyCF_ constants can use bits from
|
|
||||||
0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
|
|
||||||
#define CO_FUTURE_DIVISION 0x20000
|
|
||||||
#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */
|
|
||||||
#define CO_FUTURE_WITH_STATEMENT 0x80000
|
|
||||||
#define CO_FUTURE_PRINT_FUNCTION 0x100000
|
|
||||||
#define CO_FUTURE_UNICODE_LITERALS 0x200000
|
|
||||||
|
|
||||||
#define CO_FUTURE_BARRY_AS_BDFL 0x400000
|
|
||||||
#define CO_FUTURE_GENERATOR_STOP 0x800000
|
|
||||||
#define CO_FUTURE_ANNOTATIONS 0x1000000
|
|
||||||
|
|
||||||
/* This should be defined if a future statement modifies the syntax.
|
|
||||||
For example, when a keyword is added.
|
|
||||||
*/
|
|
||||||
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
|
||||||
|
|
||||||
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyCode_Type;
|
|
||||||
|
|
||||||
#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type)
|
|
||||||
#define PyCode_GetNumFree(op) ((op)->co_nfreevars)
|
|
||||||
#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive)
|
|
||||||
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
|
|
||||||
|
|
||||||
/* Public interface */
|
|
||||||
PyAPI_FUNC(PyCodeObject *) PyCode_New(
|
|
||||||
int, int, int, int, int, PyObject *, PyObject *,
|
|
||||||
PyObject *, PyObject *, PyObject *, PyObject *,
|
|
||||||
PyObject *, PyObject *, PyObject *, int, PyObject *,
|
|
||||||
PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs(
|
|
||||||
int, int, int, int, int, int, PyObject *, PyObject *,
|
|
||||||
PyObject *, PyObject *, PyObject *, PyObject *,
|
|
||||||
PyObject *, PyObject *, PyObject *, int, PyObject *,
|
|
||||||
PyObject *);
|
|
||||||
/* same as struct above */
|
|
||||||
|
|
||||||
/* Creates a new empty code object with the specified source location. */
|
|
||||||
PyAPI_FUNC(PyCodeObject *)
|
|
||||||
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
|
|
||||||
|
|
||||||
/* Return the line number associated with the specified bytecode index
|
|
||||||
in this code object. If you just need the line number of a frame,
|
|
||||||
use PyFrame_GetLineNumber() instead. */
|
|
||||||
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *);
|
|
||||||
|
|
||||||
/* for internal use only */
|
|
||||||
struct _opaque {
|
|
||||||
int computed_line;
|
|
||||||
const uint8_t *lo_next;
|
|
||||||
const uint8_t *limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _line_offsets {
|
|
||||||
int ar_start;
|
|
||||||
int ar_end;
|
|
||||||
int ar_line;
|
|
||||||
struct _opaque opaque;
|
|
||||||
} PyCodeAddressRange;
|
|
||||||
|
|
||||||
/* Update *bounds to describe the first and one-past-the-last instructions in the
|
|
||||||
same line as lasti. Return the number of that line.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds);
|
|
||||||
|
|
||||||
/* Create a comparable key used to compare constants taking in account the
|
|
||||||
* object type. It is used to make sure types are not coerced (e.g., float and
|
|
||||||
* complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
|
|
||||||
*
|
|
||||||
* Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
|
|
||||||
* depending on the type and the value. The type is the first item to not
|
|
||||||
* compare bytes and str which can raise a BytesWarning exception. */
|
|
||||||
PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
|
|
||||||
PyObject *names, PyObject *lnotab);
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index,
|
|
||||||
void **extra);
|
|
||||||
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index,
|
|
||||||
void *extra);
|
|
||||||
|
|
||||||
/* Equivalent to getattr(code, 'co_code') in Python.
|
|
||||||
Returns a strong reference to a bytes object. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code);
|
|
||||||
/* Equivalent to getattr(code, 'co_varnames') in Python. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code);
|
|
||||||
/* Equivalent to getattr(code, 'co_cellvars') in Python. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code);
|
|
||||||
/* Equivalent to getattr(code, 'co_freevars') in Python. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code);
|
|
||||||
|
|
||||||
typedef enum _PyCodeLocationInfoKind {
|
|
||||||
/* short forms are 0 to 9 */
|
|
||||||
PY_CODE_LOCATION_INFO_SHORT0 = 0,
|
|
||||||
/* one lineforms are 10 to 12 */
|
|
||||||
PY_CODE_LOCATION_INFO_ONE_LINE0 = 10,
|
|
||||||
PY_CODE_LOCATION_INFO_ONE_LINE1 = 11,
|
|
||||||
PY_CODE_LOCATION_INFO_ONE_LINE2 = 12,
|
|
||||||
|
|
||||||
PY_CODE_LOCATION_INFO_NO_COLUMNS = 13,
|
|
||||||
PY_CODE_LOCATION_INFO_LONG = 14,
|
|
||||||
PY_CODE_LOCATION_INFO_NONE = 15
|
|
||||||
} _PyCodeLocationInfoKind;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // !Py_CODE_H
|
|
||||||
#endif // !Py_LIMITED_API
|
|
|
@ -1,54 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_COMPILE_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Public interface */
|
|
||||||
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
|
|
||||||
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
|
|
||||||
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
|
|
||||||
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
|
|
||||||
#define PyCF_MASK_OBSOLETE (CO_NESTED)
|
|
||||||
|
|
||||||
/* bpo-39562: CO_FUTURE_ and PyCF_ constants must be kept unique.
|
|
||||||
PyCF_ constants can use bits from 0x0100 to 0x10000.
|
|
||||||
CO_FUTURE_ constants use bits starting at 0x20000. */
|
|
||||||
#define PyCF_SOURCE_IS_UTF8 0x0100
|
|
||||||
#define PyCF_DONT_IMPLY_DEDENT 0x0200
|
|
||||||
#define PyCF_ONLY_AST 0x0400
|
|
||||||
#define PyCF_IGNORE_COOKIE 0x0800
|
|
||||||
#define PyCF_TYPE_COMMENTS 0x1000
|
|
||||||
#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000
|
|
||||||
#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000
|
|
||||||
#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
|
|
||||||
PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \
|
|
||||||
PyCF_ALLOW_INCOMPLETE_INPUT)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
|
|
||||||
int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */
|
|
||||||
} PyCompilerFlags;
|
|
||||||
|
|
||||||
#define _PyCompilerFlags_INIT \
|
|
||||||
(PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}
|
|
||||||
|
|
||||||
/* Future feature support */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int ff_features; /* flags set by future statements */
|
|
||||||
int ff_lineno; /* line number of last future statement */
|
|
||||||
} PyFutureFeatures;
|
|
||||||
|
|
||||||
#define FUTURE_NESTED_SCOPES "nested_scopes"
|
|
||||||
#define FUTURE_GENERATORS "generators"
|
|
||||||
#define FUTURE_DIVISION "division"
|
|
||||||
#define FUTURE_ABSOLUTE_IMPORT "absolute_import"
|
|
||||||
#define FUTURE_WITH_STATEMENT "with_statement"
|
|
||||||
#define FUTURE_PRINT_FUNCTION "print_function"
|
|
||||||
#define FUTURE_UNICODE_LITERALS "unicode_literals"
|
|
||||||
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
|
|
||||||
#define FUTURE_GENERATOR_STOP "generator_stop"
|
|
||||||
#define FUTURE_ANNOTATIONS "annotations"
|
|
||||||
|
|
||||||
#define PY_INVALID_STACK_EFFECT INT_MAX
|
|
||||||
PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg);
|
|
||||||
PyAPI_FUNC(int) PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump);
|
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_COMPLEXOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
double real;
|
|
||||||
double imag;
|
|
||||||
} Py_complex;
|
|
||||||
|
|
||||||
/* Operations on complex numbers from complexmodule.c */
|
|
||||||
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex);
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex);
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex);
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex);
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex);
|
|
||||||
PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex);
|
|
||||||
PyAPI_FUNC(double) _Py_c_abs(Py_complex);
|
|
||||||
|
|
||||||
/* Complex object interface */
|
|
||||||
|
|
||||||
/*
|
|
||||||
PyComplexObject represents a complex number with double-precision
|
|
||||||
real and imaginary parts.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
Py_complex cval;
|
|
||||||
} PyComplexObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
|
|
||||||
|
|
||||||
PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
|
|
||||||
|
|
||||||
#ifdef Py_BUILD_CORE
|
|
||||||
/* Format the object based on the format_spec, as defined in PEP 3101
|
|
||||||
(Advanced String Formatting). */
|
|
||||||
extern int _PyComplex_FormatAdvancedWriter(
|
|
||||||
_PyUnicodeWriter *writer,
|
|
||||||
PyObject *obj,
|
|
||||||
PyObject *format_spec,
|
|
||||||
Py_ssize_t start,
|
|
||||||
Py_ssize_t end);
|
|
||||||
#endif // Py_BUILD_CORE
|
|
|
@ -1,78 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_CONTEXT_H
|
|
||||||
#define Py_CONTEXT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyContext_Type;
|
|
||||||
typedef struct _pycontextobject PyContext;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyContextVar_Type;
|
|
||||||
typedef struct _pycontextvarobject PyContextVar;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyContextToken_Type;
|
|
||||||
typedef struct _pycontexttokenobject PyContextToken;
|
|
||||||
|
|
||||||
|
|
||||||
#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type)
|
|
||||||
#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type)
|
|
||||||
#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type)
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyContext_New(void);
|
|
||||||
PyAPI_FUNC(PyObject *) PyContext_Copy(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyContext_CopyCurrent(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyContext_Enter(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyContext_Exit(PyObject *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Create a new context variable.
|
|
||||||
|
|
||||||
default_value can be NULL.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) PyContextVar_New(
|
|
||||||
const char *name, PyObject *default_value);
|
|
||||||
|
|
||||||
|
|
||||||
/* Get a value for the variable.
|
|
||||||
|
|
||||||
Returns -1 if an error occurred during lookup.
|
|
||||||
|
|
||||||
Returns 0 if value either was or was not found.
|
|
||||||
|
|
||||||
If value was found, *value will point to it.
|
|
||||||
If not, it will point to:
|
|
||||||
|
|
||||||
- default_value, if not NULL;
|
|
||||||
- the default value of "var", if not NULL;
|
|
||||||
- NULL.
|
|
||||||
|
|
||||||
'*value' will be a new ref, if not NULL.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) PyContextVar_Get(
|
|
||||||
PyObject *var, PyObject *default_value, PyObject **value);
|
|
||||||
|
|
||||||
|
|
||||||
/* Set a new value for the variable.
|
|
||||||
Returns NULL if an error occurs.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) PyContextVar_Set(PyObject *var, PyObject *value);
|
|
||||||
|
|
||||||
|
|
||||||
/* Reset a variable to its previous value.
|
|
||||||
Returns 0 on success, -1 on error.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token);
|
|
||||||
|
|
||||||
|
|
||||||
/* This method is exposed only for CPython tests. Don not use it. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_CONTEXT_H */
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
|
@ -1,64 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_DESCROBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
|
|
||||||
void *wrapped);
|
|
||||||
|
|
||||||
typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
|
|
||||||
void *wrapped, PyObject *kwds);
|
|
||||||
|
|
||||||
struct wrapperbase {
|
|
||||||
const char *name;
|
|
||||||
int offset;
|
|
||||||
void *function;
|
|
||||||
wrapperfunc wrapper;
|
|
||||||
const char *doc;
|
|
||||||
int flags;
|
|
||||||
PyObject *name_strobj;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Flags for above struct */
|
|
||||||
#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */
|
|
||||||
|
|
||||||
/* Various kinds of descriptor objects */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyTypeObject *d_type;
|
|
||||||
PyObject *d_name;
|
|
||||||
PyObject *d_qualname;
|
|
||||||
} PyDescrObject;
|
|
||||||
|
|
||||||
#define PyDescr_COMMON PyDescrObject d_common
|
|
||||||
|
|
||||||
#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
|
|
||||||
#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyDescr_COMMON;
|
|
||||||
PyMethodDef *d_method;
|
|
||||||
vectorcallfunc vectorcall;
|
|
||||||
} PyMethodDescrObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyDescr_COMMON;
|
|
||||||
PyMemberDef *d_member;
|
|
||||||
} PyMemberDescrObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyDescr_COMMON;
|
|
||||||
PyGetSetDef *d_getset;
|
|
||||||
} PyGetSetDescrObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyDescr_COMMON;
|
|
||||||
struct wrapperbase *d_base;
|
|
||||||
void *d_wrapped; /* This can be any function pointer */
|
|
||||||
} PyWrapperDescrObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
|
|
||||||
struct wrapperbase *, void *);
|
|
||||||
PyAPI_FUNC(int) PyDescr_IsData(PyObject *);
|
|
|
@ -1,78 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_DICTOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _dictkeysobject PyDictKeysObject;
|
|
||||||
typedef struct _dictvalues PyDictValues;
|
|
||||||
|
|
||||||
/* The ma_values pointer is NULL for a combined table
|
|
||||||
* or points to an array of PyObject* for a split table
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
/* Number of items in the dictionary */
|
|
||||||
Py_ssize_t ma_used;
|
|
||||||
|
|
||||||
/* Dictionary version: globally unique, value change each time
|
|
||||||
the dictionary is modified */
|
|
||||||
uint64_t ma_version_tag;
|
|
||||||
|
|
||||||
PyDictKeysObject *ma_keys;
|
|
||||||
|
|
||||||
/* If ma_values is NULL, the table is "combined": keys and values
|
|
||||||
are stored in ma_keys.
|
|
||||||
|
|
||||||
If ma_values is not NULL, the table is split:
|
|
||||||
keys are stored in ma_keys and values are stored in ma_values */
|
|
||||||
PyDictValues *ma_values;
|
|
||||||
} PyDictObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
|
|
||||||
Py_hash_t hash);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *dp, PyObject *key);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
|
|
||||||
_Py_Identifier *key);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
|
|
||||||
PyObject *mp, PyObject *key, PyObject *defaultobj);
|
|
||||||
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
|
|
||||||
PyObject *item, Py_hash_t hash);
|
|
||||||
PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
|
|
||||||
Py_hash_t hash);
|
|
||||||
PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
|
|
||||||
int (*predicate)(PyObject *value));
|
|
||||||
PyAPI_FUNC(int) _PyDict_Next(
|
|
||||||
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
|
|
||||||
|
|
||||||
/* Get the number of items of a dictionary. */
|
|
||||||
#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
|
|
||||||
PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t);
|
|
||||||
PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
|
|
||||||
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
|
|
||||||
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
|
|
||||||
PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
|
|
||||||
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
|
|
||||||
|
|
||||||
/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
|
|
||||||
the first occurrence of a key wins, if override is 1, the last occurrence
|
|
||||||
of a key wins, if override is 2, a KeyError with conflicting key as
|
|
||||||
argument is raised.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
|
|
||||||
PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key);
|
|
||||||
PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
|
|
||||||
|
|
||||||
/* _PyDictView */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyDictObject *dv_dict;
|
|
||||||
} _PyDictViewObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
|
|
|
@ -1,18 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_FILEOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
|
|
||||||
|
|
||||||
/* The std printer acts as a preliminary sys.stderr until the new io
|
|
||||||
infrastructure is in place. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
|
|
||||||
PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
|
|
||||||
|
|
||||||
typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path);
|
|
||||||
PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *);
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_FILEUTILS_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Used by _testcapi which must not use the internal C API
|
|
||||||
PyAPI_FUNC(FILE*) _Py_fopen_obj(
|
|
||||||
PyObject *path,
|
|
||||||
const char *mode);
|
|
|
@ -1,21 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_FLOATOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
double ob_fval;
|
|
||||||
} PyFloatObject;
|
|
||||||
|
|
||||||
// Macro version of PyFloat_AsDouble() trading safety for speed.
|
|
||||||
// It doesn't check if op is a double object.
|
|
||||||
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le);
|
|
||||||
PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le);
|
|
||||||
PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le);
|
|
||||||
|
|
||||||
PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le);
|
|
||||||
PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le);
|
|
||||||
PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le);
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* Frame object interface */
|
|
||||||
|
|
||||||
#ifndef Py_CPYTHON_FRAMEOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Standard object interface */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
|
|
||||||
PyObject *, PyObject *);
|
|
||||||
|
|
||||||
/* The rest of the interface is specific for frame objects */
|
|
||||||
|
|
||||||
/* Conversions between "fast locals" and locals in dictionary */
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
|
|
||||||
|
|
||||||
/* -- Caveat emptor --
|
|
||||||
* The concept of entry frames is an implementation detail of the CPython
|
|
||||||
* interpreter. This API is considered unstable and is provided for the
|
|
||||||
* convenience of debuggers, profilers and state-inspecting tools. Notice that
|
|
||||||
* this API can be changed in future minor versions if the underlying frame
|
|
||||||
* mechanism change or the concept of an 'entry frame' or its semantics becomes
|
|
||||||
* obsolete or outdated. */
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
|
|
||||||
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
|
|
|
@ -1,113 +0,0 @@
|
||||||
/* Function object interface */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_FUNCOBJECT_H
|
|
||||||
#define Py_FUNCOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define COMMON_FIELDS(PREFIX) \
|
|
||||||
PyObject *PREFIX ## globals; \
|
|
||||||
PyObject *PREFIX ## builtins; \
|
|
||||||
PyObject *PREFIX ## name; \
|
|
||||||
PyObject *PREFIX ## qualname; \
|
|
||||||
PyObject *PREFIX ## code; /* A code object, the __code__ attribute */ \
|
|
||||||
PyObject *PREFIX ## defaults; /* NULL or a tuple */ \
|
|
||||||
PyObject *PREFIX ## kwdefaults; /* NULL or a dict */ \
|
|
||||||
PyObject *PREFIX ## closure; /* NULL or a tuple of cell objects */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
COMMON_FIELDS(fc_)
|
|
||||||
} PyFrameConstructor;
|
|
||||||
|
|
||||||
/* Function objects and code objects should not be confused with each other:
|
|
||||||
*
|
|
||||||
* Function objects are created by the execution of the 'def' statement.
|
|
||||||
* They reference a code object in their __code__ attribute, which is a
|
|
||||||
* purely syntactic object, i.e. nothing more than a compiled version of some
|
|
||||||
* source code lines. There is one code object per source code "fragment",
|
|
||||||
* but each code object can be referenced by zero or many function objects
|
|
||||||
* depending only on how many times the 'def' statement in the source was
|
|
||||||
* executed so far.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
COMMON_FIELDS(func_)
|
|
||||||
PyObject *func_doc; /* The __doc__ attribute, can be anything */
|
|
||||||
PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */
|
|
||||||
PyObject *func_weakreflist; /* List of weak references */
|
|
||||||
PyObject *func_module; /* The __module__ attribute, can be anything */
|
|
||||||
PyObject *func_annotations; /* Annotations, a dict or NULL */
|
|
||||||
vectorcallfunc vectorcall;
|
|
||||||
/* Version number for use by specializer.
|
|
||||||
* Can set to non-zero when we want to specialize.
|
|
||||||
* Will be set to zero if any of these change:
|
|
||||||
* defaults
|
|
||||||
* kwdefaults (only if the object changes, not the contents of the dict)
|
|
||||||
* code
|
|
||||||
* annotations */
|
|
||||||
uint32_t func_version;
|
|
||||||
|
|
||||||
/* Invariant:
|
|
||||||
* func_closure contains the bindings for func_code->co_freevars, so
|
|
||||||
* PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code)
|
|
||||||
* (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0).
|
|
||||||
*/
|
|
||||||
} PyFunctionObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyFunction_Type;
|
|
||||||
|
|
||||||
#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFunction_GetAnnotations(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyFunction_SetAnnotations(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall(
|
|
||||||
PyObject *func,
|
|
||||||
PyObject *const *stack,
|
|
||||||
size_t nargsf,
|
|
||||||
PyObject *kwnames);
|
|
||||||
|
|
||||||
/* Macros for direct access to these values. Type checks are *not*
|
|
||||||
done, so use with care. */
|
|
||||||
#define PyFunction_GET_CODE(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_code)
|
|
||||||
#define PyFunction_GET_GLOBALS(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_globals)
|
|
||||||
#define PyFunction_GET_MODULE(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_module)
|
|
||||||
#define PyFunction_GET_DEFAULTS(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_defaults)
|
|
||||||
#define PyFunction_GET_KW_DEFAULTS(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_kwdefaults)
|
|
||||||
#define PyFunction_GET_CLOSURE(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_closure)
|
|
||||||
#define PyFunction_GET_ANNOTATIONS(func) \
|
|
||||||
(((PyFunctionObject *)func) -> func_annotations)
|
|
||||||
|
|
||||||
/* The classmethod and staticmethod types lives here, too */
|
|
||||||
PyAPI_DATA(PyTypeObject) PyClassMethod_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyStaticMethod_Type;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_FUNCOBJECT_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,88 +0,0 @@
|
||||||
/* Generator object interface */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_GENOBJECT_H
|
|
||||||
#define Py_GENOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* --- Generators --------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* _PyGenObject_HEAD defines the initial segment of generator
|
|
||||||
and coroutine objects. */
|
|
||||||
#define _PyGenObject_HEAD(prefix) \
|
|
||||||
PyObject_HEAD \
|
|
||||||
/* The code object backing the generator */ \
|
|
||||||
PyCodeObject *prefix##_code; \
|
|
||||||
/* List of weak reference. */ \
|
|
||||||
PyObject *prefix##_weakreflist; \
|
|
||||||
/* Name of the generator. */ \
|
|
||||||
PyObject *prefix##_name; \
|
|
||||||
/* Qualified name of the generator. */ \
|
|
||||||
PyObject *prefix##_qualname; \
|
|
||||||
_PyErr_StackItem prefix##_exc_state; \
|
|
||||||
PyObject *prefix##_origin_or_finalizer; \
|
|
||||||
char prefix##_hooks_inited; \
|
|
||||||
char prefix##_closed; \
|
|
||||||
char prefix##_running_async; \
|
|
||||||
/* The frame */ \
|
|
||||||
int8_t prefix##_frame_state; \
|
|
||||||
PyObject *prefix##_iframe[1];
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* The gi_ prefix is intended to remind of generator-iterator. */
|
|
||||||
_PyGenObject_HEAD(gi)
|
|
||||||
} PyGenObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyGen_Type;
|
|
||||||
|
|
||||||
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
|
|
||||||
#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *,
|
|
||||||
PyObject *name, PyObject *qualname);
|
|
||||||
PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
|
|
||||||
PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
|
|
||||||
PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- PyCoroObject ------------------------------------------------------- */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_PyGenObject_HEAD(cr)
|
|
||||||
} PyCoroObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyCoro_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type;
|
|
||||||
|
|
||||||
#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type)
|
|
||||||
PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *,
|
|
||||||
PyObject *name, PyObject *qualname);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- Asynchronous Generators -------------------------------------------- */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_PyGenObject_HEAD(ag)
|
|
||||||
} PyAsyncGenObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenWrappedValue_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *,
|
|
||||||
PyObject *name, PyObject *qualname);
|
|
||||||
|
|
||||||
#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type)
|
|
||||||
|
|
||||||
|
|
||||||
#undef _PyGenObject_HEAD
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_GENOBJECT_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,45 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_IMPORT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyMODINIT_FUNC PyInit__imp(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name);
|
|
||||||
PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module);
|
|
||||||
PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyImport_AcquireLock(void);
|
|
||||||
PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyImport_FixupBuiltin(
|
|
||||||
PyObject *mod,
|
|
||||||
const char *name, /* UTF-8 encoded string */
|
|
||||||
PyObject *modules
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *,
|
|
||||||
PyObject *, PyObject *);
|
|
||||||
|
|
||||||
struct _inittab {
|
|
||||||
const char *name; /* ASCII encoded string */
|
|
||||||
PyObject* (*initfunc)(void);
|
|
||||||
};
|
|
||||||
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
|
|
||||||
PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
|
|
||||||
|
|
||||||
struct _frozen {
|
|
||||||
const char *name; /* ASCII encoded string */
|
|
||||||
const unsigned char *code;
|
|
||||||
int size;
|
|
||||||
int is_package;
|
|
||||||
PyObject *(*get_code)(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Embedding apps may change this pointer to point to their favorite
|
|
||||||
collection of frozen modules: */
|
|
||||||
|
|
||||||
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *);
|
|
||||||
PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *);
|
|
|
@ -1,257 +0,0 @@
|
||||||
#ifndef Py_PYCORECONFIG_H
|
|
||||||
#define Py_PYCORECONFIG_H
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* --- PyStatus ----------------------------------------------- */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
enum {
|
|
||||||
_PyStatus_TYPE_OK=0,
|
|
||||||
_PyStatus_TYPE_ERROR=1,
|
|
||||||
_PyStatus_TYPE_EXIT=2
|
|
||||||
} _type;
|
|
||||||
const char *func;
|
|
||||||
const char *err_msg;
|
|
||||||
int exitcode;
|
|
||||||
} PyStatus;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyStatus) PyStatus_Ok(void);
|
|
||||||
PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg);
|
|
||||||
PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void);
|
|
||||||
PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
|
|
||||||
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
|
|
||||||
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
|
|
||||||
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
|
|
||||||
|
|
||||||
/* --- PyWideStringList ------------------------------------------------ */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* If length is greater than zero, items must be non-NULL
|
|
||||||
and all items strings must be non-NULL */
|
|
||||||
Py_ssize_t length;
|
|
||||||
wchar_t **items;
|
|
||||||
} PyWideStringList;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list,
|
|
||||||
const wchar_t *item);
|
|
||||||
PyAPI_FUNC(PyStatus) PyWideStringList_Insert(PyWideStringList *list,
|
|
||||||
Py_ssize_t index,
|
|
||||||
const wchar_t *item);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- PyPreConfig ----------------------------------------------- */
|
|
||||||
|
|
||||||
typedef struct PyPreConfig {
|
|
||||||
int _config_init; /* _PyConfigInitEnum value */
|
|
||||||
|
|
||||||
/* Parse Py_PreInitializeFromBytesArgs() arguments?
|
|
||||||
See PyConfig.parse_argv */
|
|
||||||
int parse_argv;
|
|
||||||
|
|
||||||
/* If greater than 0, enable isolated mode: sys.path contains
|
|
||||||
neither the script's directory nor the user's site-packages directory.
|
|
||||||
|
|
||||||
Set to 1 by the -I command line option. If set to -1 (default), inherit
|
|
||||||
Py_IsolatedFlag value. */
|
|
||||||
int isolated;
|
|
||||||
|
|
||||||
/* If greater than 0: use environment variables.
|
|
||||||
Set to 0 by -E command line option. If set to -1 (default), it is
|
|
||||||
set to !Py_IgnoreEnvironmentFlag. */
|
|
||||||
int use_environment;
|
|
||||||
|
|
||||||
/* Set the LC_CTYPE locale to the user preferred locale? If equals to 0,
|
|
||||||
set coerce_c_locale and coerce_c_locale_warn to 0. */
|
|
||||||
int configure_locale;
|
|
||||||
|
|
||||||
/* Coerce the LC_CTYPE locale if it's equal to "C"? (PEP 538)
|
|
||||||
|
|
||||||
Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1.
|
|
||||||
Set to 2 if the user preferred LC_CTYPE locale is "C".
|
|
||||||
|
|
||||||
If it is equal to 1, LC_CTYPE locale is read to decide if it should be
|
|
||||||
coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2
|
|
||||||
if the LC_CTYPE locale must be coerced.
|
|
||||||
|
|
||||||
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
|
||||||
should be enabled or not. */
|
|
||||||
int coerce_c_locale;
|
|
||||||
|
|
||||||
/* Emit a warning if the LC_CTYPE locale is coerced?
|
|
||||||
|
|
||||||
Set to 1 by PYTHONCOERCECLOCALE=warn.
|
|
||||||
|
|
||||||
Disable by default (set to 0). Set it to -1 to let Python decide if it
|
|
||||||
should be enabled or not. */
|
|
||||||
int coerce_c_locale_warn;
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
/* If greater than 1, use the "mbcs" encoding instead of the UTF-8
|
|
||||||
encoding for the filesystem encoding.
|
|
||||||
|
|
||||||
Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is
|
|
||||||
set to a non-empty string. If set to -1 (default), inherit
|
|
||||||
Py_LegacyWindowsFSEncodingFlag value.
|
|
||||||
|
|
||||||
See PEP 529 for more details. */
|
|
||||||
int legacy_windows_fs_encoding;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enable UTF-8 mode? (PEP 540)
|
|
||||||
|
|
||||||
Disabled by default (equals to 0).
|
|
||||||
|
|
||||||
Set to 1 by "-X utf8" and "-X utf8=1" command line options.
|
|
||||||
Set to 1 by PYTHONUTF8=1 environment variable.
|
|
||||||
|
|
||||||
Set to 0 by "-X utf8=0" and PYTHONUTF8=0.
|
|
||||||
|
|
||||||
If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or
|
|
||||||
"POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */
|
|
||||||
int utf8_mode;
|
|
||||||
|
|
||||||
/* If non-zero, enable the Python Development Mode.
|
|
||||||
|
|
||||||
Set to 1 by the -X dev command line option. Set by the PYTHONDEVMODE
|
|
||||||
environment variable. */
|
|
||||||
int dev_mode;
|
|
||||||
|
|
||||||
/* Memory allocator: PYTHONMALLOC env var.
|
|
||||||
See PyMemAllocatorName for valid values. */
|
|
||||||
int allocator;
|
|
||||||
} PyPreConfig;
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config);
|
|
||||||
PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- PyConfig ---------------------------------------------- */
|
|
||||||
|
|
||||||
/* This structure is best documented in the Doc/c-api/init_config.rst file. */
|
|
||||||
typedef struct PyConfig {
|
|
||||||
int _config_init; /* _PyConfigInitEnum value */
|
|
||||||
|
|
||||||
int isolated;
|
|
||||||
int use_environment;
|
|
||||||
int dev_mode;
|
|
||||||
int install_signal_handlers;
|
|
||||||
int use_hash_seed;
|
|
||||||
unsigned long hash_seed;
|
|
||||||
int faulthandler;
|
|
||||||
int tracemalloc;
|
|
||||||
int import_time;
|
|
||||||
int code_debug_ranges;
|
|
||||||
int show_ref_count;
|
|
||||||
int dump_refs;
|
|
||||||
wchar_t *dump_refs_file;
|
|
||||||
int malloc_stats;
|
|
||||||
wchar_t *filesystem_encoding;
|
|
||||||
wchar_t *filesystem_errors;
|
|
||||||
wchar_t *pycache_prefix;
|
|
||||||
int parse_argv;
|
|
||||||
PyWideStringList orig_argv;
|
|
||||||
PyWideStringList argv;
|
|
||||||
PyWideStringList xoptions;
|
|
||||||
PyWideStringList warnoptions;
|
|
||||||
int site_import;
|
|
||||||
int bytes_warning;
|
|
||||||
int warn_default_encoding;
|
|
||||||
int inspect;
|
|
||||||
int interactive;
|
|
||||||
int optimization_level;
|
|
||||||
int parser_debug;
|
|
||||||
int write_bytecode;
|
|
||||||
int verbose;
|
|
||||||
int quiet;
|
|
||||||
int user_site_directory;
|
|
||||||
int configure_c_stdio;
|
|
||||||
int buffered_stdio;
|
|
||||||
wchar_t *stdio_encoding;
|
|
||||||
wchar_t *stdio_errors;
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
int legacy_windows_stdio;
|
|
||||||
#endif
|
|
||||||
wchar_t *check_hash_pycs_mode;
|
|
||||||
int use_frozen_modules;
|
|
||||||
int safe_path;
|
|
||||||
|
|
||||||
/* --- Path configuration inputs ------------ */
|
|
||||||
int pathconfig_warnings;
|
|
||||||
wchar_t *program_name;
|
|
||||||
wchar_t *pythonpath_env;
|
|
||||||
wchar_t *home;
|
|
||||||
wchar_t *platlibdir;
|
|
||||||
|
|
||||||
/* --- Path configuration outputs ----------- */
|
|
||||||
int module_search_paths_set;
|
|
||||||
PyWideStringList module_search_paths;
|
|
||||||
wchar_t *stdlib_dir;
|
|
||||||
wchar_t *executable;
|
|
||||||
wchar_t *base_executable;
|
|
||||||
wchar_t *prefix;
|
|
||||||
wchar_t *base_prefix;
|
|
||||||
wchar_t *exec_prefix;
|
|
||||||
wchar_t *base_exec_prefix;
|
|
||||||
|
|
||||||
/* --- Parameter only used by Py_Main() ---------- */
|
|
||||||
int skip_source_first_line;
|
|
||||||
wchar_t *run_command;
|
|
||||||
wchar_t *run_module;
|
|
||||||
wchar_t *run_filename;
|
|
||||||
|
|
||||||
/* --- Private fields ---------------------------- */
|
|
||||||
|
|
||||||
// Install importlib? If equals to 0, importlib is not initialized at all.
|
|
||||||
// Needed by freeze_importlib.
|
|
||||||
int _install_importlib;
|
|
||||||
|
|
||||||
// If equal to 0, stop Python initialization before the "main" phase.
|
|
||||||
int _init_main;
|
|
||||||
|
|
||||||
// If non-zero, disallow threads, subprocesses, and fork.
|
|
||||||
// Default: 0.
|
|
||||||
int _isolated_interpreter;
|
|
||||||
|
|
||||||
// If non-zero, we believe we're running from a source tree.
|
|
||||||
int _is_python_build;
|
|
||||||
} PyConfig;
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config);
|
|
||||||
PyAPI_FUNC(void) PyConfig_InitIsolatedConfig(PyConfig *config);
|
|
||||||
PyAPI_FUNC(void) PyConfig_Clear(PyConfig *);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_SetString(
|
|
||||||
PyConfig *config,
|
|
||||||
wchar_t **config_str,
|
|
||||||
const wchar_t *str);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_SetBytesString(
|
|
||||||
PyConfig *config,
|
|
||||||
wchar_t **config_str,
|
|
||||||
const char *str);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
|
|
||||||
PyConfig *config,
|
|
||||||
Py_ssize_t argc,
|
|
||||||
char * const *argv);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
|
|
||||||
Py_ssize_t argc,
|
|
||||||
wchar_t * const *argv);
|
|
||||||
PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
|
|
||||||
PyWideStringList *list,
|
|
||||||
Py_ssize_t length, wchar_t **items);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- Helper functions --------------------------------------- */
|
|
||||||
|
|
||||||
/* Get the original command line arguments, before Python modified them.
|
|
||||||
|
|
||||||
See also PyConfig.orig_argv. */
|
|
||||||
PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
||||||
#endif /* !Py_PYCORECONFIG_H */
|
|
|
@ -1,51 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_LISTOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
|
|
||||||
PyObject **ob_item;
|
|
||||||
|
|
||||||
/* ob_item contains space for 'allocated' elements. The number
|
|
||||||
* currently in use is ob_size.
|
|
||||||
* Invariants:
|
|
||||||
* 0 <= ob_size <= allocated
|
|
||||||
* len(list) == ob_size
|
|
||||||
* ob_item == NULL implies ob_size == allocated == 0
|
|
||||||
* list.sort() temporarily sets allocated to -1 to detect mutations.
|
|
||||||
*
|
|
||||||
* Items must normally not be NULL, except during construction when
|
|
||||||
* the list is not yet visible outside the function that builds it.
|
|
||||||
*/
|
|
||||||
Py_ssize_t allocated;
|
|
||||||
} PyListObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out);
|
|
||||||
|
|
||||||
/* Cast argument to PyListObject* type. */
|
|
||||||
#define _PyList_CAST(op) \
|
|
||||||
(assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op)))
|
|
||||||
|
|
||||||
// Macros and static inline functions, trading safety for speed
|
|
||||||
|
|
||||||
static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) {
|
|
||||||
PyListObject *list = _PyList_CAST(op);
|
|
||||||
return Py_SIZE(list);
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[index])
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
|
|
||||||
PyListObject *list = _PyList_CAST(op);
|
|
||||||
list->ob_item[index] = value;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
#define PyList_SET_ITEM(op, index, value) \
|
|
||||||
PyList_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value))
|
|
||||||
#endif
|
|
|
@ -1,93 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_LONGINTREPR_H
|
|
||||||
#define Py_LONGINTREPR_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* This is published for the benefit of "friends" marshal.c and _decimal.c. */
|
|
||||||
|
|
||||||
/* Parameters of the integer representation. There are two different
|
|
||||||
sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit
|
|
||||||
integer type, and one set for 15-bit digits with each digit stored in an
|
|
||||||
unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at
|
|
||||||
configure time or in pyport.h, is used to decide which digit size to use.
|
|
||||||
|
|
||||||
Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits'
|
|
||||||
should be an unsigned integer type able to hold all integers up to
|
|
||||||
PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type,
|
|
||||||
and that overflow is handled by taking the result modulo 2**N for some N >
|
|
||||||
PyLong_SHIFT. The majority of the code doesn't care about the precise
|
|
||||||
value of PyLong_SHIFT, but there are some notable exceptions:
|
|
||||||
|
|
||||||
- PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8
|
|
||||||
|
|
||||||
- long_hash() requires that PyLong_SHIFT is *strictly* less than the number
|
|
||||||
of bits in an unsigned long, as do the PyLong <-> long (or unsigned long)
|
|
||||||
conversion functions
|
|
||||||
|
|
||||||
- the Python int <-> size_t/Py_ssize_t conversion functions expect that
|
|
||||||
PyLong_SHIFT is strictly less than the number of bits in a size_t
|
|
||||||
|
|
||||||
- the marshal code currently expects that PyLong_SHIFT is a multiple of 15
|
|
||||||
|
|
||||||
- NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single
|
|
||||||
digit; with the current values this forces PyLong_SHIFT >= 9
|
|
||||||
|
|
||||||
The values 15 and 30 should fit all of the above requirements, on any
|
|
||||||
platform.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if PYLONG_BITS_IN_DIGIT == 30
|
|
||||||
typedef uint32_t digit;
|
|
||||||
typedef int32_t sdigit; /* signed variant of digit */
|
|
||||||
typedef uint64_t twodigits;
|
|
||||||
typedef int64_t stwodigits; /* signed variant of twodigits */
|
|
||||||
#define PyLong_SHIFT 30
|
|
||||||
#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */
|
|
||||||
#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */
|
|
||||||
#elif PYLONG_BITS_IN_DIGIT == 15
|
|
||||||
typedef unsigned short digit;
|
|
||||||
typedef short sdigit; /* signed variant of digit */
|
|
||||||
typedef unsigned long twodigits;
|
|
||||||
typedef long stwodigits; /* signed variant of twodigits */
|
|
||||||
#define PyLong_SHIFT 15
|
|
||||||
#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */
|
|
||||||
#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */
|
|
||||||
#else
|
|
||||||
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
|
|
||||||
#endif
|
|
||||||
#define PyLong_BASE ((digit)1 << PyLong_SHIFT)
|
|
||||||
#define PyLong_MASK ((digit)(PyLong_BASE - 1))
|
|
||||||
|
|
||||||
/* Long integer representation.
|
|
||||||
The absolute value of a number is equal to
|
|
||||||
SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
|
|
||||||
Negative numbers are represented with ob_size < 0;
|
|
||||||
zero is represented by ob_size == 0.
|
|
||||||
In a normalized number, ob_digit[abs(ob_size)-1] (the most significant
|
|
||||||
digit) is never zero. Also, in all cases, for all valid i,
|
|
||||||
0 <= ob_digit[i] <= MASK.
|
|
||||||
The allocation function takes care of allocating extra memory
|
|
||||||
so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available.
|
|
||||||
|
|
||||||
CAUTION: Generic code manipulating subtypes of PyVarObject has to
|
|
||||||
aware that ints abuse ob_size's sign bit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct _longobject {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
digit ob_digit[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
|
|
||||||
|
|
||||||
/* Return a copy of src. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_LONGINTREPR_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,95 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_LONGOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyLong_AsInt(PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
|
|
||||||
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
|
|
||||||
PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
|
|
||||||
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
|
|
||||||
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
|
|
||||||
|
|
||||||
/* _PyLong_Frexp returns a double x and an exponent e such that the
|
|
||||||
true value is approximately equal to x * 2**e. e is >= 0. x is
|
|
||||||
0.0 if and only if the input is 0 (in which case, e and x are both
|
|
||||||
zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
|
|
||||||
possible if the number of bits doesn't fit into a Py_ssize_t, sets
|
|
||||||
OverflowError and returns -1.0 for x, 0 for e. */
|
|
||||||
PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int);
|
|
||||||
|
|
||||||
/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
|
|
||||||
v must not be NULL, and must be a normalized long.
|
|
||||||
There are no error cases.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyLong_Sign(PyObject *v);
|
|
||||||
|
|
||||||
/* _PyLong_NumBits. Return the number of bits needed to represent the
|
|
||||||
absolute value of a long. For example, this returns 1 for 1 and -1, 2
|
|
||||||
for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.
|
|
||||||
v must not be NULL, and must be a normalized long.
|
|
||||||
(size_t)-1 is returned and OverflowError set if the true result doesn't
|
|
||||||
fit in a size_t.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v);
|
|
||||||
|
|
||||||
/* _PyLong_DivmodNear. Given integers a and b, compute the nearest
|
|
||||||
integer q to the exact quotient a / b, rounding to the nearest even integer
|
|
||||||
in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
|
|
||||||
will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
|
|
||||||
even.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_DivmodNear(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
|
|
||||||
base 256, and return a Python int with the same numeric value.
|
|
||||||
If n is 0, the integer is 0. Else:
|
|
||||||
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
|
|
||||||
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
|
|
||||||
LSB.
|
|
||||||
If is_signed is 0/false, view the bytes as a non-negative integer.
|
|
||||||
If is_signed is 1/true, view the bytes as a 2's-complement integer,
|
|
||||||
non-negative if bit 0x80 of the MSB is clear, negative if set.
|
|
||||||
Error returns:
|
|
||||||
+ Return NULL with the appropriate exception set if there's not
|
|
||||||
enough memory to create the Python int.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
|
|
||||||
const unsigned char* bytes, size_t n,
|
|
||||||
int little_endian, int is_signed);
|
|
||||||
|
|
||||||
/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
|
|
||||||
v to a base-256 integer, stored in array bytes. Normally return 0,
|
|
||||||
return -1 on error.
|
|
||||||
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
|
|
||||||
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
|
|
||||||
the LSB at bytes[n-1].
|
|
||||||
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
|
|
||||||
are filled and there's nothing special about bit 0x80 of the MSB.
|
|
||||||
If is_signed is 1/true, bytes is filled with the 2's-complement
|
|
||||||
representation of v's value. Bit 0x80 of the MSB is the sign bit.
|
|
||||||
Error returns (-1):
|
|
||||||
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
|
|
||||||
isn't altered.
|
|
||||||
+ n isn't big enough to hold the full mathematical value of v. For
|
|
||||||
example, if is_signed is 0 and there are more digits in the v than
|
|
||||||
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
|
|
||||||
being large enough to hold a sign bit. OverflowError is set in this
|
|
||||||
case, but bytes holds the least-significant n bytes of the true value.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
|
|
||||||
unsigned char* bytes, size_t n,
|
|
||||||
int little_endian, int is_signed);
|
|
||||||
|
|
||||||
/* _PyLong_Format: Convert the long to a string object with given base,
|
|
||||||
appending a base prefix of 0[box] if base is 2, 8 or 16. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *obj, int base);
|
|
||||||
|
|
||||||
/* For use by the gcd function in mathmodule.c */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t);
|
|
|
@ -1,74 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_METHODOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PyCFunctionObject structure
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyMethodDef *m_ml; /* Description of the C function to call */
|
|
||||||
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
|
|
||||||
PyObject *m_module; /* The __module__ attribute, can be anything */
|
|
||||||
PyObject *m_weakreflist; /* List of weak references */
|
|
||||||
vectorcallfunc vectorcall;
|
|
||||||
} PyCFunctionObject;
|
|
||||||
|
|
||||||
#define _PyCFunctionObject_CAST(func) \
|
|
||||||
(assert(PyCFunction_Check(func)), \
|
|
||||||
_Py_CAST(PyCFunctionObject*, (func)))
|
|
||||||
|
|
||||||
|
|
||||||
// PyCMethodObject structure
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyCFunctionObject func;
|
|
||||||
PyTypeObject *mm_class; /* Class that defines this method */
|
|
||||||
} PyCMethodObject;
|
|
||||||
|
|
||||||
#define _PyCMethodObject_CAST(func) \
|
|
||||||
(assert(PyCMethod_Check(func)), \
|
|
||||||
_Py_CAST(PyCMethodObject*, (func)))
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyCMethod_Type;
|
|
||||||
|
|
||||||
#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type)
|
|
||||||
#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type)
|
|
||||||
|
|
||||||
|
|
||||||
/* Static inline functions for direct access to these values.
|
|
||||||
Type checks are *not* done, so use with care. */
|
|
||||||
static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) {
|
|
||||||
return _PyCFunctionObject_CAST(func)->m_ml->ml_meth;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) {
|
|
||||||
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
|
|
||||||
if (func->m_ml->ml_flags & METH_STATIC) {
|
|
||||||
return _Py_NULL;
|
|
||||||
}
|
|
||||||
return func->m_self;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int PyCFunction_GET_FLAGS(PyObject *func) {
|
|
||||||
return _PyCFunctionObject_CAST(func)->m_ml->ml_flags;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) {
|
|
||||||
PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj);
|
|
||||||
if (func->m_ml->ml_flags & METH_METHOD) {
|
|
||||||
return _PyCMethodObject_CAST(func)->mm_class;
|
|
||||||
}
|
|
||||||
return _Py_NULL;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func))
|
|
||||||
#endif
|
|
|
@ -1,107 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_MODSUPPORT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier
|
|
||||||
to mean Py_ssize_t */
|
|
||||||
#ifdef PY_SSIZE_T_CLEAN
|
|
||||||
#define _Py_VaBuildStack _Py_VaBuildStack_SizeT
|
|
||||||
#else
|
|
||||||
PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
|
|
||||||
PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT(
|
|
||||||
PyObject **small_stack,
|
|
||||||
Py_ssize_t small_stack_len,
|
|
||||||
const char *format,
|
|
||||||
va_list va,
|
|
||||||
Py_ssize_t *p_nargs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyArg_UnpackStack(
|
|
||||||
PyObject *const *args,
|
|
||||||
Py_ssize_t nargs,
|
|
||||||
const char *name,
|
|
||||||
Py_ssize_t min,
|
|
||||||
Py_ssize_t max,
|
|
||||||
...);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs);
|
|
||||||
PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames);
|
|
||||||
PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args);
|
|
||||||
#define _PyArg_NoKeywords(funcname, kwargs) \
|
|
||||||
((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs)))
|
|
||||||
#define _PyArg_NoKwnames(funcname, kwnames) \
|
|
||||||
((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames)))
|
|
||||||
#define _PyArg_NoPositional(funcname, args) \
|
|
||||||
((args) == NULL || _PyArg_NoPositional((funcname), (args)))
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *);
|
|
||||||
PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t,
|
|
||||||
Py_ssize_t, Py_ssize_t);
|
|
||||||
#define _PyArg_CheckPositional(funcname, nargs, min, max) \
|
|
||||||
((!ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \
|
|
||||||
|| _PyArg_CheckPositional((funcname), (nargs), (min), (max)))
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject **) _Py_VaBuildStack(
|
|
||||||
PyObject **small_stack,
|
|
||||||
Py_ssize_t small_stack_len,
|
|
||||||
const char *format,
|
|
||||||
va_list va,
|
|
||||||
Py_ssize_t *p_nargs);
|
|
||||||
|
|
||||||
typedef struct _PyArg_Parser {
|
|
||||||
const char *format;
|
|
||||||
const char * const *keywords;
|
|
||||||
const char *fname;
|
|
||||||
const char *custom_msg;
|
|
||||||
int pos; /* number of positional-only arguments */
|
|
||||||
int min; /* minimal number of arguments */
|
|
||||||
int max; /* maximal number of positional arguments */
|
|
||||||
PyObject *kwtuple; /* tuple of keyword parameter names */
|
|
||||||
struct _PyArg_Parser *next;
|
|
||||||
} _PyArg_Parser;
|
|
||||||
|
|
||||||
#ifdef PY_SSIZE_T_CLEAN
|
|
||||||
#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT
|
|
||||||
#define _PyArg_ParseStack _PyArg_ParseStack_SizeT
|
|
||||||
#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT
|
|
||||||
#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
|
|
||||||
struct _PyArg_Parser *, ...);
|
|
||||||
PyAPI_FUNC(int) _PyArg_ParseStack(
|
|
||||||
PyObject *const *args,
|
|
||||||
Py_ssize_t nargs,
|
|
||||||
const char *format,
|
|
||||||
...);
|
|
||||||
PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords(
|
|
||||||
PyObject *const *args,
|
|
||||||
Py_ssize_t nargs,
|
|
||||||
PyObject *kwnames,
|
|
||||||
struct _PyArg_Parser *,
|
|
||||||
...);
|
|
||||||
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
|
|
||||||
struct _PyArg_Parser *, va_list);
|
|
||||||
PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
|
|
||||||
PyObject *const *args, Py_ssize_t nargs,
|
|
||||||
PyObject *kwargs, PyObject *kwnames,
|
|
||||||
struct _PyArg_Parser *parser,
|
|
||||||
int minpos, int maxpos, int minkw,
|
|
||||||
PyObject **buf);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg(
|
|
||||||
PyObject *const *args, Py_ssize_t nargs,
|
|
||||||
PyObject *kwargs, PyObject *kwnames,
|
|
||||||
struct _PyArg_Parser *parser,
|
|
||||||
int minpos, int maxpos, int minkw,
|
|
||||||
int vararg, PyObject **buf);
|
|
||||||
|
|
||||||
#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \
|
|
||||||
(((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \
|
|
||||||
(minpos) <= (nargs) && (nargs) <= (maxpos) && args != NULL) ? (args) : \
|
|
||||||
_PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
|
|
||||||
(minpos), (maxpos), (minkw), (buf)))
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver);
|
|
||||||
|
|
||||||
PyAPI_DATA(const char *) _Py_PackageContext;
|
|
|
@ -1,511 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_OBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
|
|
||||||
|
|
||||||
#ifdef Py_TRACE_REFS
|
|
||||||
/* Py_TRACE_REFS is such major surgery that we call external routines. */
|
|
||||||
PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Py_REF_DEBUG
|
|
||||||
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/********************* String Literals ****************************************/
|
|
||||||
/* This structure helps managing static strings. The basic usage goes like this:
|
|
||||||
Instead of doing
|
|
||||||
|
|
||||||
r = PyObject_CallMethod(o, "foo", "args", ...);
|
|
||||||
|
|
||||||
do
|
|
||||||
|
|
||||||
_Py_IDENTIFIER(foo);
|
|
||||||
...
|
|
||||||
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
|
|
||||||
|
|
||||||
PyId_foo is a static variable, either on block level or file level. On first
|
|
||||||
usage, the string "foo" is interned, and the structures are linked. On interpreter
|
|
||||||
shutdown, all strings are released.
|
|
||||||
|
|
||||||
Alternatively, _Py_static_string allows choosing the variable name.
|
|
||||||
_PyUnicode_FromId returns a borrowed reference to the interned string.
|
|
||||||
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
|
|
||||||
*/
|
|
||||||
typedef struct _Py_Identifier {
|
|
||||||
const char* string;
|
|
||||||
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
|
|
||||||
// unique and must be initialized to -1.
|
|
||||||
Py_ssize_t index;
|
|
||||||
} _Py_Identifier;
|
|
||||||
|
|
||||||
#if defined(NEEDS_PY_IDENTIFIER) || !defined(Py_BUILD_CORE)
|
|
||||||
// For now we are keeping _Py_IDENTIFIER for continued use
|
|
||||||
// in non-builtin extensions (and naughty PyPI modules).
|
|
||||||
|
|
||||||
#define _Py_static_string_init(value) { .string = value, .index = -1 }
|
|
||||||
#define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
|
|
||||||
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
|
|
||||||
|
|
||||||
#endif /* NEEDS_PY_IDENTIFIER */
|
|
||||||
|
|
||||||
typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
|
|
||||||
typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
|
|
||||||
|
|
||||||
typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args,
|
|
||||||
size_t nargsf, PyObject *kwnames);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* Number implementations must check *both*
|
|
||||||
arguments for proper type and implement the necessary conversions
|
|
||||||
in the slot functions themselves. */
|
|
||||||
|
|
||||||
binaryfunc nb_add;
|
|
||||||
binaryfunc nb_subtract;
|
|
||||||
binaryfunc nb_multiply;
|
|
||||||
binaryfunc nb_remainder;
|
|
||||||
binaryfunc nb_divmod;
|
|
||||||
ternaryfunc nb_power;
|
|
||||||
unaryfunc nb_negative;
|
|
||||||
unaryfunc nb_positive;
|
|
||||||
unaryfunc nb_absolute;
|
|
||||||
inquiry nb_bool;
|
|
||||||
unaryfunc nb_invert;
|
|
||||||
binaryfunc nb_lshift;
|
|
||||||
binaryfunc nb_rshift;
|
|
||||||
binaryfunc nb_and;
|
|
||||||
binaryfunc nb_xor;
|
|
||||||
binaryfunc nb_or;
|
|
||||||
unaryfunc nb_int;
|
|
||||||
void *nb_reserved; /* the slot formerly known as nb_long */
|
|
||||||
unaryfunc nb_float;
|
|
||||||
|
|
||||||
binaryfunc nb_inplace_add;
|
|
||||||
binaryfunc nb_inplace_subtract;
|
|
||||||
binaryfunc nb_inplace_multiply;
|
|
||||||
binaryfunc nb_inplace_remainder;
|
|
||||||
ternaryfunc nb_inplace_power;
|
|
||||||
binaryfunc nb_inplace_lshift;
|
|
||||||
binaryfunc nb_inplace_rshift;
|
|
||||||
binaryfunc nb_inplace_and;
|
|
||||||
binaryfunc nb_inplace_xor;
|
|
||||||
binaryfunc nb_inplace_or;
|
|
||||||
|
|
||||||
binaryfunc nb_floor_divide;
|
|
||||||
binaryfunc nb_true_divide;
|
|
||||||
binaryfunc nb_inplace_floor_divide;
|
|
||||||
binaryfunc nb_inplace_true_divide;
|
|
||||||
|
|
||||||
unaryfunc nb_index;
|
|
||||||
|
|
||||||
binaryfunc nb_matrix_multiply;
|
|
||||||
binaryfunc nb_inplace_matrix_multiply;
|
|
||||||
} PyNumberMethods;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lenfunc sq_length;
|
|
||||||
binaryfunc sq_concat;
|
|
||||||
ssizeargfunc sq_repeat;
|
|
||||||
ssizeargfunc sq_item;
|
|
||||||
void *was_sq_slice;
|
|
||||||
ssizeobjargproc sq_ass_item;
|
|
||||||
void *was_sq_ass_slice;
|
|
||||||
objobjproc sq_contains;
|
|
||||||
|
|
||||||
binaryfunc sq_inplace_concat;
|
|
||||||
ssizeargfunc sq_inplace_repeat;
|
|
||||||
} PySequenceMethods;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lenfunc mp_length;
|
|
||||||
binaryfunc mp_subscript;
|
|
||||||
objobjargproc mp_ass_subscript;
|
|
||||||
} PyMappingMethods;
|
|
||||||
|
|
||||||
typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unaryfunc am_await;
|
|
||||||
unaryfunc am_aiter;
|
|
||||||
unaryfunc am_anext;
|
|
||||||
sendfunc am_send;
|
|
||||||
} PyAsyncMethods;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
getbufferproc bf_getbuffer;
|
|
||||||
releasebufferproc bf_releasebuffer;
|
|
||||||
} PyBufferProcs;
|
|
||||||
|
|
||||||
/* Allow printfunc in the tp_vectorcall_offset slot for
|
|
||||||
* backwards-compatibility */
|
|
||||||
typedef Py_ssize_t printfunc;
|
|
||||||
|
|
||||||
// If this structure is modified, Doc/includes/typestruct.h should be updated
|
|
||||||
// as well.
|
|
||||||
struct _typeobject {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
const char *tp_name; /* For printing, in format "<module>.<name>" */
|
|
||||||
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
|
|
||||||
|
|
||||||
/* Methods to implement standard operations */
|
|
||||||
|
|
||||||
destructor tp_dealloc;
|
|
||||||
Py_ssize_t tp_vectorcall_offset;
|
|
||||||
getattrfunc tp_getattr;
|
|
||||||
setattrfunc tp_setattr;
|
|
||||||
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
|
|
||||||
or tp_reserved (Python 3) */
|
|
||||||
reprfunc tp_repr;
|
|
||||||
|
|
||||||
/* Method suites for standard classes */
|
|
||||||
|
|
||||||
PyNumberMethods *tp_as_number;
|
|
||||||
PySequenceMethods *tp_as_sequence;
|
|
||||||
PyMappingMethods *tp_as_mapping;
|
|
||||||
|
|
||||||
/* More standard operations (here for binary compatibility) */
|
|
||||||
|
|
||||||
hashfunc tp_hash;
|
|
||||||
ternaryfunc tp_call;
|
|
||||||
reprfunc tp_str;
|
|
||||||
getattrofunc tp_getattro;
|
|
||||||
setattrofunc tp_setattro;
|
|
||||||
|
|
||||||
/* Functions to access object as input/output buffer */
|
|
||||||
PyBufferProcs *tp_as_buffer;
|
|
||||||
|
|
||||||
/* Flags to define presence of optional/expanded features */
|
|
||||||
unsigned long tp_flags;
|
|
||||||
|
|
||||||
const char *tp_doc; /* Documentation string */
|
|
||||||
|
|
||||||
/* Assigned meaning in release 2.0 */
|
|
||||||
/* call function for all accessible objects */
|
|
||||||
traverseproc tp_traverse;
|
|
||||||
|
|
||||||
/* delete references to contained objects */
|
|
||||||
inquiry tp_clear;
|
|
||||||
|
|
||||||
/* Assigned meaning in release 2.1 */
|
|
||||||
/* rich comparisons */
|
|
||||||
richcmpfunc tp_richcompare;
|
|
||||||
|
|
||||||
/* weak reference enabler */
|
|
||||||
Py_ssize_t tp_weaklistoffset;
|
|
||||||
|
|
||||||
/* Iterators */
|
|
||||||
getiterfunc tp_iter;
|
|
||||||
iternextfunc tp_iternext;
|
|
||||||
|
|
||||||
/* Attribute descriptor and subclassing stuff */
|
|
||||||
PyMethodDef *tp_methods;
|
|
||||||
PyMemberDef *tp_members;
|
|
||||||
PyGetSetDef *tp_getset;
|
|
||||||
// Strong reference on a heap type, borrowed reference on a static type
|
|
||||||
PyTypeObject *tp_base;
|
|
||||||
PyObject *tp_dict;
|
|
||||||
descrgetfunc tp_descr_get;
|
|
||||||
descrsetfunc tp_descr_set;
|
|
||||||
Py_ssize_t tp_dictoffset;
|
|
||||||
initproc tp_init;
|
|
||||||
allocfunc tp_alloc;
|
|
||||||
newfunc tp_new;
|
|
||||||
freefunc tp_free; /* Low-level free-memory routine */
|
|
||||||
inquiry tp_is_gc; /* For PyObject_IS_GC */
|
|
||||||
PyObject *tp_bases;
|
|
||||||
PyObject *tp_mro; /* method resolution order */
|
|
||||||
PyObject *tp_cache;
|
|
||||||
PyObject *tp_subclasses;
|
|
||||||
PyObject *tp_weaklist;
|
|
||||||
destructor tp_del;
|
|
||||||
|
|
||||||
/* Type attribute cache version tag. Added in version 2.6 */
|
|
||||||
unsigned int tp_version_tag;
|
|
||||||
|
|
||||||
destructor tp_finalize;
|
|
||||||
vectorcallfunc tp_vectorcall;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This struct is used by the specializer
|
|
||||||
* It should should be treated as an opaque blob
|
|
||||||
* by code other than the specializer and interpreter. */
|
|
||||||
struct _specialization_cache {
|
|
||||||
PyObject *getitem;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The *real* layout of a type object when allocated on the heap */
|
|
||||||
typedef struct _heaptypeobject {
|
|
||||||
/* Note: there's a dependency on the order of these members
|
|
||||||
in slotptr() in typeobject.c . */
|
|
||||||
PyTypeObject ht_type;
|
|
||||||
PyAsyncMethods as_async;
|
|
||||||
PyNumberMethods as_number;
|
|
||||||
PyMappingMethods as_mapping;
|
|
||||||
PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
|
|
||||||
so that the mapping wins when both
|
|
||||||
the mapping and the sequence define
|
|
||||||
a given operator (e.g. __getitem__).
|
|
||||||
see add_operators() in typeobject.c . */
|
|
||||||
PyBufferProcs as_buffer;
|
|
||||||
PyObject *ht_name, *ht_slots, *ht_qualname;
|
|
||||||
struct _dictkeysobject *ht_cached_keys;
|
|
||||||
PyObject *ht_module;
|
|
||||||
char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec
|
|
||||||
struct _specialization_cache _spec_cache; // For use by the specializer.
|
|
||||||
/* here are optional user slots, followed by the members. */
|
|
||||||
} PyHeapTypeObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
// Backward compatibility for 3rd-party extensions
|
|
||||||
// that may be using the old name.
|
|
||||||
#define _PyObject_LookupSpecial _PyObject_LookupSpecialId
|
|
||||||
#endif
|
|
||||||
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
|
|
||||||
PyAPI_FUNC(void) _Py_BreakPoint(void);
|
|
||||||
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
|
|
||||||
PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
|
|
||||||
PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
|
|
||||||
/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
|
|
||||||
don't raise AttributeError.
|
|
||||||
|
|
||||||
Return 1 and set *result != NULL if an attribute is found.
|
|
||||||
Return 0 and set *result == NULL if an attribute is not found;
|
|
||||||
an AttributeError is silenced.
|
|
||||||
Return -1 and set *result == NULL if an error other than AttributeError
|
|
||||||
is raised.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **);
|
|
||||||
PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
|
|
||||||
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
|
|
||||||
|
|
||||||
/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes
|
|
||||||
dict as the last parameter. */
|
|
||||||
PyAPI_FUNC(PyObject *)
|
|
||||||
_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int);
|
|
||||||
PyAPI_FUNC(int)
|
|
||||||
_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
|
||||||
PyObject *, PyObject *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
|
|
||||||
|
|
||||||
/* Safely decref `op` and set `op` to `op2`.
|
|
||||||
*
|
|
||||||
* As in case of Py_CLEAR "the obvious" code can be deadly:
|
|
||||||
*
|
|
||||||
* Py_DECREF(op);
|
|
||||||
* op = op2;
|
|
||||||
*
|
|
||||||
* The safe way is:
|
|
||||||
*
|
|
||||||
* Py_SETREF(op, op2);
|
|
||||||
*
|
|
||||||
* That arranges to set `op` to `op2` _before_ decref'ing, so that any code
|
|
||||||
* triggered as a side-effect of `op` getting torn down no longer believes
|
|
||||||
* `op` points to a valid object.
|
|
||||||
*
|
|
||||||
* Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of
|
|
||||||
* Py_DECREF.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define Py_SETREF(op, op2) \
|
|
||||||
do { \
|
|
||||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
|
||||||
(op) = (op2); \
|
|
||||||
Py_DECREF(_py_tmp); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define Py_XSETREF(op, op2) \
|
|
||||||
do { \
|
|
||||||
PyObject *_py_tmp = _PyObject_CAST(op); \
|
|
||||||
(op) = (op2); \
|
|
||||||
Py_XDECREF(_py_tmp); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyNone_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
|
|
||||||
|
|
||||||
/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
|
|
||||||
* Defined in object.c.
|
|
||||||
*/
|
|
||||||
PyAPI_DATA(int) _Py_SwappedOp[];
|
|
||||||
|
|
||||||
PyAPI_FUNC(void)
|
|
||||||
_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
|
|
||||||
size_t sizeof_block);
|
|
||||||
PyAPI_FUNC(void)
|
|
||||||
_PyObject_DebugTypeStats(FILE *out);
|
|
||||||
|
|
||||||
/* Define a pair of assertion macros:
|
|
||||||
_PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
|
|
||||||
|
|
||||||
These work like the regular C assert(), in that they will abort the
|
|
||||||
process with a message on stderr if the given condition fails to hold,
|
|
||||||
but compile away to nothing if NDEBUG is defined.
|
|
||||||
|
|
||||||
However, before aborting, Python will also try to call _PyObject_Dump() on
|
|
||||||
the given object. This may be of use when investigating bugs in which a
|
|
||||||
particular object is corrupt (e.g. buggy a tp_visit method in an extension
|
|
||||||
module breaking the garbage collector), to help locate the broken objects.
|
|
||||||
|
|
||||||
The WITH_MSG variant allows you to supply an additional message that Python
|
|
||||||
will attempt to print to stderr, after the object dump. */
|
|
||||||
#ifdef NDEBUG
|
|
||||||
/* No debugging: compile away the assertions: */
|
|
||||||
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
|
||||||
((void)0)
|
|
||||||
#else
|
|
||||||
/* With debugging: generate checks: */
|
|
||||||
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
|
|
||||||
((expr) \
|
|
||||||
? (void)(0) \
|
|
||||||
: _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \
|
|
||||||
(msg), (filename), (lineno), (func)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
|
|
||||||
_PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__)
|
|
||||||
#define _PyObject_ASSERT(obj, expr) \
|
|
||||||
_PyObject_ASSERT_WITH_MSG(obj, expr, NULL)
|
|
||||||
|
|
||||||
#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \
|
|
||||||
_PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__)
|
|
||||||
|
|
||||||
/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined,
|
|
||||||
to avoid causing compiler/linker errors when building extensions without
|
|
||||||
NDEBUG against a Python built with NDEBUG defined.
|
|
||||||
|
|
||||||
msg, expr and function can be NULL. */
|
|
||||||
PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed(
|
|
||||||
PyObject *obj,
|
|
||||||
const char *expr,
|
|
||||||
const char *msg,
|
|
||||||
const char *file,
|
|
||||||
int line,
|
|
||||||
const char *function);
|
|
||||||
|
|
||||||
/* Check if an object is consistent. For example, ensure that the reference
|
|
||||||
counter is greater than or equal to 1, and ensure that ob_type is not NULL.
|
|
||||||
|
|
||||||
Call _PyObject_AssertFailed() if the object is inconsistent.
|
|
||||||
|
|
||||||
If check_content is zero, only check header fields: reduce the overhead.
|
|
||||||
|
|
||||||
The function always return 1. The return value is just here to be able to
|
|
||||||
write:
|
|
||||||
|
|
||||||
assert(_PyObject_CheckConsistency(obj, 1)); */
|
|
||||||
PyAPI_FUNC(int) _PyObject_CheckConsistency(
|
|
||||||
PyObject *op,
|
|
||||||
int check_content);
|
|
||||||
|
|
||||||
|
|
||||||
/* Trashcan mechanism, thanks to Christian Tismer.
|
|
||||||
|
|
||||||
When deallocating a container object, it's possible to trigger an unbounded
|
|
||||||
chain of deallocations, as each Py_DECREF in turn drops the refcount on "the
|
|
||||||
next" object in the chain to 0. This can easily lead to stack overflows,
|
|
||||||
especially in threads (which typically have less stack space to work with).
|
|
||||||
|
|
||||||
A container object can avoid this by bracketing the body of its tp_dealloc
|
|
||||||
function with a pair of macros:
|
|
||||||
|
|
||||||
static void
|
|
||||||
mytype_dealloc(mytype *p)
|
|
||||||
{
|
|
||||||
... declarations go here ...
|
|
||||||
|
|
||||||
PyObject_GC_UnTrack(p); // must untrack first
|
|
||||||
Py_TRASHCAN_BEGIN(p, mytype_dealloc)
|
|
||||||
... The body of the deallocator goes here, including all calls ...
|
|
||||||
... to Py_DECREF on contained objects. ...
|
|
||||||
Py_TRASHCAN_END // there should be no code after this
|
|
||||||
}
|
|
||||||
|
|
||||||
CAUTION: Never return from the middle of the body! If the body needs to
|
|
||||||
"get out early", put a label immediately before the Py_TRASHCAN_END
|
|
||||||
call, and goto it. Else the call-depth counter (see below) will stay
|
|
||||||
above 0 forever, and the trashcan will never get emptied.
|
|
||||||
|
|
||||||
How it works: The BEGIN macro increments a call-depth counter. So long
|
|
||||||
as this counter is small, the body of the deallocator is run directly without
|
|
||||||
further ado. But if the counter gets large, it instead adds p to a list of
|
|
||||||
objects to be deallocated later, skips the body of the deallocator, and
|
|
||||||
resumes execution after the END macro. The tp_dealloc routine then returns
|
|
||||||
without deallocating anything (and so unbounded call-stack depth is avoided).
|
|
||||||
|
|
||||||
When the call stack finishes unwinding again, code generated by the END macro
|
|
||||||
notices this, and calls another routine to deallocate all the objects that
|
|
||||||
may have been added to the list of deferred deallocations. In effect, a
|
|
||||||
chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces,
|
|
||||||
with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL.
|
|
||||||
|
|
||||||
Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
|
|
||||||
class, we need to ensure that the trashcan is only triggered on the tp_dealloc
|
|
||||||
of the actual class being deallocated. Otherwise we might end up with a
|
|
||||||
partially-deallocated object. To check this, the tp_dealloc function must be
|
|
||||||
passed as second argument to Py_TRASHCAN_BEGIN().
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Python 3.9 private API, invoked by the macros below. */
|
|
||||||
PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op);
|
|
||||||
PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate);
|
|
||||||
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
|
|
||||||
PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc);
|
|
||||||
|
|
||||||
#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
|
|
||||||
do { \
|
|
||||||
PyThreadState *_tstate = NULL; \
|
|
||||||
/* If "cond" is false, then _tstate remains NULL and the deallocator \
|
|
||||||
* is run normally without involving the trashcan */ \
|
|
||||||
if (cond) { \
|
|
||||||
_tstate = PyThreadState_Get(); \
|
|
||||||
if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
/* The body of the deallocator is here. */
|
|
||||||
#define Py_TRASHCAN_END \
|
|
||||||
if (_tstate) { \
|
|
||||||
_PyTrash_end(_tstate); \
|
|
||||||
} \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
#define Py_TRASHCAN_BEGIN(op, dealloc) \
|
|
||||||
Py_TRASHCAN_BEGIN_CONDITION(op, \
|
|
||||||
_PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc))
|
|
||||||
|
|
||||||
/* The following two macros, Py_TRASHCAN_SAFE_BEGIN and
|
|
||||||
* Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and
|
|
||||||
* will be removed in the future.
|
|
||||||
* Use Py_TRASHCAN_BEGIN and Py_TRASHCAN_END instead.
|
|
||||||
*/
|
|
||||||
Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro;
|
|
||||||
#define Py_TRASHCAN_SAFE_BEGIN(op) \
|
|
||||||
do { \
|
|
||||||
UsingDeprecatedTrashcanMacro cond=1; \
|
|
||||||
Py_TRASHCAN_BEGIN_CONDITION(op, cond);
|
|
||||||
#define Py_TRASHCAN_SAFE_END(op) \
|
|
||||||
Py_TRASHCAN_END; \
|
|
||||||
} while(0);
|
|
|
@ -1,89 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_OBJIMPL_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
|
|
||||||
|
|
||||||
/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
|
|
||||||
vrbl-size object with nitems items, exclusive of gc overhead (if any). The
|
|
||||||
value is rounded up to the closest multiple of sizeof(void *), in order to
|
|
||||||
ensure that pointer fields at the end of the object are correctly aligned
|
|
||||||
for the platform (this is of special importance for subclasses of, e.g.,
|
|
||||||
str or int, so that pointers can be stored after the embedded data).
|
|
||||||
|
|
||||||
Note that there's no memory wastage in doing this, as malloc has to
|
|
||||||
return (at worst) pointer-aligned memory anyway.
|
|
||||||
*/
|
|
||||||
#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
|
|
||||||
# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PyObject_VAR_SIZE(typeobj, nitems) \
|
|
||||||
_Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
|
|
||||||
(nitems)*(typeobj)->tp_itemsize, \
|
|
||||||
SIZEOF_VOID_P)
|
|
||||||
|
|
||||||
|
|
||||||
/* This example code implements an object constructor with a custom
|
|
||||||
allocator, where PyObject_New is inlined, and shows the important
|
|
||||||
distinction between two steps (at least):
|
|
||||||
1) the actual allocation of the object storage;
|
|
||||||
2) the initialization of the Python specific fields
|
|
||||||
in this storage with PyObject_{Init, InitVar}.
|
|
||||||
|
|
||||||
PyObject *
|
|
||||||
YourObject_New(...)
|
|
||||||
{
|
|
||||||
PyObject *op;
|
|
||||||
|
|
||||||
op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
|
|
||||||
if (op == NULL) {
|
|
||||||
return PyErr_NoMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject_Init(op, &YourTypeStruct);
|
|
||||||
|
|
||||||
op->ob_field = value;
|
|
||||||
...
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
Note that in C++, the use of the new operator usually implies that
|
|
||||||
the 1st step is performed automatically for you, so in a C++ class
|
|
||||||
constructor you would start directly with PyObject_Init/InitVar. */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* user context passed as the first argument to the 2 functions */
|
|
||||||
void *ctx;
|
|
||||||
|
|
||||||
/* allocate an arena of size bytes */
|
|
||||||
void* (*alloc) (void *ctx, size_t size);
|
|
||||||
|
|
||||||
/* free an arena */
|
|
||||||
void (*free) (void *ctx, void *ptr, size_t size);
|
|
||||||
} PyObjectArenaAllocator;
|
|
||||||
|
|
||||||
/* Get the arena allocator. */
|
|
||||||
PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
|
|
||||||
|
|
||||||
/* Set the arena allocator. */
|
|
||||||
PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
|
|
||||||
|
|
||||||
|
|
||||||
/* Test if an object implements the garbage collector protocol */
|
|
||||||
PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);
|
|
||||||
|
|
||||||
|
|
||||||
/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which
|
|
||||||
defines a different _PyGC_FINALIZED() macro. */
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
// Kept for backward compatibility with Python 3.8
|
|
||||||
# define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Test if a type supports weak references
|
|
||||||
PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef Py_ODICTOBJECT_H
|
|
||||||
#define Py_ODICTOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* OrderedDict */
|
|
||||||
/* This API is optional and mostly redundant. */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
|
|
||||||
typedef struct _odictobject PyODictObject;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyODict_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyODictIter_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyODictKeys_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyODictItems_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyODictValues_Type;
|
|
||||||
|
|
||||||
#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type)
|
|
||||||
#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type)
|
|
||||||
#define PyODict_SIZE(op) PyDict_GET_SIZE((op))
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyODict_New(void);
|
|
||||||
PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
|
|
||||||
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
|
|
||||||
|
|
||||||
/* wrappers around PyDict* functions */
|
|
||||||
#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key)
|
|
||||||
#define PyODict_GetItemWithError(od, key) \
|
|
||||||
PyDict_GetItemWithError(_PyObject_CAST(od), key)
|
|
||||||
#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key)
|
|
||||||
#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od))
|
|
||||||
#define PyODict_GetItemString(od, key) \
|
|
||||||
PyDict_GetItemString(_PyObject_CAST(od), key)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_ODICTOBJECT_H */
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* PickleBuffer object. This is built-in for ease of use from third-party
|
|
||||||
* C extensions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Py_PICKLEBUFOBJECT_H
|
|
||||||
#define Py_PICKLEBUFOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type;
|
|
||||||
|
|
||||||
#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type)
|
|
||||||
|
|
||||||
/* Create a PickleBuffer redirecting to the given buffer-enabled object */
|
|
||||||
PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *);
|
|
||||||
/* Get the PickleBuffer's underlying view to the original object
|
|
||||||
* (NULL if released)
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *);
|
|
||||||
/* Release the PickleBuffer. Returns 0 on success, -1 on error. */
|
|
||||||
PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *);
|
|
||||||
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_PICKLEBUFOBJECT_H */
|
|
|
@ -1,88 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PTRHEAD_STUBS_H
|
|
||||||
#define Py_CPYTHON_PTRHEAD_STUBS_H
|
|
||||||
|
|
||||||
#if !defined(HAVE_PTHREAD_STUBS)
|
|
||||||
# error "this header file requires stubbed pthreads."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _POSIX_THREADS
|
|
||||||
# define _POSIX_THREADS 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Minimal pthread stubs for CPython.
|
|
||||||
*
|
|
||||||
* The stubs implement the minimum pthread API for CPython.
|
|
||||||
* - pthread_create() fails.
|
|
||||||
* - pthread_exit() calls exit(0).
|
|
||||||
* - pthread_key_*() functions implement minimal TSS without destructor.
|
|
||||||
* - all other functions do nothing and return 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __wasi__
|
|
||||||
// WASI's bits/alltypes.h provides type definitions when __NEED_ is set.
|
|
||||||
// The header file can be included multiple times.
|
|
||||||
# define __NEED_pthread_cond_t 1
|
|
||||||
# define __NEED_pthread_condattr_t 1
|
|
||||||
# define __NEED_pthread_mutex_t 1
|
|
||||||
# define __NEED_pthread_mutexattr_t 1
|
|
||||||
# define __NEED_pthread_key_t 1
|
|
||||||
# define __NEED_pthread_t 1
|
|
||||||
# define __NEED_pthread_attr_t 1
|
|
||||||
# include <bits/alltypes.h>
|
|
||||||
#else
|
|
||||||
typedef struct { void *__x; } pthread_cond_t;
|
|
||||||
typedef struct { unsigned __attr; } pthread_condattr_t;
|
|
||||||
typedef struct { void *__x; } pthread_mutex_t;
|
|
||||||
typedef struct { unsigned __attr; } pthread_mutexattr_t;
|
|
||||||
typedef unsigned pthread_key_t;
|
|
||||||
typedef unsigned pthread_t;
|
|
||||||
typedef struct { unsigned __attr; } pthread_attr_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// mutex
|
|
||||||
PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex,
|
|
||||||
const pthread_mutexattr_t *restrict attr);
|
|
||||||
PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex);
|
|
||||||
PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex);
|
|
||||||
PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex);
|
|
||||||
PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex);
|
|
||||||
|
|
||||||
// condition
|
|
||||||
PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond,
|
|
||||||
const pthread_condattr_t *restrict attr);
|
|
||||||
PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond);
|
|
||||||
PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond,
|
|
||||||
pthread_mutex_t *restrict mutex);
|
|
||||||
PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond,
|
|
||||||
pthread_mutex_t *restrict mutex,
|
|
||||||
const struct timespec *restrict abstime);
|
|
||||||
PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond);
|
|
||||||
PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr);
|
|
||||||
PyAPI_FUNC(int) pthread_condattr_setclock(
|
|
||||||
pthread_condattr_t *attr, clockid_t clock_id);
|
|
||||||
|
|
||||||
// pthread
|
|
||||||
PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread,
|
|
||||||
const pthread_attr_t *restrict attr,
|
|
||||||
void *(*start_routine)(void *),
|
|
||||||
void *restrict arg);
|
|
||||||
PyAPI_FUNC(int) pthread_detach(pthread_t thread);
|
|
||||||
PyAPI_FUNC(pthread_t) pthread_self(void);
|
|
||||||
PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__));
|
|
||||||
PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr);
|
|
||||||
PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
|
|
||||||
PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr);
|
|
||||||
|
|
||||||
|
|
||||||
// pthread_key
|
|
||||||
#ifndef PTHREAD_KEYS_MAX
|
|
||||||
# define PTHREAD_KEYS_MAX 128
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key,
|
|
||||||
void (*destr_function)(void *));
|
|
||||||
PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key);
|
|
||||||
PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key);
|
|
||||||
PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value);
|
|
||||||
|
|
||||||
#endif // Py_CPYTHON_PTRHEAD_STUBS_H
|
|
|
@ -1,39 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef PYCTYPE_H
|
|
||||||
#define PYCTYPE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PY_CTF_LOWER 0x01
|
|
||||||
#define PY_CTF_UPPER 0x02
|
|
||||||
#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER)
|
|
||||||
#define PY_CTF_DIGIT 0x04
|
|
||||||
#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT)
|
|
||||||
#define PY_CTF_SPACE 0x08
|
|
||||||
#define PY_CTF_XDIGIT 0x10
|
|
||||||
|
|
||||||
PyAPI_DATA(const unsigned int) _Py_ctype_table[256];
|
|
||||||
|
|
||||||
/* Unlike their C counterparts, the following macros are not meant to
|
|
||||||
* handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument
|
|
||||||
* must be a signed/unsigned char. */
|
|
||||||
#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER)
|
|
||||||
#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER)
|
|
||||||
#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA)
|
|
||||||
#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT)
|
|
||||||
#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT)
|
|
||||||
#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM)
|
|
||||||
#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE)
|
|
||||||
|
|
||||||
PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256];
|
|
||||||
PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256];
|
|
||||||
|
|
||||||
#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)])
|
|
||||||
#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)])
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !PYCTYPE_H */
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_PYDEBUG_H
|
|
||||||
#define Py_PYDEBUG_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(int) Py_DebugFlag;
|
|
||||||
PyAPI_DATA(int) Py_VerboseFlag;
|
|
||||||
PyAPI_DATA(int) Py_QuietFlag;
|
|
||||||
PyAPI_DATA(int) Py_InteractiveFlag;
|
|
||||||
PyAPI_DATA(int) Py_InspectFlag;
|
|
||||||
PyAPI_DATA(int) Py_OptimizeFlag;
|
|
||||||
PyAPI_DATA(int) Py_NoSiteFlag;
|
|
||||||
PyAPI_DATA(int) Py_BytesWarningFlag;
|
|
||||||
PyAPI_DATA(int) Py_FrozenFlag;
|
|
||||||
PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
|
|
||||||
PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
|
|
||||||
PyAPI_DATA(int) Py_NoUserSiteDirectory;
|
|
||||||
PyAPI_DATA(int) Py_UnbufferedStdioFlag;
|
|
||||||
PyAPI_DATA(int) Py_HashRandomizationFlag;
|
|
||||||
PyAPI_DATA(int) Py_IsolatedFlag;
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag;
|
|
||||||
PyAPI_DATA(int) Py_LegacyWindowsStdioFlag;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* this is a wrapper around getenv() that pays attention to
|
|
||||||
Py_IgnoreEnvironmentFlag. It should be used for getting variables like
|
|
||||||
PYTHONPATH and PYTHONHOME from the environment */
|
|
||||||
PyAPI_DATA(char*) Py_GETENV(const char *name);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_PYDEBUG_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,179 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_ERRORS_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Error objects */
|
|
||||||
|
|
||||||
/* PyException_HEAD defines the initial segment of every exception class. */
|
|
||||||
#define PyException_HEAD PyObject_HEAD PyObject *dict;\
|
|
||||||
PyObject *args; PyObject *notes; PyObject *traceback;\
|
|
||||||
PyObject *context; PyObject *cause;\
|
|
||||||
char suppress_context;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
} PyBaseExceptionObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *msg;
|
|
||||||
PyObject *excs;
|
|
||||||
} PyBaseExceptionGroupObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *msg;
|
|
||||||
PyObject *filename;
|
|
||||||
PyObject *lineno;
|
|
||||||
PyObject *offset;
|
|
||||||
PyObject *end_lineno;
|
|
||||||
PyObject *end_offset;
|
|
||||||
PyObject *text;
|
|
||||||
PyObject *print_file_and_line;
|
|
||||||
} PySyntaxErrorObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *msg;
|
|
||||||
PyObject *name;
|
|
||||||
PyObject *path;
|
|
||||||
} PyImportErrorObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *encoding;
|
|
||||||
PyObject *object;
|
|
||||||
Py_ssize_t start;
|
|
||||||
Py_ssize_t end;
|
|
||||||
PyObject *reason;
|
|
||||||
} PyUnicodeErrorObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *code;
|
|
||||||
} PySystemExitObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *myerrno;
|
|
||||||
PyObject *strerror;
|
|
||||||
PyObject *filename;
|
|
||||||
PyObject *filename2;
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
PyObject *winerror;
|
|
||||||
#endif
|
|
||||||
Py_ssize_t written; /* only for BlockingIOError, -1 otherwise */
|
|
||||||
} PyOSErrorObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *value;
|
|
||||||
} PyStopIterationObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *name;
|
|
||||||
} PyNameErrorObject;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyException_HEAD
|
|
||||||
PyObject *obj;
|
|
||||||
PyObject *name;
|
|
||||||
} PyAttributeErrorObject;
|
|
||||||
|
|
||||||
/* Compatibility typedefs */
|
|
||||||
typedef PyOSErrorObject PyEnvironmentErrorObject;
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
typedef PyOSErrorObject PyWindowsErrorObject;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Error handling definitions */
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
|
|
||||||
PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate);
|
|
||||||
PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *);
|
|
||||||
PyAPI_FUNC(void) _PyErr_SetHandledException(PyThreadState *, PyObject *);
|
|
||||||
PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **);
|
|
||||||
|
|
||||||
/* Context manipulation (PEP 3134) */
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
|
|
||||||
|
|
||||||
/* Like PyErr_Format(), but saves current exception as __context__ and
|
|
||||||
__cause__.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause(
|
|
||||||
PyObject *exception,
|
|
||||||
const char *format, /* ASCII-encoded string */
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
/* In exceptions.c */
|
|
||||||
|
|
||||||
/* Helper that attempts to replace the current exception with one of the
|
|
||||||
* same type but with a prefix added to the exception text. The resulting
|
|
||||||
* exception description looks like:
|
|
||||||
*
|
|
||||||
* prefix (exc_type: original_exc_str)
|
|
||||||
*
|
|
||||||
* Only some exceptions can be safely replaced. If the function determines
|
|
||||||
* it isn't safe to perform the replacement, it will leave the original
|
|
||||||
* unmodified exception in place.
|
|
||||||
*
|
|
||||||
* Returns a borrowed reference to the new exception (if any), NULL if the
|
|
||||||
* existing exception was left in place.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause(
|
|
||||||
const char *prefix_format, /* ASCII-encoded string */
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
/* In signalmodule.c */
|
|
||||||
|
|
||||||
int PySignal_SetWakeupFd(int fd);
|
|
||||||
PyAPI_FUNC(int) _PyErr_CheckSignals(void);
|
|
||||||
|
|
||||||
/* Support for adding program text to SyntaxErrors */
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyErr_SyntaxLocationObject(
|
|
||||||
PyObject *filename,
|
|
||||||
int lineno,
|
|
||||||
int col_offset);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) PyErr_RangedSyntaxLocationObject(
|
|
||||||
PyObject *filename,
|
|
||||||
int lineno,
|
|
||||||
int col_offset,
|
|
||||||
int end_lineno,
|
|
||||||
int end_col_offset);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject(
|
|
||||||
PyObject *filename,
|
|
||||||
int lineno);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject(
|
|
||||||
PyObject *filename,
|
|
||||||
int lineno,
|
|
||||||
const char* encoding);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create(
|
|
||||||
PyObject *object,
|
|
||||||
Py_ssize_t start,
|
|
||||||
Py_ssize_t end,
|
|
||||||
const char *reason /* UTF-8 encoded string */
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg(
|
|
||||||
const char *err_msg,
|
|
||||||
PyObject *obj);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFunc(
|
|
||||||
const char *func,
|
|
||||||
const char *message);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat(
|
|
||||||
const char *func,
|
|
||||||
const char *format,
|
|
||||||
...);
|
|
||||||
|
|
||||||
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message)
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef Py_PYFPE_H
|
|
||||||
#define Py_PYFPE_H
|
|
||||||
/* Header excluded from the stable API */
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
|
|
||||||
/* These macros used to do something when Python was built with --with-fpectl,
|
|
||||||
* but support for that was dropped in 3.7. We continue to define them though,
|
|
||||||
* to avoid breaking API users.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PyFPE_START_PROTECT(err_string, leave_stmt)
|
|
||||||
#define PyFPE_END_PROTECT(v)
|
|
||||||
|
|
||||||
#endif /* !defined(Py_LIMITED_API) */
|
|
||||||
#endif /* !Py_PYFPE_H */
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYFRAME_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyFrame_Type;
|
|
||||||
|
|
||||||
#define PyFrame_Check(op) Py_IS_TYPE((op), &PyFrame_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame);
|
|
||||||
PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame);
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYLIFECYCLE_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Py_FrozenMain is kept out of the Limited API until documented and present
|
|
||||||
in all builds of Python */
|
|
||||||
PyAPI_FUNC(int) Py_FrozenMain(int argc, char **argv);
|
|
||||||
|
|
||||||
/* Only used by applications that embed the interpreter and need to
|
|
||||||
* override the standard encoding determination mechanism
|
|
||||||
*/
|
|
||||||
Py_DEPRECATED(3.11) PyAPI_FUNC(int) Py_SetStandardStreamEncoding(
|
|
||||||
const char *encoding,
|
|
||||||
const char *errors);
|
|
||||||
|
|
||||||
/* PEP 432 Multi-phase initialization API (Private while provisional!) */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyStatus) Py_PreInitialize(
|
|
||||||
const PyPreConfig *src_config);
|
|
||||||
PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs(
|
|
||||||
const PyPreConfig *src_config,
|
|
||||||
Py_ssize_t argc,
|
|
||||||
char **argv);
|
|
||||||
PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs(
|
|
||||||
const PyPreConfig *src_config,
|
|
||||||
Py_ssize_t argc,
|
|
||||||
wchar_t **argv);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* Initialization and finalization */
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
|
|
||||||
const PyConfig *config);
|
|
||||||
PyAPI_FUNC(PyStatus) _Py_InitializeMain(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) Py_RunMain(void);
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err);
|
|
||||||
|
|
||||||
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */
|
|
||||||
PyAPI_FUNC(void) _Py_RestoreSignals(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
|
|
||||||
PyAPI_FUNC(int) _Py_FdIsInteractive(FILE *fp, PyObject *filename);
|
|
||||||
|
|
||||||
Py_DEPRECATED(3.11) PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(const char *) _Py_gitidentifier(void);
|
|
||||||
PyAPI_FUNC(const char *) _Py_gitversion(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _Py_IsFinalizing(void);
|
|
||||||
|
|
||||||
/* Random */
|
|
||||||
PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size);
|
|
||||||
PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size);
|
|
||||||
|
|
||||||
/* Legacy locale support */
|
|
||||||
PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn);
|
|
||||||
PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn);
|
|
||||||
PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter);
|
|
|
@ -1,98 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYMEM_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size);
|
|
||||||
PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize);
|
|
||||||
PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size);
|
|
||||||
PyAPI_FUNC(void) PyMem_RawFree(void *ptr);
|
|
||||||
|
|
||||||
/* Try to get the allocators name set by _PyMem_SetupAllocators(). */
|
|
||||||
PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);
|
|
||||||
|
|
||||||
/* strdup() using PyMem_RawMalloc() */
|
|
||||||
PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str);
|
|
||||||
|
|
||||||
/* strdup() using PyMem_Malloc() */
|
|
||||||
PyAPI_FUNC(char *) _PyMem_Strdup(const char *str);
|
|
||||||
|
|
||||||
/* wcsdup() using PyMem_RawMalloc() */
|
|
||||||
PyAPI_FUNC(wchar_t*) _PyMem_RawWcsdup(const wchar_t *str);
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* PyMem_RawMalloc(), PyMem_RawRealloc() and PyMem_RawFree() */
|
|
||||||
PYMEM_DOMAIN_RAW,
|
|
||||||
|
|
||||||
/* PyMem_Malloc(), PyMem_Realloc() and PyMem_Free() */
|
|
||||||
PYMEM_DOMAIN_MEM,
|
|
||||||
|
|
||||||
/* PyObject_Malloc(), PyObject_Realloc() and PyObject_Free() */
|
|
||||||
PYMEM_DOMAIN_OBJ
|
|
||||||
} PyMemAllocatorDomain;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
PYMEM_ALLOCATOR_NOT_SET = 0,
|
|
||||||
PYMEM_ALLOCATOR_DEFAULT = 1,
|
|
||||||
PYMEM_ALLOCATOR_DEBUG = 2,
|
|
||||||
PYMEM_ALLOCATOR_MALLOC = 3,
|
|
||||||
PYMEM_ALLOCATOR_MALLOC_DEBUG = 4,
|
|
||||||
#ifdef WITH_PYMALLOC
|
|
||||||
PYMEM_ALLOCATOR_PYMALLOC = 5,
|
|
||||||
PYMEM_ALLOCATOR_PYMALLOC_DEBUG = 6,
|
|
||||||
#endif
|
|
||||||
} PyMemAllocatorName;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* user context passed as the first argument to the 4 functions */
|
|
||||||
void *ctx;
|
|
||||||
|
|
||||||
/* allocate a memory block */
|
|
||||||
void* (*malloc) (void *ctx, size_t size);
|
|
||||||
|
|
||||||
/* allocate a memory block initialized by zeros */
|
|
||||||
void* (*calloc) (void *ctx, size_t nelem, size_t elsize);
|
|
||||||
|
|
||||||
/* allocate or resize a memory block */
|
|
||||||
void* (*realloc) (void *ctx, void *ptr, size_t new_size);
|
|
||||||
|
|
||||||
/* release a memory block */
|
|
||||||
void (*free) (void *ctx, void *ptr);
|
|
||||||
} PyMemAllocatorEx;
|
|
||||||
|
|
||||||
/* Get the memory block allocator of the specified domain. */
|
|
||||||
PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain,
|
|
||||||
PyMemAllocatorEx *allocator);
|
|
||||||
|
|
||||||
/* Set the memory block allocator of the specified domain.
|
|
||||||
|
|
||||||
The new allocator must return a distinct non-NULL pointer when requesting
|
|
||||||
zero bytes.
|
|
||||||
|
|
||||||
For the PYMEM_DOMAIN_RAW domain, the allocator must be thread-safe: the GIL
|
|
||||||
is not held when the allocator is called.
|
|
||||||
|
|
||||||
If the new allocator is not a hook (don't call the previous allocator), the
|
|
||||||
PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks
|
|
||||||
on top on the new allocator. */
|
|
||||||
PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain,
|
|
||||||
PyMemAllocatorEx *allocator);
|
|
||||||
|
|
||||||
/* Setup hooks to detect bugs in the following Python memory allocator
|
|
||||||
functions:
|
|
||||||
|
|
||||||
- PyMem_RawMalloc(), PyMem_RawRealloc(), PyMem_RawFree()
|
|
||||||
- PyMem_Malloc(), PyMem_Realloc(), PyMem_Free()
|
|
||||||
- PyObject_Malloc(), PyObject_Realloc() and PyObject_Free()
|
|
||||||
|
|
||||||
Newly allocated memory is filled with the byte 0xCB, freed memory is filled
|
|
||||||
with the byte 0xDB. Additional checks:
|
|
||||||
|
|
||||||
- detect API violations, ex: PyObject_Free() called on a buffer allocated
|
|
||||||
by PyMem_Malloc()
|
|
||||||
- detect write before the start of the buffer (buffer underflow)
|
|
||||||
- detect write after the end of the buffer (buffer overflow)
|
|
||||||
|
|
||||||
The function does nothing if Python is not compiled is debug mode. */
|
|
||||||
PyAPI_FUNC(void) PyMem_SetupDebugHooks(void);
|
|
|
@ -1,366 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYSTATE_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
|
|
||||||
PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *);
|
|
||||||
|
|
||||||
/* State unique per thread */
|
|
||||||
|
|
||||||
/* Py_tracefunc return -1 when raising an exception, or 0 for success. */
|
|
||||||
typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *);
|
|
||||||
|
|
||||||
/* The following values are used for 'what' for tracefunc functions
|
|
||||||
*
|
|
||||||
* To add a new kind of trace event, also update "trace_init" in
|
|
||||||
* Python/sysmodule.c to define the Python level event name
|
|
||||||
*/
|
|
||||||
#define PyTrace_CALL 0
|
|
||||||
#define PyTrace_EXCEPTION 1
|
|
||||||
#define PyTrace_LINE 2
|
|
||||||
#define PyTrace_RETURN 3
|
|
||||||
#define PyTrace_C_CALL 4
|
|
||||||
#define PyTrace_C_EXCEPTION 5
|
|
||||||
#define PyTrace_C_RETURN 6
|
|
||||||
#define PyTrace_OPCODE 7
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyCodeObject *code; // The code object for the bounds. May be NULL.
|
|
||||||
PyCodeAddressRange bounds; // Only valid if code != NULL.
|
|
||||||
} PyTraceInfo;
|
|
||||||
|
|
||||||
// Internal structure: you should not use it directly, but use public functions
|
|
||||||
// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing().
|
|
||||||
typedef struct _PyCFrame {
|
|
||||||
/* This struct will be threaded through the C stack
|
|
||||||
* allowing fast access to per-thread state that needs
|
|
||||||
* to be accessed quickly by the interpreter, but can
|
|
||||||
* be modified outside of the interpreter.
|
|
||||||
*
|
|
||||||
* WARNING: This makes data on the C stack accessible from
|
|
||||||
* heap objects. Care must be taken to maintain stack
|
|
||||||
* discipline and make sure that instances of this struct cannot
|
|
||||||
* accessed outside of their lifetime.
|
|
||||||
*/
|
|
||||||
uint8_t use_tracing; // 0 or 255 (or'ed into opcode, hence 8-bit type)
|
|
||||||
/* Pointer to the currently executing frame (it can be NULL) */
|
|
||||||
struct _PyInterpreterFrame *current_frame;
|
|
||||||
struct _PyCFrame *previous;
|
|
||||||
} _PyCFrame;
|
|
||||||
|
|
||||||
typedef struct _err_stackitem {
|
|
||||||
/* This struct represents a single execution context where we might
|
|
||||||
* be currently handling an exception. It is a per-coroutine state
|
|
||||||
* (coroutine in the computer science sense, including the thread
|
|
||||||
* and generators).
|
|
||||||
*
|
|
||||||
* This is used as an entry on the exception stack, where each
|
|
||||||
* entry indicates if it is currently handling an exception.
|
|
||||||
* This ensures that the exception state is not impacted
|
|
||||||
* by "yields" from an except handler. The thread
|
|
||||||
* always has an entry (the bottom-most one).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The exception currently being handled in this context, if any. */
|
|
||||||
PyObject *exc_value;
|
|
||||||
|
|
||||||
struct _err_stackitem *previous_item;
|
|
||||||
|
|
||||||
} _PyErr_StackItem;
|
|
||||||
|
|
||||||
typedef struct _stack_chunk {
|
|
||||||
struct _stack_chunk *previous;
|
|
||||||
size_t size;
|
|
||||||
size_t top;
|
|
||||||
PyObject * data[1]; /* Variable sized */
|
|
||||||
} _PyStackChunk;
|
|
||||||
|
|
||||||
struct _ts {
|
|
||||||
/* See Python/ceval.c for comments explaining most fields */
|
|
||||||
|
|
||||||
PyThreadState *prev;
|
|
||||||
PyThreadState *next;
|
|
||||||
PyInterpreterState *interp;
|
|
||||||
|
|
||||||
/* Has been initialized to a safe state.
|
|
||||||
|
|
||||||
In order to be effective, this must be set to 0 during or right
|
|
||||||
after allocation. */
|
|
||||||
int _initialized;
|
|
||||||
|
|
||||||
/* Was this thread state statically allocated? */
|
|
||||||
int _static;
|
|
||||||
|
|
||||||
int recursion_remaining;
|
|
||||||
int recursion_limit;
|
|
||||||
int recursion_headroom; /* Allow 50 more calls to handle any errors. */
|
|
||||||
|
|
||||||
/* 'tracing' keeps track of the execution depth when tracing/profiling.
|
|
||||||
This is to prevent the actual trace/profile code from being recorded in
|
|
||||||
the trace/profile. */
|
|
||||||
int tracing;
|
|
||||||
int tracing_what; /* The event currently being traced, if any. */
|
|
||||||
|
|
||||||
/* Pointer to current _PyCFrame in the C stack frame of the currently,
|
|
||||||
* or most recently, executing _PyEval_EvalFrameDefault. */
|
|
||||||
_PyCFrame *cframe;
|
|
||||||
|
|
||||||
Py_tracefunc c_profilefunc;
|
|
||||||
Py_tracefunc c_tracefunc;
|
|
||||||
PyObject *c_profileobj;
|
|
||||||
PyObject *c_traceobj;
|
|
||||||
|
|
||||||
/* The exception currently being raised */
|
|
||||||
PyObject *curexc_type;
|
|
||||||
PyObject *curexc_value;
|
|
||||||
PyObject *curexc_traceback;
|
|
||||||
|
|
||||||
/* Pointer to the top of the exception stack for the exceptions
|
|
||||||
* we may be currently handling. (See _PyErr_StackItem above.)
|
|
||||||
* This is never NULL. */
|
|
||||||
_PyErr_StackItem *exc_info;
|
|
||||||
|
|
||||||
PyObject *dict; /* Stores per-thread state */
|
|
||||||
|
|
||||||
int gilstate_counter;
|
|
||||||
|
|
||||||
PyObject *async_exc; /* Asynchronous exception to raise */
|
|
||||||
unsigned long thread_id; /* Thread id where this tstate was created */
|
|
||||||
|
|
||||||
/* Native thread id where this tstate was created. This will be 0 except on
|
|
||||||
* those platforms that have the notion of native thread id, for which the
|
|
||||||
* macro PY_HAVE_THREAD_NATIVE_ID is then defined.
|
|
||||||
*/
|
|
||||||
unsigned long native_thread_id;
|
|
||||||
|
|
||||||
int trash_delete_nesting;
|
|
||||||
PyObject *trash_delete_later;
|
|
||||||
|
|
||||||
/* Called when a thread state is deleted normally, but not when it
|
|
||||||
* is destroyed after fork().
|
|
||||||
* Pain: to prevent rare but fatal shutdown errors (issue 18808),
|
|
||||||
* Thread.join() must wait for the join'ed thread's tstate to be unlinked
|
|
||||||
* from the tstate chain. That happens at the end of a thread's life,
|
|
||||||
* in pystate.c.
|
|
||||||
* The obvious way doesn't quite work: create a lock which the tstate
|
|
||||||
* unlinking code releases, and have Thread.join() wait to acquire that
|
|
||||||
* lock. The problem is that we _are_ at the end of the thread's life:
|
|
||||||
* if the thread holds the last reference to the lock, decref'ing the
|
|
||||||
* lock will delete the lock, and that may trigger arbitrary Python code
|
|
||||||
* if there's a weakref, with a callback, to the lock. But by this time
|
|
||||||
* _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
|
|
||||||
* of C code can be allowed to run (in particular it must not be possible to
|
|
||||||
* release the GIL).
|
|
||||||
* So instead of holding the lock directly, the tstate holds a weakref to
|
|
||||||
* the lock: that's the value of on_delete_data below. Decref'ing a
|
|
||||||
* weakref is harmless.
|
|
||||||
* on_delete points to _threadmodule.c's static release_sentinel() function.
|
|
||||||
* After the tstate is unlinked, release_sentinel is called with the
|
|
||||||
* weakref-to-lock (on_delete_data) argument, and release_sentinel releases
|
|
||||||
* the indirectly held lock.
|
|
||||||
*/
|
|
||||||
void (*on_delete)(void *);
|
|
||||||
void *on_delete_data;
|
|
||||||
|
|
||||||
int coroutine_origin_tracking_depth;
|
|
||||||
|
|
||||||
PyObject *async_gen_firstiter;
|
|
||||||
PyObject *async_gen_finalizer;
|
|
||||||
|
|
||||||
PyObject *context;
|
|
||||||
uint64_t context_ver;
|
|
||||||
|
|
||||||
/* Unique thread state id. */
|
|
||||||
uint64_t id;
|
|
||||||
|
|
||||||
PyTraceInfo trace_info;
|
|
||||||
|
|
||||||
_PyStackChunk *datastack_chunk;
|
|
||||||
PyObject **datastack_top;
|
|
||||||
PyObject **datastack_limit;
|
|
||||||
/* XXX signal handlers should also be here */
|
|
||||||
|
|
||||||
/* The following fields are here to avoid allocation during init.
|
|
||||||
The data is exposed through PyThreadState pointer fields.
|
|
||||||
These fields should not be accessed directly outside of init.
|
|
||||||
This is indicated by an underscore prefix on the field names.
|
|
||||||
|
|
||||||
All other PyInterpreterState pointer fields are populated when
|
|
||||||
needed and default to NULL.
|
|
||||||
*/
|
|
||||||
// Note some fields do not have a leading underscore for backward
|
|
||||||
// compatibility. See https://bugs.python.org/issue45953#msg412046.
|
|
||||||
|
|
||||||
/* The thread's exception stack entry. (Always the last entry.) */
|
|
||||||
_PyErr_StackItem exc_state;
|
|
||||||
|
|
||||||
/* The bottom-most frame on the stack. */
|
|
||||||
_PyCFrame root_cframe;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* other API */
|
|
||||||
|
|
||||||
// Alias for backward compatibility with Python 3.8
|
|
||||||
#define _PyInterpreterState_Get PyInterpreterState_Get
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *);
|
|
||||||
|
|
||||||
/* Similar to PyThreadState_Get(), but don't issue a fatal error
|
|
||||||
* if it is NULL. */
|
|
||||||
PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate);
|
|
||||||
|
|
||||||
// Disable tracing and profiling.
|
|
||||||
PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate);
|
|
||||||
|
|
||||||
// Reset tracing and profiling: enable them if a trace function or a profile
|
|
||||||
// function is set, otherwise disable them.
|
|
||||||
PyAPI_FUNC(void) PyThreadState_LeaveTracing(PyThreadState *tstate);
|
|
||||||
|
|
||||||
/* PyGILState */
|
|
||||||
|
|
||||||
/* Helper/diagnostic function - return 1 if the current thread
|
|
||||||
currently holds the GIL, 0 otherwise.
|
|
||||||
|
|
||||||
The function returns 1 if _PyGILState_check_enabled is non-zero. */
|
|
||||||
PyAPI_FUNC(int) PyGILState_Check(void);
|
|
||||||
|
|
||||||
/* Get the single PyInterpreterState used by this process' GILState
|
|
||||||
implementation.
|
|
||||||
|
|
||||||
This function doesn't check for error. Return NULL before _PyGILState_Init()
|
|
||||||
is called and after _PyGILState_Fini() is called.
|
|
||||||
|
|
||||||
See also _PyInterpreterState_Get() and _PyInterpreterState_GET(). */
|
|
||||||
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
|
|
||||||
|
|
||||||
/* The implementation of sys._current_frames() Returns a dict mapping
|
|
||||||
thread id to that thread's current frame.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void);
|
|
||||||
|
|
||||||
/* The implementation of sys._current_exceptions() Returns a dict mapping
|
|
||||||
thread id to that thread's current exception.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(PyObject *) _PyThread_CurrentExceptions(void);
|
|
||||||
|
|
||||||
/* Routines for advanced debuggers, requested by David Beazley.
|
|
||||||
Don't use unless you know what you are doing! */
|
|
||||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Main(void);
|
|
||||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void);
|
|
||||||
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *);
|
|
||||||
PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *);
|
|
||||||
PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
|
|
||||||
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
|
|
||||||
|
|
||||||
/* Frame evaluation API */
|
|
||||||
|
|
||||||
typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int);
|
|
||||||
|
|
||||||
PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
|
|
||||||
PyInterpreterState *interp);
|
|
||||||
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
|
|
||||||
PyInterpreterState *interp,
|
|
||||||
_PyFrameEvalFunction eval_frame);
|
|
||||||
|
|
||||||
PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *interp);
|
|
||||||
|
|
||||||
/* Get a copy of the current interpreter configuration.
|
|
||||||
|
|
||||||
Return 0 on success. Raise an exception and return -1 on error.
|
|
||||||
|
|
||||||
The caller must initialize 'config', using PyConfig_InitPythonConfig()
|
|
||||||
for example.
|
|
||||||
|
|
||||||
Python must be preinitialized to call this method.
|
|
||||||
The caller must hold the GIL. */
|
|
||||||
PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy(
|
|
||||||
struct PyConfig *config);
|
|
||||||
|
|
||||||
/* Set the configuration of the current interpreter.
|
|
||||||
|
|
||||||
This function should be called during or just after the Python
|
|
||||||
initialization.
|
|
||||||
|
|
||||||
Update the sys module with the new configuration. If the sys module was
|
|
||||||
modified directly after the Python initialization, these changes are lost.
|
|
||||||
|
|
||||||
Some configuration like faulthandler or warnoptions can be updated in the
|
|
||||||
configuration, but don't reconfigure Python (don't enable/disable
|
|
||||||
faulthandler and don't reconfigure warnings filters).
|
|
||||||
|
|
||||||
Return 0 on success. Raise an exception and return -1 on error.
|
|
||||||
|
|
||||||
The configuration should come from _PyInterpreterState_GetConfigCopy(). */
|
|
||||||
PyAPI_FUNC(int) _PyInterpreterState_SetConfig(
|
|
||||||
const struct PyConfig *config);
|
|
||||||
|
|
||||||
// Get the configuration of the current interpreter.
|
|
||||||
// The caller must hold the GIL.
|
|
||||||
PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* cross-interpreter data */
|
|
||||||
|
|
||||||
// _PyCrossInterpreterData is similar to Py_buffer as an effectively
|
|
||||||
// opaque struct that holds data outside the object machinery. This
|
|
||||||
// is necessary to pass safely between interpreters in the same process.
|
|
||||||
typedef struct _xid _PyCrossInterpreterData;
|
|
||||||
|
|
||||||
struct _xid {
|
|
||||||
// data is the cross-interpreter-safe derivation of a Python object
|
|
||||||
// (see _PyObject_GetCrossInterpreterData). It will be NULL if the
|
|
||||||
// new_object func (below) encodes the data.
|
|
||||||
void *data;
|
|
||||||
// obj is the Python object from which the data was derived. This
|
|
||||||
// is non-NULL only if the data remains bound to the object in some
|
|
||||||
// way, such that the object must be "released" (via a decref) when
|
|
||||||
// the data is released. In that case the code that sets the field,
|
|
||||||
// likely a registered "crossinterpdatafunc", is responsible for
|
|
||||||
// ensuring it owns the reference (i.e. incref).
|
|
||||||
PyObject *obj;
|
|
||||||
// interp is the ID of the owning interpreter of the original
|
|
||||||
// object. It corresponds to the active interpreter when
|
|
||||||
// _PyObject_GetCrossInterpreterData() was called. This should only
|
|
||||||
// be set by the cross-interpreter machinery.
|
|
||||||
//
|
|
||||||
// We use the ID rather than the PyInterpreterState to avoid issues
|
|
||||||
// with deleted interpreters. Note that IDs are never re-used, so
|
|
||||||
// each one will always correspond to a specific interpreter
|
|
||||||
// (whether still alive or not).
|
|
||||||
int64_t interp;
|
|
||||||
// new_object is a function that returns a new object in the current
|
|
||||||
// interpreter given the data. The resulting object (a new
|
|
||||||
// reference) will be equivalent to the original object. This field
|
|
||||||
// is required.
|
|
||||||
PyObject *(*new_object)(_PyCrossInterpreterData *);
|
|
||||||
// free is called when the data is released. If it is NULL then
|
|
||||||
// nothing will be done to free the data. For some types this is
|
|
||||||
// okay (e.g. bytes) and for those types this field should be set
|
|
||||||
// to NULL. However, for most the data was allocated just for
|
|
||||||
// cross-interpreter use, so it must be freed when
|
|
||||||
// _PyCrossInterpreterData_Release is called or the memory will
|
|
||||||
// leak. In that case, at the very least this field should be set
|
|
||||||
// to PyMem_RawFree (the default if not explicitly set to NULL).
|
|
||||||
// The call will happen with the original interpreter activated.
|
|
||||||
void (*free)(void *);
|
|
||||||
};
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
|
|
||||||
PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
|
|
||||||
|
|
||||||
/* cross-interpreter data registry */
|
|
||||||
|
|
||||||
typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
|
|
||||||
PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
|
|
|
@ -1,121 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYTHONRUN_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
|
|
||||||
PyAPI_FUNC(int) _PyRun_SimpleFileObject(
|
|
||||||
FILE *fp,
|
|
||||||
PyObject *filename,
|
|
||||||
int closeit,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) PyRun_AnyFileExFlags(
|
|
||||||
FILE *fp,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
int closeit,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) _PyRun_AnyFileObject(
|
|
||||||
FILE *fp,
|
|
||||||
PyObject *filename,
|
|
||||||
int closeit,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) PyRun_SimpleFileExFlags(
|
|
||||||
FILE *fp,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
int closeit,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) PyRun_InteractiveOneFlags(
|
|
||||||
FILE *fp,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) PyRun_InteractiveOneObject(
|
|
||||||
FILE *fp,
|
|
||||||
PyObject *filename,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(
|
|
||||||
FILE *fp,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
PyAPI_FUNC(int) _PyRun_InteractiveLoopObject(
|
|
||||||
FILE *fp,
|
|
||||||
PyObject *filename,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *,
|
|
||||||
PyObject *, PyCompilerFlags *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_FileExFlags(
|
|
||||||
FILE *fp,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
int start,
|
|
||||||
PyObject *globals,
|
|
||||||
PyObject *locals,
|
|
||||||
int closeit,
|
|
||||||
PyCompilerFlags *flags);
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) Py_CompileStringExFlags(
|
|
||||||
const char *str,
|
|
||||||
const char *filename, /* decoded from the filesystem encoding */
|
|
||||||
int start,
|
|
||||||
PyCompilerFlags *flags,
|
|
||||||
int optimize);
|
|
||||||
PyAPI_FUNC(PyObject *) Py_CompileStringObject(
|
|
||||||
const char *str,
|
|
||||||
PyObject *filename, int start,
|
|
||||||
PyCompilerFlags *flags,
|
|
||||||
int optimize);
|
|
||||||
|
|
||||||
#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1)
|
|
||||||
#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1)
|
|
||||||
|
|
||||||
|
|
||||||
PyAPI_FUNC(const char *) _Py_SourceAsString(
|
|
||||||
PyObject *cmd,
|
|
||||||
const char *funcname,
|
|
||||||
const char *what,
|
|
||||||
PyCompilerFlags *cf,
|
|
||||||
PyObject **cmd_copy);
|
|
||||||
|
|
||||||
|
|
||||||
/* A function flavor is also exported by libpython. It is required when
|
|
||||||
libpython is accessed directly rather than using header files which defines
|
|
||||||
macros below. On Windows, for example, PyAPI_FUNC() uses dllexport to
|
|
||||||
export functions in pythonXX.dll. */
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l);
|
|
||||||
PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name);
|
|
||||||
PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit);
|
|
||||||
PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *);
|
|
||||||
PyAPI_FUNC(int) PyRun_SimpleString(const char *s);
|
|
||||||
PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p);
|
|
||||||
PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c);
|
|
||||||
PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p);
|
|
||||||
PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p);
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l);
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c);
|
|
||||||
PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags);
|
|
||||||
|
|
||||||
/* Use macros for a bunch of old variants */
|
|
||||||
#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
|
|
||||||
#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL)
|
|
||||||
#define PyRun_AnyFileEx(fp, name, closeit) \
|
|
||||||
PyRun_AnyFileExFlags(fp, name, closeit, NULL)
|
|
||||||
#define PyRun_AnyFileFlags(fp, name, flags) \
|
|
||||||
PyRun_AnyFileExFlags(fp, name, 0, flags)
|
|
||||||
#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL)
|
|
||||||
#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL)
|
|
||||||
#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL)
|
|
||||||
#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL)
|
|
||||||
#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL)
|
|
||||||
#define PyRun_File(fp, p, s, g, l) \
|
|
||||||
PyRun_FileExFlags(fp, p, s, g, l, 0, NULL)
|
|
||||||
#define PyRun_FileEx(fp, p, s, g, l, c) \
|
|
||||||
PyRun_FileExFlags(fp, p, s, g, l, c, NULL)
|
|
||||||
#define PyRun_FileFlags(fp, p, s, g, l, flags) \
|
|
||||||
PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
|
|
||||||
|
|
||||||
|
|
||||||
/* Stuff with no proper home (yet) */
|
|
||||||
PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *);
|
|
||||||
PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState;
|
|
||||||
PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *);
|
|
|
@ -1,42 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_PYTHREAD_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)
|
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
|
||||||
/* Private function to reinitialize a lock at fork in the child process.
|
|
||||||
Reset the lock to the unlocked state.
|
|
||||||
Return 0 on success, return -1 on error. */
|
|
||||||
PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock);
|
|
||||||
#endif /* HAVE_FORK */
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_H
|
|
||||||
/* Darwin needs pthread.h to know type name the pthread_key_t. */
|
|
||||||
# include <pthread.h>
|
|
||||||
# define NATIVE_TSS_KEY_T pthread_key_t
|
|
||||||
#elif defined(NT_THREADS)
|
|
||||||
/* In Windows, native TSS key type is DWORD,
|
|
||||||
but hardcode the unsigned long to avoid errors for include directive.
|
|
||||||
*/
|
|
||||||
# define NATIVE_TSS_KEY_T unsigned long
|
|
||||||
#elif defined(HAVE_PTHREAD_STUBS)
|
|
||||||
# include "cpython/pthread_stubs.h"
|
|
||||||
# define NATIVE_TSS_KEY_T pthread_key_t
|
|
||||||
#else
|
|
||||||
# error "Require native threads. See https://bugs.python.org/issue31370"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is
|
|
||||||
exposed to allow static allocation in the API clients. Even in this case,
|
|
||||||
you must handle TSS keys through API functions due to compatibility.
|
|
||||||
*/
|
|
||||||
struct _Py_tss_t {
|
|
||||||
int _is_initialized;
|
|
||||||
NATIVE_TSS_KEY_T _key;
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef NATIVE_TSS_KEY_T
|
|
||||||
|
|
||||||
/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */
|
|
||||||
#define Py_tss_NEEDS_INIT {0}
|
|
|
@ -1,323 +0,0 @@
|
||||||
// The _PyTime_t API is written to use timestamp and timeout values stored in
|
|
||||||
// various formats and to read clocks.
|
|
||||||
//
|
|
||||||
// The _PyTime_t type is an integer to support directly common arithmetic
|
|
||||||
// operations like t1 + t2.
|
|
||||||
//
|
|
||||||
// The _PyTime_t API supports a resolution of 1 nanosecond. The _PyTime_t type
|
|
||||||
// is signed to support negative timestamps. The supported range is around
|
|
||||||
// [-292.3 years; +292.3 years]. Using the Unix epoch (January 1st, 1970), the
|
|
||||||
// supported date range is around [1677-09-21; 2262-04-11].
|
|
||||||
//
|
|
||||||
// Formats:
|
|
||||||
//
|
|
||||||
// * seconds
|
|
||||||
// * seconds as a floating pointer number (C double)
|
|
||||||
// * milliseconds (10^-3 seconds)
|
|
||||||
// * microseconds (10^-6 seconds)
|
|
||||||
// * 100 nanoseconds (10^-7 seconds)
|
|
||||||
// * nanoseconds (10^-9 seconds)
|
|
||||||
// * timeval structure, 1 microsecond resolution (10^-6 seconds)
|
|
||||||
// * timespec structure, 1 nanosecond resolution (10^-9 seconds)
|
|
||||||
//
|
|
||||||
// Integer overflows are detected and raise OverflowError. Conversion to a
|
|
||||||
// resolution worse than 1 nanosecond is rounded correctly with the requested
|
|
||||||
// rounding mode. There are 4 rounding modes: floor (towards -inf), ceiling
|
|
||||||
// (towards +inf), half even and up (away from zero).
|
|
||||||
//
|
|
||||||
// Some functions clamp the result in the range [_PyTime_MIN; _PyTime_MAX], so
|
|
||||||
// the caller doesn't have to handle errors and doesn't need to hold the GIL.
|
|
||||||
// For example, _PyTime_Add(t1, t2) computes t1+t2 and clamp the result on
|
|
||||||
// overflow.
|
|
||||||
//
|
|
||||||
// Clocks:
|
|
||||||
//
|
|
||||||
// * System clock
|
|
||||||
// * Monotonic clock
|
|
||||||
// * Performance counter
|
|
||||||
//
|
|
||||||
// Operations like (t * k / q) with integers are implemented in a way to reduce
|
|
||||||
// the risk of integer overflow. Such operation is used to convert a clock
|
|
||||||
// value expressed in ticks with a frequency to _PyTime_t, like
|
|
||||||
// QueryPerformanceCounter() with QueryPerformanceFrequency().
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_PYTIME_H
|
|
||||||
#define Py_PYTIME_H
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
Symbols and macros to supply platform-independent interfaces to time related
|
|
||||||
functions and constants
|
|
||||||
**************************************************************************/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* _PyTime_t: Python timestamp with subsecond precision. It can be used to
|
|
||||||
store a duration, and so indirectly a date (related to another date, like
|
|
||||||
UNIX epoch). */
|
|
||||||
typedef int64_t _PyTime_t;
|
|
||||||
// _PyTime_MIN nanoseconds is around -292.3 years
|
|
||||||
#define _PyTime_MIN INT64_MIN
|
|
||||||
// _PyTime_MAX nanoseconds is around +292.3 years
|
|
||||||
#define _PyTime_MAX INT64_MAX
|
|
||||||
#define _SIZEOF_PYTIME_T 8
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
/* Round towards minus infinity (-inf).
|
|
||||||
For example, used to read a clock. */
|
|
||||||
_PyTime_ROUND_FLOOR=0,
|
|
||||||
/* Round towards infinity (+inf).
|
|
||||||
For example, used for timeout to wait "at least" N seconds. */
|
|
||||||
_PyTime_ROUND_CEILING=1,
|
|
||||||
/* Round to nearest with ties going to nearest even integer.
|
|
||||||
For example, used to round from a Python float. */
|
|
||||||
_PyTime_ROUND_HALF_EVEN=2,
|
|
||||||
/* Round away from zero
|
|
||||||
For example, used for timeout. _PyTime_ROUND_CEILING rounds
|
|
||||||
-1e-9 to 0 milliseconds which causes bpo-31786 issue.
|
|
||||||
_PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
|
|
||||||
the timeout sign as expected. select.poll(timeout) must block
|
|
||||||
for negative values." */
|
|
||||||
_PyTime_ROUND_UP=3,
|
|
||||||
/* _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
|
|
||||||
used for timeouts. */
|
|
||||||
_PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
|
|
||||||
} _PyTime_round_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* Convert a time_t to a PyLong. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
|
|
||||||
time_t sec);
|
|
||||||
|
|
||||||
/* Convert a PyLong to a time_t. */
|
|
||||||
PyAPI_FUNC(time_t) _PyLong_AsTime_t(
|
|
||||||
PyObject *obj);
|
|
||||||
|
|
||||||
/* Convert a number of seconds, int or float, to time_t. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
|
|
||||||
PyObject *obj,
|
|
||||||
time_t *sec,
|
|
||||||
_PyTime_round_t);
|
|
||||||
|
|
||||||
/* Convert a number of seconds, int or float, to a timeval structure.
|
|
||||||
usec is in the range [0; 999999] and rounded towards zero.
|
|
||||||
For example, -1.2 is converted to (-2, 800000). */
|
|
||||||
PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
|
|
||||||
PyObject *obj,
|
|
||||||
time_t *sec,
|
|
||||||
long *usec,
|
|
||||||
_PyTime_round_t);
|
|
||||||
|
|
||||||
/* Convert a number of seconds, int or float, to a timespec structure.
|
|
||||||
nsec is in the range [0; 999999999] and rounded towards zero.
|
|
||||||
For example, -1.2 is converted to (-2, 800000000). */
|
|
||||||
PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
|
|
||||||
PyObject *obj,
|
|
||||||
time_t *sec,
|
|
||||||
long *nsec,
|
|
||||||
_PyTime_round_t);
|
|
||||||
|
|
||||||
|
|
||||||
/* Create a timestamp from a number of seconds. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds);
|
|
||||||
|
|
||||||
/* Macro to create a timestamp from a number of seconds, no integer overflow.
|
|
||||||
Only use the macro for small values, prefer _PyTime_FromSeconds(). */
|
|
||||||
#define _PYTIME_FROMSECONDS(seconds) \
|
|
||||||
((_PyTime_t)(seconds) * (1000 * 1000 * 1000))
|
|
||||||
|
|
||||||
/* Create a timestamp from a number of nanoseconds. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns);
|
|
||||||
|
|
||||||
/* Create a timestamp from nanoseconds (Python int). */
|
|
||||||
PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t,
|
|
||||||
PyObject *obj);
|
|
||||||
|
|
||||||
/* Convert a number of seconds (Python float or int) to a timestamp.
|
|
||||||
Raise an exception and return -1 on error, return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_FromSecondsObject(_PyTime_t *t,
|
|
||||||
PyObject *obj,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
|
|
||||||
Raise an exception and return -1 on error, return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(_PyTime_t *t,
|
|
||||||
PyObject *obj,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Convert a timestamp to a number of seconds as a C double. */
|
|
||||||
PyAPI_FUNC(double) _PyTime_AsSecondsDouble(_PyTime_t t);
|
|
||||||
|
|
||||||
/* Convert timestamp to a number of milliseconds (10^-3 seconds). */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_AsMilliseconds(_PyTime_t t,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Convert timestamp to a number of microseconds (10^-6 seconds). */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_AsMicroseconds(_PyTime_t t,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Convert timestamp to a number of nanoseconds (10^-9 seconds). */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_AsNanoseconds(_PyTime_t t);
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_As100Nanoseconds(_PyTime_t t,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert timestamp to a number of nanoseconds (10^-9 seconds) as a Python int
|
|
||||||
object. */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
|
|
||||||
|
|
||||||
#ifndef MS_WINDOWS
|
|
||||||
/* Create a timestamp from a timeval structure.
|
|
||||||
Raise an exception and return -1 on overflow, return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert a timestamp to a timeval structure (microsecond resolution).
|
|
||||||
tv_usec is always positive.
|
|
||||||
Raise an exception and return -1 if the conversion overflowed,
|
|
||||||
return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
|
|
||||||
struct timeval *tv,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Similar to _PyTime_AsTimeval() but don't raise an exception on overflow.
|
|
||||||
On overflow, clamp tv_sec to _PyTime_t min/max. */
|
|
||||||
PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(_PyTime_t t,
|
|
||||||
struct timeval *tv,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
/* Convert a timestamp to a number of seconds (secs) and microseconds (us).
|
|
||||||
us is always positive. This function is similar to _PyTime_AsTimeval()
|
|
||||||
except that secs is always a time_t type, whereas the timeval structure
|
|
||||||
uses a C long for tv_sec on Windows.
|
|
||||||
Raise an exception and return -1 if the conversion overflowed,
|
|
||||||
return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
|
|
||||||
_PyTime_t t,
|
|
||||||
time_t *secs,
|
|
||||||
int *us,
|
|
||||||
_PyTime_round_t round);
|
|
||||||
|
|
||||||
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
|
|
||||||
/* Create a timestamp from a timespec structure.
|
|
||||||
Raise an exception and return -1 on overflow, return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts);
|
|
||||||
|
|
||||||
/* Convert a timestamp to a timespec structure (nanosecond resolution).
|
|
||||||
tv_nsec is always positive.
|
|
||||||
Raise an exception and return -1 on error, return 0 on success. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
|
|
||||||
|
|
||||||
/* Similar to _PyTime_AsTimespec() but don't raise an exception on overflow.
|
|
||||||
On overflow, clamp tv_sec to _PyTime_t min/max. */
|
|
||||||
PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(_PyTime_t t, struct timespec *ts);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Compute t1 + t2. Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_Add(_PyTime_t t1, _PyTime_t t2);
|
|
||||||
|
|
||||||
/* Compute ticks * mul / div.
|
|
||||||
Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow.
|
|
||||||
The caller must ensure that ((div - 1) * mul) cannot overflow. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_MulDiv(_PyTime_t ticks,
|
|
||||||
_PyTime_t mul,
|
|
||||||
_PyTime_t div);
|
|
||||||
|
|
||||||
/* Structure used by time.get_clock_info() */
|
|
||||||
typedef struct {
|
|
||||||
const char *implementation;
|
|
||||||
int monotonic;
|
|
||||||
int adjustable;
|
|
||||||
double resolution;
|
|
||||||
} _Py_clock_info_t;
|
|
||||||
|
|
||||||
/* Get the current time from the system clock.
|
|
||||||
|
|
||||||
If the internal clock fails, silently ignore the error and return 0.
|
|
||||||
On integer overflow, silently ignore the overflow and clamp the clock to
|
|
||||||
[_PyTime_MIN; _PyTime_MAX].
|
|
||||||
|
|
||||||
Use _PyTime_GetSystemClockWithInfo() to check for failure. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
|
|
||||||
|
|
||||||
/* Get the current time from the system clock.
|
|
||||||
* On success, set *t and *info (if not NULL), and return 0.
|
|
||||||
* On error, raise an exception and return -1.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) _PyTime_GetSystemClockWithInfo(
|
|
||||||
_PyTime_t *t,
|
|
||||||
_Py_clock_info_t *info);
|
|
||||||
|
|
||||||
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
|
|
||||||
The clock is not affected by system clock updates. The reference point of
|
|
||||||
the returned value is undefined, so that only the difference between the
|
|
||||||
results of consecutive calls is valid.
|
|
||||||
|
|
||||||
If the internal clock fails, silently ignore the error and return 0.
|
|
||||||
On integer overflow, silently ignore the overflow and clamp the clock to
|
|
||||||
[_PyTime_MIN; _PyTime_MAX].
|
|
||||||
|
|
||||||
Use _PyTime_GetMonotonicClockWithInfo() to check for failure. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetMonotonicClock(void);
|
|
||||||
|
|
||||||
/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
|
|
||||||
The clock is not affected by system clock updates. The reference point of
|
|
||||||
the returned value is undefined, so that only the difference between the
|
|
||||||
results of consecutive calls is valid.
|
|
||||||
|
|
||||||
Fill info (if set) with information of the function used to get the time.
|
|
||||||
|
|
||||||
Return 0 on success, raise an exception and return -1 on error. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_GetMonotonicClockWithInfo(
|
|
||||||
_PyTime_t *t,
|
|
||||||
_Py_clock_info_t *info);
|
|
||||||
|
|
||||||
|
|
||||||
/* Converts a timestamp to the Gregorian time, using the local time zone.
|
|
||||||
Return 0 on success, raise an exception and return -1 on error. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
|
|
||||||
|
|
||||||
/* Converts a timestamp to the Gregorian time, assuming UTC.
|
|
||||||
Return 0 on success, raise an exception and return -1 on error. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
|
|
||||||
|
|
||||||
/* Get the performance counter: clock with the highest available resolution to
|
|
||||||
measure a short duration.
|
|
||||||
|
|
||||||
If the internal clock fails, silently ignore the error and return 0.
|
|
||||||
On integer overflow, silently ignore the overflow and clamp the clock to
|
|
||||||
[_PyTime_MIN; _PyTime_MAX].
|
|
||||||
|
|
||||||
Use _PyTime_GetPerfCounterWithInfo() to check for failure. */
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyTime_GetPerfCounter(void);
|
|
||||||
|
|
||||||
/* Get the performance counter: clock with the highest available resolution to
|
|
||||||
measure a short duration.
|
|
||||||
|
|
||||||
Fill info (if set) with information of the function used to get the time.
|
|
||||||
|
|
||||||
Return 0 on success, raise an exception and return -1 on error. */
|
|
||||||
PyAPI_FUNC(int) _PyTime_GetPerfCounterWithInfo(
|
|
||||||
_PyTime_t *t,
|
|
||||||
_Py_clock_info_t *info);
|
|
||||||
|
|
||||||
|
|
||||||
// Create a deadline.
|
|
||||||
// Pseudo code: _PyTime_GetMonotonicClock() + timeout.
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyDeadline_Init(_PyTime_t timeout);
|
|
||||||
|
|
||||||
// Get remaining time from a deadline.
|
|
||||||
// Pseudo code: deadline - _PyTime_GetMonotonicClock().
|
|
||||||
PyAPI_FUNC(_PyTime_t) _PyDeadline_Get(_PyTime_t deadline);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* Py_PYTIME_H */
|
|
||||||
#endif /* Py_LIMITED_API */
|
|
|
@ -1,67 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_SETOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* There are three kinds of entries in the table:
|
|
||||||
|
|
||||||
1. Unused: key == NULL and hash == 0
|
|
||||||
2. Dummy: key == dummy and hash == -1
|
|
||||||
3. Active: key != NULL and key != dummy and hash != -1
|
|
||||||
|
|
||||||
The hash field of Unused slots is always zero.
|
|
||||||
|
|
||||||
The hash field of Dummy slots are set to -1
|
|
||||||
meaning that dummy entries can be detected by
|
|
||||||
either entry->key==dummy or by entry->hash==-1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PySet_MINSIZE 8
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject *key;
|
|
||||||
Py_hash_t hash; /* Cached hash code of the key */
|
|
||||||
} setentry;
|
|
||||||
|
|
||||||
/* The SetObject data structure is shared by set and frozenset objects.
|
|
||||||
|
|
||||||
Invariant for sets:
|
|
||||||
- hash is -1
|
|
||||||
|
|
||||||
Invariants for frozensets:
|
|
||||||
- data is immutable.
|
|
||||||
- hash is the hash of the frozenset or -1 if not computed yet.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
Py_ssize_t fill; /* Number active and dummy entries*/
|
|
||||||
Py_ssize_t used; /* Number active entries */
|
|
||||||
|
|
||||||
/* The table contains mask + 1 slots, and that's a power of 2.
|
|
||||||
* We store the mask instead of the size because the mask is more
|
|
||||||
* frequently needed.
|
|
||||||
*/
|
|
||||||
Py_ssize_t mask;
|
|
||||||
|
|
||||||
/* The table points to a fixed-size smalltable for small tables
|
|
||||||
* or to additional malloc'ed memory for bigger tables.
|
|
||||||
* The table pointer is never NULL which saves us from repeated
|
|
||||||
* runtime null-tests.
|
|
||||||
*/
|
|
||||||
setentry *table;
|
|
||||||
Py_hash_t hash; /* Only used by frozenset objects */
|
|
||||||
Py_ssize_t finger; /* Search finger for pop() */
|
|
||||||
|
|
||||||
setentry smalltable[PySet_MINSIZE];
|
|
||||||
PyObject *weakreflist; /* List of weak references */
|
|
||||||
} PySetObject;
|
|
||||||
|
|
||||||
#define PySet_GET_SIZE(so) \
|
|
||||||
(assert(PyAnySet_Check(so)), (((PySetObject *)(so))->used))
|
|
||||||
|
|
||||||
PyAPI_DATA(PyObject *) _PySet_Dummy;
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash);
|
|
||||||
PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
|
|
|
@ -1,16 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_SYSMODULE_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate,
|
|
||||||
PyObject *name);
|
|
||||||
|
|
||||||
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
|
|
||||||
|
|
||||||
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PySys_Audit(
|
|
||||||
const char *event,
|
|
||||||
const char *argFormat,
|
|
||||||
...);
|
|
||||||
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);
|
|
|
@ -1,16 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_TRACEBACK_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _traceback PyTracebackObject;
|
|
||||||
|
|
||||||
struct _traceback {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyTracebackObject *tb_next;
|
|
||||||
PyFrameObject *tb_frame;
|
|
||||||
int tb_lasti;
|
|
||||||
int tb_lineno;
|
|
||||||
};
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **);
|
|
||||||
PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_TUPLEOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_VAR_HEAD
|
|
||||||
/* ob_item contains space for 'ob_size' elements.
|
|
||||||
Items must normally not be NULL, except during construction when
|
|
||||||
the tuple is not yet visible outside the function that builds it. */
|
|
||||||
PyObject *ob_item[1];
|
|
||||||
} PyTupleObject;
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t);
|
|
||||||
PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
|
|
||||||
|
|
||||||
/* Cast argument to PyTupleObject* type. */
|
|
||||||
#define _PyTuple_CAST(op) \
|
|
||||||
(assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op)))
|
|
||||||
|
|
||||||
// Macros and static inline functions, trading safety for speed
|
|
||||||
|
|
||||||
static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) {
|
|
||||||
PyTupleObject *tuple = _PyTuple_CAST(op);
|
|
||||||
return Py_SIZE(tuple);
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[index])
|
|
||||||
|
|
||||||
/* Function *only* to be used to fill in brand new tuples */
|
|
||||||
static inline void
|
|
||||||
PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
|
|
||||||
PyTupleObject *tuple = _PyTuple_CAST(op);
|
|
||||||
tuple->ob_item[index] = value;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
#define PyTuple_SET_ITEM(op, index, value) \
|
|
||||||
PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,20 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_WARNINGS_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyErr_WarnExplicitObject(
|
|
||||||
PyObject *category,
|
|
||||||
PyObject *message,
|
|
||||||
PyObject *filename,
|
|
||||||
int lineno,
|
|
||||||
PyObject *module,
|
|
||||||
PyObject *registry);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyErr_WarnExplicitFormat(
|
|
||||||
PyObject *category,
|
|
||||||
const char *filename, int lineno,
|
|
||||||
const char *module, PyObject *registry,
|
|
||||||
const char *format, ...);
|
|
||||||
|
|
||||||
// DEPRECATED: Use PyErr_WarnEx() instead.
|
|
||||||
#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1)
|
|
|
@ -1,58 +0,0 @@
|
||||||
#ifndef Py_CPYTHON_WEAKREFOBJECT_H
|
|
||||||
# error "this header file must not be included directly"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType,
|
|
||||||
* and CallableProxyType.
|
|
||||||
*/
|
|
||||||
struct _PyWeakReference {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
/* The object to which this is a weak reference, or Py_None if none.
|
|
||||||
* Note that this is a stealth reference: wr_object's refcount is
|
|
||||||
* not incremented to reflect this pointer.
|
|
||||||
*/
|
|
||||||
PyObject *wr_object;
|
|
||||||
|
|
||||||
/* A callable to invoke when wr_object dies, or NULL if none. */
|
|
||||||
PyObject *wr_callback;
|
|
||||||
|
|
||||||
/* A cache for wr_object's hash code. As usual for hashes, this is -1
|
|
||||||
* if the hash code isn't known yet.
|
|
||||||
*/
|
|
||||||
Py_hash_t hash;
|
|
||||||
|
|
||||||
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
|
|
||||||
* terminated list of weak references to it. These are the list pointers.
|
|
||||||
* If wr_object goes away, wr_object is set to Py_None, and these pointers
|
|
||||||
* have no meaning then.
|
|
||||||
*/
|
|
||||||
PyWeakReference *wr_prev;
|
|
||||||
PyWeakReference *wr_next;
|
|
||||||
vectorcallfunc vectorcall;
|
|
||||||
};
|
|
||||||
|
|
||||||
PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head);
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
|
|
||||||
|
|
||||||
static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
|
|
||||||
PyWeakReference *ref;
|
|
||||||
PyObject *obj;
|
|
||||||
assert(PyWeakref_Check(ref_obj));
|
|
||||||
ref = _Py_CAST(PyWeakReference*, ref_obj);
|
|
||||||
obj = ref->wr_object;
|
|
||||||
// Explanation for the Py_REFCNT() check: when a weakref's target is part
|
|
||||||
// of a long chain of deallocations which triggers the trashcan mechanism,
|
|
||||||
// clearing the weakrefs can be delayed long after the target's refcount
|
|
||||||
// has dropped to zero. In the meantime, code accessing the weakref will
|
|
||||||
// be able to "see" the target object even though it is supposed to be
|
|
||||||
// unreachable. See issue gh-60806.
|
|
||||||
if (Py_REFCNT(obj) > 0) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
return Py_None;
|
|
||||||
}
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
|
|
||||||
# define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))
|
|
||||||
#endif
|
|
|
@ -1,267 +0,0 @@
|
||||||
/* datetime.h
|
|
||||||
*/
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef DATETIME_H
|
|
||||||
#define DATETIME_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Fields are packed into successive bytes, each viewed as unsigned and
|
|
||||||
* big-endian, unless otherwise noted:
|
|
||||||
*
|
|
||||||
* byte offset
|
|
||||||
* 0 year 2 bytes, 1-9999
|
|
||||||
* 2 month 1 byte, 1-12
|
|
||||||
* 3 day 1 byte, 1-31
|
|
||||||
* 4 hour 1 byte, 0-23
|
|
||||||
* 5 minute 1 byte, 0-59
|
|
||||||
* 6 second 1 byte, 0-59
|
|
||||||
* 7 usecond 3 bytes, 0-999999
|
|
||||||
* 10
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* # of bytes for year, month, and day. */
|
|
||||||
#define _PyDateTime_DATE_DATASIZE 4
|
|
||||||
|
|
||||||
/* # of bytes for hour, minute, second, and usecond. */
|
|
||||||
#define _PyDateTime_TIME_DATASIZE 6
|
|
||||||
|
|
||||||
/* # of bytes for year, month, day, hour, minute, second, and usecond. */
|
|
||||||
#define _PyDateTime_DATETIME_DATASIZE 10
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD
|
|
||||||
Py_hash_t hashcode; /* -1 when unknown */
|
|
||||||
int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
|
|
||||||
int seconds; /* 0 <= seconds < 24*3600 is invariant */
|
|
||||||
int microseconds; /* 0 <= microseconds < 1000000 is invariant */
|
|
||||||
} PyDateTime_Delta;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject_HEAD /* a pure abstract base class */
|
|
||||||
} PyDateTime_TZInfo;
|
|
||||||
|
|
||||||
|
|
||||||
/* The datetime and time types have hashcodes, and an optional tzinfo member,
|
|
||||||
* present if and only if hastzinfo is true.
|
|
||||||
*/
|
|
||||||
#define _PyTZINFO_HEAD \
|
|
||||||
PyObject_HEAD \
|
|
||||||
Py_hash_t hashcode; \
|
|
||||||
char hastzinfo; /* boolean flag */
|
|
||||||
|
|
||||||
/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
|
|
||||||
* convenient to cast to, when getting at the hastzinfo member of objects
|
|
||||||
* starting with _PyTZINFO_HEAD.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyTZINFO_HEAD
|
|
||||||
} _PyDateTime_BaseTZInfo;
|
|
||||||
|
|
||||||
/* All time objects are of PyDateTime_TimeType, but that can be allocated
|
|
||||||
* in two ways, with or without a tzinfo member. Without is the same as
|
|
||||||
* tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an
|
|
||||||
* internal struct used to allocate the right amount of space for the
|
|
||||||
* "without" case.
|
|
||||||
*/
|
|
||||||
#define _PyDateTime_TIMEHEAD \
|
|
||||||
_PyTZINFO_HEAD \
|
|
||||||
unsigned char data[_PyDateTime_TIME_DATASIZE];
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyDateTime_TIMEHEAD
|
|
||||||
} _PyDateTime_BaseTime; /* hastzinfo false */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyDateTime_TIMEHEAD
|
|
||||||
unsigned char fold;
|
|
||||||
PyObject *tzinfo;
|
|
||||||
} PyDateTime_Time; /* hastzinfo true */
|
|
||||||
|
|
||||||
|
|
||||||
/* All datetime objects are of PyDateTime_DateTimeType, but that can be
|
|
||||||
* allocated in two ways too, just like for time objects above. In addition,
|
|
||||||
* the plain date type is a base class for datetime, so it must also have
|
|
||||||
* a hastzinfo member (although it's unused there).
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyTZINFO_HEAD
|
|
||||||
unsigned char data[_PyDateTime_DATE_DATASIZE];
|
|
||||||
} PyDateTime_Date;
|
|
||||||
|
|
||||||
#define _PyDateTime_DATETIMEHEAD \
|
|
||||||
_PyTZINFO_HEAD \
|
|
||||||
unsigned char data[_PyDateTime_DATETIME_DATASIZE];
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyDateTime_DATETIMEHEAD
|
|
||||||
} _PyDateTime_BaseDateTime; /* hastzinfo false */
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
_PyDateTime_DATETIMEHEAD
|
|
||||||
unsigned char fold;
|
|
||||||
PyObject *tzinfo;
|
|
||||||
} PyDateTime_DateTime; /* hastzinfo true */
|
|
||||||
|
|
||||||
|
|
||||||
/* Apply for date and datetime instances. */
|
|
||||||
|
|
||||||
// o is a pointer to a time or a datetime object.
|
|
||||||
#define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo)
|
|
||||||
|
|
||||||
#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
|
|
||||||
((PyDateTime_Date*)o)->data[1])
|
|
||||||
#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
|
|
||||||
#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3])
|
|
||||||
|
|
||||||
#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4])
|
|
||||||
#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5])
|
|
||||||
#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6])
|
|
||||||
#define PyDateTime_DATE_GET_MICROSECOND(o) \
|
|
||||||
((((PyDateTime_DateTime*)o)->data[7] << 16) | \
|
|
||||||
(((PyDateTime_DateTime*)o)->data[8] << 8) | \
|
|
||||||
((PyDateTime_DateTime*)o)->data[9])
|
|
||||||
#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold)
|
|
||||||
#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
|
||||||
((PyDateTime_DateTime *)(o))->tzinfo : Py_None)
|
|
||||||
|
|
||||||
/* Apply for time instances. */
|
|
||||||
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
|
|
||||||
#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])
|
|
||||||
#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2])
|
|
||||||
#define PyDateTime_TIME_GET_MICROSECOND(o) \
|
|
||||||
((((PyDateTime_Time*)o)->data[3] << 16) | \
|
|
||||||
(((PyDateTime_Time*)o)->data[4] << 8) | \
|
|
||||||
((PyDateTime_Time*)o)->data[5])
|
|
||||||
#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold)
|
|
||||||
#define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \
|
|
||||||
((PyDateTime_Time *)(o))->tzinfo : Py_None)
|
|
||||||
|
|
||||||
/* Apply for time delta instances */
|
|
||||||
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
|
||||||
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
|
|
||||||
#define PyDateTime_DELTA_GET_MICROSECONDS(o) \
|
|
||||||
(((PyDateTime_Delta*)o)->microseconds)
|
|
||||||
|
|
||||||
|
|
||||||
/* Define structure for C API. */
|
|
||||||
typedef struct {
|
|
||||||
/* type objects */
|
|
||||||
PyTypeObject *DateType;
|
|
||||||
PyTypeObject *DateTimeType;
|
|
||||||
PyTypeObject *TimeType;
|
|
||||||
PyTypeObject *DeltaType;
|
|
||||||
PyTypeObject *TZInfoType;
|
|
||||||
|
|
||||||
/* singletons */
|
|
||||||
PyObject *TimeZone_UTC;
|
|
||||||
|
|
||||||
/* constructors */
|
|
||||||
PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
|
|
||||||
PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
|
|
||||||
PyObject*, PyTypeObject*);
|
|
||||||
PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
|
|
||||||
PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
|
|
||||||
PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name);
|
|
||||||
|
|
||||||
/* constructors for the DB API */
|
|
||||||
PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
|
|
||||||
PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
|
|
||||||
|
|
||||||
/* PEP 495 constructors */
|
|
||||||
PyObject *(*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int,
|
|
||||||
PyObject*, int, PyTypeObject*);
|
|
||||||
PyObject *(*Time_FromTimeAndFold)(int, int, int, int, PyObject*, int, PyTypeObject*);
|
|
||||||
|
|
||||||
} PyDateTime_CAPI;
|
|
||||||
|
|
||||||
#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
|
|
||||||
|
|
||||||
|
|
||||||
/* This block is only used as part of the public API and should not be
|
|
||||||
* included in _datetimemodule.c, which does not use the C API capsule.
|
|
||||||
* See bpo-35081 for more details.
|
|
||||||
* */
|
|
||||||
#ifndef _PY_DATETIME_IMPL
|
|
||||||
/* Define global variable for the C API and a macro for setting it. */
|
|
||||||
static PyDateTime_CAPI *PyDateTimeAPI = NULL;
|
|
||||||
|
|
||||||
#define PyDateTime_IMPORT \
|
|
||||||
PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
|
|
||||||
|
|
||||||
/* Macro for access to the UTC singleton */
|
|
||||||
#define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC
|
|
||||||
|
|
||||||
/* Macros for type checking when not building the Python core. */
|
|
||||||
#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
|
|
||||||
#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType)
|
|
||||||
|
|
||||||
#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
|
|
||||||
#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType)
|
|
||||||
|
|
||||||
#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
|
|
||||||
#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType)
|
|
||||||
|
|
||||||
#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
|
|
||||||
#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType)
|
|
||||||
|
|
||||||
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
|
|
||||||
#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType)
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros for accessing constructors in a simplified fashion. */
|
|
||||||
#define PyDate_FromDate(year, month, day) \
|
|
||||||
PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
|
|
||||||
|
|
||||||
#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
|
|
||||||
PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
|
|
||||||
min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
|
|
||||||
|
|
||||||
#define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \
|
|
||||||
PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \
|
|
||||||
min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType)
|
|
||||||
|
|
||||||
#define PyTime_FromTime(hour, minute, second, usecond) \
|
|
||||||
PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
|
|
||||||
Py_None, PyDateTimeAPI->TimeType)
|
|
||||||
|
|
||||||
#define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \
|
|
||||||
PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \
|
|
||||||
Py_None, fold, PyDateTimeAPI->TimeType)
|
|
||||||
|
|
||||||
#define PyDelta_FromDSU(days, seconds, useconds) \
|
|
||||||
PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
|
|
||||||
PyDateTimeAPI->DeltaType)
|
|
||||||
|
|
||||||
#define PyTimeZone_FromOffset(offset) \
|
|
||||||
PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL)
|
|
||||||
|
|
||||||
#define PyTimeZone_FromOffsetAndName(offset, name) \
|
|
||||||
PyDateTimeAPI->TimeZone_FromTimeZone(offset, name)
|
|
||||||
|
|
||||||
/* Macros supporting the DB API. */
|
|
||||||
#define PyDateTime_FromTimestamp(args) \
|
|
||||||
PyDateTimeAPI->DateTime_FromTimestamp( \
|
|
||||||
(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
|
|
||||||
|
|
||||||
#define PyDate_FromTimestamp(args) \
|
|
||||||
PyDateTimeAPI->Date_FromTimestamp( \
|
|
||||||
(PyObject*) (PyDateTimeAPI->DateType), args)
|
|
||||||
|
|
||||||
#endif /* !defined(_PY_DATETIME_IMPL) */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* Descriptors */
|
|
||||||
#ifndef Py_DESCROBJECT_H
|
|
||||||
#define Py_DESCROBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef PyObject *(*getter)(PyObject *, void *);
|
|
||||||
typedef int (*setter)(PyObject *, PyObject *, void *);
|
|
||||||
|
|
||||||
struct PyGetSetDef {
|
|
||||||
const char *name;
|
|
||||||
getter get;
|
|
||||||
setter set;
|
|
||||||
const char *doc;
|
|
||||||
void *closure;
|
|
||||||
};
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyMemberDescr_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyMethodDescr_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyProperty_Type;
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, PyMemberDef *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, PyGetSetDef *);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
|
|
||||||
PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_DESCROBJECT_H
|
|
||||||
# include "cpython/descrobject.h"
|
|
||||||
# undef Py_CPYTHON_DESCROBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_DESCROBJECT_H */
|
|
|
@ -1,97 +0,0 @@
|
||||||
#ifndef Py_DICTOBJECT_H
|
|
||||||
#define Py_DICTOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Dictionary object type -- mapping from hashable object to object */
|
|
||||||
|
|
||||||
/* The distribution includes a separate file, Objects/dictnotes.txt,
|
|
||||||
describing explorations into dictionary design and optimization.
|
|
||||||
It covers typical dictionary use patterns, the parameters for
|
|
||||||
tuning dictionaries, and several ideas for possible optimizations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDict_Type;
|
|
||||||
|
|
||||||
#define PyDict_Check(op) \
|
|
||||||
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
|
|
||||||
#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_New(void);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
|
|
||||||
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
|
|
||||||
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
|
|
||||||
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
|
|
||||||
PyAPI_FUNC(int) PyDict_Next(
|
|
||||||
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
|
|
||||||
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
|
|
||||||
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
|
|
||||||
|
|
||||||
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
|
|
||||||
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
|
|
||||||
|
|
||||||
/* PyDict_Merge updates/merges from a mapping object (an object that
|
|
||||||
supports PyMapping_Keys() and PyObject_GetItem()). If override is true,
|
|
||||||
the last occurrence of a key wins, else the first. The Python
|
|
||||||
dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
|
|
||||||
PyObject *other,
|
|
||||||
int override);
|
|
||||||
|
|
||||||
/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
|
|
||||||
iterable objects of length 2. If override is true, the last occurrence
|
|
||||||
of a key wins, else the first. The Python dict constructor dict(seq2)
|
|
||||||
is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
|
|
||||||
PyObject *seq2,
|
|
||||||
int override);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
|
|
||||||
PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
|
|
||||||
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Dictionary (keys, values, items) views */
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictValues_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictItems_Type;
|
|
||||||
|
|
||||||
#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
|
|
||||||
#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
|
|
||||||
#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
|
|
||||||
/* This excludes Values, since they are not sets. */
|
|
||||||
# define PyDictViewSet_Check(op) \
|
|
||||||
(PyDictKeys_Check(op) || PyDictItems_Check(op))
|
|
||||||
|
|
||||||
/* Dictionary (key, value, items) iterators */
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_DICTOBJECT_H
|
|
||||||
# include "cpython/dictobject.h"
|
|
||||||
# undef Py_CPYTHON_DICTOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_DICTOBJECT_H */
|
|
|
@ -1,499 +0,0 @@
|
||||||
/* Copyright (c) 2008-2009, Google Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Neither the name of Google Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* ---
|
|
||||||
* Author: Kostya Serebryany
|
|
||||||
* Copied to CPython by Jeffrey Yasskin, with all macros renamed to
|
|
||||||
* start with _Py_ to avoid colliding with users embedding Python, and
|
|
||||||
* with deprecated macros removed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This file defines dynamic annotations for use with dynamic analysis
|
|
||||||
tool such as valgrind, PIN, etc.
|
|
||||||
|
|
||||||
Dynamic annotation is a source code annotation that affects
|
|
||||||
the generated code (that is, the annotation is not a comment).
|
|
||||||
Each such annotation is attached to a particular
|
|
||||||
instruction and/or to a particular object (address) in the program.
|
|
||||||
|
|
||||||
The annotations that should be used by users are macros in all upper-case
|
|
||||||
(e.g., _Py_ANNOTATE_NEW_MEMORY).
|
|
||||||
|
|
||||||
Actual implementation of these macros may differ depending on the
|
|
||||||
dynamic analysis tool being used.
|
|
||||||
|
|
||||||
See https://code.google.com/p/data-race-test/ for more information.
|
|
||||||
|
|
||||||
This file supports the following dynamic analysis tools:
|
|
||||||
- None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).
|
|
||||||
Macros are defined empty.
|
|
||||||
- ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).
|
|
||||||
Macros are defined as calls to non-inlinable empty functions
|
|
||||||
that are intercepted by Valgrind. */
|
|
||||||
|
|
||||||
#ifndef __DYNAMIC_ANNOTATIONS_H__
|
|
||||||
#define __DYNAMIC_ANNOTATIONS_H__
|
|
||||||
|
|
||||||
#ifndef DYNAMIC_ANNOTATIONS_ENABLED
|
|
||||||
# define DYNAMIC_ANNOTATIONS_ENABLED 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DYNAMIC_ANNOTATIONS_ENABLED != 0
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful when implementing condition variables such as CondVar,
|
|
||||||
using conditional critical sections (Await/LockWhen) and when constructing
|
|
||||||
user-defined synchronization mechanisms.
|
|
||||||
|
|
||||||
The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and
|
|
||||||
_Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in
|
|
||||||
user-defined synchronization mechanisms: the race detector will infer an
|
|
||||||
arc from the former to the latter when they share the same argument
|
|
||||||
pointer.
|
|
||||||
|
|
||||||
Example 1 (reference counting):
|
|
||||||
|
|
||||||
void Unref() {
|
|
||||||
_Py_ANNOTATE_HAPPENS_BEFORE(&refcount_);
|
|
||||||
if (AtomicDecrementByOne(&refcount_) == 0) {
|
|
||||||
_Py_ANNOTATE_HAPPENS_AFTER(&refcount_);
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Example 2 (message queue):
|
|
||||||
|
|
||||||
void MyQueue::Put(Type *e) {
|
|
||||||
MutexLock lock(&mu_);
|
|
||||||
_Py_ANNOTATE_HAPPENS_BEFORE(e);
|
|
||||||
PutElementIntoMyQueue(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *MyQueue::Get() {
|
|
||||||
MutexLock lock(&mu_);
|
|
||||||
Type *e = GetElementFromMyQueue();
|
|
||||||
_Py_ANNOTATE_HAPPENS_AFTER(e);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
Note: when possible, please use the existing reference counting and message
|
|
||||||
queue implementations instead of inventing new ones. */
|
|
||||||
|
|
||||||
/* Report that wait on the condition variable at address "cv" has succeeded
|
|
||||||
and the lock at address "lock" is held. */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
|
|
||||||
AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)
|
|
||||||
|
|
||||||
/* Report that wait on the condition variable at "cv" has succeeded. Variant
|
|
||||||
w/o lock. */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \
|
|
||||||
AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)
|
|
||||||
|
|
||||||
/* Report that we are about to signal on the condition variable at address
|
|
||||||
"cv". */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \
|
|
||||||
AnnotateCondVarSignal(__FILE__, __LINE__, cv)
|
|
||||||
|
|
||||||
/* Report that we are about to signal_all on the condition variable at "cv". */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
|
|
||||||
AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)
|
|
||||||
|
|
||||||
/* Annotations for user-defined synchronization mechanisms. */
|
|
||||||
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj)
|
|
||||||
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj)
|
|
||||||
|
|
||||||
/* Report that the bytes in the range [pointer, pointer+size) are about
|
|
||||||
to be published safely. The race checker will create a happens-before
|
|
||||||
arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
|
|
||||||
subsequent accesses to this memory.
|
|
||||||
Note: this annotation may not work properly if the race detector uses
|
|
||||||
sampling, i.e. does not observe all memory accesses.
|
|
||||||
*/
|
|
||||||
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
|
|
||||||
AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)
|
|
||||||
|
|
||||||
/* Instruct the tool to create a happens-before arc between mu->Unlock() and
|
|
||||||
mu->Lock(). This annotation may slow down the race detector and hide real
|
|
||||||
races. Normally it is used only when it would be difficult to annotate each
|
|
||||||
of the mutex's critical sections individually using the annotations above.
|
|
||||||
This annotation makes sense only for hybrid race detectors. For pure
|
|
||||||
happens-before detectors this is a no-op. For more details see
|
|
||||||
https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */
|
|
||||||
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
|
|
||||||
AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful when defining memory allocators, or when memory that
|
|
||||||
was protected in one way starts to be protected in another. */
|
|
||||||
|
|
||||||
/* Report that a new memory at "address" of size "size" has been allocated.
|
|
||||||
This might be used when the memory has been retrieved from a free list and
|
|
||||||
is about to be reused, or when the locking discipline for a variable
|
|
||||||
changes. */
|
|
||||||
#define _Py_ANNOTATE_NEW_MEMORY(address, size) \
|
|
||||||
AnnotateNewMemory(__FILE__, __LINE__, address, size)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful when defining FIFO queues that transfer data between
|
|
||||||
threads. */
|
|
||||||
|
|
||||||
/* Report that the producer-consumer queue (such as ProducerConsumerQueue) at
|
|
||||||
address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should
|
|
||||||
be used only for FIFO queues. For non-FIFO queues use
|
|
||||||
_Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for
|
|
||||||
get). */
|
|
||||||
#define _Py_ANNOTATE_PCQ_CREATE(pcq) \
|
|
||||||
AnnotatePCQCreate(__FILE__, __LINE__, pcq)
|
|
||||||
|
|
||||||
/* Report that the queue at address "pcq" is about to be destroyed. */
|
|
||||||
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \
|
|
||||||
AnnotatePCQDestroy(__FILE__, __LINE__, pcq)
|
|
||||||
|
|
||||||
/* Report that we are about to put an element into a FIFO queue at address
|
|
||||||
"pcq". */
|
|
||||||
#define _Py_ANNOTATE_PCQ_PUT(pcq) \
|
|
||||||
AnnotatePCQPut(__FILE__, __LINE__, pcq)
|
|
||||||
|
|
||||||
/* Report that we've just got an element from a FIFO queue at address "pcq". */
|
|
||||||
#define _Py_ANNOTATE_PCQ_GET(pcq) \
|
|
||||||
AnnotatePCQGet(__FILE__, __LINE__, pcq)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations that suppress errors. It is usually better to express the
|
|
||||||
program's synchronization using the other annotations, but these can
|
|
||||||
be used when all else fails. */
|
|
||||||
|
|
||||||
/* Report that we may have a benign race at "pointer", with size
|
|
||||||
"sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the
|
|
||||||
point where "pointer" has been allocated, preferably close to the point
|
|
||||||
where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \
|
|
||||||
AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
|
|
||||||
sizeof(*(pointer)), description)
|
|
||||||
|
|
||||||
/* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to
|
|
||||||
the memory range [address, address+size). */
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
|
|
||||||
AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
|
|
||||||
|
|
||||||
/* Request the analysis tool to ignore all reads in the current thread
|
|
||||||
until _Py_ANNOTATE_IGNORE_READS_END is called.
|
|
||||||
Useful to ignore intentional racey reads, while still checking
|
|
||||||
other reads and all writes.
|
|
||||||
See also _Py_ANNOTATE_UNPROTECTED_READ. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \
|
|
||||||
AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
/* Stop ignoring reads. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_END() \
|
|
||||||
AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \
|
|
||||||
AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
/* Stop ignoring writes. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_WRITES_END() \
|
|
||||||
AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
/* Start ignoring all memory accesses (reads and writes). */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
|
|
||||||
do {\
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();\
|
|
||||||
_Py_ANNOTATE_IGNORE_WRITES_BEGIN();\
|
|
||||||
}while(0)\
|
|
||||||
|
|
||||||
/* Stop ignoring all memory accesses. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \
|
|
||||||
do {\
|
|
||||||
_Py_ANNOTATE_IGNORE_WRITES_END();\
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_END();\
|
|
||||||
}while(0)\
|
|
||||||
|
|
||||||
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events:
|
|
||||||
RWLOCK* and CONDVAR*. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \
|
|
||||||
AnnotateIgnoreSyncBegin(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
/* Stop ignoring sync events. */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_SYNC_END() \
|
|
||||||
AnnotateIgnoreSyncEnd(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
|
|
||||||
/* Enable (enable!=0) or disable (enable==0) race detection for all threads.
|
|
||||||
This annotation could be useful if you want to skip expensive race analysis
|
|
||||||
during some period of program execution, e.g. during initialization. */
|
|
||||||
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \
|
|
||||||
AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful for debugging. */
|
|
||||||
|
|
||||||
/* Request to trace every access to "address". */
|
|
||||||
#define _Py_ANNOTATE_TRACE_MEMORY(address) \
|
|
||||||
AnnotateTraceMemory(__FILE__, __LINE__, address)
|
|
||||||
|
|
||||||
/* Report the current thread name to a race detector. */
|
|
||||||
#define _Py_ANNOTATE_THREAD_NAME(name) \
|
|
||||||
AnnotateThreadName(__FILE__, __LINE__, name)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful when implementing locks. They are not
|
|
||||||
normally needed by modules that merely use locks.
|
|
||||||
The "lock" argument is a pointer to the lock object. */
|
|
||||||
|
|
||||||
/* Report that a lock has been created at address "lock". */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \
|
|
||||||
AnnotateRWLockCreate(__FILE__, __LINE__, lock)
|
|
||||||
|
|
||||||
/* Report that the lock at address "lock" is about to be destroyed. */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \
|
|
||||||
AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
|
|
||||||
|
|
||||||
/* Report that the lock at address "lock" has been acquired.
|
|
||||||
is_w=1 for writer lock, is_w=0 for reader lock. */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
|
|
||||||
AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
|
|
||||||
|
|
||||||
/* Report that the lock at address "lock" is about to be released. */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
|
|
||||||
AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful when implementing barriers. They are not
|
|
||||||
normally needed by modules that merely use barriers.
|
|
||||||
The "barrier" argument is a pointer to the barrier object. */
|
|
||||||
|
|
||||||
/* Report that the "barrier" has been initialized with initial "count".
|
|
||||||
If 'reinitialization_allowed' is true, initialization is allowed to happen
|
|
||||||
multiple times w/o calling barrier_destroy() */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
|
|
||||||
AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \
|
|
||||||
reinitialization_allowed)
|
|
||||||
|
|
||||||
/* Report that we are about to enter barrier_wait("barrier"). */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
|
|
||||||
AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)
|
|
||||||
|
|
||||||
/* Report that we just exited barrier_wait("barrier"). */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
|
|
||||||
AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)
|
|
||||||
|
|
||||||
/* Report that the "barrier" has been destroyed. */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \
|
|
||||||
AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------
|
|
||||||
Annotations useful for testing race detectors. */
|
|
||||||
|
|
||||||
/* Report that we expect a race on the variable at "address".
|
|
||||||
Use only in unit tests for a race detector. */
|
|
||||||
#define _Py_ANNOTATE_EXPECT_RACE(address, description) \
|
|
||||||
AnnotateExpectRace(__FILE__, __LINE__, address, description)
|
|
||||||
|
|
||||||
/* A no-op. Insert where you like to test the interceptors. */
|
|
||||||
#define _Py_ANNOTATE_NO_OP(arg) \
|
|
||||||
AnnotateNoOp(__FILE__, __LINE__, arg)
|
|
||||||
|
|
||||||
/* Force the race detector to flush its state. The actual effect depends on
|
|
||||||
* the implementation of the detector. */
|
|
||||||
#define _Py_ANNOTATE_FLUSH_STATE() \
|
|
||||||
AnnotateFlushState(__FILE__, __LINE__)
|
|
||||||
|
|
||||||
|
|
||||||
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
|
|
||||||
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
|
|
||||||
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */
|
|
||||||
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */
|
|
||||||
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */
|
|
||||||
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */
|
|
||||||
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */
|
|
||||||
#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */
|
|
||||||
#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */
|
|
||||||
#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */
|
|
||||||
#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
|
|
||||||
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */
|
|
||||||
#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */
|
|
||||||
#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */
|
|
||||||
#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */
|
|
||||||
#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */
|
|
||||||
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
|
|
||||||
#define _Py_ANNOTATE_NO_OP(arg) /* empty */
|
|
||||||
#define _Py_ANNOTATE_FLUSH_STATE() /* empty */
|
|
||||||
|
|
||||||
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
|
|
||||||
|
|
||||||
/* Use the macros above rather than using these functions directly. */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
void AnnotateRWLockCreate(const char *file, int line,
|
|
||||||
const volatile void *lock);
|
|
||||||
void AnnotateRWLockDestroy(const char *file, int line,
|
|
||||||
const volatile void *lock);
|
|
||||||
void AnnotateRWLockAcquired(const char *file, int line,
|
|
||||||
const volatile void *lock, long is_w);
|
|
||||||
void AnnotateRWLockReleased(const char *file, int line,
|
|
||||||
const volatile void *lock, long is_w);
|
|
||||||
void AnnotateBarrierInit(const char *file, int line,
|
|
||||||
const volatile void *barrier, long count,
|
|
||||||
long reinitialization_allowed);
|
|
||||||
void AnnotateBarrierWaitBefore(const char *file, int line,
|
|
||||||
const volatile void *barrier);
|
|
||||||
void AnnotateBarrierWaitAfter(const char *file, int line,
|
|
||||||
const volatile void *barrier);
|
|
||||||
void AnnotateBarrierDestroy(const char *file, int line,
|
|
||||||
const volatile void *barrier);
|
|
||||||
void AnnotateCondVarWait(const char *file, int line,
|
|
||||||
const volatile void *cv,
|
|
||||||
const volatile void *lock);
|
|
||||||
void AnnotateCondVarSignal(const char *file, int line,
|
|
||||||
const volatile void *cv);
|
|
||||||
void AnnotateCondVarSignalAll(const char *file, int line,
|
|
||||||
const volatile void *cv);
|
|
||||||
void AnnotatePublishMemoryRange(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
long size);
|
|
||||||
void AnnotateUnpublishMemoryRange(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
long size);
|
|
||||||
void AnnotatePCQCreate(const char *file, int line,
|
|
||||||
const volatile void *pcq);
|
|
||||||
void AnnotatePCQDestroy(const char *file, int line,
|
|
||||||
const volatile void *pcq);
|
|
||||||
void AnnotatePCQPut(const char *file, int line,
|
|
||||||
const volatile void *pcq);
|
|
||||||
void AnnotatePCQGet(const char *file, int line,
|
|
||||||
const volatile void *pcq);
|
|
||||||
void AnnotateNewMemory(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
long size);
|
|
||||||
void AnnotateExpectRace(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
const char *description);
|
|
||||||
void AnnotateBenignRace(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
const char *description);
|
|
||||||
void AnnotateBenignRaceSized(const char *file, int line,
|
|
||||||
const volatile void *address,
|
|
||||||
long size,
|
|
||||||
const char *description);
|
|
||||||
void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
|
|
||||||
const volatile void *mu);
|
|
||||||
void AnnotateTraceMemory(const char *file, int line,
|
|
||||||
const volatile void *arg);
|
|
||||||
void AnnotateThreadName(const char *file, int line,
|
|
||||||
const char *name);
|
|
||||||
void AnnotateIgnoreReadsBegin(const char *file, int line);
|
|
||||||
void AnnotateIgnoreReadsEnd(const char *file, int line);
|
|
||||||
void AnnotateIgnoreWritesBegin(const char *file, int line);
|
|
||||||
void AnnotateIgnoreWritesEnd(const char *file, int line);
|
|
||||||
void AnnotateEnableRaceDetection(const char *file, int line, int enable);
|
|
||||||
void AnnotateNoOp(const char *file, int line,
|
|
||||||
const volatile void *arg);
|
|
||||||
void AnnotateFlushState(const char *file, int line);
|
|
||||||
|
|
||||||
/* Return non-zero value if running under valgrind.
|
|
||||||
|
|
||||||
If "valgrind.h" is included into dynamic_annotations.c,
|
|
||||||
the regular valgrind mechanism will be used.
|
|
||||||
See http://valgrind.org/docs/manual/manual-core-adv.html about
|
|
||||||
RUNNING_ON_VALGRIND and other valgrind "client requests".
|
|
||||||
The file "valgrind.h" may be obtained by doing
|
|
||||||
svn co svn://svn.valgrind.org/valgrind/trunk/include
|
|
||||||
|
|
||||||
If for some reason you can't use "valgrind.h" or want to fake valgrind,
|
|
||||||
there are two ways to make this function return non-zero:
|
|
||||||
- Use environment variable: export RUNNING_ON_VALGRIND=1
|
|
||||||
- Make your tool intercept the function RunningOnValgrind() and
|
|
||||||
change its return value.
|
|
||||||
*/
|
|
||||||
int RunningOnValgrind(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
|
|
||||||
|
|
||||||
/* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
|
|
||||||
|
|
||||||
Instead of doing
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();
|
|
||||||
... = x;
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_END();
|
|
||||||
one can use
|
|
||||||
... = _Py_ANNOTATE_UNPROTECTED_READ(x); */
|
|
||||||
template <class T>
|
|
||||||
inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) {
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_BEGIN();
|
|
||||||
T res = x;
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_END();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
/* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
|
|
||||||
namespace { \
|
|
||||||
class static_var ## _annotator { \
|
|
||||||
public: \
|
|
||||||
static_var ## _annotator() { \
|
|
||||||
_Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \
|
|
||||||
sizeof(static_var), \
|
|
||||||
# static_var ": " description); \
|
|
||||||
} \
|
|
||||||
}; \
|
|
||||||
static static_var ## _annotator the ## static_var ## _annotator;\
|
|
||||||
}
|
|
||||||
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
|
|
||||||
|
|
||||||
#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x)
|
|
||||||
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */
|
|
||||||
|
|
||||||
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
|
|
||||||
|
|
||||||
#endif /* __DYNAMIC_ANNOTATIONS_H__ */
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef Py_ENUMOBJECT_H
|
|
||||||
#define Py_ENUMOBJECT_H
|
|
||||||
|
|
||||||
/* Enumerate Object */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyEnum_Type;
|
|
||||||
PyAPI_DATA(PyTypeObject) PyReversed_Type;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !Py_ENUMOBJECT_H */
|
|
|
@ -1,38 +0,0 @@
|
||||||
#ifndef Py_ERRCODE_H
|
|
||||||
#define Py_ERRCODE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Error codes passed around between file input, tokenizer, parser and
|
|
||||||
interpreter. This is necessary so we can turn them into Python
|
|
||||||
exceptions at a higher level. Note that some errors have a
|
|
||||||
slightly different meaning when passed from the tokenizer to the
|
|
||||||
parser than when passed from the parser to the interpreter; e.g.
|
|
||||||
the parser only returns E_EOF when it hits EOF immediately, and it
|
|
||||||
never returns E_OK. */
|
|
||||||
|
|
||||||
#define E_OK 10 /* No error */
|
|
||||||
#define E_EOF 11 /* End Of File */
|
|
||||||
#define E_INTR 12 /* Interrupted */
|
|
||||||
#define E_TOKEN 13 /* Bad token */
|
|
||||||
#define E_SYNTAX 14 /* Syntax error */
|
|
||||||
#define E_NOMEM 15 /* Ran out of memory */
|
|
||||||
#define E_DONE 16 /* Parsing complete */
|
|
||||||
#define E_ERROR 17 /* Execution error */
|
|
||||||
#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */
|
|
||||||
#define E_OVERFLOW 19 /* Node had too many children */
|
|
||||||
#define E_TOODEEP 20 /* Too many indentation levels */
|
|
||||||
#define E_DEDENT 21 /* No matching outer block for dedent */
|
|
||||||
#define E_DECODE 22 /* Error in decoding into Unicode */
|
|
||||||
#define E_EOFS 23 /* EOF in triple-quoted string */
|
|
||||||
#define E_EOLS 24 /* EOL in single-quoted string */
|
|
||||||
#define E_LINECONT 25 /* Unexpected characters after a line continuation */
|
|
||||||
#define E_BADSINGLE 27 /* Ill-formed single statement input */
|
|
||||||
#define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_ERRCODE_H */
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef Py_EXPORTS_H
|
|
||||||
#define Py_EXPORTS_H
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
||||||
#define Py_IMPORTED_SYMBOL __declspec(dllimport)
|
|
||||||
#define Py_EXPORTED_SYMBOL __declspec(dllexport)
|
|
||||||
#define Py_LOCAL_SYMBOL
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* If we only ever used gcc >= 5, we could use __has_attribute(visibility)
|
|
||||||
* as a cross-platform way to determine if visibility is supported. However,
|
|
||||||
* we may still need to support gcc >= 4, as some Ubuntu LTS and Centos versions
|
|
||||||
* have 4 < gcc < 5.
|
|
||||||
*/
|
|
||||||
#ifndef __has_attribute
|
|
||||||
#define __has_attribute(x) 0 // Compatibility with non-clang compilers.
|
|
||||||
#endif
|
|
||||||
#if (defined(__GNUC__) && (__GNUC__ >= 4)) ||\
|
|
||||||
(defined(__clang__) && __has_attribute(visibility))
|
|
||||||
#define Py_IMPORTED_SYMBOL __attribute__ ((visibility ("default")))
|
|
||||||
#define Py_EXPORTED_SYMBOL __attribute__ ((visibility ("default")))
|
|
||||||
#define Py_LOCAL_SYMBOL __attribute__ ((visibility ("hidden")))
|
|
||||||
#else
|
|
||||||
#define Py_IMPORTED_SYMBOL
|
|
||||||
#define Py_EXPORTED_SYMBOL
|
|
||||||
#define Py_LOCAL_SYMBOL
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* Py_EXPORTS_H */
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* File object interface (what's left of it -- see io.py) */
|
|
||||||
|
|
||||||
#ifndef Py_FILEOBJECT_H
|
|
||||||
#define Py_FILEOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PY_STDIOTEXTMODE "b"
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int,
|
|
||||||
const char *, const char *,
|
|
||||||
const char *, int);
|
|
||||||
PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
|
|
||||||
PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
|
|
||||||
PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
|
|
||||||
PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
|
|
||||||
|
|
||||||
/* The default encoding used by the platform file system APIs
|
|
||||||
If non-NULL, this is different than the default encoding for strings
|
|
||||||
*/
|
|
||||||
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
|
|
||||||
PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
|
|
||||||
#endif
|
|
||||||
PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
|
|
||||||
PyAPI_DATA(int) Py_UTF8Mode;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A routine to check if a file descriptor can be select()-ed. */
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* On Windows, any socket fd can be select()-ed, no matter how high */
|
|
||||||
#define _PyIsSelectable_fd(FD) (1)
|
|
||||||
#else
|
|
||||||
#define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_FILEOBJECT_H
|
|
||||||
# include "cpython/fileobject.h"
|
|
||||||
# undef Py_CPYTHON_FILEOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_FILEOBJECT_H */
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef Py_FILEUTILS_H
|
|
||||||
#define Py_FILEUTILS_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
|
||||||
PyAPI_FUNC(wchar_t *) Py_DecodeLocale(
|
|
||||||
const char *arg,
|
|
||||||
size_t *size);
|
|
||||||
|
|
||||||
PyAPI_FUNC(char*) Py_EncodeLocale(
|
|
||||||
const wchar_t *text,
|
|
||||||
size_t *error_pos);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_FILEUTILS_H
|
|
||||||
# include "cpython/fileutils.h"
|
|
||||||
# undef Py_CPYTHON_FILEUTILS_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_FILEUTILS_H */
|
|
|
@ -1,54 +0,0 @@
|
||||||
|
|
||||||
/* Float object interface */
|
|
||||||
|
|
||||||
/*
|
|
||||||
PyFloatObject represents a (double precision) floating point number.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Py_FLOATOBJECT_H
|
|
||||||
#define Py_FLOATOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_DATA(PyTypeObject) PyFloat_Type;
|
|
||||||
|
|
||||||
#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
|
|
||||||
#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type)
|
|
||||||
|
|
||||||
#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN)
|
|
||||||
|
|
||||||
#define Py_RETURN_INF(sign) \
|
|
||||||
do { \
|
|
||||||
if (copysign(1., sign) == 1.) { \
|
|
||||||
return PyFloat_FromDouble(Py_HUGE_VAL); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
return PyFloat_FromDouble(-Py_HUGE_VAL); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
PyAPI_FUNC(double) PyFloat_GetMax(void);
|
|
||||||
PyAPI_FUNC(double) PyFloat_GetMin(void);
|
|
||||||
PyAPI_FUNC(PyObject*) PyFloat_GetInfo(void);
|
|
||||||
|
|
||||||
/* Return Python float from string PyObject. */
|
|
||||||
PyAPI_FUNC(PyObject*) PyFloat_FromString(PyObject*);
|
|
||||||
|
|
||||||
/* Return Python float from C double. */
|
|
||||||
PyAPI_FUNC(PyObject*) PyFloat_FromDouble(double);
|
|
||||||
|
|
||||||
/* Extract C double from Python float. The macro version trades safety for
|
|
||||||
speed. */
|
|
||||||
PyAPI_FUNC(double) PyFloat_AsDouble(PyObject*);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_FLOATOBJECT_H
|
|
||||||
# include "cpython/floatobject.h"
|
|
||||||
# undef Py_CPYTHON_FLOATOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_FLOATOBJECT_H */
|
|
|
@ -1,20 +0,0 @@
|
||||||
/* Frame object interface */
|
|
||||||
|
|
||||||
#ifndef Py_FRAMEOBJECT_H
|
|
||||||
#define Py_FRAMEOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pyframe.h"
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_FRAMEOBJECT_H
|
|
||||||
# include "cpython/frameobject.h"
|
|
||||||
# undef Py_CPYTHON_FRAMEOBJECT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_FRAMEOBJECT_H */
|
|
|
@ -1,14 +0,0 @@
|
||||||
// Implementation of PEP 585: support list[int] etc.
|
|
||||||
#ifndef Py_GENERICALIASOBJECT_H
|
|
||||||
#define Py_GENERICALIASOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) Py_GenericAlias(PyObject *, PyObject *);
|
|
||||||
PyAPI_DATA(PyTypeObject) Py_GenericAliasType;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_GENERICALIASOBJECT_H */
|
|
|
@ -1,98 +0,0 @@
|
||||||
/* Module definition and import interface */
|
|
||||||
|
|
||||||
#ifndef Py_IMPORT_H
|
|
||||||
#define Py_IMPORT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(long) PyImport_GetMagicNumber(void);
|
|
||||||
PyAPI_FUNC(const char *) PyImport_GetMagicTag(void);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(
|
|
||||||
const char *name, /* UTF-8 encoded string */
|
|
||||||
PyObject *co
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
|
|
||||||
const char *name, /* UTF-8 encoded string */
|
|
||||||
PyObject *co,
|
|
||||||
const char *pathname /* decoded from the filesystem encoding */
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleWithPathnames(
|
|
||||||
const char *name, /* UTF-8 encoded string */
|
|
||||||
PyObject *co,
|
|
||||||
const char *pathname, /* decoded from the filesystem encoding */
|
|
||||||
const char *cpathname /* decoded from the filesystem encoding */
|
|
||||||
);
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleObject(
|
|
||||||
PyObject *name,
|
|
||||||
PyObject *co,
|
|
||||||
PyObject *pathname,
|
|
||||||
PyObject *cpathname
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_GetModule(PyObject *name);
|
|
||||||
#endif
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_AddModuleObject(
|
|
||||||
PyObject *name
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_AddModule(
|
|
||||||
const char *name /* UTF-8 encoded string */
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModule(
|
|
||||||
const char *name /* UTF-8 encoded string */
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(
|
|
||||||
const char *name /* UTF-8 encoded string */
|
|
||||||
);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(
|
|
||||||
const char *name, /* UTF-8 encoded string */
|
|
||||||
PyObject *globals,
|
|
||||||
PyObject *locals,
|
|
||||||
PyObject *fromlist,
|
|
||||||
int level
|
|
||||||
);
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject(
|
|
||||||
PyObject *name,
|
|
||||||
PyObject *globals,
|
|
||||||
PyObject *locals,
|
|
||||||
PyObject *fromlist,
|
|
||||||
int level
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PyImport_ImportModuleEx(n, g, l, f) \
|
|
||||||
PyImport_ImportModuleLevel(n, g, l, f, 0)
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name);
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m);
|
|
||||||
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
|
|
||||||
PyAPI_FUNC(int) PyImport_ImportFrozenModuleObject(
|
|
||||||
PyObject *name
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
PyAPI_FUNC(int) PyImport_ImportFrozenModule(
|
|
||||||
const char *name /* UTF-8 encoded string */
|
|
||||||
);
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyImport_AppendInittab(
|
|
||||||
const char *name, /* ASCII encoded string */
|
|
||||||
PyObject* (*initfunc)(void)
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# define Py_CPYTHON_IMPORT_H
|
|
||||||
# include "cpython/import.h"
|
|
||||||
# undef Py_CPYTHON_IMPORT_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_IMPORT_H */
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_ABSTRACT_H
|
|
||||||
#define Py_INTERNAL_ABSTRACT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Fast inlined version of PyIndex_Check()
|
|
||||||
static inline int
|
|
||||||
_PyIndex_Check(PyObject *obj)
|
|
||||||
{
|
|
||||||
PyNumberMethods *tp_as_number = Py_TYPE(obj)->tp_as_number;
|
|
||||||
return (tp_as_number != NULL && tp_as_number->nb_index != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
|
|
||||||
PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_ABSTRACT_H */
|
|
|
@ -1,39 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_INTERNAL_ACCU_H
|
|
||||||
#define Py_INTERNAL_ACCU_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** This is a private API for use by the interpreter and the stdlib.
|
|
||||||
*** Its definition may be changed or removed at any moment.
|
|
||||||
***/
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A two-level accumulator of unicode objects that avoids both the overhead
|
|
||||||
* of keeping a huge number of small separate objects, and the quadratic
|
|
||||||
* behaviour of using a naive repeated concatenation scheme.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef small /* defined by some Windows headers */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject *large; /* A list of previously accumulated large strings */
|
|
||||||
PyObject *small; /* Pending small strings */
|
|
||||||
} _PyAccu;
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc);
|
|
||||||
PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc);
|
|
||||||
PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc);
|
|
||||||
PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_ACCU_H */
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
|
@ -1,112 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_ASDL_H
|
|
||||||
#define Py_INTERNAL_ASDL_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pycore_pyarena.h" // _PyArena_Malloc()
|
|
||||||
|
|
||||||
typedef PyObject * identifier;
|
|
||||||
typedef PyObject * string;
|
|
||||||
typedef PyObject * object;
|
|
||||||
typedef PyObject * constant;
|
|
||||||
|
|
||||||
/* It would be nice if the code generated by asdl_c.py was completely
|
|
||||||
independent of Python, but it is a goal the requires too much work
|
|
||||||
at this stage. So, for example, I'll represent identifiers as
|
|
||||||
interned Python strings.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _ASDL_SEQ_HEAD \
|
|
||||||
Py_ssize_t size; \
|
|
||||||
void **elements;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
} asdl_seq;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
void *typed_elements[1];
|
|
||||||
} asdl_generic_seq;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
PyObject *typed_elements[1];
|
|
||||||
} asdl_identifier_seq;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
int typed_elements[1];
|
|
||||||
} asdl_int_seq;
|
|
||||||
|
|
||||||
asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
|
|
||||||
#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \
|
|
||||||
asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \
|
|
||||||
{ \
|
|
||||||
asdl_ ## NAME ## _seq *seq = NULL; \
|
|
||||||
size_t n; \
|
|
||||||
/* check size is sane */ \
|
|
||||||
if (size < 0 || \
|
|
||||||
(size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \
|
|
||||||
PyErr_NoMemory(); \
|
|
||||||
return NULL; \
|
|
||||||
} \
|
|
||||||
n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \
|
|
||||||
/* check if size can be added safely */ \
|
|
||||||
if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \
|
|
||||||
PyErr_NoMemory(); \
|
|
||||||
return NULL; \
|
|
||||||
} \
|
|
||||||
n += sizeof(asdl_ ## NAME ## _seq); \
|
|
||||||
seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \
|
|
||||||
if (!seq) { \
|
|
||||||
PyErr_NoMemory(); \
|
|
||||||
return NULL; \
|
|
||||||
} \
|
|
||||||
memset(seq, 0, n); \
|
|
||||||
seq->size = size; \
|
|
||||||
seq->elements = (void**)seq->typed_elements; \
|
|
||||||
return seq; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define asdl_seq_GET_UNTYPED(S, I) _Py_RVALUE((S)->elements[(I)])
|
|
||||||
#define asdl_seq_GET(S, I) _Py_RVALUE((S)->typed_elements[(I)])
|
|
||||||
#define asdl_seq_LEN(S) _Py_RVALUE(((S) == NULL ? 0 : (S)->size))
|
|
||||||
|
|
||||||
#ifdef Py_DEBUG
|
|
||||||
# define asdl_seq_SET(S, I, V) \
|
|
||||||
do { \
|
|
||||||
Py_ssize_t _asdl_i = (I); \
|
|
||||||
assert((S) != NULL); \
|
|
||||||
assert(0 <= _asdl_i && _asdl_i < (S)->size); \
|
|
||||||
(S)->typed_elements[_asdl_i] = (V); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
# define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[I] = (V))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Py_DEBUG
|
|
||||||
# define asdl_seq_SET_UNTYPED(S, I, V) \
|
|
||||||
do { \
|
|
||||||
Py_ssize_t _asdl_i = (I); \
|
|
||||||
assert((S) != NULL); \
|
|
||||||
assert(0 <= _asdl_i && _asdl_i < (S)->size); \
|
|
||||||
(S)->elements[_asdl_i] = (V); \
|
|
||||||
} while (0)
|
|
||||||
#else
|
|
||||||
# define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[I] = (V))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_ASDL_H */
|
|
|
@ -1,866 +0,0 @@
|
||||||
// File automatically generated by Parser/asdl_c.py.
|
|
||||||
|
|
||||||
#ifndef Py_INTERNAL_AST_H
|
|
||||||
#define Py_INTERNAL_AST_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pycore_asdl.h"
|
|
||||||
|
|
||||||
typedef struct _mod *mod_ty;
|
|
||||||
|
|
||||||
typedef struct _stmt *stmt_ty;
|
|
||||||
|
|
||||||
typedef struct _expr *expr_ty;
|
|
||||||
|
|
||||||
typedef enum _expr_context { Load=1, Store=2, Del=3 } expr_context_ty;
|
|
||||||
|
|
||||||
typedef enum _boolop { And=1, Or=2 } boolop_ty;
|
|
||||||
|
|
||||||
typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7,
|
|
||||||
LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12,
|
|
||||||
FloorDiv=13 } operator_ty;
|
|
||||||
|
|
||||||
typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty;
|
|
||||||
|
|
||||||
typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8,
|
|
||||||
In=9, NotIn=10 } cmpop_ty;
|
|
||||||
|
|
||||||
typedef struct _comprehension *comprehension_ty;
|
|
||||||
|
|
||||||
typedef struct _excepthandler *excepthandler_ty;
|
|
||||||
|
|
||||||
typedef struct _arguments *arguments_ty;
|
|
||||||
|
|
||||||
typedef struct _arg *arg_ty;
|
|
||||||
|
|
||||||
typedef struct _keyword *keyword_ty;
|
|
||||||
|
|
||||||
typedef struct _alias *alias_ty;
|
|
||||||
|
|
||||||
typedef struct _withitem *withitem_ty;
|
|
||||||
|
|
||||||
typedef struct _match_case *match_case_ty;
|
|
||||||
|
|
||||||
typedef struct _pattern *pattern_ty;
|
|
||||||
|
|
||||||
typedef struct _type_ignore *type_ignore_ty;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
mod_ty typed_elements[1];
|
|
||||||
} asdl_mod_seq;
|
|
||||||
|
|
||||||
asdl_mod_seq *_Py_asdl_mod_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
stmt_ty typed_elements[1];
|
|
||||||
} asdl_stmt_seq;
|
|
||||||
|
|
||||||
asdl_stmt_seq *_Py_asdl_stmt_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
expr_ty typed_elements[1];
|
|
||||||
} asdl_expr_seq;
|
|
||||||
|
|
||||||
asdl_expr_seq *_Py_asdl_expr_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
comprehension_ty typed_elements[1];
|
|
||||||
} asdl_comprehension_seq;
|
|
||||||
|
|
||||||
asdl_comprehension_seq *_Py_asdl_comprehension_seq_new(Py_ssize_t size, PyArena
|
|
||||||
*arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
excepthandler_ty typed_elements[1];
|
|
||||||
} asdl_excepthandler_seq;
|
|
||||||
|
|
||||||
asdl_excepthandler_seq *_Py_asdl_excepthandler_seq_new(Py_ssize_t size, PyArena
|
|
||||||
*arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
arguments_ty typed_elements[1];
|
|
||||||
} asdl_arguments_seq;
|
|
||||||
|
|
||||||
asdl_arguments_seq *_Py_asdl_arguments_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
arg_ty typed_elements[1];
|
|
||||||
} asdl_arg_seq;
|
|
||||||
|
|
||||||
asdl_arg_seq *_Py_asdl_arg_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
keyword_ty typed_elements[1];
|
|
||||||
} asdl_keyword_seq;
|
|
||||||
|
|
||||||
asdl_keyword_seq *_Py_asdl_keyword_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
alias_ty typed_elements[1];
|
|
||||||
} asdl_alias_seq;
|
|
||||||
|
|
||||||
asdl_alias_seq *_Py_asdl_alias_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
withitem_ty typed_elements[1];
|
|
||||||
} asdl_withitem_seq;
|
|
||||||
|
|
||||||
asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
match_case_ty typed_elements[1];
|
|
||||||
} asdl_match_case_seq;
|
|
||||||
|
|
||||||
asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena
|
|
||||||
*arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
pattern_ty typed_elements[1];
|
|
||||||
} asdl_pattern_seq;
|
|
||||||
|
|
||||||
asdl_pattern_seq *_Py_asdl_pattern_seq_new(Py_ssize_t size, PyArena *arena);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_ASDL_SEQ_HEAD
|
|
||||||
type_ignore_ty typed_elements[1];
|
|
||||||
} asdl_type_ignore_seq;
|
|
||||||
|
|
||||||
asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena
|
|
||||||
*arena);
|
|
||||||
|
|
||||||
|
|
||||||
enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
|
|
||||||
FunctionType_kind=4};
|
|
||||||
struct _mod {
|
|
||||||
enum _mod_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_type_ignore_seq *type_ignores;
|
|
||||||
} Module;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
} Interactive;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty body;
|
|
||||||
} Expression;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *argtypes;
|
|
||||||
expr_ty returns;
|
|
||||||
} FunctionType;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3,
|
|
||||||
Return_kind=4, Delete_kind=5, Assign_kind=6,
|
|
||||||
AugAssign_kind=7, AnnAssign_kind=8, For_kind=9,
|
|
||||||
AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13,
|
|
||||||
AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17,
|
|
||||||
TryStar_kind=18, Assert_kind=19, Import_kind=20,
|
|
||||||
ImportFrom_kind=21, Global_kind=22, Nonlocal_kind=23,
|
|
||||||
Expr_kind=24, Pass_kind=25, Break_kind=26, Continue_kind=27};
|
|
||||||
struct _stmt {
|
|
||||||
enum _stmt_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
identifier name;
|
|
||||||
arguments_ty args;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_expr_seq *decorator_list;
|
|
||||||
expr_ty returns;
|
|
||||||
string type_comment;
|
|
||||||
} FunctionDef;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
identifier name;
|
|
||||||
arguments_ty args;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_expr_seq *decorator_list;
|
|
||||||
expr_ty returns;
|
|
||||||
string type_comment;
|
|
||||||
} AsyncFunctionDef;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
identifier name;
|
|
||||||
asdl_expr_seq *bases;
|
|
||||||
asdl_keyword_seq *keywords;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_expr_seq *decorator_list;
|
|
||||||
} ClassDef;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} Return;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *targets;
|
|
||||||
} Delete;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *targets;
|
|
||||||
expr_ty value;
|
|
||||||
string type_comment;
|
|
||||||
} Assign;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty target;
|
|
||||||
operator_ty op;
|
|
||||||
expr_ty value;
|
|
||||||
} AugAssign;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty target;
|
|
||||||
expr_ty annotation;
|
|
||||||
expr_ty value;
|
|
||||||
int simple;
|
|
||||||
} AnnAssign;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty target;
|
|
||||||
expr_ty iter;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
string type_comment;
|
|
||||||
} For;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty target;
|
|
||||||
expr_ty iter;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
string type_comment;
|
|
||||||
} AsyncFor;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty test;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
} While;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty test;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
} If;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_withitem_seq *items;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
string type_comment;
|
|
||||||
} With;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_withitem_seq *items;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
string type_comment;
|
|
||||||
} AsyncWith;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty subject;
|
|
||||||
asdl_match_case_seq *cases;
|
|
||||||
} Match;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty exc;
|
|
||||||
expr_ty cause;
|
|
||||||
} Raise;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_excepthandler_seq *handlers;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
asdl_stmt_seq *finalbody;
|
|
||||||
} Try;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
asdl_excepthandler_seq *handlers;
|
|
||||||
asdl_stmt_seq *orelse;
|
|
||||||
asdl_stmt_seq *finalbody;
|
|
||||||
} TryStar;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty test;
|
|
||||||
expr_ty msg;
|
|
||||||
} Assert;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_alias_seq *names;
|
|
||||||
} Import;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
identifier module;
|
|
||||||
asdl_alias_seq *names;
|
|
||||||
int level;
|
|
||||||
} ImportFrom;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_identifier_seq *names;
|
|
||||||
} Global;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_identifier_seq *names;
|
|
||||||
} Nonlocal;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} Expr;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4,
|
|
||||||
Lambda_kind=5, IfExp_kind=6, Dict_kind=7, Set_kind=8,
|
|
||||||
ListComp_kind=9, SetComp_kind=10, DictComp_kind=11,
|
|
||||||
GeneratorExp_kind=12, Await_kind=13, Yield_kind=14,
|
|
||||||
YieldFrom_kind=15, Compare_kind=16, Call_kind=17,
|
|
||||||
FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20,
|
|
||||||
Attribute_kind=21, Subscript_kind=22, Starred_kind=23,
|
|
||||||
Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27};
|
|
||||||
struct _expr {
|
|
||||||
enum _expr_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
boolop_ty op;
|
|
||||||
asdl_expr_seq *values;
|
|
||||||
} BoolOp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty target;
|
|
||||||
expr_ty value;
|
|
||||||
} NamedExpr;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty left;
|
|
||||||
operator_ty op;
|
|
||||||
expr_ty right;
|
|
||||||
} BinOp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
unaryop_ty op;
|
|
||||||
expr_ty operand;
|
|
||||||
} UnaryOp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
arguments_ty args;
|
|
||||||
expr_ty body;
|
|
||||||
} Lambda;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty test;
|
|
||||||
expr_ty body;
|
|
||||||
expr_ty orelse;
|
|
||||||
} IfExp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *keys;
|
|
||||||
asdl_expr_seq *values;
|
|
||||||
} Dict;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *elts;
|
|
||||||
} Set;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty elt;
|
|
||||||
asdl_comprehension_seq *generators;
|
|
||||||
} ListComp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty elt;
|
|
||||||
asdl_comprehension_seq *generators;
|
|
||||||
} SetComp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty key;
|
|
||||||
expr_ty value;
|
|
||||||
asdl_comprehension_seq *generators;
|
|
||||||
} DictComp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty elt;
|
|
||||||
asdl_comprehension_seq *generators;
|
|
||||||
} GeneratorExp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} Await;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} Yield;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} YieldFrom;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty left;
|
|
||||||
asdl_int_seq *ops;
|
|
||||||
asdl_expr_seq *comparators;
|
|
||||||
} Compare;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty func;
|
|
||||||
asdl_expr_seq *args;
|
|
||||||
asdl_keyword_seq *keywords;
|
|
||||||
} Call;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
int conversion;
|
|
||||||
expr_ty format_spec;
|
|
||||||
} FormattedValue;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *values;
|
|
||||||
} JoinedStr;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
constant value;
|
|
||||||
string kind;
|
|
||||||
} Constant;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
identifier attr;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} Attribute;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
expr_ty slice;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} Subscript;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} Starred;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
identifier id;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} Name;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *elts;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} List;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *elts;
|
|
||||||
expr_context_ty ctx;
|
|
||||||
} Tuple;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty lower;
|
|
||||||
expr_ty upper;
|
|
||||||
expr_ty step;
|
|
||||||
} Slice;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _comprehension {
|
|
||||||
expr_ty target;
|
|
||||||
expr_ty iter;
|
|
||||||
asdl_expr_seq *ifs;
|
|
||||||
int is_async;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _excepthandler_kind {ExceptHandler_kind=1};
|
|
||||||
struct _excepthandler {
|
|
||||||
enum _excepthandler_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
expr_ty type;
|
|
||||||
identifier name;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
} ExceptHandler;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _arguments {
|
|
||||||
asdl_arg_seq *posonlyargs;
|
|
||||||
asdl_arg_seq *args;
|
|
||||||
arg_ty vararg;
|
|
||||||
asdl_arg_seq *kwonlyargs;
|
|
||||||
asdl_expr_seq *kw_defaults;
|
|
||||||
arg_ty kwarg;
|
|
||||||
asdl_expr_seq *defaults;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _arg {
|
|
||||||
identifier arg;
|
|
||||||
expr_ty annotation;
|
|
||||||
string type_comment;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _keyword {
|
|
||||||
identifier arg;
|
|
||||||
expr_ty value;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _alias {
|
|
||||||
identifier name;
|
|
||||||
identifier asname;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _withitem {
|
|
||||||
expr_ty context_expr;
|
|
||||||
expr_ty optional_vars;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _match_case {
|
|
||||||
pattern_ty pattern;
|
|
||||||
expr_ty guard;
|
|
||||||
asdl_stmt_seq *body;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _pattern_kind {MatchValue_kind=1, MatchSingleton_kind=2,
|
|
||||||
MatchSequence_kind=3, MatchMapping_kind=4,
|
|
||||||
MatchClass_kind=5, MatchStar_kind=6, MatchAs_kind=7,
|
|
||||||
MatchOr_kind=8};
|
|
||||||
struct _pattern {
|
|
||||||
enum _pattern_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
expr_ty value;
|
|
||||||
} MatchValue;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
constant value;
|
|
||||||
} MatchSingleton;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_pattern_seq *patterns;
|
|
||||||
} MatchSequence;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_expr_seq *keys;
|
|
||||||
asdl_pattern_seq *patterns;
|
|
||||||
identifier rest;
|
|
||||||
} MatchMapping;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
expr_ty cls;
|
|
||||||
asdl_pattern_seq *patterns;
|
|
||||||
asdl_identifier_seq *kwd_attrs;
|
|
||||||
asdl_pattern_seq *kwd_patterns;
|
|
||||||
} MatchClass;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
identifier name;
|
|
||||||
} MatchStar;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
pattern_ty pattern;
|
|
||||||
identifier name;
|
|
||||||
} MatchAs;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
asdl_pattern_seq *patterns;
|
|
||||||
} MatchOr;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
int lineno;
|
|
||||||
int col_offset;
|
|
||||||
int end_lineno;
|
|
||||||
int end_col_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum _type_ignore_kind {TypeIgnore_kind=1};
|
|
||||||
struct _type_ignore {
|
|
||||||
enum _type_ignore_kind kind;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int lineno;
|
|
||||||
string tag;
|
|
||||||
} TypeIgnore;
|
|
||||||
|
|
||||||
} v;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Note: these macros affect function definitions, not only call sites.
|
|
||||||
mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores,
|
|
||||||
PyArena *arena);
|
|
||||||
mod_ty _PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena);
|
|
||||||
mod_ty _PyAST_Expression(expr_ty body, PyArena *arena);
|
|
||||||
mod_ty _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena
|
|
||||||
*arena);
|
|
||||||
stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
|
|
||||||
body, asdl_expr_seq * decorator_list, expr_ty
|
|
||||||
returns, string type_comment, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args,
|
|
||||||
asdl_stmt_seq * body, asdl_expr_seq *
|
|
||||||
decorator_list, expr_ty returns, string
|
|
||||||
type_comment, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases,
|
|
||||||
asdl_keyword_seq * keywords, asdl_stmt_seq * body,
|
|
||||||
asdl_expr_seq * decorator_list, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string
|
|
||||||
type_comment, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int
|
|
||||||
simple, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body,
|
|
||||||
asdl_stmt_seq * orelse, string type_comment, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
stmt_ty _PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body,
|
|
||||||
asdl_stmt_seq * orelse, string type_comment, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq *
|
|
||||||
orelse, int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse,
|
|
||||||
int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string
|
|
||||||
type_comment, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body,
|
|
||||||
string type_comment, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno,
|
|
||||||
int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset,
|
|
||||||
int end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
|
|
||||||
asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int
|
|
||||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
stmt_ty _PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
|
|
||||||
asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
|
|
||||||
int end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level,
|
|
||||||
int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset,
|
|
||||||
int end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
stmt_ty _PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Pass(int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Break(int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
stmt_ty _PyAST_Continue(int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
expr_ty _PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno,
|
|
||||||
int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
expr_ty _PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno,
|
|
||||||
int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
expr_ty _PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno,
|
|
||||||
int col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq *
|
|
||||||
generators, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators,
|
|
||||||
int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq *
|
|
||||||
comparators, int lineno, int col_offset, int end_lineno,
|
|
||||||
int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq *
|
|
||||||
keywords, int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_FormattedValue(expr_ty value, int conversion, expr_ty
|
|
||||||
format_spec, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset,
|
|
||||||
int end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Constant(constant value, string kind, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx,
|
|
||||||
int lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int
|
|
||||||
lineno, int col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
expr_ty _PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
expr_ty _PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno,
|
|
||||||
int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
comprehension_ty _PyAST_comprehension(expr_ty target, expr_ty iter,
|
|
||||||
asdl_expr_seq * ifs, int is_async,
|
|
||||||
PyArena *arena);
|
|
||||||
excepthandler_ty _PyAST_ExceptHandler(expr_ty type, identifier name,
|
|
||||||
asdl_stmt_seq * body, int lineno, int
|
|
||||||
col_offset, int end_lineno, int
|
|
||||||
end_col_offset, PyArena *arena);
|
|
||||||
arguments_ty _PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args,
|
|
||||||
arg_ty vararg, asdl_arg_seq * kwonlyargs,
|
|
||||||
asdl_expr_seq * kw_defaults, arg_ty kwarg,
|
|
||||||
asdl_expr_seq * defaults, PyArena *arena);
|
|
||||||
arg_ty _PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int
|
|
||||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
keyword_ty _PyAST_keyword(identifier arg, expr_ty value, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
alias_ty _PyAST_alias(identifier name, identifier asname, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
withitem_ty _PyAST_withitem(expr_ty context_expr, expr_ty optional_vars,
|
|
||||||
PyArena *arena);
|
|
||||||
match_case_ty _PyAST_match_case(pattern_ty pattern, expr_ty guard,
|
|
||||||
asdl_stmt_seq * body, PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchSingleton(constant value, int lineno, int col_offset,
|
|
||||||
int end_lineno, int end_col_offset, PyArena
|
|
||||||
*arena);
|
|
||||||
pattern_ty _PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq *
|
|
||||||
patterns, identifier rest, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns,
|
|
||||||
asdl_identifier_seq * kwd_attrs, asdl_pattern_seq
|
|
||||||
* kwd_patterns, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchStar(identifier name, int lineno, int col_offset, int
|
|
||||||
end_lineno, int end_col_offset, PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int
|
|
||||||
col_offset, int end_lineno, int end_col_offset,
|
|
||||||
PyArena *arena);
|
|
||||||
type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena);
|
|
||||||
|
|
||||||
|
|
||||||
PyObject* PyAST_mod2obj(mod_ty t);
|
|
||||||
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);
|
|
||||||
int PyAST_Check(PyObject* obj);
|
|
||||||
|
|
||||||
extern int _PyAST_Validate(mod_ty);
|
|
||||||
|
|
||||||
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
|
|
||||||
extern PyObject* _PyAST_ExprAsUnicode(expr_ty);
|
|
||||||
|
|
||||||
/* Return the borrowed reference to the first literal string in the
|
|
||||||
sequence of statements or NULL if it doesn't start from a literal string.
|
|
||||||
Doesn't set exception. */
|
|
||||||
extern PyObject* _PyAST_GetDocString(asdl_stmt_seq *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_AST_H */
|
|
|
@ -1,258 +0,0 @@
|
||||||
// File automatically generated by Parser/asdl_c.py.
|
|
||||||
|
|
||||||
#ifndef Py_INTERNAL_AST_STATE_H
|
|
||||||
#define Py_INTERNAL_AST_STATE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ast_state {
|
|
||||||
int initialized;
|
|
||||||
int recursion_depth;
|
|
||||||
int recursion_limit;
|
|
||||||
PyObject *AST_type;
|
|
||||||
PyObject *Add_singleton;
|
|
||||||
PyObject *Add_type;
|
|
||||||
PyObject *And_singleton;
|
|
||||||
PyObject *And_type;
|
|
||||||
PyObject *AnnAssign_type;
|
|
||||||
PyObject *Assert_type;
|
|
||||||
PyObject *Assign_type;
|
|
||||||
PyObject *AsyncFor_type;
|
|
||||||
PyObject *AsyncFunctionDef_type;
|
|
||||||
PyObject *AsyncWith_type;
|
|
||||||
PyObject *Attribute_type;
|
|
||||||
PyObject *AugAssign_type;
|
|
||||||
PyObject *Await_type;
|
|
||||||
PyObject *BinOp_type;
|
|
||||||
PyObject *BitAnd_singleton;
|
|
||||||
PyObject *BitAnd_type;
|
|
||||||
PyObject *BitOr_singleton;
|
|
||||||
PyObject *BitOr_type;
|
|
||||||
PyObject *BitXor_singleton;
|
|
||||||
PyObject *BitXor_type;
|
|
||||||
PyObject *BoolOp_type;
|
|
||||||
PyObject *Break_type;
|
|
||||||
PyObject *Call_type;
|
|
||||||
PyObject *ClassDef_type;
|
|
||||||
PyObject *Compare_type;
|
|
||||||
PyObject *Constant_type;
|
|
||||||
PyObject *Continue_type;
|
|
||||||
PyObject *Del_singleton;
|
|
||||||
PyObject *Del_type;
|
|
||||||
PyObject *Delete_type;
|
|
||||||
PyObject *DictComp_type;
|
|
||||||
PyObject *Dict_type;
|
|
||||||
PyObject *Div_singleton;
|
|
||||||
PyObject *Div_type;
|
|
||||||
PyObject *Eq_singleton;
|
|
||||||
PyObject *Eq_type;
|
|
||||||
PyObject *ExceptHandler_type;
|
|
||||||
PyObject *Expr_type;
|
|
||||||
PyObject *Expression_type;
|
|
||||||
PyObject *FloorDiv_singleton;
|
|
||||||
PyObject *FloorDiv_type;
|
|
||||||
PyObject *For_type;
|
|
||||||
PyObject *FormattedValue_type;
|
|
||||||
PyObject *FunctionDef_type;
|
|
||||||
PyObject *FunctionType_type;
|
|
||||||
PyObject *GeneratorExp_type;
|
|
||||||
PyObject *Global_type;
|
|
||||||
PyObject *GtE_singleton;
|
|
||||||
PyObject *GtE_type;
|
|
||||||
PyObject *Gt_singleton;
|
|
||||||
PyObject *Gt_type;
|
|
||||||
PyObject *IfExp_type;
|
|
||||||
PyObject *If_type;
|
|
||||||
PyObject *ImportFrom_type;
|
|
||||||
PyObject *Import_type;
|
|
||||||
PyObject *In_singleton;
|
|
||||||
PyObject *In_type;
|
|
||||||
PyObject *Interactive_type;
|
|
||||||
PyObject *Invert_singleton;
|
|
||||||
PyObject *Invert_type;
|
|
||||||
PyObject *IsNot_singleton;
|
|
||||||
PyObject *IsNot_type;
|
|
||||||
PyObject *Is_singleton;
|
|
||||||
PyObject *Is_type;
|
|
||||||
PyObject *JoinedStr_type;
|
|
||||||
PyObject *LShift_singleton;
|
|
||||||
PyObject *LShift_type;
|
|
||||||
PyObject *Lambda_type;
|
|
||||||
PyObject *ListComp_type;
|
|
||||||
PyObject *List_type;
|
|
||||||
PyObject *Load_singleton;
|
|
||||||
PyObject *Load_type;
|
|
||||||
PyObject *LtE_singleton;
|
|
||||||
PyObject *LtE_type;
|
|
||||||
PyObject *Lt_singleton;
|
|
||||||
PyObject *Lt_type;
|
|
||||||
PyObject *MatMult_singleton;
|
|
||||||
PyObject *MatMult_type;
|
|
||||||
PyObject *MatchAs_type;
|
|
||||||
PyObject *MatchClass_type;
|
|
||||||
PyObject *MatchMapping_type;
|
|
||||||
PyObject *MatchOr_type;
|
|
||||||
PyObject *MatchSequence_type;
|
|
||||||
PyObject *MatchSingleton_type;
|
|
||||||
PyObject *MatchStar_type;
|
|
||||||
PyObject *MatchValue_type;
|
|
||||||
PyObject *Match_type;
|
|
||||||
PyObject *Mod_singleton;
|
|
||||||
PyObject *Mod_type;
|
|
||||||
PyObject *Module_type;
|
|
||||||
PyObject *Mult_singleton;
|
|
||||||
PyObject *Mult_type;
|
|
||||||
PyObject *Name_type;
|
|
||||||
PyObject *NamedExpr_type;
|
|
||||||
PyObject *Nonlocal_type;
|
|
||||||
PyObject *NotEq_singleton;
|
|
||||||
PyObject *NotEq_type;
|
|
||||||
PyObject *NotIn_singleton;
|
|
||||||
PyObject *NotIn_type;
|
|
||||||
PyObject *Not_singleton;
|
|
||||||
PyObject *Not_type;
|
|
||||||
PyObject *Or_singleton;
|
|
||||||
PyObject *Or_type;
|
|
||||||
PyObject *Pass_type;
|
|
||||||
PyObject *Pow_singleton;
|
|
||||||
PyObject *Pow_type;
|
|
||||||
PyObject *RShift_singleton;
|
|
||||||
PyObject *RShift_type;
|
|
||||||
PyObject *Raise_type;
|
|
||||||
PyObject *Return_type;
|
|
||||||
PyObject *SetComp_type;
|
|
||||||
PyObject *Set_type;
|
|
||||||
PyObject *Slice_type;
|
|
||||||
PyObject *Starred_type;
|
|
||||||
PyObject *Store_singleton;
|
|
||||||
PyObject *Store_type;
|
|
||||||
PyObject *Sub_singleton;
|
|
||||||
PyObject *Sub_type;
|
|
||||||
PyObject *Subscript_type;
|
|
||||||
PyObject *TryStar_type;
|
|
||||||
PyObject *Try_type;
|
|
||||||
PyObject *Tuple_type;
|
|
||||||
PyObject *TypeIgnore_type;
|
|
||||||
PyObject *UAdd_singleton;
|
|
||||||
PyObject *UAdd_type;
|
|
||||||
PyObject *USub_singleton;
|
|
||||||
PyObject *USub_type;
|
|
||||||
PyObject *UnaryOp_type;
|
|
||||||
PyObject *While_type;
|
|
||||||
PyObject *With_type;
|
|
||||||
PyObject *YieldFrom_type;
|
|
||||||
PyObject *Yield_type;
|
|
||||||
PyObject *__dict__;
|
|
||||||
PyObject *__doc__;
|
|
||||||
PyObject *__match_args__;
|
|
||||||
PyObject *__module__;
|
|
||||||
PyObject *_attributes;
|
|
||||||
PyObject *_fields;
|
|
||||||
PyObject *alias_type;
|
|
||||||
PyObject *annotation;
|
|
||||||
PyObject *arg;
|
|
||||||
PyObject *arg_type;
|
|
||||||
PyObject *args;
|
|
||||||
PyObject *argtypes;
|
|
||||||
PyObject *arguments_type;
|
|
||||||
PyObject *asname;
|
|
||||||
PyObject *ast;
|
|
||||||
PyObject *attr;
|
|
||||||
PyObject *bases;
|
|
||||||
PyObject *body;
|
|
||||||
PyObject *boolop_type;
|
|
||||||
PyObject *cases;
|
|
||||||
PyObject *cause;
|
|
||||||
PyObject *cls;
|
|
||||||
PyObject *cmpop_type;
|
|
||||||
PyObject *col_offset;
|
|
||||||
PyObject *comparators;
|
|
||||||
PyObject *comprehension_type;
|
|
||||||
PyObject *context_expr;
|
|
||||||
PyObject *conversion;
|
|
||||||
PyObject *ctx;
|
|
||||||
PyObject *decorator_list;
|
|
||||||
PyObject *defaults;
|
|
||||||
PyObject *elt;
|
|
||||||
PyObject *elts;
|
|
||||||
PyObject *end_col_offset;
|
|
||||||
PyObject *end_lineno;
|
|
||||||
PyObject *exc;
|
|
||||||
PyObject *excepthandler_type;
|
|
||||||
PyObject *expr_context_type;
|
|
||||||
PyObject *expr_type;
|
|
||||||
PyObject *finalbody;
|
|
||||||
PyObject *format_spec;
|
|
||||||
PyObject *func;
|
|
||||||
PyObject *generators;
|
|
||||||
PyObject *guard;
|
|
||||||
PyObject *handlers;
|
|
||||||
PyObject *id;
|
|
||||||
PyObject *ifs;
|
|
||||||
PyObject *is_async;
|
|
||||||
PyObject *items;
|
|
||||||
PyObject *iter;
|
|
||||||
PyObject *key;
|
|
||||||
PyObject *keys;
|
|
||||||
PyObject *keyword_type;
|
|
||||||
PyObject *keywords;
|
|
||||||
PyObject *kind;
|
|
||||||
PyObject *kw_defaults;
|
|
||||||
PyObject *kwarg;
|
|
||||||
PyObject *kwd_attrs;
|
|
||||||
PyObject *kwd_patterns;
|
|
||||||
PyObject *kwonlyargs;
|
|
||||||
PyObject *left;
|
|
||||||
PyObject *level;
|
|
||||||
PyObject *lineno;
|
|
||||||
PyObject *lower;
|
|
||||||
PyObject *match_case_type;
|
|
||||||
PyObject *mod_type;
|
|
||||||
PyObject *module;
|
|
||||||
PyObject *msg;
|
|
||||||
PyObject *name;
|
|
||||||
PyObject *names;
|
|
||||||
PyObject *op;
|
|
||||||
PyObject *operand;
|
|
||||||
PyObject *operator_type;
|
|
||||||
PyObject *ops;
|
|
||||||
PyObject *optional_vars;
|
|
||||||
PyObject *orelse;
|
|
||||||
PyObject *pattern;
|
|
||||||
PyObject *pattern_type;
|
|
||||||
PyObject *patterns;
|
|
||||||
PyObject *posonlyargs;
|
|
||||||
PyObject *rest;
|
|
||||||
PyObject *returns;
|
|
||||||
PyObject *right;
|
|
||||||
PyObject *simple;
|
|
||||||
PyObject *slice;
|
|
||||||
PyObject *step;
|
|
||||||
PyObject *stmt_type;
|
|
||||||
PyObject *subject;
|
|
||||||
PyObject *tag;
|
|
||||||
PyObject *target;
|
|
||||||
PyObject *targets;
|
|
||||||
PyObject *test;
|
|
||||||
PyObject *type;
|
|
||||||
PyObject *type_comment;
|
|
||||||
PyObject *type_ignore_type;
|
|
||||||
PyObject *type_ignores;
|
|
||||||
PyObject *unaryop_type;
|
|
||||||
PyObject *upper;
|
|
||||||
PyObject *value;
|
|
||||||
PyObject *values;
|
|
||||||
PyObject *vararg;
|
|
||||||
PyObject *withitem_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_AST_STATE_H */
|
|
||||||
|
|
|
@ -1,557 +0,0 @@
|
||||||
#ifndef Py_ATOMIC_H
|
|
||||||
#define Py_ATOMIC_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */
|
|
||||||
#include "pyconfig.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_STD_ATOMIC
|
|
||||||
# include <stdatomic.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <intrin.h>
|
|
||||||
#if defined(_M_IX86) || defined(_M_X64)
|
|
||||||
# include <immintrin.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is modeled after the atomics interface from C1x, according to
|
|
||||||
* the draft at
|
|
||||||
* http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf.
|
|
||||||
* Operations and types are named the same except with a _Py_ prefix
|
|
||||||
* and have the same semantics.
|
|
||||||
*
|
|
||||||
* Beware, the implementations here are deep magic.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(HAVE_STD_ATOMIC)
|
|
||||||
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed = memory_order_relaxed,
|
|
||||||
_Py_memory_order_acquire = memory_order_acquire,
|
|
||||||
_Py_memory_order_release = memory_order_release,
|
|
||||||
_Py_memory_order_acq_rel = memory_order_acq_rel,
|
|
||||||
_Py_memory_order_seq_cst = memory_order_seq_cst
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
atomic_uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
atomic_int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
|
|
||||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
|
|
||||||
atomic_signal_fence(ORDER)
|
|
||||||
|
|
||||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
|
|
||||||
atomic_thread_fence(ORDER)
|
|
||||||
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)
|
|
||||||
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER)
|
|
||||||
|
|
||||||
// Use builtin atomic operations in GCC >= 4.7 and clang
|
|
||||||
#elif defined(HAVE_BUILTIN_ATOMIC)
|
|
||||||
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed = __ATOMIC_RELAXED,
|
|
||||||
_Py_memory_order_acquire = __ATOMIC_ACQUIRE,
|
|
||||||
_Py_memory_order_release = __ATOMIC_RELEASE,
|
|
||||||
_Py_memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
|
||||||
_Py_memory_order_seq_cst = __ATOMIC_SEQ_CST
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
|
|
||||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
|
|
||||||
__atomic_signal_fence(ORDER)
|
|
||||||
|
|
||||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
|
|
||||||
__atomic_thread_fence(ORDER)
|
|
||||||
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
(assert((ORDER) == __ATOMIC_RELAXED \
|
|
||||||
|| (ORDER) == __ATOMIC_SEQ_CST \
|
|
||||||
|| (ORDER) == __ATOMIC_RELEASE), \
|
|
||||||
__atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER))
|
|
||||||
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
(assert((ORDER) == __ATOMIC_RELAXED \
|
|
||||||
|| (ORDER) == __ATOMIC_SEQ_CST \
|
|
||||||
|| (ORDER) == __ATOMIC_ACQUIRE \
|
|
||||||
|| (ORDER) == __ATOMIC_CONSUME), \
|
|
||||||
__atomic_load_n(&((ATOMIC_VAL)->_value), ORDER))
|
|
||||||
|
|
||||||
/* Only support GCC (for expression statements) and x86 (for simple
|
|
||||||
* atomic semantics) and MSVC x86/x64/ARM */
|
|
||||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64))
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed,
|
|
||||||
_Py_memory_order_acquire,
|
|
||||||
_Py_memory_order_release,
|
|
||||||
_Py_memory_order_acq_rel,
|
|
||||||
_Py_memory_order_seq_cst
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
|
|
||||||
|
|
||||||
static __inline__ void
|
|
||||||
_Py_atomic_signal_fence(_Py_memory_order order)
|
|
||||||
{
|
|
||||||
if (order != _Py_memory_order_relaxed)
|
|
||||||
__asm__ volatile("":::"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ void
|
|
||||||
_Py_atomic_thread_fence(_Py_memory_order order)
|
|
||||||
{
|
|
||||||
if (order != _Py_memory_order_relaxed)
|
|
||||||
__asm__ volatile("mfence":::"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tell the race checker about this operation's effects. */
|
|
||||||
static __inline__ void
|
|
||||||
_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order)
|
|
||||||
{
|
|
||||||
(void)address; /* shut up -Wunused-parameter */
|
|
||||||
switch(order) {
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
case _Py_memory_order_acq_rel:
|
|
||||||
case _Py_memory_order_seq_cst:
|
|
||||||
_Py_ANNOTATE_HAPPENS_BEFORE(address);
|
|
||||||
break;
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch(order) {
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
case _Py_memory_order_acq_rel:
|
|
||||||
case _Py_memory_order_seq_cst:
|
|
||||||
_Py_ANNOTATE_HAPPENS_AFTER(address);
|
|
||||||
break;
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
__extension__ ({ \
|
|
||||||
__typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
|
|
||||||
__typeof__(atomic_val->_value) new_val = NEW_VAL;\
|
|
||||||
volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \
|
|
||||||
_Py_memory_order order = ORDER; \
|
|
||||||
_Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
|
|
||||||
\
|
|
||||||
/* Perform the operation. */ \
|
|
||||||
_Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \
|
|
||||||
switch(order) { \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
_Py_atomic_signal_fence(_Py_memory_order_release); \
|
|
||||||
/* fallthrough */ \
|
|
||||||
case _Py_memory_order_relaxed: \
|
|
||||||
*volatile_data = new_val; \
|
|
||||||
break; \
|
|
||||||
\
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
case _Py_memory_order_acq_rel: \
|
|
||||||
case _Py_memory_order_seq_cst: \
|
|
||||||
__asm__ volatile("xchg %0, %1" \
|
|
||||||
: "+r"(new_val) \
|
|
||||||
: "m"(atomic_val->_value) \
|
|
||||||
: "memory"); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
_Py_ANNOTATE_IGNORE_WRITES_END(); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
__extension__ ({ \
|
|
||||||
__typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
|
|
||||||
__typeof__(atomic_val->_value) result; \
|
|
||||||
volatile __typeof__(result) *volatile_data = &atomic_val->_value; \
|
|
||||||
_Py_memory_order order = ORDER; \
|
|
||||||
_Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
|
|
||||||
\
|
|
||||||
/* Perform the operation. */ \
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_BEGIN(); \
|
|
||||||
switch(order) { \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
case _Py_memory_order_acq_rel: \
|
|
||||||
case _Py_memory_order_seq_cst: \
|
|
||||||
/* Loads on x86 are not releases by default, so need a */ \
|
|
||||||
/* thread fence. */ \
|
|
||||||
_Py_atomic_thread_fence(_Py_memory_order_release); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
/* No fence */ \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
result = *volatile_data; \
|
|
||||||
switch(order) { \
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
case _Py_memory_order_acq_rel: \
|
|
||||||
case _Py_memory_order_seq_cst: \
|
|
||||||
/* Loads on x86 are automatically acquire operations so */ \
|
|
||||||
/* can get by with just a compiler fence. */ \
|
|
||||||
_Py_atomic_signal_fence(_Py_memory_order_acquire); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
/* No fence */ \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
_Py_ANNOTATE_IGNORE_READS_END(); \
|
|
||||||
result; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
/* _Interlocked* functions provide a full memory barrier and are therefore
|
|
||||||
enough for acq_rel and seq_cst. If the HLE variants aren't available
|
|
||||||
in hardware they will fall back to a full memory barrier as well.
|
|
||||||
|
|
||||||
This might affect performance but likely only in some very specific and
|
|
||||||
hard to measure scenario.
|
|
||||||
*/
|
|
||||||
#if defined(_M_IX86) || defined(_M_X64)
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed,
|
|
||||||
_Py_memory_order_acquire,
|
|
||||||
_Py_memory_order_release,
|
|
||||||
_Py_memory_order_acq_rel,
|
|
||||||
_Py_memory_order_seq_cst
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
volatile uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
volatile int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_M_X64)
|
|
||||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
switch (ORDER) { \
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
_InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
_InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
_InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
switch (ORDER) { \
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
_InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
_InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
_InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_M_X64)
|
|
||||||
/* This has to be an intptr_t for now.
|
|
||||||
gil_created() uses -1 as a sentinel value, if this returns
|
|
||||||
a uintptr_t it will do an unsigned compare and crash
|
|
||||||
*/
|
|
||||||
inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
|
|
||||||
__int64 old;
|
|
||||||
switch (order) {
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
old = *value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
|
|
||||||
_Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
|
|
||||||
long old;
|
|
||||||
switch (order) {
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
old = *value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange((volatile long*)value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
|
|
||||||
_Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
|
|
||||||
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
if (sizeof((ATOMIC_VAL)->_value) == 8) { \
|
|
||||||
_Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \
|
|
||||||
_Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) }
|
|
||||||
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
( \
|
|
||||||
sizeof((ATOMIC_VAL)->_value) == 8 ? \
|
|
||||||
_Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \
|
|
||||||
_Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \
|
|
||||||
)
|
|
||||||
#elif defined(_M_ARM) || defined(_M_ARM64)
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed,
|
|
||||||
_Py_memory_order_acquire,
|
|
||||||
_Py_memory_order_release,
|
|
||||||
_Py_memory_order_acq_rel,
|
|
||||||
_Py_memory_order_seq_cst
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
volatile uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
volatile int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_M_ARM64)
|
|
||||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
switch (ORDER) { \
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
_InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
_InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
_InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
switch (ORDER) { \
|
|
||||||
case _Py_memory_order_acquire: \
|
|
||||||
_InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
case _Py_memory_order_release: \
|
|
||||||
_InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
_InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_M_ARM64)
|
|
||||||
/* This has to be an intptr_t for now.
|
|
||||||
gil_created() uses -1 as a sentinel value, if this returns
|
|
||||||
a uintptr_t it will do an unsigned compare and crash
|
|
||||||
*/
|
|
||||||
inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
|
|
||||||
uintptr_t old;
|
|
||||||
switch (order) {
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64_acq(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64_rel(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
old = *value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange64(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
|
|
||||||
_Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
|
|
||||||
int old;
|
|
||||||
switch (order) {
|
|
||||||
case _Py_memory_order_acquire:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange_acq(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_release:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange_rel(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case _Py_memory_order_relaxed:
|
|
||||||
old = *value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
old = *value;
|
|
||||||
} while(_InterlockedCompareExchange(value, old, old) != old);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
|
|
||||||
_Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
|
|
||||||
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
if (sizeof((ATOMIC_VAL)->_value) == 8) { \
|
|
||||||
_Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \
|
|
||||||
_Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) }
|
|
||||||
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
( \
|
|
||||||
sizeof((ATOMIC_VAL)->_value) == 8 ? \
|
|
||||||
_Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \
|
|
||||||
_Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \
|
|
||||||
)
|
|
||||||
#endif
|
|
||||||
#else /* !gcc x86 !_msc_ver */
|
|
||||||
typedef enum _Py_memory_order {
|
|
||||||
_Py_memory_order_relaxed,
|
|
||||||
_Py_memory_order_acquire,
|
|
||||||
_Py_memory_order_release,
|
|
||||||
_Py_memory_order_acq_rel,
|
|
||||||
_Py_memory_order_seq_cst
|
|
||||||
} _Py_memory_order;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_address {
|
|
||||||
uintptr_t _value;
|
|
||||||
} _Py_atomic_address;
|
|
||||||
|
|
||||||
typedef struct _Py_atomic_int {
|
|
||||||
int _value;
|
|
||||||
} _Py_atomic_int;
|
|
||||||
/* Fall back to other compilers and processors by assuming that simple
|
|
||||||
volatile accesses are atomic. This is false, so people should port
|
|
||||||
this. */
|
|
||||||
#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0)
|
|
||||||
#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0)
|
|
||||||
#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
|
|
||||||
((ATOMIC_VAL)->_value = NEW_VAL)
|
|
||||||
#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
|
|
||||||
((ATOMIC_VAL)->_value)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Standardized shortcuts. */
|
|
||||||
#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \
|
|
||||||
_Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst)
|
|
||||||
#define _Py_atomic_load(ATOMIC_VAL) \
|
|
||||||
_Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst)
|
|
||||||
|
|
||||||
/* Python-local extensions */
|
|
||||||
|
|
||||||
#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \
|
|
||||||
_Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed)
|
|
||||||
#define _Py_atomic_load_relaxed(ATOMIC_VAL) \
|
|
||||||
_Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* Py_ATOMIC_H */
|
|
|
@ -1,94 +0,0 @@
|
||||||
/* Atomic functions: similar to pycore_atomic.h, but don't need
|
|
||||||
to declare variables as atomic.
|
|
||||||
|
|
||||||
Py_ssize_t type:
|
|
||||||
|
|
||||||
* value = _Py_atomic_size_get(&var)
|
|
||||||
* _Py_atomic_size_set(&var, value)
|
|
||||||
|
|
||||||
Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order):
|
|
||||||
enforce total ordering with all other atomic functions.
|
|
||||||
*/
|
|
||||||
#ifndef Py_ATOMIC_FUNC_H
|
|
||||||
#define Py_ATOMIC_FUNC_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# include <intrin.h> // _InterlockedExchange()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Use builtin atomic operations in GCC >= 4.7 and clang
|
|
||||||
#ifdef HAVE_BUILTIN_ATOMIC
|
|
||||||
|
|
||||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
|
||||||
{
|
|
||||||
return __atomic_load_n(var, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
|
||||||
{
|
|
||||||
__atomic_store_n(var, value, __ATOMIC_SEQ_CST);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
|
|
||||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
|
||||||
{
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
|
|
||||||
volatile __int64 *volatile_var = (volatile __int64 *)var;
|
|
||||||
__int64 old;
|
|
||||||
do {
|
|
||||||
old = *volatile_var;
|
|
||||||
} while(_InterlockedCompareExchange64(volatile_var, old, old) != old);
|
|
||||||
#else
|
|
||||||
Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
|
|
||||||
volatile long *volatile_var = (volatile long *)var;
|
|
||||||
long old;
|
|
||||||
do {
|
|
||||||
old = *volatile_var;
|
|
||||||
} while(_InterlockedCompareExchange(volatile_var, old, old) != old);
|
|
||||||
#endif
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
|
||||||
{
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
|
|
||||||
volatile __int64 *volatile_var = (volatile __int64 *)var;
|
|
||||||
_InterlockedExchange64(volatile_var, value);
|
|
||||||
#else
|
|
||||||
Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
|
|
||||||
volatile long *volatile_var = (volatile long *)var;
|
|
||||||
_InterlockedExchange(volatile_var, value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// Fallback implementation using volatile
|
|
||||||
|
|
||||||
static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
|
|
||||||
{
|
|
||||||
volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
|
|
||||||
return *volatile_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
|
|
||||||
{
|
|
||||||
volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
|
|
||||||
*volatile_var = value;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* Py_ATOMIC_FUNC_H */
|
|
|
@ -1,186 +0,0 @@
|
||||||
/* Bit and bytes utilities.
|
|
||||||
|
|
||||||
Bytes swap functions, reverse order of bytes:
|
|
||||||
|
|
||||||
- _Py_bswap16(uint16_t)
|
|
||||||
- _Py_bswap32(uint32_t)
|
|
||||||
- _Py_bswap64(uint64_t)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Py_INTERNAL_BITUTILS_H
|
|
||||||
#define Py_INTERNAL_BITUTILS_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__) \
|
|
||||||
&& ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))
|
|
||||||
/* __builtin_bswap16() is available since GCC 4.8,
|
|
||||||
__builtin_bswap32() is available since GCC 4.3,
|
|
||||||
__builtin_bswap64() is available since GCC 4.3. */
|
|
||||||
# define _PY_HAVE_BUILTIN_BSWAP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */
|
|
||||||
# include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
_Py_bswap16(uint16_t word)
|
|
||||||
{
|
|
||||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap16)
|
|
||||||
return __builtin_bswap16(word);
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short));
|
|
||||||
return _byteswap_ushort(word);
|
|
||||||
#else
|
|
||||||
// Portable implementation which doesn't rely on circular bit shift
|
|
||||||
return ( ((word & UINT16_C(0x00FF)) << 8)
|
|
||||||
| ((word & UINT16_C(0xFF00)) >> 8));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
_Py_bswap32(uint32_t word)
|
|
||||||
{
|
|
||||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap32)
|
|
||||||
return __builtin_bswap32(word);
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long));
|
|
||||||
return _byteswap_ulong(word);
|
|
||||||
#else
|
|
||||||
// Portable implementation which doesn't rely on circular bit shift
|
|
||||||
return ( ((word & UINT32_C(0x000000FF)) << 24)
|
|
||||||
| ((word & UINT32_C(0x0000FF00)) << 8)
|
|
||||||
| ((word & UINT32_C(0x00FF0000)) >> 8)
|
|
||||||
| ((word & UINT32_C(0xFF000000)) >> 24));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t
|
|
||||||
_Py_bswap64(uint64_t word)
|
|
||||||
{
|
|
||||||
#if defined(_PY_HAVE_BUILTIN_BSWAP) || _Py__has_builtin(__builtin_bswap64)
|
|
||||||
return __builtin_bswap64(word);
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
return _byteswap_uint64(word);
|
|
||||||
#else
|
|
||||||
// Portable implementation which doesn't rely on circular bit shift
|
|
||||||
return ( ((word & UINT64_C(0x00000000000000FF)) << 56)
|
|
||||||
| ((word & UINT64_C(0x000000000000FF00)) << 40)
|
|
||||||
| ((word & UINT64_C(0x0000000000FF0000)) << 24)
|
|
||||||
| ((word & UINT64_C(0x00000000FF000000)) << 8)
|
|
||||||
| ((word & UINT64_C(0x000000FF00000000)) >> 8)
|
|
||||||
| ((word & UINT64_C(0x0000FF0000000000)) >> 24)
|
|
||||||
| ((word & UINT64_C(0x00FF000000000000)) >> 40)
|
|
||||||
| ((word & UINT64_C(0xFF00000000000000)) >> 56));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Population count: count the number of 1's in 'x'
|
|
||||||
// (number of bits set to 1), also known as the hamming weight.
|
|
||||||
//
|
|
||||||
// Implementation note. CPUID is not used, to test if x86 POPCNT instruction
|
|
||||||
// can be used, to keep the implementation simple. For example, Visual Studio
|
|
||||||
// __popcnt() is not used this reason. The clang and GCC builtin function can
|
|
||||||
// use the x86 POPCNT instruction if the target architecture has SSE4a or
|
|
||||||
// newer.
|
|
||||||
static inline int
|
|
||||||
_Py_popcount32(uint32_t x)
|
|
||||||
{
|
|
||||||
#if (defined(__clang__) || defined(__GNUC__))
|
|
||||||
|
|
||||||
#if SIZEOF_INT >= 4
|
|
||||||
Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned int));
|
|
||||||
return __builtin_popcount(x);
|
|
||||||
#else
|
|
||||||
// The C standard guarantees that unsigned long will always be big enough
|
|
||||||
// to hold a uint32_t value without losing information.
|
|
||||||
Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned long));
|
|
||||||
return __builtin_popcountl(x);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
// 32-bit SWAR (SIMD Within A Register) popcount
|
|
||||||
|
|
||||||
// Binary: 0 1 0 1 ...
|
|
||||||
const uint32_t M1 = 0x55555555;
|
|
||||||
// Binary: 00 11 00 11. ..
|
|
||||||
const uint32_t M2 = 0x33333333;
|
|
||||||
// Binary: 0000 1111 0000 1111 ...
|
|
||||||
const uint32_t M4 = 0x0F0F0F0F;
|
|
||||||
|
|
||||||
// Put count of each 2 bits into those 2 bits
|
|
||||||
x = x - ((x >> 1) & M1);
|
|
||||||
// Put count of each 4 bits into those 4 bits
|
|
||||||
x = (x & M2) + ((x >> 2) & M2);
|
|
||||||
// Put count of each 8 bits into those 8 bits
|
|
||||||
x = (x + (x >> 4)) & M4;
|
|
||||||
// Sum of the 4 byte counts.
|
|
||||||
// Take care when considering changes to the next line. Portability and
|
|
||||||
// correctness are delicate here, thanks to C's "integer promotions" (C99
|
|
||||||
// §6.3.1.1p2). On machines where the `int` type has width greater than 32
|
|
||||||
// bits, `x` will be promoted to an `int`, and following C's "usual
|
|
||||||
// arithmetic conversions" (C99 §6.3.1.8), the multiplication will be
|
|
||||||
// performed as a multiplication of two `unsigned int` operands. In this
|
|
||||||
// case it's critical that we cast back to `uint32_t` in order to keep only
|
|
||||||
// the least significant 32 bits. On machines where the `int` type has
|
|
||||||
// width no greater than 32, the multiplication is of two 32-bit unsigned
|
|
||||||
// integer types, and the (uint32_t) cast is a no-op. In both cases, we
|
|
||||||
// avoid the risk of undefined behaviour due to overflow of a
|
|
||||||
// multiplication of signed integer types.
|
|
||||||
return (uint32_t)(x * 0x01010101U) >> 24;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return the index of the most significant 1 bit in 'x'. This is the smallest
|
|
||||||
// integer k such that x < 2**k. Equivalent to floor(log2(x)) + 1 for x != 0.
|
|
||||||
static inline int
|
|
||||||
_Py_bit_length(unsigned long x)
|
|
||||||
{
|
|
||||||
#if (defined(__clang__) || defined(__GNUC__))
|
|
||||||
if (x != 0) {
|
|
||||||
// __builtin_clzl() is available since GCC 3.4.
|
|
||||||
// Undefined behavior for x == 0.
|
|
||||||
return (int)sizeof(unsigned long) * 8 - __builtin_clzl(x);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
// _BitScanReverse() is documented to search 32 bits.
|
|
||||||
Py_BUILD_ASSERT(sizeof(unsigned long) <= 4);
|
|
||||||
unsigned long msb;
|
|
||||||
if (_BitScanReverse(&msb, x)) {
|
|
||||||
return (int)msb + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const int BIT_LENGTH_TABLE[32] = {
|
|
||||||
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
||||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
|
||||||
};
|
|
||||||
int msb = 0;
|
|
||||||
while (x >= 32) {
|
|
||||||
msb += 6;
|
|
||||||
x >>= 6;
|
|
||||||
}
|
|
||||||
msb += BIT_LENGTH_TABLE[x];
|
|
||||||
return msb;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_BITUTILS_H */
|
|
|
@ -1,317 +0,0 @@
|
||||||
/*
|
|
||||||
_BlocksOutputBuffer is used to maintain an output buffer
|
|
||||||
that has unpredictable size. Suitable for compression/decompression
|
|
||||||
API (bz2/lzma/zlib) that has stream->next_out and stream->avail_out:
|
|
||||||
|
|
||||||
stream->next_out: point to the next output position.
|
|
||||||
stream->avail_out: the number of available bytes left in the buffer.
|
|
||||||
|
|
||||||
It maintains a list of bytes object, so there is no overhead of resizing
|
|
||||||
the buffer.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
1, Initialize the struct instance like this:
|
|
||||||
_BlocksOutputBuffer buffer = {.list = NULL};
|
|
||||||
Set .list to NULL for _BlocksOutputBuffer_OnError()
|
|
||||||
|
|
||||||
2, Initialize the buffer use one of these functions:
|
|
||||||
_BlocksOutputBuffer_InitAndGrow()
|
|
||||||
_BlocksOutputBuffer_InitWithSize()
|
|
||||||
|
|
||||||
3, If (avail_out == 0), grow the buffer:
|
|
||||||
_BlocksOutputBuffer_Grow()
|
|
||||||
|
|
||||||
4, Get the current outputted data size:
|
|
||||||
_BlocksOutputBuffer_GetDataSize()
|
|
||||||
|
|
||||||
5, Finish the buffer, and return a bytes object:
|
|
||||||
_BlocksOutputBuffer_Finish()
|
|
||||||
|
|
||||||
6, Clean up the buffer when an error occurred:
|
|
||||||
_BlocksOutputBuffer_OnError()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H
|
|
||||||
#define Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Python.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
// List of bytes objects
|
|
||||||
PyObject *list;
|
|
||||||
// Number of whole allocated size
|
|
||||||
Py_ssize_t allocated;
|
|
||||||
// Max length of the buffer, negative number means unlimited length.
|
|
||||||
Py_ssize_t max_length;
|
|
||||||
} _BlocksOutputBuffer;
|
|
||||||
|
|
||||||
static const char unable_allocate_msg[] = "Unable to allocate output buffer.";
|
|
||||||
|
|
||||||
/* In 32-bit build, the max block size should <= INT32_MAX. */
|
|
||||||
#define OUTPUT_BUFFER_MAX_BLOCK_SIZE (256*1024*1024)
|
|
||||||
|
|
||||||
/* Block size sequence */
|
|
||||||
#define KB (1024)
|
|
||||||
#define MB (1024*1024)
|
|
||||||
static const Py_ssize_t BUFFER_BLOCK_SIZE[] =
|
|
||||||
{ 32*KB, 64*KB, 256*KB, 1*MB, 4*MB, 8*MB, 16*MB, 16*MB,
|
|
||||||
32*MB, 32*MB, 32*MB, 32*MB, 64*MB, 64*MB, 128*MB, 128*MB,
|
|
||||||
OUTPUT_BUFFER_MAX_BLOCK_SIZE };
|
|
||||||
#undef KB
|
|
||||||
#undef MB
|
|
||||||
|
|
||||||
/* According to the block sizes defined by BUFFER_BLOCK_SIZE, the whole
|
|
||||||
allocated size growth step is:
|
|
||||||
1 32 KB +32 KB
|
|
||||||
2 96 KB +64 KB
|
|
||||||
3 352 KB +256 KB
|
|
||||||
4 1.34 MB +1 MB
|
|
||||||
5 5.34 MB +4 MB
|
|
||||||
6 13.34 MB +8 MB
|
|
||||||
7 29.34 MB +16 MB
|
|
||||||
8 45.34 MB +16 MB
|
|
||||||
9 77.34 MB +32 MB
|
|
||||||
10 109.34 MB +32 MB
|
|
||||||
11 141.34 MB +32 MB
|
|
||||||
12 173.34 MB +32 MB
|
|
||||||
13 237.34 MB +64 MB
|
|
||||||
14 301.34 MB +64 MB
|
|
||||||
15 429.34 MB +128 MB
|
|
||||||
16 557.34 MB +128 MB
|
|
||||||
17 813.34 MB +256 MB
|
|
||||||
18 1069.34 MB +256 MB
|
|
||||||
19 1325.34 MB +256 MB
|
|
||||||
20 1581.34 MB +256 MB
|
|
||||||
21 1837.34 MB +256 MB
|
|
||||||
22 2093.34 MB +256 MB
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Initialize the buffer, and grow the buffer.
|
|
||||||
|
|
||||||
max_length: Max length of the buffer, -1 for unlimited length.
|
|
||||||
|
|
||||||
On success, return allocated size (>=0)
|
|
||||||
On failure, return -1
|
|
||||||
*/
|
|
||||||
static inline Py_ssize_t
|
|
||||||
_BlocksOutputBuffer_InitAndGrow(_BlocksOutputBuffer *buffer,
|
|
||||||
const Py_ssize_t max_length,
|
|
||||||
void **next_out)
|
|
||||||
{
|
|
||||||
PyObject *b;
|
|
||||||
Py_ssize_t block_size;
|
|
||||||
|
|
||||||
// ensure .list was set to NULL
|
|
||||||
assert(buffer->list == NULL);
|
|
||||||
|
|
||||||
// get block size
|
|
||||||
if (0 <= max_length && max_length < BUFFER_BLOCK_SIZE[0]) {
|
|
||||||
block_size = max_length;
|
|
||||||
} else {
|
|
||||||
block_size = BUFFER_BLOCK_SIZE[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// the first block
|
|
||||||
b = PyBytes_FromStringAndSize(NULL, block_size);
|
|
||||||
if (b == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the list
|
|
||||||
buffer->list = PyList_New(1);
|
|
||||||
if (buffer->list == NULL) {
|
|
||||||
Py_DECREF(b);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
PyList_SET_ITEM(buffer->list, 0, b);
|
|
||||||
|
|
||||||
// set variables
|
|
||||||
buffer->allocated = block_size;
|
|
||||||
buffer->max_length = max_length;
|
|
||||||
|
|
||||||
*next_out = PyBytes_AS_STRING(b);
|
|
||||||
return block_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the buffer, with an initial size.
|
|
||||||
|
|
||||||
Check block size limit in the outer wrapper function. For example, some libs
|
|
||||||
accept UINT32_MAX as the maximum block size, then init_size should <= it.
|
|
||||||
|
|
||||||
On success, return allocated size (>=0)
|
|
||||||
On failure, return -1
|
|
||||||
*/
|
|
||||||
static inline Py_ssize_t
|
|
||||||
_BlocksOutputBuffer_InitWithSize(_BlocksOutputBuffer *buffer,
|
|
||||||
const Py_ssize_t init_size,
|
|
||||||
void **next_out)
|
|
||||||
{
|
|
||||||
PyObject *b;
|
|
||||||
|
|
||||||
// ensure .list was set to NULL
|
|
||||||
assert(buffer->list == NULL);
|
|
||||||
|
|
||||||
// the first block
|
|
||||||
b = PyBytes_FromStringAndSize(NULL, init_size);
|
|
||||||
if (b == NULL) {
|
|
||||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the list
|
|
||||||
buffer->list = PyList_New(1);
|
|
||||||
if (buffer->list == NULL) {
|
|
||||||
Py_DECREF(b);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
PyList_SET_ITEM(buffer->list, 0, b);
|
|
||||||
|
|
||||||
// set variables
|
|
||||||
buffer->allocated = init_size;
|
|
||||||
buffer->max_length = -1;
|
|
||||||
|
|
||||||
*next_out = PyBytes_AS_STRING(b);
|
|
||||||
return init_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grow the buffer. The avail_out must be 0, please check it before calling.
|
|
||||||
|
|
||||||
On success, return allocated size (>=0)
|
|
||||||
On failure, return -1
|
|
||||||
*/
|
|
||||||
static inline Py_ssize_t
|
|
||||||
_BlocksOutputBuffer_Grow(_BlocksOutputBuffer *buffer,
|
|
||||||
void **next_out,
|
|
||||||
const Py_ssize_t avail_out)
|
|
||||||
{
|
|
||||||
PyObject *b;
|
|
||||||
const Py_ssize_t list_len = Py_SIZE(buffer->list);
|
|
||||||
Py_ssize_t block_size;
|
|
||||||
|
|
||||||
// ensure no gaps in the data
|
|
||||||
if (avail_out != 0) {
|
|
||||||
PyErr_SetString(PyExc_SystemError,
|
|
||||||
"avail_out is non-zero in _BlocksOutputBuffer_Grow().");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get block size
|
|
||||||
if (list_len < (Py_ssize_t) Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE)) {
|
|
||||||
block_size = BUFFER_BLOCK_SIZE[list_len];
|
|
||||||
} else {
|
|
||||||
block_size = BUFFER_BLOCK_SIZE[Py_ARRAY_LENGTH(BUFFER_BLOCK_SIZE) - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// check max_length
|
|
||||||
if (buffer->max_length >= 0) {
|
|
||||||
// if (rest == 0), should not grow the buffer.
|
|
||||||
Py_ssize_t rest = buffer->max_length - buffer->allocated;
|
|
||||||
assert(rest > 0);
|
|
||||||
|
|
||||||
// block_size of the last block
|
|
||||||
if (block_size > rest) {
|
|
||||||
block_size = rest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check buffer->allocated overflow
|
|
||||||
if (block_size > PY_SSIZE_T_MAX - buffer->allocated) {
|
|
||||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the block
|
|
||||||
b = PyBytes_FromStringAndSize(NULL, block_size);
|
|
||||||
if (b == NULL) {
|
|
||||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (PyList_Append(buffer->list, b) < 0) {
|
|
||||||
Py_DECREF(b);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
Py_DECREF(b);
|
|
||||||
|
|
||||||
// set variables
|
|
||||||
buffer->allocated += block_size;
|
|
||||||
|
|
||||||
*next_out = PyBytes_AS_STRING(b);
|
|
||||||
return block_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the current outputted data size. */
|
|
||||||
static inline Py_ssize_t
|
|
||||||
_BlocksOutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer,
|
|
||||||
const Py_ssize_t avail_out)
|
|
||||||
{
|
|
||||||
return buffer->allocated - avail_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finish the buffer.
|
|
||||||
|
|
||||||
Return a bytes object on success
|
|
||||||
Return NULL on failure
|
|
||||||
*/
|
|
||||||
static inline PyObject *
|
|
||||||
_BlocksOutputBuffer_Finish(_BlocksOutputBuffer *buffer,
|
|
||||||
const Py_ssize_t avail_out)
|
|
||||||
{
|
|
||||||
PyObject *result, *block;
|
|
||||||
const Py_ssize_t list_len = Py_SIZE(buffer->list);
|
|
||||||
|
|
||||||
// fast path for single block
|
|
||||||
if ((list_len == 1 && avail_out == 0) ||
|
|
||||||
(list_len == 2 && Py_SIZE(PyList_GET_ITEM(buffer->list, 1)) == avail_out))
|
|
||||||
{
|
|
||||||
block = PyList_GET_ITEM(buffer->list, 0);
|
|
||||||
Py_INCREF(block);
|
|
||||||
|
|
||||||
Py_CLEAR(buffer->list);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
// final bytes object
|
|
||||||
result = PyBytes_FromStringAndSize(NULL, buffer->allocated - avail_out);
|
|
||||||
if (result == NULL) {
|
|
||||||
PyErr_SetString(PyExc_MemoryError, unable_allocate_msg);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// memory copy
|
|
||||||
if (list_len > 0) {
|
|
||||||
char *posi = PyBytes_AS_STRING(result);
|
|
||||||
|
|
||||||
// blocks except the last one
|
|
||||||
Py_ssize_t i = 0;
|
|
||||||
for (; i < list_len-1; i++) {
|
|
||||||
block = PyList_GET_ITEM(buffer->list, i);
|
|
||||||
memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block));
|
|
||||||
posi += Py_SIZE(block);
|
|
||||||
}
|
|
||||||
// the last block
|
|
||||||
block = PyList_GET_ITEM(buffer->list, i);
|
|
||||||
memcpy(posi, PyBytes_AS_STRING(block), Py_SIZE(block) - avail_out);
|
|
||||||
} else {
|
|
||||||
assert(Py_SIZE(result) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_CLEAR(buffer->list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean up the buffer when an error occurred. */
|
|
||||||
static inline void
|
|
||||||
_BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer)
|
|
||||||
{
|
|
||||||
Py_CLEAR(buffer->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */
|
|
|
@ -1,73 +0,0 @@
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
#ifndef Py_BYTES_CTYPE_H
|
|
||||||
#define Py_BYTES_CTYPE_H
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The internal implementation behind PyBytes (bytes) and PyByteArray (bytearray)
|
|
||||||
* methods of the given names, they operate on ASCII byte strings.
|
|
||||||
*/
|
|
||||||
extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_isascii(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len);
|
|
||||||
extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len);
|
|
||||||
|
|
||||||
/* These store their len sized answer in the given preallocated *result arg. */
|
|
||||||
extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len);
|
|
||||||
extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len);
|
|
||||||
extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len);
|
|
||||||
extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len);
|
|
||||||
extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len);
|
|
||||||
|
|
||||||
extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg);
|
|
||||||
extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args);
|
|
||||||
|
|
||||||
/* The maketrans() static method. */
|
|
||||||
extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to);
|
|
||||||
|
|
||||||
/* Shared __doc__ strings. */
|
|
||||||
extern const char _Py_isspace__doc__[];
|
|
||||||
extern const char _Py_isalpha__doc__[];
|
|
||||||
extern const char _Py_isalnum__doc__[];
|
|
||||||
extern const char _Py_isascii__doc__[];
|
|
||||||
extern const char _Py_isdigit__doc__[];
|
|
||||||
extern const char _Py_islower__doc__[];
|
|
||||||
extern const char _Py_isupper__doc__[];
|
|
||||||
extern const char _Py_istitle__doc__[];
|
|
||||||
extern const char _Py_lower__doc__[];
|
|
||||||
extern const char _Py_upper__doc__[];
|
|
||||||
extern const char _Py_title__doc__[];
|
|
||||||
extern const char _Py_capitalize__doc__[];
|
|
||||||
extern const char _Py_swapcase__doc__[];
|
|
||||||
extern const char _Py_count__doc__[];
|
|
||||||
extern const char _Py_find__doc__[];
|
|
||||||
extern const char _Py_index__doc__[];
|
|
||||||
extern const char _Py_rfind__doc__[];
|
|
||||||
extern const char _Py_rindex__doc__[];
|
|
||||||
extern const char _Py_startswith__doc__[];
|
|
||||||
extern const char _Py_endswith__doc__[];
|
|
||||||
extern const char _Py_maketrans__doc__[];
|
|
||||||
extern const char _Py_expandtabs__doc__[];
|
|
||||||
extern const char _Py_ljust__doc__[];
|
|
||||||
extern const char _Py_rjust__doc__[];
|
|
||||||
extern const char _Py_center__doc__[];
|
|
||||||
extern const char _Py_zfill__doc__[];
|
|
||||||
|
|
||||||
/* this is needed because some docs are shared from the .o, not static */
|
|
||||||
#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str)
|
|
||||||
|
|
||||||
#endif /* !Py_BYTES_CTYPE_H */
|
|
||||||
#endif /* !Py_LIMITED_API */
|
|
|
@ -1,52 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_BYTESOBJECT_H
|
|
||||||
#define Py_INTERNAL_BYTESOBJECT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* runtime lifecycle */
|
|
||||||
|
|
||||||
extern PyStatus _PyBytes_InitTypes(PyInterpreterState *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Substring Search.
|
|
||||||
|
|
||||||
Returns the index of the first occurrence of
|
|
||||||
a substring ("needle") in a larger text ("haystack").
|
|
||||||
If the needle is not found, return -1.
|
|
||||||
If the needle is found, add offset to the index.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PyAPI_FUNC(Py_ssize_t)
|
|
||||||
_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack,
|
|
||||||
const char *needle, Py_ssize_t len_needle,
|
|
||||||
Py_ssize_t offset);
|
|
||||||
|
|
||||||
/* Same as above, but search right-to-left */
|
|
||||||
PyAPI_FUNC(Py_ssize_t)
|
|
||||||
_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack,
|
|
||||||
const char *needle, Py_ssize_t len_needle,
|
|
||||||
Py_ssize_t offset);
|
|
||||||
|
|
||||||
|
|
||||||
/** Helper function to implement the repeat and inplace repeat methods on a buffer
|
|
||||||
*
|
|
||||||
* len_dest is assumed to be an integer multiple of len_src.
|
|
||||||
* If src equals dest, then assume the operation is inplace.
|
|
||||||
*
|
|
||||||
* This method repeately doubles the number of bytes copied to reduce
|
|
||||||
* the number of invocations of memcpy.
|
|
||||||
*/
|
|
||||||
PyAPI_FUNC(void)
|
|
||||||
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
|
|
||||||
const char* src, Py_ssize_t len_src);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_BYTESOBJECT_H */
|
|
|
@ -1,121 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_CALL_H
|
|
||||||
#define Py_INTERNAL_CALL_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *obj,
|
|
||||||
PyObject *args,
|
|
||||||
PyObject *kwargs);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *const *args,
|
|
||||||
size_t nargsf,
|
|
||||||
PyObject *kwargs);
|
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_Call(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *callable,
|
|
||||||
PyObject *args,
|
|
||||||
PyObject *kwargs);
|
|
||||||
|
|
||||||
extern PyObject * _PyObject_CallMethodFormat(
|
|
||||||
PyThreadState *tstate, PyObject *callable, const char *format, ...);
|
|
||||||
|
|
||||||
|
|
||||||
// Static inline variant of public PyVectorcall_Function().
|
|
||||||
static inline vectorcallfunc
|
|
||||||
_PyVectorcall_FunctionInline(PyObject *callable)
|
|
||||||
{
|
|
||||||
assert(callable != NULL);
|
|
||||||
|
|
||||||
PyTypeObject *tp = Py_TYPE(callable);
|
|
||||||
if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
assert(PyCallable_Check(callable));
|
|
||||||
|
|
||||||
Py_ssize_t offset = tp->tp_vectorcall_offset;
|
|
||||||
assert(offset > 0);
|
|
||||||
|
|
||||||
vectorcallfunc ptr;
|
|
||||||
memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Call the callable object 'callable' with the "vectorcall" calling
|
|
||||||
convention.
|
|
||||||
|
|
||||||
args is a C array for positional arguments.
|
|
||||||
|
|
||||||
nargsf is the number of positional arguments plus optionally the flag
|
|
||||||
PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to
|
|
||||||
modify args[-1].
|
|
||||||
|
|
||||||
kwnames is a tuple of keyword names. The values of the keyword arguments
|
|
||||||
are stored in "args" after the positional arguments (note that the number
|
|
||||||
of keyword arguments does not change nargsf). kwnames can also be NULL if
|
|
||||||
there are no keyword arguments.
|
|
||||||
|
|
||||||
keywords must only contain strings and all keys must be unique.
|
|
||||||
|
|
||||||
Return the result on success. Raise an exception and return NULL on
|
|
||||||
error. */
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
|
|
||||||
PyObject *const *args, size_t nargsf,
|
|
||||||
PyObject *kwnames)
|
|
||||||
{
|
|
||||||
vectorcallfunc func;
|
|
||||||
PyObject *res;
|
|
||||||
|
|
||||||
assert(kwnames == NULL || PyTuple_Check(kwnames));
|
|
||||||
assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
|
|
||||||
|
|
||||||
func = _PyVectorcall_FunctionInline(callable);
|
|
||||||
if (func == NULL) {
|
|
||||||
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
|
||||||
return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
|
|
||||||
}
|
|
||||||
res = func(callable, args, nargsf, kwnames);
|
|
||||||
return _Py_CheckFunctionResult(tstate, callable, res, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
|
|
||||||
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Private static inline function variant of public PyObject_CallNoArgs()
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_CallNoArgs(PyObject *func) {
|
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
|
||||||
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
|
||||||
{
|
|
||||||
return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_CALL_H */
|
|
|
@ -1,138 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_CEVAL_H
|
|
||||||
#define Py_INTERNAL_CEVAL_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
struct pyruntimestate;
|
|
||||||
struct _ceval_runtime_state;
|
|
||||||
|
|
||||||
/* WASI has limited call stack. Python's recursion limit depends on code
|
|
||||||
layout, optimization, and WASI runtime. Wasmtime can handle about 700-750
|
|
||||||
recursions, sometimes less. 600 is a more conservative limit. */
|
|
||||||
#ifndef Py_DEFAULT_RECURSION_LIMIT
|
|
||||||
# ifdef __wasi__
|
|
||||||
# define Py_DEFAULT_RECURSION_LIMIT 600
|
|
||||||
# else
|
|
||||||
# define Py_DEFAULT_RECURSION_LIMIT 1000
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pycore_interp.h" // PyInterpreterState.eval_frame
|
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
|
||||||
|
|
||||||
|
|
||||||
extern void _Py_FinishPendingCalls(PyThreadState *tstate);
|
|
||||||
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
|
|
||||||
extern void _PyEval_InitState(struct _ceval_state *, PyThread_type_lock);
|
|
||||||
extern void _PyEval_FiniState(struct _ceval_state *ceval);
|
|
||||||
PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp);
|
|
||||||
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
|
||||||
PyInterpreterState *interp,
|
|
||||||
int (*func)(void *),
|
|
||||||
void *arg);
|
|
||||||
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp);
|
|
||||||
#ifdef HAVE_FORK
|
|
||||||
extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Used by sys.call_tracing()
|
|
||||||
extern PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args);
|
|
||||||
|
|
||||||
// Used by sys.get_asyncgen_hooks()
|
|
||||||
extern PyObject* _PyEval_GetAsyncGenFirstiter(void);
|
|
||||||
extern PyObject* _PyEval_GetAsyncGenFinalizer(void);
|
|
||||||
|
|
||||||
// Used by sys.set_asyncgen_hooks()
|
|
||||||
extern int _PyEval_SetAsyncGenFirstiter(PyObject *);
|
|
||||||
extern int _PyEval_SetAsyncGenFinalizer(PyObject *);
|
|
||||||
|
|
||||||
// Used by sys.get_coroutine_origin_tracking_depth()
|
|
||||||
// and sys.set_coroutine_origin_tracking_depth()
|
|
||||||
extern int _PyEval_GetCoroutineOriginTrackingDepth(void);
|
|
||||||
extern int _PyEval_SetCoroutineOriginTrackingDepth(int depth);
|
|
||||||
|
|
||||||
extern void _PyEval_Fini(void);
|
|
||||||
|
|
||||||
|
|
||||||
extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate);
|
|
||||||
extern PyObject* _PyEval_BuiltinsFromGlobals(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
PyObject *globals);
|
|
||||||
|
|
||||||
|
|
||||||
static inline PyObject*
|
|
||||||
_PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag)
|
|
||||||
{
|
|
||||||
if (tstate->interp->eval_frame == NULL) {
|
|
||||||
return _PyEval_EvalFrameDefault(tstate, frame, throwflag);
|
|
||||||
}
|
|
||||||
return tstate->interp->eval_frame(tstate, frame, throwflag);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern PyObject*
|
|
||||||
_PyEval_Vector(PyThreadState *tstate,
|
|
||||||
PyFunctionObject *func, PyObject *locals,
|
|
||||||
PyObject* const* args, size_t argcount,
|
|
||||||
PyObject *kwnames);
|
|
||||||
|
|
||||||
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
|
|
||||||
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
|
|
||||||
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
|
|
||||||
|
|
||||||
extern void _PyEval_ReleaseLock(PyThreadState *tstate);
|
|
||||||
|
|
||||||
extern void _PyEval_DeactivateOpCache(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- _Py_EnterRecursiveCall() ----------------------------------------- */
|
|
||||||
|
|
||||||
#ifdef USE_STACKCHECK
|
|
||||||
/* With USE_STACKCHECK macro defined, trigger stack checks in
|
|
||||||
_Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */
|
|
||||||
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
|
||||||
return (tstate->recursion_remaining-- <= 0
|
|
||||||
|| (tstate->recursion_remaining & 63) == 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
|
||||||
return tstate->recursion_remaining-- <= 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) _Py_CheckRecursiveCall(
|
|
||||||
PyThreadState *tstate,
|
|
||||||
const char *where);
|
|
||||||
|
|
||||||
static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
|
|
||||||
const char *where) {
|
|
||||||
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int _Py_EnterRecursiveCall(const char *where) {
|
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
|
||||||
return _Py_EnterRecursiveCallTstate(tstate, where);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) {
|
|
||||||
tstate->recursion_remaining++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _Py_LeaveRecursiveCall(void) {
|
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
|
||||||
_Py_LeaveRecursiveCallTstate(tstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
|
|
||||||
|
|
||||||
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_CEVAL_H */
|
|
|
@ -1,564 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_CODE_H
|
|
||||||
#define Py_INTERNAL_CODE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PEP 659
|
|
||||||
* Specialization and quickening structs and helper functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Inline caches. If you change the number of cache entries for an instruction,
|
|
||||||
// you must *also* update the number of cache entries in Lib/opcode.py and bump
|
|
||||||
// the magic number in Lib/importlib/_bootstrap_external.py!
|
|
||||||
|
|
||||||
#define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT index;
|
|
||||||
_Py_CODEUNIT module_keys_version[2];
|
|
||||||
_Py_CODEUNIT builtin_keys_version;
|
|
||||||
} _PyLoadGlobalCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
} _PyBinaryOpCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
} _PyUnpackSequenceCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \
|
|
||||||
CACHE_ENTRIES(_PyUnpackSequenceCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT mask;
|
|
||||||
} _PyCompareOpCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT type_version[2];
|
|
||||||
_Py_CODEUNIT func_version;
|
|
||||||
} _PyBinarySubscrCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT version[2];
|
|
||||||
_Py_CODEUNIT index;
|
|
||||||
} _PyAttrCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyAttrCache)
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT type_version[2];
|
|
||||||
_Py_CODEUNIT dict_offset;
|
|
||||||
_Py_CODEUNIT keys_version[2];
|
|
||||||
_Py_CODEUNIT descr[4];
|
|
||||||
} _PyLoadMethodCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
_Py_CODEUNIT func_version[2];
|
|
||||||
_Py_CODEUNIT min_args;
|
|
||||||
} _PyCallCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
} _PyPrecallCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_PRECALL CACHE_ENTRIES(_PyPrecallCache)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Py_CODEUNIT counter;
|
|
||||||
} _PyStoreSubscrCache;
|
|
||||||
|
|
||||||
#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache)
|
|
||||||
|
|
||||||
#define QUICKENING_WARMUP_DELAY 8
|
|
||||||
|
|
||||||
/* We want to compare to zero for efficiency, so we offset values accordingly */
|
|
||||||
#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY)
|
|
||||||
|
|
||||||
void _PyCode_Quicken(PyCodeObject *code);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
_PyCode_Warmup(PyCodeObject *code)
|
|
||||||
{
|
|
||||||
if (code->co_warmup != 0) {
|
|
||||||
code->co_warmup++;
|
|
||||||
if (code->co_warmup == 0) {
|
|
||||||
_PyCode_Quicken(code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern uint8_t _PyOpcode_Adaptive[256];
|
|
||||||
|
|
||||||
extern Py_ssize_t _Py_QuickenedCount;
|
|
||||||
|
|
||||||
// Borrowed references to common callables:
|
|
||||||
struct callable_cache {
|
|
||||||
PyObject *isinstance;
|
|
||||||
PyObject *len;
|
|
||||||
PyObject *list_append;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* "Locals plus" for a code object is the set of locals + cell vars +
|
|
||||||
* free vars. This relates to variable names as well as offsets into
|
|
||||||
* the "fast locals" storage array of execution frames. The compiler
|
|
||||||
* builds the list of names, their offsets, and the corresponding
|
|
||||||
* kind of local.
|
|
||||||
*
|
|
||||||
* Those kinds represent the source of the initial value and the
|
|
||||||
* variable's scope (as related to closures). A "local" is an
|
|
||||||
* argument or other variable defined in the current scope. A "free"
|
|
||||||
* variable is one that is defined in an outer scope and comes from
|
|
||||||
* the function's closure. A "cell" variable is a local that escapes
|
|
||||||
* into an inner function as part of a closure, and thus must be
|
|
||||||
* wrapped in a cell. Any "local" can also be a "cell", but the
|
|
||||||
* "free" kind is mutually exclusive with both.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Note that these all fit within a byte, as do combinations.
|
|
||||||
// Later, we will use the smaller numbers to differentiate the different
|
|
||||||
// kinds of locals (e.g. pos-only arg, varkwargs, local-only).
|
|
||||||
#define CO_FAST_LOCAL 0x20
|
|
||||||
#define CO_FAST_CELL 0x40
|
|
||||||
#define CO_FAST_FREE 0x80
|
|
||||||
|
|
||||||
typedef unsigned char _PyLocals_Kind;
|
|
||||||
|
|
||||||
static inline _PyLocals_Kind
|
|
||||||
_PyLocals_GetKind(PyObject *kinds, int i)
|
|
||||||
{
|
|
||||||
assert(PyBytes_Check(kinds));
|
|
||||||
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
|
||||||
char *ptr = PyBytes_AS_STRING(kinds);
|
|
||||||
return (_PyLocals_Kind)(ptr[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
_PyLocals_SetKind(PyObject *kinds, int i, _PyLocals_Kind kind)
|
|
||||||
{
|
|
||||||
assert(PyBytes_Check(kinds));
|
|
||||||
assert(0 <= i && i < PyBytes_GET_SIZE(kinds));
|
|
||||||
char *ptr = PyBytes_AS_STRING(kinds);
|
|
||||||
ptr[i] = (char) kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct _PyCodeConstructor {
|
|
||||||
/* metadata */
|
|
||||||
PyObject *filename;
|
|
||||||
PyObject *name;
|
|
||||||
PyObject *qualname;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
/* the code */
|
|
||||||
PyObject *code;
|
|
||||||
int firstlineno;
|
|
||||||
PyObject *linetable;
|
|
||||||
|
|
||||||
/* used by the code */
|
|
||||||
PyObject *consts;
|
|
||||||
PyObject *names;
|
|
||||||
|
|
||||||
/* mapping frame offsets to information */
|
|
||||||
PyObject *localsplusnames; // Tuple of strings
|
|
||||||
PyObject *localspluskinds; // Bytes object, one byte per variable
|
|
||||||
|
|
||||||
/* args (within varnames) */
|
|
||||||
int argcount;
|
|
||||||
int posonlyargcount;
|
|
||||||
// XXX Replace argcount with posorkwargcount (argcount - posonlyargcount).
|
|
||||||
int kwonlyargcount;
|
|
||||||
|
|
||||||
/* needed to create the frame */
|
|
||||||
int stacksize;
|
|
||||||
|
|
||||||
/* used by the eval loop */
|
|
||||||
PyObject *exceptiontable;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Using an "arguments struct" like this is helpful for maintainability
|
|
||||||
// in a case such as this with many parameters. It does bear a risk:
|
|
||||||
// if the struct changes and callers are not updated properly then the
|
|
||||||
// compiler will not catch problems (like a missing argument). This can
|
|
||||||
// cause hard-to-debug problems. The risk is mitigated by the use of
|
|
||||||
// check_code() in codeobject.c. However, we may decide to switch
|
|
||||||
// back to a regular function signature. Regardless, this approach
|
|
||||||
// wouldn't be appropriate if this weren't a strictly internal API.
|
|
||||||
// (See the comments in https://github.com/python/cpython/pull/26258.)
|
|
||||||
PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *);
|
|
||||||
PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Private API */
|
|
||||||
|
|
||||||
/* Getters for internal PyCodeObject data. */
|
|
||||||
extern PyObject* _PyCode_GetVarnames(PyCodeObject *);
|
|
||||||
extern PyObject* _PyCode_GetCellvars(PyCodeObject *);
|
|
||||||
extern PyObject* _PyCode_GetFreevars(PyCodeObject *);
|
|
||||||
extern PyObject* _PyCode_GetCode(PyCodeObject *);
|
|
||||||
|
|
||||||
/** API for initializing the line number tables. */
|
|
||||||
extern int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds);
|
|
||||||
|
|
||||||
/** Out of process API for initializing the location table. */
|
|
||||||
extern void _PyLineTable_InitAddressRange(
|
|
||||||
const char *linetable,
|
|
||||||
Py_ssize_t length,
|
|
||||||
int firstlineno,
|
|
||||||
PyCodeAddressRange *range);
|
|
||||||
|
|
||||||
/** API for traversing the line number table. */
|
|
||||||
extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range);
|
|
||||||
extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
|
|
||||||
|
|
||||||
/* Specialization functions */
|
|
||||||
|
|
||||||
extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr,
|
|
||||||
PyObject *name);
|
|
||||||
extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr,
|
|
||||||
PyObject *name);
|
|
||||||
extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name);
|
|
||||||
extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr,
|
|
||||||
PyObject *name);
|
|
||||||
extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr);
|
|
||||||
extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr);
|
|
||||||
extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
|
|
||||||
int nargs, PyObject *kwnames);
|
|
||||||
extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr,
|
|
||||||
int nargs, PyObject *kwnames, int oparg);
|
|
||||||
extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|
||||||
int oparg, PyObject **locals);
|
|
||||||
extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
|
|
||||||
_Py_CODEUNIT *instr, int oparg);
|
|
||||||
extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
|
|
||||||
int oparg);
|
|
||||||
|
|
||||||
/* Deallocator function for static codeobjects used in deepfreeze.py */
|
|
||||||
extern void _PyStaticCode_Dealloc(PyCodeObject *co);
|
|
||||||
/* Function to intern strings of codeobjects */
|
|
||||||
extern int _PyStaticCode_InternStrings(PyCodeObject *co);
|
|
||||||
|
|
||||||
#ifdef Py_STATS
|
|
||||||
|
|
||||||
#define SPECIALIZATION_FAILURE_KINDS 30
|
|
||||||
|
|
||||||
typedef struct _specialization_stats {
|
|
||||||
uint64_t success;
|
|
||||||
uint64_t failure;
|
|
||||||
uint64_t hit;
|
|
||||||
uint64_t deferred;
|
|
||||||
uint64_t miss;
|
|
||||||
uint64_t deopt;
|
|
||||||
uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS];
|
|
||||||
} SpecializationStats;
|
|
||||||
|
|
||||||
typedef struct _opcode_stats {
|
|
||||||
SpecializationStats specialization;
|
|
||||||
uint64_t execution_count;
|
|
||||||
uint64_t pair_count[256];
|
|
||||||
} OpcodeStats;
|
|
||||||
|
|
||||||
typedef struct _call_stats {
|
|
||||||
uint64_t inlined_py_calls;
|
|
||||||
uint64_t pyeval_calls;
|
|
||||||
uint64_t frames_pushed;
|
|
||||||
uint64_t frame_objects_created;
|
|
||||||
} CallStats;
|
|
||||||
|
|
||||||
typedef struct _object_stats {
|
|
||||||
uint64_t allocations;
|
|
||||||
uint64_t allocations512;
|
|
||||||
uint64_t allocations4k;
|
|
||||||
uint64_t allocations_big;
|
|
||||||
uint64_t frees;
|
|
||||||
uint64_t to_freelist;
|
|
||||||
uint64_t from_freelist;
|
|
||||||
uint64_t new_values;
|
|
||||||
uint64_t dict_materialized_on_request;
|
|
||||||
uint64_t dict_materialized_new_key;
|
|
||||||
uint64_t dict_materialized_too_big;
|
|
||||||
uint64_t dict_materialized_str_subclass;
|
|
||||||
} ObjectStats;
|
|
||||||
|
|
||||||
typedef struct _stats {
|
|
||||||
OpcodeStats opcode_stats[256];
|
|
||||||
CallStats call_stats;
|
|
||||||
ObjectStats object_stats;
|
|
||||||
} PyStats;
|
|
||||||
|
|
||||||
extern PyStats _py_stats;
|
|
||||||
|
|
||||||
#define STAT_INC(opname, name) _py_stats.opcode_stats[opname].specialization.name++
|
|
||||||
#define STAT_DEC(opname, name) _py_stats.opcode_stats[opname].specialization.name--
|
|
||||||
#define OPCODE_EXE_INC(opname) _py_stats.opcode_stats[opname].execution_count++
|
|
||||||
#define CALL_STAT_INC(name) _py_stats.call_stats.name++
|
|
||||||
#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++
|
|
||||||
#define OBJECT_STAT_INC_COND(name, cond) \
|
|
||||||
do { if (cond) _py_stats.object_stats.name++; } while (0)
|
|
||||||
|
|
||||||
extern void _Py_PrintSpecializationStats(int to_file);
|
|
||||||
|
|
||||||
// Used by the _opcode extension which is built as a shared library
|
|
||||||
PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define STAT_INC(opname, name) ((void)0)
|
|
||||||
#define STAT_DEC(opname, name) ((void)0)
|
|
||||||
#define OPCODE_EXE_INC(opname) ((void)0)
|
|
||||||
#define CALL_STAT_INC(name) ((void)0)
|
|
||||||
#define OBJECT_STAT_INC(name) ((void)0)
|
|
||||||
#define OBJECT_STAT_INC_COND(name, cond) ((void)0)
|
|
||||||
#endif // !Py_STATS
|
|
||||||
|
|
||||||
// Cache values are only valid in memory, so use native endianness.
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
write_u32(uint16_t *p, uint32_t val)
|
|
||||||
{
|
|
||||||
p[0] = (uint16_t)(val >> 16);
|
|
||||||
p[1] = (uint16_t)(val >> 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
write_u64(uint16_t *p, uint64_t val)
|
|
||||||
{
|
|
||||||
p[0] = (uint16_t)(val >> 48);
|
|
||||||
p[1] = (uint16_t)(val >> 32);
|
|
||||||
p[2] = (uint16_t)(val >> 16);
|
|
||||||
p[3] = (uint16_t)(val >> 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
read_u32(uint16_t *p)
|
|
||||||
{
|
|
||||||
uint32_t val = 0;
|
|
||||||
val |= (uint32_t)p[0] << 16;
|
|
||||||
val |= (uint32_t)p[1] << 0;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t
|
|
||||||
read_u64(uint16_t *p)
|
|
||||||
{
|
|
||||||
uint64_t val = 0;
|
|
||||||
val |= (uint64_t)p[0] << 48;
|
|
||||||
val |= (uint64_t)p[1] << 32;
|
|
||||||
val |= (uint64_t)p[2] << 16;
|
|
||||||
val |= (uint64_t)p[3] << 0;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
write_u32(uint16_t *p, uint32_t val)
|
|
||||||
{
|
|
||||||
p[0] = (uint16_t)(val >> 0);
|
|
||||||
p[1] = (uint16_t)(val >> 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
write_u64(uint16_t *p, uint64_t val)
|
|
||||||
{
|
|
||||||
p[0] = (uint16_t)(val >> 0);
|
|
||||||
p[1] = (uint16_t)(val >> 16);
|
|
||||||
p[2] = (uint16_t)(val >> 32);
|
|
||||||
p[3] = (uint16_t)(val >> 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
read_u32(uint16_t *p)
|
|
||||||
{
|
|
||||||
uint32_t val = 0;
|
|
||||||
val |= (uint32_t)p[0] << 0;
|
|
||||||
val |= (uint32_t)p[1] << 16;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t
|
|
||||||
read_u64(uint16_t *p)
|
|
||||||
{
|
|
||||||
uint64_t val = 0;
|
|
||||||
val |= (uint64_t)p[0] << 0;
|
|
||||||
val |= (uint64_t)p[1] << 16;
|
|
||||||
val |= (uint64_t)p[2] << 32;
|
|
||||||
val |= (uint64_t)p[3] << 48;
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
write_obj(uint16_t *p, PyObject *obj)
|
|
||||||
{
|
|
||||||
uintptr_t val = (uintptr_t)obj;
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
write_u64(p, val);
|
|
||||||
#elif SIZEOF_VOID_P == 4
|
|
||||||
write_u32(p, val);
|
|
||||||
#else
|
|
||||||
#error "SIZEOF_VOID_P must be 4 or 8"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline PyObject *
|
|
||||||
read_obj(uint16_t *p)
|
|
||||||
{
|
|
||||||
uintptr_t val;
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
val = read_u64(p);
|
|
||||||
#elif SIZEOF_VOID_P == 4
|
|
||||||
val = read_u32(p);
|
|
||||||
#else
|
|
||||||
#error "SIZEOF_VOID_P must be 4 or 8"
|
|
||||||
#endif
|
|
||||||
return (PyObject *)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See Objects/exception_handling_notes.txt for details.
|
|
||||||
*/
|
|
||||||
static inline unsigned char *
|
|
||||||
parse_varint(unsigned char *p, int *result) {
|
|
||||||
int val = p[0] & 63;
|
|
||||||
while (p[0] & 64) {
|
|
||||||
p++;
|
|
||||||
val = (val << 6) | (p[0] & 63);
|
|
||||||
}
|
|
||||||
*result = val;
|
|
||||||
return p+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
write_varint(uint8_t *ptr, unsigned int val)
|
|
||||||
{
|
|
||||||
int written = 1;
|
|
||||||
while (val >= 64) {
|
|
||||||
*ptr++ = 64 | (val & 63);
|
|
||||||
val >>= 6;
|
|
||||||
written++;
|
|
||||||
}
|
|
||||||
*ptr = val;
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
write_signed_varint(uint8_t *ptr, int val)
|
|
||||||
{
|
|
||||||
if (val < 0) {
|
|
||||||
val = ((-val)<<1) | 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val = val << 1;
|
|
||||||
}
|
|
||||||
return write_varint(ptr, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
write_location_entry_start(uint8_t *ptr, int code, int length)
|
|
||||||
{
|
|
||||||
assert((code & 15) == code);
|
|
||||||
*ptr = 128 | (code << 3) | (length - 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Counters
|
|
||||||
* The first 16-bit value in each inline cache is a counter.
|
|
||||||
* When counting misses, the counter is treated as a simple unsigned value.
|
|
||||||
*
|
|
||||||
* When counting executions until the next specialization attempt,
|
|
||||||
* exponential backoff is used to reduce the number of specialization failures.
|
|
||||||
* The high 12 bits store the counter, the low 4 bits store the backoff exponent.
|
|
||||||
* On a specialization failure, the backoff exponent is incremented and the
|
|
||||||
* counter set to (2**backoff - 1).
|
|
||||||
* Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */
|
|
||||||
#define ADAPTIVE_BACKOFF_BITS 4
|
|
||||||
/* The initial counter value is 31 == 2**ADAPTIVE_BACKOFF_START - 1 */
|
|
||||||
#define ADAPTIVE_BACKOFF_START 5
|
|
||||||
|
|
||||||
#define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS)
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
adaptive_counter_bits(int value, int backoff) {
|
|
||||||
return (value << ADAPTIVE_BACKOFF_BITS) |
|
|
||||||
(backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
adaptive_counter_start(void) {
|
|
||||||
unsigned int value = (1 << ADAPTIVE_BACKOFF_START) - 1;
|
|
||||||
return adaptive_counter_bits(value, ADAPTIVE_BACKOFF_START);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
adaptive_counter_backoff(uint16_t counter) {
|
|
||||||
unsigned int backoff = counter & ((1<<ADAPTIVE_BACKOFF_BITS)-1);
|
|
||||||
backoff++;
|
|
||||||
if (backoff > MAX_BACKOFF_VALUE) {
|
|
||||||
backoff = MAX_BACKOFF_VALUE;
|
|
||||||
}
|
|
||||||
unsigned int value = (1 << backoff) - 1;
|
|
||||||
return adaptive_counter_bits(value, backoff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Line array cache for tracing */
|
|
||||||
|
|
||||||
extern int _PyCode_CreateLineArray(PyCodeObject *co);
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
_PyCode_InitLineArray(PyCodeObject *co)
|
|
||||||
{
|
|
||||||
if (co->_co_linearray) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _PyCode_CreateLineArray(co);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
_PyCode_LineNumberFromArray(PyCodeObject *co, int index)
|
|
||||||
{
|
|
||||||
assert(co->_co_linearray != NULL);
|
|
||||||
assert(index >= 0);
|
|
||||||
assert(index < Py_SIZE(co));
|
|
||||||
if (co->_co_linearray_entry_size == 2) {
|
|
||||||
return ((int16_t *)co->_co_linearray)[index];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(co->_co_linearray_entry_size == 4);
|
|
||||||
return ((int32_t *)co->_co_linearray)[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_CODE_H */
|
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_COMPILE_H
|
|
||||||
#define Py_INTERNAL_COMPILE_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _arena; // Type defined in pycore_pyarena.h
|
|
||||||
struct _mod; // Type defined in pycore_ast.h
|
|
||||||
|
|
||||||
// Export the symbol for test_peg_generator (built as a library)
|
|
||||||
PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
|
|
||||||
struct _mod *mod,
|
|
||||||
PyObject *filename,
|
|
||||||
PyCompilerFlags *flags,
|
|
||||||
int optimize,
|
|
||||||
struct _arena *arena);
|
|
||||||
extern PyFutureFeatures* _PyFuture_FromAST(
|
|
||||||
struct _mod * mod,
|
|
||||||
PyObject *filename
|
|
||||||
);
|
|
||||||
|
|
||||||
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int optimize;
|
|
||||||
int ff_features;
|
|
||||||
|
|
||||||
int recursion_depth; /* current recursion depth */
|
|
||||||
int recursion_limit; /* recursion limit */
|
|
||||||
} _PyASTOptimizeState;
|
|
||||||
|
|
||||||
extern int _PyAST_Optimize(
|
|
||||||
struct _mod *,
|
|
||||||
struct _arena *arena,
|
|
||||||
_PyASTOptimizeState *state);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_COMPILE_H */
|
|
|
@ -1,97 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_CONDVAR_H
|
|
||||||
#define Py_INTERNAL_CONDVAR_H
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _POSIX_THREADS
|
|
||||||
/* This means pthreads are not implemented in libc headers, hence the macro
|
|
||||||
not present in unistd.h. But they still can be implemented as an external
|
|
||||||
library (e.g. gnu pth in pthread emulation) */
|
|
||||||
# ifdef HAVE_PTHREAD_H
|
|
||||||
# include <pthread.h> /* _POSIX_THREADS */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _POSIX_THREADS
|
|
||||||
/*
|
|
||||||
* POSIX support
|
|
||||||
*/
|
|
||||||
#define Py_HAVE_CONDVAR
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_H
|
|
||||||
# include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PyMUTEX_T pthread_mutex_t
|
|
||||||
#define PyCOND_T pthread_cond_t
|
|
||||||
|
|
||||||
#elif defined(NT_THREADS)
|
|
||||||
/*
|
|
||||||
* Windows (XP, 2003 server and later, as well as (hopefully) CE) support
|
|
||||||
*
|
|
||||||
* Emulated condition variables ones that work with XP and later, plus
|
|
||||||
* example native support on VISTA and onwards.
|
|
||||||
*/
|
|
||||||
#define Py_HAVE_CONDVAR
|
|
||||||
|
|
||||||
/* include windows if it hasn't been done before */
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
/* options */
|
|
||||||
/* non-emulated condition variables are provided for those that want
|
|
||||||
* to target Windows Vista. Modify this macro to enable them.
|
|
||||||
*/
|
|
||||||
#ifndef _PY_EMULATED_WIN_CV
|
|
||||||
#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* fall back to emulation if not targeting Vista */
|
|
||||||
#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA
|
|
||||||
#undef _PY_EMULATED_WIN_CV
|
|
||||||
#define _PY_EMULATED_WIN_CV 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _PY_EMULATED_WIN_CV
|
|
||||||
|
|
||||||
typedef CRITICAL_SECTION PyMUTEX_T;
|
|
||||||
|
|
||||||
/* The ConditionVariable object. From XP onwards it is easily emulated
|
|
||||||
with a Semaphore.
|
|
||||||
Semaphores are available on Windows XP (2003 server) and later.
|
|
||||||
We use a Semaphore rather than an auto-reset event, because although
|
|
||||||
an auto-reset event might appear to solve the lost-wakeup bug (race
|
|
||||||
condition between releasing the outer lock and waiting) because it
|
|
||||||
maintains state even though a wait hasn't happened, there is still
|
|
||||||
a lost wakeup problem if more than one thread are interrupted in the
|
|
||||||
critical place. A semaphore solves that, because its state is
|
|
||||||
counted, not Boolean.
|
|
||||||
Because it is ok to signal a condition variable with no one
|
|
||||||
waiting, we need to keep track of the number of
|
|
||||||
waiting threads. Otherwise, the semaphore's state could rise
|
|
||||||
without bound. This also helps reduce the number of "spurious wakeups"
|
|
||||||
that would otherwise happen.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct _PyCOND_T
|
|
||||||
{
|
|
||||||
HANDLE sem;
|
|
||||||
int waiting; /* to allow PyCOND_SIGNAL to be a no-op */
|
|
||||||
} PyCOND_T;
|
|
||||||
|
|
||||||
#else /* !_PY_EMULATED_WIN_CV */
|
|
||||||
|
|
||||||
/* Use native Win7 primitives if build target is Win7 or higher */
|
|
||||||
|
|
||||||
/* SRWLOCK is faster and better than CriticalSection */
|
|
||||||
typedef SRWLOCK PyMUTEX_T;
|
|
||||||
|
|
||||||
typedef CONDITION_VARIABLE PyCOND_T;
|
|
||||||
|
|
||||||
#endif /* _PY_EMULATED_WIN_CV */
|
|
||||||
|
|
||||||
#endif /* _POSIX_THREADS, NT_THREADS */
|
|
||||||
|
|
||||||
#endif /* Py_INTERNAL_CONDVAR_H */
|
|
|
@ -1,67 +0,0 @@
|
||||||
#ifndef Py_INTERNAL_CONTEXT_H
|
|
||||||
#define Py_INTERNAL_CONTEXT_H
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pycore_hamt.h" /* PyHamtObject */
|
|
||||||
|
|
||||||
|
|
||||||
extern PyTypeObject _PyContextTokenMissing_Type;
|
|
||||||
|
|
||||||
/* runtime lifecycle */
|
|
||||||
|
|
||||||
PyStatus _PyContext_Init(PyInterpreterState *);
|
|
||||||
void _PyContext_Fini(PyInterpreterState *);
|
|
||||||
|
|
||||||
|
|
||||||
/* other API */
|
|
||||||
|
|
||||||
#ifndef WITH_FREELISTS
|
|
||||||
// without freelists
|
|
||||||
# define PyContext_MAXFREELIST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyContext_MAXFREELIST
|
|
||||||
# define PyContext_MAXFREELIST 255
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _Py_context_state {
|
|
||||||
#if PyContext_MAXFREELIST > 0
|
|
||||||
// List of free PyContext objects
|
|
||||||
PyContext *freelist;
|
|
||||||
int numfree;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _pycontextobject {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyContext *ctx_prev;
|
|
||||||
PyHamtObject *ctx_vars;
|
|
||||||
PyObject *ctx_weakreflist;
|
|
||||||
int ctx_entered;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct _pycontextvarobject {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyObject *var_name;
|
|
||||||
PyObject *var_default;
|
|
||||||
PyObject *var_cached;
|
|
||||||
uint64_t var_cached_tsid;
|
|
||||||
uint64_t var_cached_tsver;
|
|
||||||
Py_hash_t var_hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct _pycontexttokenobject {
|
|
||||||
PyObject_HEAD
|
|
||||||
PyContext *tok_ctx;
|
|
||||||
PyContextVar *tok_var;
|
|
||||||
PyObject *tok_oldval;
|
|
||||||
int tok_used;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !Py_INTERNAL_CONTEXT_H */
|
|
|
@ -1,178 +0,0 @@
|
||||||
|
|
||||||
#ifndef Py_INTERNAL_DICT_H
|
|
||||||
#define Py_INTERNAL_DICT_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* runtime lifecycle */
|
|
||||||
|
|
||||||
extern void _PyDict_Fini(PyInterpreterState *interp);
|
|
||||||
|
|
||||||
|
|
||||||
/* other API */
|
|
||||||
|
|
||||||
#ifndef WITH_FREELISTS
|
|
||||||
// without freelists
|
|
||||||
# define PyDict_MAXFREELIST 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PyDict_MAXFREELIST
|
|
||||||
# define PyDict_MAXFREELIST 80
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct _Py_dict_state {
|
|
||||||
#if PyDict_MAXFREELIST > 0
|
|
||||||
/* Dictionary reuse scheme to save calls to malloc and free */
|
|
||||||
PyDictObject *free_list[PyDict_MAXFREELIST];
|
|
||||||
int numfree;
|
|
||||||
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
|
|
||||||
int keys_numfree;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* Cached hash code of me_key. */
|
|
||||||
Py_hash_t me_hash;
|
|
||||||
PyObject *me_key;
|
|
||||||
PyObject *me_value; /* This field is only meaningful for combined tables */
|
|
||||||
} PyDictKeyEntry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject *me_key; /* The key must be Unicode and have hash. */
|
|
||||||
PyObject *me_value; /* This field is only meaningful for combined tables */
|
|
||||||
} PyDictUnicodeEntry;
|
|
||||||
|
|
||||||
extern PyDictKeysObject *_PyDict_NewKeysForClass(void);
|
|
||||||
extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
|
|
||||||
|
|
||||||
/* Gets a version number unique to the current state of the keys of dict, if possible.
|
|
||||||
* Returns the version number, or zero if it was not possible to get a version number. */
|
|
||||||
extern uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys);
|
|
||||||
|
|
||||||
extern Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
|
|
||||||
|
|
||||||
/* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index].
|
|
||||||
* -1 when no entry found, -3 when compare raises error.
|
|
||||||
*/
|
|
||||||
extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr);
|
|
||||||
|
|
||||||
extern Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **);
|
|
||||||
extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key);
|
|
||||||
extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
|
|
||||||
|
|
||||||
/* Consumes references to key and value */
|
|
||||||
extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value);
|
|
||||||
extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
|
|
||||||
|
|
||||||
extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
|
|
||||||
|
|
||||||
#define DKIX_EMPTY (-1)
|
|
||||||
#define DKIX_DUMMY (-2) /* Used internally */
|
|
||||||
#define DKIX_ERROR (-3)
|
|
||||||
#define DKIX_KEY_CHANGED (-4) /* Used internally */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
DICT_KEYS_GENERAL = 0,
|
|
||||||
DICT_KEYS_UNICODE = 1,
|
|
||||||
DICT_KEYS_SPLIT = 2
|
|
||||||
} DictKeysKind;
|
|
||||||
|
|
||||||
/* See dictobject.c for actual layout of DictKeysObject */
|
|
||||||
struct _dictkeysobject {
|
|
||||||
Py_ssize_t dk_refcnt;
|
|
||||||
|
|
||||||
/* Size of the hash table (dk_indices). It must be a power of 2. */
|
|
||||||
uint8_t dk_log2_size;
|
|
||||||
|
|
||||||
/* Size of the hash table (dk_indices) by bytes. */
|
|
||||||
uint8_t dk_log2_index_bytes;
|
|
||||||
|
|
||||||
/* Kind of keys */
|
|
||||||
uint8_t dk_kind;
|
|
||||||
|
|
||||||
/* Version number -- Reset to 0 by any modification to keys */
|
|
||||||
uint32_t dk_version;
|
|
||||||
|
|
||||||
/* Number of usable entries in dk_entries. */
|
|
||||||
Py_ssize_t dk_usable;
|
|
||||||
|
|
||||||
/* Number of used entries in dk_entries. */
|
|
||||||
Py_ssize_t dk_nentries;
|
|
||||||
|
|
||||||
/* Actual hash table of dk_size entries. It holds indices in dk_entries,
|
|
||||||
or DKIX_EMPTY(-1) or DKIX_DUMMY(-2).
|
|
||||||
|
|
||||||
Indices must be: 0 <= indice < USABLE_FRACTION(dk_size).
|
|
||||||
|
|
||||||
The size in bytes of an indice depends on dk_size:
|
|
||||||
|
|
||||||
- 1 byte if dk_size <= 0xff (char*)
|
|
||||||
- 2 bytes if dk_size <= 0xffff (int16_t*)
|
|
||||||
- 4 bytes if dk_size <= 0xffffffff (int32_t*)
|
|
||||||
- 8 bytes otherwise (int64_t*)
|
|
||||||
|
|
||||||
Dynamically sized, SIZEOF_VOID_P is minimum. */
|
|
||||||
char dk_indices[]; /* char is required to avoid strict aliasing. */
|
|
||||||
|
|
||||||
/* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows:
|
|
||||||
see the DK_ENTRIES() macro */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This must be no more than 250, for the prefix size to fit in one byte. */
|
|
||||||
#define SHARED_KEYS_MAX_SIZE 30
|
|
||||||
#define NEXT_LOG2_SHARED_KEYS_MAX_SIZE 6
|
|
||||||
|
|
||||||
/* Layout of dict values:
|
|
||||||
*
|
|
||||||
* The PyObject *values are preceded by an array of bytes holding
|
|
||||||
* the insertion order and size.
|
|
||||||
* [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order.
|
|
||||||
*/
|
|
||||||
struct _dictvalues {
|
|
||||||
PyObject *values[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DK_LOG_SIZE(dk) ((dk)->dk_log2_size)
|
|
||||||
#if SIZEOF_VOID_P > 4
|
|
||||||
#define DK_SIZE(dk) (((int64_t)1)<<DK_LOG_SIZE(dk))
|
|
||||||
#else
|
|
||||||
#define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk))
|
|
||||||
#endif
|
|
||||||
#define DK_ENTRIES(dk) \
|
|
||||||
(assert(dk->dk_kind == DICT_KEYS_GENERAL), (PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))
|
|
||||||
#define DK_UNICODE_ENTRIES(dk) \
|
|
||||||
(assert(dk->dk_kind != DICT_KEYS_GENERAL), (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))
|
|
||||||
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)
|
|
||||||
|
|
||||||
extern uint64_t _pydict_global_version;
|
|
||||||
|
|
||||||
#define DICT_NEXT_VERSION() (++_pydict_global_version)
|
|
||||||
|
|
||||||
extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values);
|
|
||||||
extern PyObject *_PyDict_FromItems(
|
|
||||||
PyObject *const *keys, Py_ssize_t keys_offset,
|
|
||||||
PyObject *const *values, Py_ssize_t values_offset,
|
|
||||||
Py_ssize_t length);
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
_PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix)
|
|
||||||
{
|
|
||||||
assert(ix < SHARED_KEYS_MAX_SIZE);
|
|
||||||
uint8_t *size_ptr = ((uint8_t *)values)-2;
|
|
||||||
int size = *size_ptr;
|
|
||||||
assert(size+2 < ((uint8_t *)values)[-1]);
|
|
||||||
size++;
|
|
||||||
size_ptr[-size] = (uint8_t)ix;
|
|
||||||
*size_ptr = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* !Py_INTERNAL_DICT_H */
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue