159 Commits

Author SHA1 Message Date
server
49e8eac809 Revert stream M2Pack archive support
Some checks are pending
build / Windows Build (push) Waiting to run
2026-04-15 19:06:59 +02:00
server
0b852faf0e Support experimental stream M2Pack archives
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 18:40:40 +02:00
server
b353339bd8 Add GM smoke compare workflow for pack profiling
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 17:35:02 +02:00
server
db7ae1f841 Persist pack profile snapshots during timed captures
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 17:06:11 +02:00
server
2d9beb4793 Add pack profile capture workflow
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 16:39:16 +02:00
server
6ff59498d2 Add pack profile report parser
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 16:34:26 +02:00
server
ba6af8115b Add pack runtime profiling hooks
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 16:22:10 +02:00
server
ef7cdf2809 Reduce m2pack client hot-path overhead
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-15 15:43:26 +02:00
server
cb0867432e Add key id based m2p rotation support
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-14 12:20:19 +02:00
server
229c809b96 Add secure m2p loader with runtime key enforcement
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-14 12:12:41 +02:00
server
0c2d6c7c9c docs: add repo instructions
Some checks failed
build / Windows Build (push) Has been cancelled
2026-04-14 09:08:35 +02:00
d1str4ught
a755511082 Merge pull request #122 from SunTrustDev/bugfix/guild-mark
Fix default guild mark, color and format
2026-03-09 01:19:47 +01:00
SuntrustDev
127d60c604 Fix default guild mark, color and format 2026-03-04 20:18:02 +01:00
rtw1x1
f7a0480156 Merge pull request #118 from ErLullo/big-blind-fix 2026-02-19 20:15:29 +00:00
ErLullo
3ee2d9cb0f Merge branch 'main' into big-blind-fix 2026-02-19 20:32:03 +01:00
rtw1x1
a74adb8f6d Merge pull request #120 from rtw1x1/main
ML: HotReload fix TextTail
2026-02-19 18:58:04 +00:00
rtw1x1
5a11424733 Merge branch 'main' of https://github.com/rtw1x1/m2dev-client-src 2026-02-19 18:55:39 +00:00
rtw1x1
faa8f99dfc ML: HotReload fix TextTail 2026-02-19 18:55:22 +00:00
rtw1x1
eb7be12e5c Merge pull request #119 from rtw1x1/main
fix: SpeedTree fog fix
2026-02-19 18:52:59 +00:00
rtw1x1
3f8a664c2c fix: SpeedTree fog fix 2026-02-19 18:51:43 +00:00
ErLullo
94a773a1d5 Refactor fog settings handling in MapUtil 2026-02-19 12:09:33 +01:00
ErLullo
a3151f46c2 Refactor fog handling logic in MapManager 2026-02-19 12:08:38 +01:00
ErLullo
45335ca19a Add fog level default setting to environment data loading 2026-02-19 02:51:51 +01:00
rtw1x1
7ef5077b97 Merge pull request #117 from MindRapist/mr-16
Enable tooltip and countdown for all affects
2026-02-18 20:07:22 +00:00
Mind Rapist
6fb10a9135 Enable tooltip and countdown for all affects 2026-02-18 18:47:47 +02:00
rtw1x1
498c351d4c Merge pull request #110 from onurcan488/main 2026-02-18 15:52:06 +00:00
rtw1x1
3471964030 Merge pull request #116 from ErLullo/dump_fix 2026-02-18 15:51:45 +00:00
rtw1x1
0d748d2eb2 Merge pull request #114 from MindRapist/mr-15 2026-02-18 15:51:17 +00:00
rtw1x1
5db5e5543f Merge pull request #113 from SunTrustDev/bugfix/text-fields-improvements 2026-02-18 15:50:53 +00:00
rtw1x1
9f292a1719 Merge pull request #112 from SunTrustDev/bugfix/map-markers-uniform-scaling 2026-02-18 15:50:41 +00:00
rtw1x1
cfeaf05126 Merge pull request #111 from SunTrustDev/bugfix/pack-loading 2026-02-18 15:50:27 +00:00
ErLullo
216b82b32a Change uiSize type to lzo_uint in Decompress method 2026-02-18 09:27:31 +01:00
Mind Rapist
46c7c0ed59 DumpProto fix 2026-02-18 01:59:08 +02:00
Mind Rapist
2400d2a36f Various fixes and improvements 2026-02-18 01:00:24 +02:00
SuntrustDev
7eca2871d7 Use character midpoint calculation to increase cursor placement accuracy in text fields 2026-02-17 21:33:33 +01:00
SuntrustDev
122ca058de Prevent text fields cursor from being stuck on n-1 character when clicking on the end of the text field 2026-02-17 21:32:13 +01:00
SuntrustDev
c687bf7ed4 Prevent Password fields from being cut/copied 2026-02-17 21:30:15 +01:00
SuntrustDev
65c265067d Restore original clear behavior (Clear both guild marks and NPC/Warps) 2026-02-17 20:26:19 +01:00
SuntrustDev
41aecfbc4d Implement uniform scaling (Fixes GF large maps marker positionng issues)
Clear guild terrain marker on map change
Add AtlasScale capability
2026-02-17 14:46:41 +01:00
SuntrustDev
264a0a43d7 Fix: Reverted to sequential pack loading to avoid race conditions
Loads packs one by one so that duplicate file resolution
follows a deterministic order (last pack wins). Parallel loading made
the effective order depend on lock acquisition order, allowing older
packs to override newer ones. Sequential load stays under ~1s (~350ms
on typical hardware), so the performance tradeoff is considered acceptable.
2026-02-17 10:30:13 +01:00
onurcan488
f895a1a4a2 DirectX8 to DirectX 2026-02-16 21:37:53 +03:00
rtw1x1
a0279b8f4b Merge pull request #109 from MindRapist/mr-14
Fog fixes
2026-02-16 17:55:36 +00:00
Mind Rapist
3e604d5f10 Fog fixes 2026-02-16 16:47:52 +02:00
rtw1x1
2c73eb7bb0 Merge pull request #108 from MindRapist/mr-12
Various fixes
2026-02-15 20:46:19 +00:00
Mind Rapist
74a93ad116 Various fixes 2026-02-15 21:40:52 +02:00
rtw1x1
fb48dbc9ce Merge pull request #106 from mq1n/main
fix some problems
2026-02-15 17:58:28 +00:00
Koray
cd2529ee15 prevent leaf render AV and harden leaf shader setup for speedtree
- Guard leaf LOD access in CSpeedTreeWrapper::RenderLeaves() to avoid out-of-bounds indexing of m_pLeafVertexBuffer and m_pLeavesUpdatedByCpu.
  - Skip leaf update/draw when LOD is invalid, inactive, empty, or has no vertex buffer.
  - Add early safety returns for missing leaf buffer arrays and zero LOD count.
  - Guard CSpeedTreeWrapper::EndLeafForTreeType() against null m_pLeavesUpdatedByCpu.
  - Add shader re-init path in wrapper render entrypoints via CSpeedTreeForestDirectX8::EnsureVertexShaders() when cached shader state is missing.
  - Introduce public EnsureVertexShaders() in SpeedTreeForestDirectX8 while keeping InitVertexShaders() private (resolves private-access compile error).
  - Fix leaf shader input declaration to emit dcl_texcoord2 v9 for both GPU wind and GPU leaf placement configurations.
  - Make LoadLeafShader() atomic: create new shader/decl first, then swap only if both succeed, preserving previous valid shader state on failure.
  - Improve leaf shader failure logs to include HRESULT for easier diagnosis.
2026-02-15 16:03:18 +03:00
Koray
cfe3c3cb7c Fix SpeedTree LOD strip handling to render all strips per LOD 2026-02-15 15:40:54 +03:00
Koray
acb0ac0af5 fix missing resource exception handling
Unhandled exception at 0x00007FF9433E8B9C (KERNELBASE.dll) in metin2client__20260215_143044.dmp: 0xE06D7363: Microsoft C++ Exception (parameters: 0x0000000019930520, 0x0000001E1CF2CF80, 0x00007FF698014258, 0x00007FF696940000).

 	[External Code]
>	Metin2_Debug.exe!std::filesystem::_Throw_fs_error(const char * _Op, const std::error_code & _Error, const std::filesystem::path & _Path1) Line 1863	C++
 	Metin2_Debug.exe!std::filesystem::exists(const std::filesystem::path & _Target) Line 3463	C++
 	Metin2_Debug.exe!CPackManager::IsExist(std::basic_string_view<char,std::char_traits<char>> path) Line 95	C++
 	Metin2_Debug.exe!CResourceManager::IsFileExist(const char * c_szFileName) Line 498	C++
 	Metin2_Debug.exe!CArea::__SetObjectInstance_SetBuilding(CArea::SObjectInstance * pObjectInstance, const CArea::SObjectData * c_pData, CProperty * pProperty) Line 599	C++
 	Metin2_Debug.exe!CArea::__SetObjectInstance(CArea::SObjectInstance * pObjectInstance, const CArea::SObjectData * c_pData) Line 479	C++
 	Metin2_Debug.exe!CArea::__Load_BuildObjectInstances() Line 449	C++
 	Metin2_Debug.exe!CArea::Load(const char * c_szPathName) Line 750	C++
 	Metin2_Debug.exe!CMapOutdoor::LoadArea(unsigned short wAreaCoordX, unsigned short wAreaCoordY, unsigned short wCellCoordX, unsigned short wCellCoordY) Line 173	C++
 	Metin2_Debug.exe!CMapOutdoor::Update(float fX, float fY, float fZ) Line 103	C++
 	Metin2_Debug.exe!CMapOutdoor::Load(float x, float y, float z) Line 40	C++
 	Metin2_Debug.exe!CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z) Line 124	C++
 	Metin2_Debug.exe!CPythonBackground::Warp(unsigned long dwX, unsigned long dwY) Line 744	C++
 	Metin2_Debug.exe!CPythonNetworkStream::Warp(long lGlobalX, long lGlobalY) Line 374	C++
 	Metin2_Debug.exe!netWarp(_object * poSelf, _object * poArgs) Line 81	C++
 	[External Code]
 	Metin2_Debug.exe!CPythonLauncher::RunFile(const char * c_szFileName) Line 319	C++
 	Metin2_Debug.exe!RunMainScript(CPythonLauncher & pyLauncher, const char * lpCmdLine) Line 246	C++
 	Metin2_Debug.exe!Main(HINSTANCE__ * hInstance, char * lpCmdLine) Line 302	C++
 	Metin2_Debug.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 329	C++
 	[External Code]

+		this	0x0000001e1cf2f6a0 {m_load_from_pack=true m_entries={ size=50983 } m_pBufferPool=0x0000001e1d03b350 {...} ...}	const CPackManager *
		buf	<Unable to read memory>
+		path	"d:/ymir work/zone/b/obj/general_obj_stone19_lod_01.gr2"	std::basic_string_view<char,std::char_traits<char>>
2026-02-15 14:33:59 +03:00
Koray
219cf7e624 fix speedtree crash
Unhandled exception at 0x00007FF6DBFC5EB1 (Metin2_Debug.exe) in metin2client__20260215_142707.dmp: 0xC0000005: Access violation reading location 0x0000000000000000.

>	Metin2_Debug.exe!LoadLeafShader(IDirect3DDevice9 * pDx, IDirect3DVertexDeclaration9 * & pVertexDecl, IDirect3DVertexShader9 * & pVertexShader) Line 290	C++
 	Metin2_Debug.exe!CSpeedTreeForestDirectX8::InitVertexShaders() Line 70	C++
 	Metin2_Debug.exe!CSpeedTreeForestDirectX8::SetRenderingDevice(IDirect3DDevice9 * lpDevice) Line 85	C++
 	Metin2_Debug.exe!CMapOutdoor::Load(float x, float y, float z) Line 38	C++
 	Metin2_Debug.exe!CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z) Line 124	C++
 	Metin2_Debug.exe!CPythonBackground::Warp(unsigned long dwX, unsigned long dwY) Line 744	C++
 	Metin2_Debug.exe!CPythonNetworkStream::Warp(long lGlobalX, long lGlobalY) Line 374	C++
 	Metin2_Debug.exe!netWarp(_object * poSelf, _object * poArgs) Line 81	C++
 	[External Code]
 	Metin2_Debug.exe!CPythonLauncher::RunFile(const char * c_szFileName) Line 319	C++
 	Metin2_Debug.exe!RunMainScript(CPythonLauncher & pyLauncher, const char * lpCmdLine) Line 246	C++
 	Metin2_Debug.exe!Main(HINSTANCE__ * hInstance, char * lpCmdLine) Line 302	C++
 	Metin2_Debug.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 329	C++
 	[External Code]
 	[Frames may be missing, no binary loaded for kernel32.dll]
 	[External Code]

+		leafVertexDecl	0x000000dff7aed768 {{Stream=0 Offset=0 Type=2 '\x2' ...}, {Stream=0 Offset=12 Type=4 '\x4' ...}, {Stream=...}, ...}	const _D3DVERTEXELEMENT9[5]
+		pCode	0x0000000000000000 <NULL>	ID3DXBuffer *
+		pDx	0x000000dfbdbc37c0 {...}	IDirect3DDevice9 *
+		pError	0x0000000000000000 <NULL>	ID3DXBuffer *
+		pVertexDecl	0x0000000000000000 <NULL>	IDirect3DVertexDeclaration9 * &
+		pVertexShader	0x0000000000000000 <NULL>	IDirect3DVertexShader9 * &
2026-02-15 14:31:32 +03:00
Koray
eaf744e48d fix unknown encoding: utf-8-sig
Fix for:
Fatal Python error: init_import_site: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1179, in exec_module
  File "<frozen site>", line 723, in <module>
  File "<frozen site>", line 709, in main
  File "<frozen site>", line 382, in addusersitepackages
  File "<frozen site>", line 254, in addsitedir
  File "<frozen site>", line 197, in addpackage
LookupError: unknown encoding: utf-8-sig
2026-02-15 14:11:26 +03:00
rtw1x1
06a686672b Merge pull request #105 from rtw1x1/main
Packet miss match
2026-02-13 00:00:50 +00:00
rtw1x1
c34b46a9a4 Packet miss match
fixed: Packet miss match for command_safebox_money

fixed: Py_BuildException

log: Detailed TraceError for CreateMemoryFile
2026-02-13 00:00:23 +00:00
rtw1x1
eea43e504c Merge pull request #104 from MindRapist/mr-11
Several bug fixes
2026-02-12 23:51:49 +00:00
Mind Rapist
7a942e4fc0 Several bug fixes 2026-02-13 01:48:07 +02:00
rtw1x1
aa30091ced Merge pull request #103 from mq1n/main
fix rare crash after char select
2026-02-12 22:54:55 +00:00
Koray
9a896f982d fix rare crash after char select 2026-02-10 14:37:38 +03:00
d1str4ught
4bd8f8e66e Merge pull request #101 from SunTrustDev/bugfix/tolower_breaking_utf8
tolower breaking utf8
2026-02-09 02:54:04 +01:00
SuntrustDev
335da689b6 Merge branch 'main' of https://github.com/d1str4ught/m2dev-client-src into bugfix/tolower_breaking_utf8 2026-02-09 02:48:00 +01:00
d1str4ught
6dfb708888 crash fix: when __ClearReserveDeleteWindowList() was destroying Windows, some might have pushed it's children for deletion to m_ReserveDeleteWindowList, invalidating iterators 2026-02-09 02:43:36 +01:00
SuntrustDev
6929730dd6 Change from korean_tolower to ascii_tolower for better understandability 2026-02-09 02:41:59 +01:00
d1str4ught
73defc20d0 crash fix: when __ClearReserveDeleteWindowList() was destroying Windows, some might have pushed it's children for deletion to m_ReserveDeleteWindowList, invalidating iterators 2026-02-09 02:34:03 +01:00
d1str4ught
de25f437ed python3 lib with JIT enabled 2026-02-09 01:26:46 +01:00
d1str4ught
85609303d8 python 2.7 -> python 3.14 2026-02-09 01:07:50 +01:00
rtw1x1
0ca2a293c8 Merge pull request #100 from SunTrustDev/bugfix/guild-packet-crashes 2026-02-08 23:27:59 +00:00
SuntrustDev
19b894ba8f Fix guild packet lenth dismatch by adding parameter length 2026-02-09 00:20:54 +01:00
rtw1x1
57691c7dbc Merge pull request #99 from SunTrustDev/bugfix/missing-freetype 2026-02-08 21:44:12 +00:00
SuntrustDev
e3731fda30 Add missing freetype 2026-02-08 22:40:02 +01:00
rtw1x1
a1f47ea520 Merge pull request #98 from MindRapist/mr-10 2026-02-08 21:33:15 +00:00
Mind Rapist
39030c5aed FreeType added, synched POINT_*'s, Celine's Splash Fix 2026-02-08 23:32:06 +02:00
rtw1x1
2b82fe2678 Merge pull request #97 from SunTrustDev/bugfix/refine-not-showing 2026-02-08 21:27:24 +00:00
SuntrustDev
23aa6807ef Fix refine not showing item information 2026-02-08 22:24:15 +01:00
rtw1x1
43af66b808 Merge pull request #96 from rtw1x1/main
FreeType2 & Networking Overhaul
2026-02-08 20:03:55 +00:00
rtw1x1
a40c11859e Merge branch 'd1str4ught:main' into main 2026-02-08 07:37:20 +00:00
rtw1x1
cda1c73bd3 Networking Overhaul: Modern packets, buffers, handshake, dispatch & security hardening
See Readme
2026-02-08 07:36:07 +00:00
d1str4ught
9afd6ee906 deform optimized even more 2026-02-08 07:35:41 +01:00
rtw1x1
058589ca1b Merge branch 'd1str4ught:main' into main 2026-02-08 06:34:04 +00:00
rtw1x1
e0be217d3f Merge pull request #94 from MindRapist/mr-9 2026-02-06 21:16:25 +00:00
Mind Rapist
a865e0c00f MR-9: Instructions in README 2026-02-05 00:34:53 +02:00
rtw1x1
87cfa1540f FreeType: LCD subpixel 2026-02-04 12:30:14 +00:00
rtw1x1
ba514d2e9a FreeType: Kerning API and font adjustments 2026-02-04 11:59:36 +00:00
rtw1x1
4280220819 FreeType: TextBar boldness fix 2026-02-04 10:50:00 +00:00
rtw1x1
a3009f4bff FreeType: Fixed mem leak and adjustments 2026-02-04 10:35:46 +00:00
rtw1x1
8f0b956fa9 Add FreeType 2-13.3 (vendor, LFS) 2026-02-04 08:43:22 +00:00
rtw1x1
ce5ef584c9 Implementation FreeType2-13.3 2026-02-04 08:37:37 +00:00
rtw1x1
00cd91524e Merge pull request #91 from rtw1x1/main
Client: Implementation XChaCha20-Poly1305 via libsodium & client login key reworked
2026-02-04 08:23:42 +00:00
rtw1x1
a9407a5781 fix: Key validation failure 2026-02-03 11:58:21 +00:00
rtw1x1
509e2638cb XChaCha20-Poly1305 via libsodium 2026-02-03 11:12:32 +00:00
rtw1x1
857ef33627 Merge pull request #89 from MindL0ve/main 2026-02-01 20:52:57 +00:00
MindL0ve
ac7c9aed7c Removed AlphaFog 2026-02-01 00:31:21 +03:00
MindL0ve
4a85743893 Removed Themida 2026-01-31 23:46:32 +03:00
MindL0ve
eb4dd129b9 Update NetStream.cpp 2026-01-31 23:40:14 +03:00
d1str4ught
30ff18e982 helping branch prediction 2026-01-30 03:29:58 +01:00
d1str4ught
1eb9743742 character instance sorting to reduce overdraw 2026-01-30 02:46:33 +01:00
d1str4ught
eadd6fa878 Update README.md 2026-01-30 01:23:41 +01:00
d1str4ught
48807bfc20 Merge pull request #86 from SunTrustDev/feature/STD-3
Remove unused atlas marker info (_point.txt files)
2026-01-30 01:17:53 +01:00
rtw1x1
ac7306efb9 Merge pull request #87 from rtw1x1/main
QoL: LimitType & Value
2026-01-21 21:49:16 +00:00
rtw1x1
50a665af78 QoL: LimitType & Value 2026-01-21 21:46:41 +00:00
Simone Romano
04c1806a8b Remove unused atlas marker info (_point.txt files) 2026-01-21 22:44:55 +01:00
rtw1x1
ac614c2303 Merge pull request #85 from rtw1x1/main
fix: Mark refresh and BGM failure
2026-01-21 18:34:09 +00:00
rtw1x1
aabb6d0945 fix: Mark cooldown request 2026-01-21 18:31:43 +00:00
rtw1x1
b04f360612 fix: BGM failed to load 2026-01-21 12:39:38 +00:00
rtw1x1
2e2becf1a3 fix: Refresh Mark & Mark window lag spike
Added Server-Side mark broadcast
2026-01-21 08:34:32 +00:00
rtw1x1
9299cea61c Merge pull request #84 from rtw1x1/main
ML: Item / Mob / NPC client sided
2026-01-21 01:53:20 +00:00
rtw1x1
9eea8d9bc0 ML-Client: Item Names client sided 2026-01-21 01:51:43 +00:00
rtw1x1
e40fdcb7d6 ML-Client: NPC Names client sided #2 2026-01-21 01:07:17 +00:00
rtw1x1
1903420820 ML-Client: NPC Names client sided 2026-01-21 00:22:18 +00:00
rtw1x1
4e41646822 Merge pull request #82 from MindRapist/mr-8
MR-8: Fix semi-transparent effects
2026-01-20 22:55:30 +00:00
rtw1x1
7d0b5d545d Merge pull request #81 from ErLullo/letter-autoremove
letter-autoremove fix
2026-01-20 22:55:09 +00:00
rtw1x1
e38dfaca45 Merge pull request #83 from rtw1x1/main
Optimization for BiDi algorithm, UTF8, Debug, Arabic.
Fixed skill desc
2026-01-20 21:25:14 +00:00
rtw1x1
100dd2b87b fix: Optimized UTF8, BiDi, Debug 2026-01-20 21:23:31 +00:00
Mind Rapist
4df27653da MR-8: Fix semi-transparent effects 2026-01-18 09:00:29 +02:00
ErLullo
d08b2fb53b letter-autoremove fix 2026-01-15 11:12:35 +01:00
rtw1x1
ba79e137f0 Merge pull request #79 from rtw1x1/main
ML: Hot-Reload Locale
2026-01-07 20:20:40 +00:00
rtw1x1
34c6e514d4 Merge branch 'd1str4ught:main' into main 2026-01-07 17:53:31 +00:00
rtw1x1
874f6a7fd5 Merge pull request #72 from savisxss/main 2026-01-07 17:40:58 +00:00
rtw1x1
86a6fbb1d2 Merge pull request #78 from amun3808/main 2026-01-07 17:40:39 +00:00
Amun
6320f99388 Sound effects volume bug 2026-01-07 18:47:25 +02:00
savis
b94b971e32 Refactor GameThreadPool for improved thread-safety and lifecycle management 2026-01-07 15:26:37 +01:00
savis
3b32269a74 Merge branch 'main' of https://github.com/savisxss/m2dev-client-src-1 2026-01-07 15:22:42 +01:00
savis
144dddb518 removed preload motions 2026-01-07 15:22:32 +01:00
rtw1x1
dfe2368c8f ML: Refactored Hot-Reload System 2026-01-07 09:55:18 +00:00
rtw1x1
c4cc59a4f2 ML: Hot reload locale system 2026-01-05 18:55:36 +00:00
savis
2243141402 Merge branch 'main' of https://github.com/savisxss/m2dev-client-src-1 2026-01-05 17:42:19 +01:00
savis
4e68003fdd Consolidate file loading threading to CGameThreadPool 2026-01-05 17:42:13 +01:00
rtw1x1
f19dfa1fe2 Merge pull request #74 from savisxss/dsdsdsds 2026-01-05 16:21:48 +00:00
savis
7718c65d7a add GameThreadPool 2026-01-05 17:20:12 +01:00
rtw1x1
dbdfd57c41 Merge pull request #73 from d1str4ught/rtw1x1-patch-1
Reverted horse rotation speed
2026-01-05 15:29:28 +00:00
rtw1x1
d5c659d404 Reverted horse rotation speed 2026-01-05 15:29:02 +00:00
savis
40625c8bd8 add DumpProto 2026-01-05 15:58:48 +01:00
rtw1x1
625849e0e4 Merge pull request #70 from savisxss/main 2026-01-04 19:51:40 +00:00
savis
074a05bb9b Optimize terrain 2026-01-04 19:44:59 +01:00
rtw1x1
b4171084c3 Merge pull request #68 from savisxss/main
Add parallel race/motion loading and thread-safe Pack/Pool managers
2026-01-04 16:30:19 +00:00
savis
d5624a8cdd Add parallel race/motion loading and thread-safe Pack/Pool managers 2026-01-04 17:27:32 +01:00
rtw1x1
fa96b25dad Merge pull request #46 from rfdomingues98/fix/client-freeze-on-drag
Added Amun fix for window freeze on drag
2026-01-04 11:10:38 +00:00
rtw1x1
9b57cd1414 Merge branch 'main' into fix/client-freeze-on-drag 2026-01-04 11:10:28 +00:00
rtw1x1
54b6f8c4a9 Merge pull request #67 from savisxss/main
eliminate freeze when encountering players by preloading race motions
2026-01-04 09:43:36 +00:00
savis
2550008f6d eliminate freeze when encountering players by preloading race motions 2026-01-04 10:41:48 +01:00
rtw1x1
4c21fe697c Merge pull request #66 from rfdomingues98/feat/add-bravery-cape-effect
Added new effect for Bravery Cape
2026-01-04 09:29:14 +00:00
rtw1x1
3d8a8f8e3b Merge pull request #65 from savisxss/main
A bit late, but Happy New Year!
2026-01-04 09:29:02 +00:00
rtw1x1
3b359393d1 Merge pull request #63 from MindRapist/mr-7
MR-7
2026-01-04 09:28:48 +00:00
Ricardo Domingues
117f1234b5 Added new effect for Bravery Cape 2026-01-03 20:47:56 +00:00
savis
6fcf2c58e2 Parallelize pack file initialization
- Load pack files across multiple threads
- Scales to CPU core count
- Load root.pck first, then parallelize remaining packs
- Track and report failed pack loads
2026-01-03 20:38:21 +01:00
savis
de0b8052fe Batch terrain texture loading
- Pre-request all textures for async loading
- Reduces sequential blocking during terrain load
2026-01-03 20:38:10 +01:00
savis
6984fef736 Integrate async loading infrastructure
- Initialize FileLoaderThreadPool and TextureCache
- Route file requests through thread pool
- Handle pre-decoded images from worker threads
- Reduce loading delay from 20ms to 1ms
- 512MB texture cache (up from 256MB)
2026-01-03 20:38:02 +01:00
savis
f702b4953d Add support for pre-decoded image loading
- OnLoadFromDecodedData method for async decoded images
- Bypasses redundant decoding when data comes from worker thread
- Integrates with FileLoaderThreadPool pipeline
2026-01-03 20:37:52 +01:00
savis
3f0f3c792d Add SIMD-optimized texture color conversion
- SSE2/SSSE3 RGBA to BGRA conversion (10x faster)
- Processes 4 pixels per iteration
- Automatic fallback for non-x86 platforms
- Applied to both STB and decoded image paths
2026-01-03 20:37:41 +01:00
savis
e55fc4db17 Optimize pack file loading
- Add thread-local ZSTD decompression context reuse
- Integrate BufferPool for temporary buffers
- PackManager auto-uses BufferPool for all GetFile calls
- Thread-safe pack loading with mutex
2026-01-03 20:37:32 +01:00
savis
0958ea6214 Add multi-threaded file loader pool
- 4-16 worker threads based on CPU core count
- Auto-detects and decodes images on worker threads
- SPSC queues: 16K request, 32K completion
- Atomic task counter for fast idle checks
- Smart idle handling with yield and minimal sleep
2026-01-03 20:37:22 +01:00
savis
049eca38a4 Add LRU texture cache
- 512MB default cache size for decoded textures
- Thread-safe LRU eviction policy
- Tracks hit/miss statistics
- Prevents re-decoding frequently used textures
2026-01-03 20:37:08 +01:00
savis
fd1218bd4e Add worker-thread image decoder
- Decodes DDS, PNG, JPG, TGA, BMP formats
- Thread-safe for use in worker threads
- Uses stb_image for common formats
- Custom DDS header parsing
2026-01-03 20:36:37 +01:00
savis
c6aa6b4149 Add decoded image data structure
- Stores decoded pixel data ready for GPU upload
- Supports RGBA8, RGB8, and DDS formats
- Separates CPU decoding from GPU upload phases
2026-01-03 20:35:45 +01:00
savis
7fb832ad6b Add buffer pool for I/O operations
- Reuses vector<uint8_t> buffers to reduce allocations
- Thread-safe with mutex protection
- Max 64 buffers, 64MB buffer size limit
- Tracks allocation statistics and pooled memory
2026-01-03 20:35:06 +01:00
savis
33ac4b69f4 Add lock-free SPSC queue implementation
- Single producer/single consumer bounded queue
- Cache-line aligned atomics to prevent false sharing
- Used for async file loading communication
2026-01-03 20:34:47 +01:00
Mind Rapist
efbdf9155e Minor fixes & corrections 2026-01-02 06:33:57 +02:00
Ricardo Domingues
e881517775 Merge branch 'main' into fix/client-freeze-on-drag 2025-12-30 17:51:50 +00:00
Ricardo Domingues
96876420d1 Increased horse rotation speed 2025-12-30 17:37:42 +00:00
Ricardo Domingues
46f2c9de0f Updated README 2025-12-26 19:18:41 +00:00
Ricardo Domingues
2a8d881ef3 Added Amun fix for window freeze on drag 2025-12-26 19:13:40 +00:00
2675 changed files with 1294701 additions and 273501 deletions

49
AGENTS.md Normal file
View File

@@ -0,0 +1,49 @@
# AGENTS.md
## Repository Role
This repository contains the Windows client source code and build system.
It owns:
- client executable source
- protocol/client networking code
- UI/client runtime C++ modules
- build-time tools such as client-side pack/proto helpers
## Working Rules
- Treat this repository as Windows-first.
- Prefer protocol-safe, targeted changes over broad refactors.
- Keep packet and login-flow changes aligned with `m2dev-server-src`.
- Do not mix packed asset/data changes into this repository unless they are source-side build assets.
## Build Notes
Typical build entrypoint:
```bash
cmake -S . -B build
cmake --build build
```
In practice, most real builds happen on Windows with Visual Studio toolchains.
## High-Risk Areas
- `src/UserInterface/Packet.h`
- `AccountConnector`
- `PythonNetworkStream*`
- `NetStream`
When changing login/auth/protocol behavior:
- mirror the server-side packet expectations in `m2dev-server-src`
- verify the live asset-side flow in `m2dev-client`
- avoid silent header drift between client and server
## Cross-Repo Boundaries
- client executable and protocol code belong here
- packed/unpacked client data under `assets/` belong in `m2dev-client`
- server packet/auth implementation belongs in `m2dev-server-src`

10
CLAUDE.md Normal file
View File

@@ -0,0 +1,10 @@
# CLAUDE.md
Follow [AGENTS.md](AGENTS.md) as the canonical repo guide.
Short version:
- this is the Windows client source repo
- protocol/login changes must stay aligned with `m2dev-server-src`
- asset-side login/serverlist behavior lives in `m2dev-client`
- avoid broad refactors unless the task is explicitly architectural

View File

@@ -33,6 +33,7 @@ endif()
add_compile_options( add_compile_options(
$<$<CXX_COMPILER_ID:MSVC>:/wd4828> $<$<CXX_COMPILER_ID:MSVC>:/wd4828>
$<$<CXX_COMPILER_ID:MSVC>:/wd4996> $<$<CXX_COMPILER_ID:MSVC>:/wd4996>
$<$<CXX_COMPILER_ID:MSVC>:/wd5033>
) )
# ASan flags # ASan flags
@@ -65,6 +66,8 @@ add_compile_definitions("$<$<CONFIG:Release>:_DISTRIBUTE>")
include_directories("src") include_directories("src")
include_directories("extern/include") include_directories("extern/include")
include_directories("vendor/libsodium/src/libsodium/include")
include_directories("vendor/freetype-2.13.3/include")
# Add subdirectories for libraries and executables # Add subdirectories for libraries and executables
add_subdirectory(vendor) add_subdirectory(vendor)

222
README.md
View File

@@ -1,16 +1,230 @@
# Client Source Repository # M2Dev Client Source
[![build](https://github.com/d1str4ught/m2dev-client-src/actions/workflows/main.yml/badge.svg)](https://github.com/d1str4ught/m2dev-client-src/actions/workflows/main.yml)
This repository contains the source code necessary to compile the game client executable. This repository contains the source code necessary to compile the game client executable.
## How to build ## How to build (short version)
> cmake -S . -B build > cmake -S . -B build
> >
> cmake --build build > cmake --build build
**For more installation/configuration, check out the [instructions](#installationconfiguration) below.**
--- ---
## 📋 Changelog ## 📋 Changelog
### 🐛 Bug fixes
- **Affect tooltips**: ALL affects now display realtime countdowns, titles and are wrapped in tooltips! Realtime countdowns does not apply to infinite affects such as the Exorcism Scroll, the Concentrated Reading and the Medal of the Dragon (Death penalty prevention)
- **AFFECT_FIRE**: The Continuous Fire debuff has been added to the affects dictionary by name.
### 🐛 Bug Fixes <br>
* **PK Mode:** Resolved conflict for Hostile mode when both players have negative alignment, added PK_PROTECT mode safeguards. <br>
---
<br>
<br>
# Installation/Configuration
This is the third part of the entire project and it's about the client binary, the executable of the game.
Below you will find a comprehensive guide on how to configure all the necessary components from scratch.
This guide is made using a **Windows** environment as the main environment and **cannot work in non-Windows operating systems!**
This guide also uses the latest versions for all software demonstrated as of its creation date at February 4, 2026.
© All copyrights reserved to the owners/developers of any third party software demonstrated in this guide other than this project/group of projects.
<br>
### 📋 Order of projects configuration
If one or more of the previous items is not yet configured please come back to this section after you complete their configuration steps.
> - ✅ [M2Dev Server Source](https://github.com/d1str4ught/m2dev-server-src)
> - ✅ [M2Dev Server](https://github.com/d1str4ught/m2dev-server)
> - ▶️ [M2Dev Client Source](https://github.com/d1str4ught/m2dev-client-src)&nbsp;&nbsp;&nbsp;&nbsp;[**YOU ARE HERE**]
> - ⏳ [M2Dev Client](https://github.com/d1str4ught/m2dev-client)&nbsp;&nbsp;&nbsp;&nbsp;[**ALSO CONTAINS ADDITIONAL INFORMATION FOR POST-INSTALLATION STEPS**]
<br>
### 🧱 Software Prerequisites
<details>
<summary>
Please make sure that you have installed the following software in your machine before continuing:
</summary>
<br>
> <br>
>
> - ![Visual Studio](https://metin2.download/picture/B6U1Pg0lMlA486D1ekVLIytP72pDP8Yg/.png)&nbsp;&nbsp;**Visual Studio**:&nbsp;&nbsp;The software used to edit and compile the source code. [Download](https://visualstudio.microsoft.com/vs/)
>
> - ![Visual Studio Code](https://metin2.download/picture/Hp33762v422mjz6lgil91Gey380NwA7j/.png)&nbsp;&nbsp;**Visual Studio Code (VS Code)**:&nbsp;&nbsp;A lighter alternative to Visual Studio, harder to build the project in this software but it is recommended for code editing. [Download](https://code.visualstudio.com/Download)
> - ![Git](https://metin2.download/picture/eCpg436LhgG1zg9ZqvyfcANS68F60y6O/.png)&nbsp;&nbsp;**Git**:&nbsp;&nbsp;Used to clone the repositories in your Windows machine. [Download](https://git-scm.com/install/windows)
> - ![CMake](https://metin2.download/picture/6O8Ho9N0XScDaLLL8h0lrkh8DcKlgJ6M/.png)&nbsp;&nbsp;**CMake**:&nbsp;&nbsp;Required for setting up and configuring the build of the source code. [Download](https://git-scm.com/install/windows)
> - ![Notepad++](https://metin2.download/picture/7Vf5Yv1T48nHprT2hiH0VfZx635HAZP2/.png)&nbsp;&nbsp;**Notepad++ (optional but recommended)**:&nbsp;&nbsp;Helps with quick, last minute edits. [Download](https://notepad-plus-plus.org/downloads/)
>
> <br>
>
</details>
<br>
### 👁️ Required Visual Studio packages
Make sure you have installed these packages with Visual Studio Installer in order to compile C++ codebases:
<details>
<summary>
Packages
</summary>
<br>
>
> <br>
>
> ![](https://metin2.download/picture/Rh6PJwXf0J6Y3TZFg7Zx8HVBUGNXDVDN/.png)
>
> ![](https://metin2.download/picture/1eoYD0IJB5k9c9BhhyWTjDVm6zidv8rM/.png)
>
> **Note**: **Windows 11 SDK**'s can be replaced by **Windows 10 SDK**'s, but it is recommended to install one of them.
>
> <br>
>
</details>
<br>
### ⬇️ Obtaining the Client Source
To build the source for the first time, you first need to clone it. In your command prompt, `cd` into your desired location or create a new folder wherever you want and download the project using `Git`.
<details>
<summary>
Here's how
</summary>
<br>
>
> <br>
>
>
> Open up your terminal inside or `cd` into your desired folder and type this command:
>
> ```
> git clone https://github.com/d1str4ught/m2dev-client-src.git
> ```
>
> <br>
>
> ### ✅ You have successfully obtained the Client Source project!
>
> <br>
>
</details>
<br>
### 🛠️ Building the Source Code
Building the project is extremely simple, if all Visual Studio components are being installed correctly.
<details>
<summary>
Instructions
</summary>
<br>
>
> <br>
>
> Open up your terminal inside, or `cd` in your project's root working directory and initialize the build with this command:
>
> ```
> cmake -S . -B build
> ```
>
> A new `build` folder has been created in your project's root directory. This folder contains all the build files and configurations, along with the `sln` file to open the project in Visual Studio.
>
> ![](https://metin2.download/picture/icUIK7eITD7ng1jNmMtz3N1jhc6GjKS9/.png)
>
> ![](https://metin2.download/picture/jS099wxf40xlxdPXRy1ZR7YqO86h7N3w/.png)
>
> Double click on that file to launch Visual Studio and load the project.
>
> In the Solution Explorer, select all the projects minus the container folders, right click on one of the selected items, and click **Properties**
>
> ![](https://metin2.download/picture/J6aHw6uw330DeqyTaw2ZDVgRcT9hr3hr/.png)
>
> Next, make sure that the following settings are adjusted like this:
>
> 1. **Windows SDK Version** should be the latest of Windows 10. It is not recommended to select any Windows 11 versions yet if avalable.
> 2. **Platform Toolset** is the most important part for your build to succeed! Select the highest number you see. **v145** is for Visual Studio 2026. If you are running Visual Studio 2022 you won't have that, you will have **v143**, select that one, same goes for older Visual Studio versions.
> 3. **C++ Language Standard** should be C++20 as it is the new standard defined in the CMakeList.txt files as well. Might as well set it like that for all dependencies.
> 4. **C Language Standard** should be C17 as it is the new standard defined in the CMakeList.txt files as well. Might as well set it like that for all dependencies.
>
> Once done, click Apply and then OK to close this dialog.
>
> ![](https://metin2.download/picture/2uacNZ4zOCYfI6vmigMTFwbuQ4tcmZ1C/.png)
>
> After that, in the toolbar at the top of the window, select your desired output configuration:
>
> ![](https://metin2.download/picture/cB0AGhHJ3TKFResDSeIgGmF7Vbo2SyGK/.png)
>
> Finally, click on the **Build** option at the top and select **Build Solution**, or simply press **CTRL+SHIFT+B** in your keyboard with all the projects selected.
>
> ![](https://metin2.download/picture/EN38Dz0Yef2edZ5Ptp4a5t4xWs1tr9V5/.png)
>
> **Note**: if this is **NOT** your first build after executing the `cmake -S . -B build` command for this workspace, it is recommended to click **Clean Solution** before **Build Solution**.
>
> <br>
>
> Where to find your compiled binaries:
>
> Inside the **build** folder in your cloned repository, you should have a **bin** folder and inside that, you should have a **Debug**, **Release**, **RelWithDebInfo** or **MinSizeRel** folder, depending on your build configuration selection.
>
> In that folder you should be seeing all your binaries:
>
> ![](https://metin2.download/picture/4cVxiU2Ac8CON58Gh70f6Do34dGBXpOz/.png)
>
> If you did **NOT** install the **Client** project yet, you are done here.
>
> If you **HAVE** the **Client** project installed, paste these 2 `.exe` files in these locations inside the Server project:
>
> - **Metin2_<Debug|Release|RelWithDebInfo|MinSizeRel>.exe**: inside root folder of the Client project
> - **PackMaker.exe**: inside `assets\PackMaker.exe`
>
> <br>
>
> ### ✅ You have successfully built the Client Source!
>
> <br>
>
</details>
<br>
<br>
---
<br>
<br>
## 🔥 The Client Source part of the guide is complete!
<br>
<br>
## Next steps
You should now be finally ready to proceed to [Client project](https://github.com/d1str4ught/m2dev-client) packing and entering the game for the first time!
**NEW**: We are now on Discord, feel free to [check us out](https://discord.gg/ETnBChu2Ca)!

View File

@@ -0,0 +1,147 @@
# Pack Profile Analysis
The client can now emit a runtime pack profiler report into:
```text
log/pack_profile.txt
```
Enable it with either:
```bash
M2PACK_PROFILE=1 ./scripts/run-wine-headless.sh ./build-mingw64-lld/bin
```
or:
```bash
./scripts/run-wine-headless.sh ./build-mingw64-lld/bin -- --m2pack-profile
```
## Typical workflow
Collect two runs with the same scenario:
1. legacy `.pck` runtime
2. `m2p` runtime
After each run, copy or rename the profiler output so it is not overwritten:
```bash
cp build-mingw64-lld/bin/log/pack_profile.txt logs/pack_profile.pck.txt
cp build-mingw64-lld/bin/log/pack_profile.txt logs/pack_profile.m2p.txt
```
Then compare both runs:
```bash
python3 scripts/pack-profile-report.py \
pck=logs/pack_profile.pck.txt \
m2p=logs/pack_profile.m2p.txt
```
For repeated testing, use the wrapper scripts:
```bash
./scripts/capture-pack-profile.sh \
--runtime-root ../m2dev-client \
--label pck
```
This stages the runtime into `build-mingw64-lld/bin`, runs the client with
`M2PACK_PROFILE=1`, then archives:
- raw report: `build-mingw64-lld/bin/log/pack-profile-runs/<label>.pack_profile.txt`
- parsed summary: `build-mingw64-lld/bin/log/pack-profile-runs/<label>.summary.txt`
To run a full `pck` vs `m2p` comparison in one go:
```bash
./scripts/compare-pack-profile-runs.sh \
--left-label pck \
--left-runtime-root /path/to/runtime-pck \
--right-label m2p \
--right-runtime-root /path/to/runtime-m2p
```
The script captures both runs back-to-back and writes a combined compare report
into the same output directory.
## Real game-flow smoke compare
Startup-only runs are useful for bootstrap regressions, but they do not show the
real hot path once the client reaches `login`, `loading`, and `game`.
For that case, use the CH99 GM smoke compare wrapper:
```bash
python3 scripts/compare-pack-profile-gm-smoke.py \
--left-label pck-only \
--left-runtime-root /path/to/runtime-pck \
--right-label secure-mixed \
--right-runtime-root /path/to/runtime-m2p \
--master-key /path/to/master.key \
--sign-pubkey /path/to/signing.pub \
--account-login admin
```
What it does:
- copies the built client into a temporary workspace outside the repository
- stages each runtime into that workspace
- temporarily updates the selected GM account password and map position
- auto-logins through the special GM smoke channel (`11991` by default)
- enters game, performs one deterministic GM warp, archives `pack_profile.txt`
- restores the account password and the character map/position afterward
- deletes the temporary workspace unless `--keep-workspaces` is used
Archived outputs per run:
- raw report: `<out-dir>/<label>.pack_profile.txt`
- parsed summary: `<out-dir>/<label>.summary.txt`
- headless trace: `<out-dir>/<label>.headless_gm_teleport_trace.txt`
- startup trace when present: `<out-dir>/<label>.startup_trace.txt`
This flow is the current best approximation of a real client loading path on the
Linux-hosted Wine setup because it records phase markers beyond pure startup.
You can also summarize a single run:
```bash
python3 scripts/pack-profile-report.py logs/pack_profile.m2p.txt
```
## What to read first
`Packed Load Totals`
- Best top-level comparison for pack I/O cost in the measured run.
- Focus on `delta_ms` and `delta_pct`.
`Phase Markers`
- Shows where startup time actually moved.
- Useful for deciding whether the gain happened before login, during loading, or mostly in game.
`Load Time By Phase`
- Confirms which phase is paying for asset work.
- Usually the most important line is `loading`.
`Loader Stages`
- Shows whether the cost is mostly in decrypt or zstd.
- For `m2p`, expect small manifest overhead and the main costs in `aead_decrypt` and `zstd_decompress`.
- For legacy `.pck`, expect `xchacha20_decrypt` and `zstd_decompress`.
`Top Phase Pack Loads`
- Useful when the total difference is small, but one or two packs dominate the budget.
## Decision hints
If `Packed Load Totals` improve, but `Phase Markers` do not, the bottleneck is probably outside pack loading.
If `zstd_decompress` dominates both formats, the next lever is compression strategy and pack layout.
If decrypt dominates, the next lever is reducing decrypt work on the hot path or changing how often the same data is touched.

View File

@@ -1,535 +0,0 @@
/* File automatically generated by Parser/asdl_c.py. */
#include "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, AugLoad=4, AugStore=5,
Param=6 } expr_context_ty;
typedef struct _slice *slice_ty;
typedef enum _boolop { And=1, Or=2 } boolop_ty;
typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7,
RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 }
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 _keyword *keyword_ty;
typedef struct _alias *alias_ty;
enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
Suite_kind=4};
struct _mod {
enum _mod_kind kind;
union {
struct {
asdl_seq *body;
} Module;
struct {
asdl_seq *body;
} Interactive;
struct {
expr_ty body;
} Expression;
struct {
asdl_seq *body;
} Suite;
} v;
};
enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7,
For_kind=8, While_kind=9, If_kind=10, With_kind=11,
Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14,
Assert_kind=15, Import_kind=16, ImportFrom_kind=17,
Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21,
Break_kind=22, Continue_kind=23};
struct _stmt {
enum _stmt_kind kind;
union {
struct {
identifier name;
arguments_ty args;
asdl_seq *body;
asdl_seq *decorator_list;
} FunctionDef;
struct {
identifier name;
asdl_seq *bases;
asdl_seq *body;
asdl_seq *decorator_list;
} ClassDef;
struct {
expr_ty value;
} Return;
struct {
asdl_seq *targets;
} Delete;
struct {
asdl_seq *targets;
expr_ty value;
} Assign;
struct {
expr_ty target;
operator_ty op;
expr_ty value;
} AugAssign;
struct {
expr_ty dest;
asdl_seq *values;
bool nl;
} Print;
struct {
expr_ty target;
expr_ty iter;
asdl_seq *body;
asdl_seq *orelse;
} For;
struct {
expr_ty test;
asdl_seq *body;
asdl_seq *orelse;
} While;
struct {
expr_ty test;
asdl_seq *body;
asdl_seq *orelse;
} If;
struct {
expr_ty context_expr;
expr_ty optional_vars;
asdl_seq *body;
} With;
struct {
expr_ty type;
expr_ty inst;
expr_ty tback;
} Raise;
struct {
asdl_seq *body;
asdl_seq *handlers;
asdl_seq *orelse;
} TryExcept;
struct {
asdl_seq *body;
asdl_seq *finalbody;
} TryFinally;
struct {
expr_ty test;
expr_ty msg;
} Assert;
struct {
asdl_seq *names;
} Import;
struct {
identifier module;
asdl_seq *names;
int level;
} ImportFrom;
struct {
expr_ty body;
expr_ty globals;
expr_ty locals;
} Exec;
struct {
asdl_seq *names;
} Global;
struct {
expr_ty value;
} Expr;
} v;
int lineno;
int col_offset;
};
enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8,
SetComp_kind=9, DictComp_kind=10, GeneratorExp_kind=11,
Yield_kind=12, Compare_kind=13, Call_kind=14, Repr_kind=15,
Num_kind=16, Str_kind=17, Attribute_kind=18,
Subscript_kind=19, Name_kind=20, List_kind=21, Tuple_kind=22};
struct _expr {
enum _expr_kind kind;
union {
struct {
boolop_ty op;
asdl_seq *values;
} BoolOp;
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_seq *keys;
asdl_seq *values;
} Dict;
struct {
asdl_seq *elts;
} Set;
struct {
expr_ty elt;
asdl_seq *generators;
} ListComp;
struct {
expr_ty elt;
asdl_seq *generators;
} SetComp;
struct {
expr_ty key;
expr_ty value;
asdl_seq *generators;
} DictComp;
struct {
expr_ty elt;
asdl_seq *generators;
} GeneratorExp;
struct {
expr_ty value;
} Yield;
struct {
expr_ty left;
asdl_int_seq *ops;
asdl_seq *comparators;
} Compare;
struct {
expr_ty func;
asdl_seq *args;
asdl_seq *keywords;
expr_ty starargs;
expr_ty kwargs;
} Call;
struct {
expr_ty value;
} Repr;
struct {
object n;
} Num;
struct {
string s;
} Str;
struct {
expr_ty value;
identifier attr;
expr_context_ty ctx;
} Attribute;
struct {
expr_ty value;
slice_ty slice;
expr_context_ty ctx;
} Subscript;
struct {
identifier id;
expr_context_ty ctx;
} Name;
struct {
asdl_seq *elts;
expr_context_ty ctx;
} List;
struct {
asdl_seq *elts;
expr_context_ty ctx;
} Tuple;
} v;
int lineno;
int col_offset;
};
enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4};
struct _slice {
enum _slice_kind kind;
union {
struct {
expr_ty lower;
expr_ty upper;
expr_ty step;
} Slice;
struct {
asdl_seq *dims;
} ExtSlice;
struct {
expr_ty value;
} Index;
} v;
};
struct _comprehension {
expr_ty target;
expr_ty iter;
asdl_seq *ifs;
};
enum _excepthandler_kind {ExceptHandler_kind=1};
struct _excepthandler {
enum _excepthandler_kind kind;
union {
struct {
expr_ty type;
expr_ty name;
asdl_seq *body;
} ExceptHandler;
} v;
int lineno;
int col_offset;
};
struct _arguments {
asdl_seq *args;
identifier vararg;
identifier kwarg;
asdl_seq *defaults;
};
struct _keyword {
identifier arg;
expr_ty value;
};
struct _alias {
identifier name;
identifier asname;
};
#define Module(a0, a1) _Py_Module(a0, a1)
mod_ty _Py_Module(asdl_seq * body, PyArena *arena);
#define Interactive(a0, a1) _Py_Interactive(a0, a1)
mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena);
#define Expression(a0, a1) _Py_Expression(a0, a1)
mod_ty _Py_Expression(expr_ty body, PyArena *arena);
#define Suite(a0, a1) _Py_Suite(a0, a1)
mod_ty _Py_Suite(asdl_seq * body, PyArena *arena);
#define FunctionDef(a0, a1, a2, a3, a4, a5, a6) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6)
stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
asdl_seq * decorator_list, int lineno, int col_offset,
PyArena *arena);
#define ClassDef(a0, a1, a2, a3, a4, a5, a6) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6)
stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body,
asdl_seq * decorator_list, int lineno, int col_offset,
PyArena *arena);
#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3)
stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena);
#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3)
stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena
*arena);
#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4)
stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int
col_offset, PyArena *arena);
#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
lineno, int col_offset, PyArena *arena);
#define Print(a0, a1, a2, a3, a4, a5) _Py_Print(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int
col_offset, PyArena *arena);
#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6)
stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq *
orelse, int lineno, int col_offset, PyArena *arena);
#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
int col_offset, PyArena *arena);
#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
int col_offset, PyArena *arena);
#define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body,
int lineno, int col_offset, PyArena *arena);
#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int
col_offset, PyArena *arena);
#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse,
int lineno, int col_offset, PyArena *arena);
#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4)
stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int
col_offset, PyArena *arena);
#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4)
stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset,
PyArena *arena);
#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3)
stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena
*arena);
#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int
lineno, int col_offset, PyArena *arena);
#define Exec(a0, a1, a2, a3, a4, a5) _Py_Exec(a0, a1, a2, a3, a4, a5)
stmt_ty _Py_Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int
col_offset, PyArena *arena);
#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3)
stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena
*arena);
#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3)
stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena);
#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2)
stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena);
#define Break(a0, a1, a2) _Py_Break(a0, a1, a2)
stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena);
#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2)
stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena);
#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4)
expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset,
PyArena *arena);
#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5)
expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int
col_offset, PyArena *arena);
#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4)
expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset,
PyArena *arena);
#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4)
expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset,
PyArena *arena);
#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5)
expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
col_offset, PyArena *arena);
#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4)
expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int
col_offset, PyArena *arena);
#define Set(a0, a1, a2, a3) _Py_Set(a0, a1, a2, a3)
expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena);
#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4)
expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int
col_offset, PyArena *arena);
#define SetComp(a0, a1, a2, a3, a4) _Py_SetComp(a0, a1, a2, a3, a4)
expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int
col_offset, PyArena *arena);
#define DictComp(a0, a1, a2, a3, a4, a5) _Py_DictComp(a0, a1, a2, a3, a4, a5)
expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int
lineno, int col_offset, PyArena *arena);
#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4)
expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int
col_offset, PyArena *arena);
#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3)
expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena);
#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5)
expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators,
int lineno, int col_offset, PyArena *arena);
#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7)
expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
starargs, expr_ty kwargs, int lineno, int col_offset, PyArena
*arena);
#define Repr(a0, a1, a2, a3) _Py_Repr(a0, a1, a2, a3)
expr_ty _Py_Repr(expr_ty value, int lineno, int col_offset, PyArena *arena);
#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3)
expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena);
#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3)
expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena);
#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5)
expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
lineno, int col_offset, PyArena *arena);
#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5)
expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
lineno, int col_offset, PyArena *arena);
#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4)
expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int
col_offset, PyArena *arena);
#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4)
expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int
col_offset, PyArena *arena);
#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4)
expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int
col_offset, PyArena *arena);
#define Ellipsis(a0) _Py_Ellipsis(a0)
slice_ty _Py_Ellipsis(PyArena *arena);
#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3)
slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1)
slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena);
#define Index(a0, a1) _Py_Index(a0, a1)
slice_ty _Py_Index(expr_ty value, PyArena *arena);
#define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3)
comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq *
ifs, PyArena *arena);
#define ExceptHandler(a0, a1, a2, a3, a4, a5) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5)
excepthandler_ty _Py_ExceptHandler(expr_ty type, expr_ty name, asdl_seq * body,
int lineno, int col_offset, PyArena *arena);
#define arguments(a0, a1, a2, a3, a4) _Py_arguments(a0, a1, a2, a3, a4)
arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, identifier
kwarg, asdl_seq * defaults, PyArena *arena);
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
#define alias(a0, a1, a2) _Py_alias(a0, a1, a2)
alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena);
PyObject* PyAST_mod2obj(mod_ty t);
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);
int PyAST_Check(PyObject* obj);

View File

@@ -1,178 +1,155 @@
// 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 #ifndef Py_PYTHON_H
#define Py_PYTHON_H #define Py_PYTHON_H
/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
/* Include nearly all Python header files */ // Since this is a "meta-include" file, "#ifdef __cplusplus / extern "C" {"
// is not needed.
// Include Python header files
#include "patchlevel.h" #include "patchlevel.h"
#include "pyconfig.h" #include "pyconfig.h"
#include "pymacconfig.h" #include "pymacconfig.h"
/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the
* old symbol for the benefit of extension modules written before then // Include standard header files
* that may be conditionalizing on it. The core doesn't use it anymore. // When changing these files, remember to update Doc/extending/extending.rst.
*/ #include <assert.h> // assert()
#ifndef WITH_CYCLE_GC #include <inttypes.h> // uintptr_t
#define WITH_CYCLE_GC 1 #include <limits.h> // INT_MAX
#include <math.h> // HUGE_VAL
#include <stdarg.h> // va_list
#include <wchar.h> // wchar_t
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> // ssize_t
#endif #endif
#include <limits.h> // <errno.h>, <stdio.h>, <stdlib.h> and <string.h> headers are no longer used
// by Python, but kept for the backward compatibility of existing third party C
#ifndef UCHAR_MAX // extensions. They are not included by limited C API version 3.11 and newer.
#error "Something's broken. UCHAR_MAX should be defined in limits.h." //
// The <ctype.h> and <unistd.h> headers are not included by limited C API
// version 3.13 and newer.
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# include <errno.h> // errno
# include <stdio.h> // FILE*
# include <stdlib.h> // getenv()
# include <string.h> // memcpy()
#endif
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000
# include <ctype.h> // tolower()
# ifndef MS_WINDOWS
# include <unistd.h> // close()
# endif
#endif #endif
#if UCHAR_MAX != 255 // gh-111506: The free-threaded build is not compatible with the limited API
#error "Python's source code assumes C's unsigned char is an 8-bit type." // or the stable ABI.
#if defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED)
# error "The limited API is not currently supported in the free-threaded build"
#endif #endif
#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) #if defined(Py_GIL_DISABLED) && defined(_MSC_VER)
#define _SGI_MP_SOURCE # include <intrin.h> // __readgsqword()
#endif #endif
#include <stdio.h> #if defined(Py_GIL_DISABLED) && defined(__MINGW32__)
#ifndef NULL # include <intrin.h> // __readgsqword()
# error "Python.h requires that stdio.h define NULL."
#endif #endif
#include <string.h> // Suppress known warnings in Python header files.
#ifdef HAVE_ERRNO_H #if defined(_MSC_VER)
#include <errno.h> // Warning that alignas behaviour has changed. Doesn't affect us, because we
#endif // never relied on the old behaviour.
#include <stdlib.h> #pragma warning(push)
#ifdef HAVE_UNISTD_H #pragma warning(disable: 5274)
#include <unistd.h>
#endif #endif
/* For size_t? */ // Include Python header files
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
/* CAUTION: Build setups should ensure that NDEBUG is defined on the
* compiler command line when building Python in release mode; else
* assert() calls won't be removed.
*/
#include <assert.h>
#include "pyport.h" #include "pyport.h"
#include "pymacro.h"
/* pyconfig.h or pyport.h may or may not define DL_IMPORT */
#ifndef DL_IMPORT /* declarations for DLL import/export */
#define DL_IMPORT(RTYPE) RTYPE
#endif
#ifndef DL_EXPORT /* declarations for DLL import/export */
#define DL_EXPORT(RTYPE) RTYPE
#endif
/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG.
* PYMALLOC_DEBUG is in error if pymalloc is not in use.
*/
#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG)
#define PYMALLOC_DEBUG
#endif
#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC)
#error "PYMALLOC_DEBUG requires WITH_PYMALLOC"
#endif
#include "pymath.h" #include "pymath.h"
#include "pymem.h" #include "pymem.h"
#include "pytypedefs.h"
#include "pybuffer.h"
#include "pystats.h"
#include "pyatomic.h"
#include "lock.h"
#include "critical_section.h"
#include "object.h" #include "object.h"
#include "refcount.h"
#include "objimpl.h" #include "objimpl.h"
#include "typeslots.h"
#include "pydebug.h" #include "pyhash.h"
#include "cpython/pydebug.h"
#include "unicodeobject.h"
#include "intobject.h"
#include "boolobject.h"
#include "longobject.h"
#include "floatobject.h"
#ifndef WITHOUT_COMPLEX
#include "complexobject.h"
#endif
#include "rangeobject.h"
#include "stringobject.h"
#include "memoryobject.h"
#include "bufferobject.h"
#include "bytesobject.h"
#include "bytearrayobject.h" #include "bytearrayobject.h"
#include "bytesobject.h"
#include "unicodeobject.h"
#include "pyerrors.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 "tupleobject.h"
#include "listobject.h" #include "listobject.h"
#include "dictobject.h" #include "dictobject.h"
#include "cpython/odictobject.h"
#include "enumobject.h" #include "enumobject.h"
#include "setobject.h" #include "setobject.h"
#include "methodobject.h" #include "methodobject.h"
#include "moduleobject.h" #include "moduleobject.h"
#include "funcobject.h" #include "monitoring.h"
#include "classobject.h" #include "cpython/funcobject.h"
#include "cpython/classobject.h"
#include "fileobject.h" #include "fileobject.h"
#include "cobject.h"
#include "pycapsule.h" #include "pycapsule.h"
#include "cpython/code.h"
#include "pyframe.h"
#include "traceback.h" #include "traceback.h"
#include "sliceobject.h" #include "sliceobject.h"
#include "cellobject.h" #include "cpython/cellobject.h"
#include "iterobject.h" #include "iterobject.h"
#include "genobject.h" #include "cpython/initconfig.h"
#include "pystate.h"
#include "cpython/genobject.h"
#include "descrobject.h" #include "descrobject.h"
#include "genericaliasobject.h"
#include "warnings.h" #include "warnings.h"
#include "weakrefobject.h" #include "weakrefobject.h"
#include "structseq.h"
#include "cpython/picklebufobject.h"
#include "cpython/pytime.h"
#include "codecs.h" #include "codecs.h"
#include "pyerrors.h" #include "pythread.h"
#include "cpython/context.h"
#include "pystate.h"
#include "pyarena.h"
#include "modsupport.h" #include "modsupport.h"
#include "compile.h"
#include "pythonrun.h" #include "pythonrun.h"
#include "pylifecycle.h"
#include "ceval.h" #include "ceval.h"
#include "sysmodule.h" #include "sysmodule.h"
#include "audit.h"
#include "osmodule.h"
#include "intrcheck.h" #include "intrcheck.h"
#include "import.h" #include "import.h"
#include "abstract.h" #include "abstract.h"
#include "bltinmodule.h"
#include "compile.h" #include "cpython/pyctype.h"
#include "eval.h"
#include "pyctype.h"
#include "pystrtod.h" #include "pystrtod.h"
#include "pystrcmp.h" #include "pystrcmp.h"
#include "dtoa.h" #include "fileutils.h"
#include "cpython/pyfpe.h"
#include "cpython/tracemalloc.h"
/* _Py_Mangle is defined in compile.c */ // Restore warning filter
PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); #ifdef _MSC_VER
#pragma warning(pop)
/* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */
#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a))
/* PyArg_NoArgs should not be necessary.
Set ml_flags in the PyMethodDef to METH_NOARGS. */
#define PyArg_NoArgs(v) PyArg_Parse(v, "")
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
#include "pyfpe.h"
/* These definitions must match corresponding definitions in graminit.h.
There's code in compile.c that checks that they are the same. */
#define Py_single_input 256
#define Py_file_input 257
#define Py_eval_input 258
#ifdef HAVE_PTH
/* GNU pth user-space thread support */
#include <pth.h>
#endif
/* Define macros for inline documentation. */
#define PyDoc_VAR(name) static char name[]
#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
#ifdef WITH_DOC_STRINGS
#define PyDoc_STR(str) str
#else
#define PyDoc_STR(str) ""
#endif #endif
#endif /* !Py_PYTHON_H */ #endif /* !Py_PYTHON_H */

14
extern/include/python/README.rst vendored Normal file
View File

@@ -0,0 +1,14 @@
The Python C API
================
The C API is divided into these sections:
1. ``Include/``: Limited API
2. ``Include/cpython/``: CPython implementation details
3. ``Include/cpython/``, names with the ``PyUnstable_`` prefix: API that can
change between minor releases
4. ``Include/internal/``, and any name with ``_`` prefix: 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/

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
#ifndef Py_ASDL_H
#define Py_ASDL_H
typedef PyObject * identifier;
typedef PyObject * string;
typedef PyObject * object;
#ifndef __cplusplus
typedef enum {false, true} bool;
#endif
/* 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.
*/
/* XXX A sequence should be typed so that its use can be typechecked. */
typedef struct {
int size;
void *elements[1];
} asdl_seq;
typedef struct {
int size;
int elements[1];
} asdl_int_seq;
asdl_seq *asdl_seq_new(int size, PyArena *arena);
asdl_int_seq *asdl_int_seq_new(int size, PyArena *arena);
#define asdl_seq_GET(S, I) (S)->elements[(I)]
#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
#ifdef Py_DEBUG
#define asdl_seq_SET(S, I, V) { \
int _asdl_i = (I); \
assert((S) && _asdl_i < (S)->size); \
(S)->elements[_asdl_i] = (V); \
}
#else
#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V)
#endif
#endif /* !Py_ASDL_H */

View File

@@ -1,13 +0,0 @@
#ifndef Py_AST_H
#define Py_AST_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags,
const char *, PyArena *);
#ifdef __cplusplus
}
#endif
#endif /* !Py_AST_H */

30
extern/include/python/audit.h vendored Normal file
View File

@@ -0,0 +1,30 @@
#ifndef _Py_AUDIT_H
#define _Py_AUDIT_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
PyAPI_FUNC(int) PySys_Audit(
const char *event,
const char *argFormat,
...);
PyAPI_FUNC(int) PySys_AuditTuple(
const char *event,
PyObject *args);
#endif
#ifndef Py_LIMITED_API
# define _Py_CPYTHON_AUDIT_H
# include "cpython/audit.h"
# undef _Py_CPYTHON_AUDIT_H
#endif
#ifdef __cplusplus
}
#endif
#endif /* !_Py_AUDIT_H */

View File

@@ -1,32 +0,0 @@
#ifndef Py_BITSET_H
#define Py_BITSET_H
#ifdef __cplusplus
extern "C" {
#endif
/* Bitset interface */
#define BYTE char
typedef BYTE *bitset;
bitset newbitset(int nbits);
void delbitset(bitset bs);
#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0)
int addbit(bitset bs, int ibit); /* Returns 0 if already set */
int samebitset(bitset bs1, bitset bs2, int nbits);
void mergebitset(bitset bs1, bitset bs2, int nbits);
#define BITSPERBYTE (8*sizeof(BYTE))
#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE)
#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE)
#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE)
#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit))
#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE)
#ifdef __cplusplus
}
#endif
#endif /* !Py_BITSET_H */

14
extern/include/python/bltinmodule.h vendored Normal file
View File

@@ -0,0 +1,14 @@
#ifndef Py_BLTINMODULE_H
#define Py_BLTINMODULE_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_DATA(PyTypeObject) PyFilter_Type;
PyAPI_DATA(PyTypeObject) PyMap_Type;
PyAPI_DATA(PyTypeObject) PyZip_Type;
#ifdef __cplusplus
}
#endif
#endif /* !Py_BLTINMODULE_H */

View File

@@ -7,25 +7,43 @@ extern "C" {
#endif #endif
typedef PyIntObject PyBoolObject; // PyBool_Type is declared by object.h
PyAPI_DATA(PyTypeObject) PyBool_Type; #define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type)
#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) /* Py_False and Py_True are the only two bools in existence. */
/* 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 */ /* Don't use these directly */
PyAPI_DATA(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct; PyAPI_DATA(PyLongObject) _Py_FalseStruct;
PyAPI_DATA(PyLongObject) _Py_TrueStruct;
/* Use these macros */ /* Use these macros */
#define Py_False ((PyObject *) &_Py_ZeroStruct) #if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030D0000
#define Py_True ((PyObject *) &_Py_TrueStruct) # define Py_False Py_GetConstantBorrowed(Py_CONSTANT_FALSE)
# define Py_True Py_GetConstantBorrowed(Py_CONSTANT_TRUE)
#else
# define Py_False _PyObject_CAST(&_Py_FalseStruct)
# define Py_True _PyObject_CAST(&_Py_TrueStruct)
#endif
/* Macros for returning Py_True or Py_False, respectively */ // Test if an object is the True singleton, the same as "x is True" in Python.
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False #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.
* Only treat Py_True and Py_False as immortal in the limited C API 3.12
* and newer. */
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030c0000
# define Py_RETURN_TRUE return Py_NewRef(Py_True)
# define Py_RETURN_FALSE return Py_NewRef(Py_False)
#else
# define Py_RETURN_TRUE return Py_True
# define Py_RETURN_FALSE return Py_False
#endif
/* Function to return a bool from a C long */ /* Function to return a bool from a C long */
PyAPI_FUNC(PyObject *) PyBool_FromLong(long); PyAPI_FUNC(PyObject *) PyBool_FromLong(long);

View File

@@ -1,33 +0,0 @@
/* Buffer object interface */
/* Note: the object's structure is private */
#ifndef Py_BUFFEROBJECT_H
#define Py_BUFFEROBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_DATA(PyTypeObject) PyBuffer_Type;
#define PyBuffer_Check(op) (Py_TYPE(op) == &PyBuffer_Type)
#define Py_END_OF_BUFFER (-1)
PyAPI_FUNC(PyObject *) PyBuffer_FromObject(PyObject *base,
Py_ssize_t offset, Py_ssize_t size);
PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteObject(PyObject *base,
Py_ssize_t offset,
Py_ssize_t size);
PyAPI_FUNC(PyObject *) PyBuffer_FromMemory(void *ptr, Py_ssize_t size);
PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size);
PyAPI_FUNC(PyObject *) PyBuffer_New(Py_ssize_t size);
#ifdef __cplusplus
}
#endif
#endif /* !Py_BUFFEROBJECT_H */

View File

@@ -6,8 +6,6 @@
extern "C" { extern "C" {
#endif #endif
#include <stdarg.h>
/* Type PyByteArrayObject represents a mutable array of bytes. /* Type PyByteArrayObject represents a mutable array of bytes.
* The Python API is that of a sequence; * The Python API is that of a sequence;
* the bytes are mapped to ints in [0, 256). * the bytes are mapped to ints in [0, 256).
@@ -18,22 +16,13 @@ extern "C" {
* to contain a char pointer, not an unsigned char pointer. * to contain a char pointer, not an unsigned char pointer.
*/ */
/* Object layout */
typedef struct {
PyObject_VAR_HEAD
/* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
int ob_exports; /* how many buffer exports */
Py_ssize_t ob_alloc; /* How many bytes allocated */
char *ob_bytes;
} PyByteArrayObject;
/* Type object */ /* Type object */
PyAPI_DATA(PyTypeObject) PyByteArray_Type; PyAPI_DATA(PyTypeObject) PyByteArray_Type;
PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type;
/* Type check macros */ /* Type check macros */
#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) #define PyByteArray_Check(self) PyObject_TypeCheck((self), &PyByteArray_Type)
#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) #define PyByteArray_CheckExact(self) Py_IS_TYPE((self), &PyByteArray_Type)
/* Direct API functions */ /* Direct API functions */
PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *);
@@ -43,13 +32,11 @@ PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *);
PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *);
PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);
/* Macros, trading safety for speed */ #ifndef Py_LIMITED_API
#define PyByteArray_AS_STRING(self) \ # define Py_CPYTHON_BYTEARRAYOBJECT_H
(assert(PyByteArray_Check(self)), \ # include "cpython/bytearrayobject.h"
Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_bytes : _PyByteArray_empty_string) # undef Py_CPYTHON_BYTEARRAYOBJECT_H
#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self)) #endif
PyAPI_DATA(char) _PyByteArray_empty_string[];
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,75 +0,0 @@
#ifndef Py_BYTES_CTYPE_H
#define Py_BYTES_CTYPE_H
/*
* The internal implementation behind PyString (bytes) and PyBytes (buffer)
* 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_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, char *s, Py_ssize_t len);
extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len);
extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len);
/* 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_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__[];
/* These are left in for backward compatibility and will be removed
in 2.8/3.2 */
#define ISLOWER(c) Py_ISLOWER(c)
#define ISUPPER(c) Py_ISUPPER(c)
#define ISALPHA(c) Py_ISALPHA(c)
#define ISDIGIT(c) Py_ISDIGIT(c)
#define ISXDIGIT(c) Py_ISXDIGIT(c)
#define ISALNUM(c) Py_ISALNUM(c)
#define ISSPACE(c) Py_ISSPACE(c)
#undef islower
#define islower(c) undefined_islower(c)
#undef isupper
#define isupper(c) undefined_isupper(c)
#undef isalpha
#define isalpha(c) undefined_isalpha(c)
#undef isdigit
#define isdigit(c) undefined_isdigit(c)
#undef isxdigit
#define isxdigit(c) undefined_isxdigit(c)
#undef isalnum
#define isalnum(c) undefined_isalnum(c)
#undef isspace
#define isspace(c) undefined_isspace(c)
/* These are left in for backward compatibility and will be removed
in 2.8/3.2 */
#define TOLOWER(c) Py_TOLOWER(c)
#define TOUPPER(c) Py_TOUPPER(c)
#undef tolower
#define tolower(c) undefined_tolower(c)
#undef toupper
#define toupper(c) undefined_toupper(c)
/* 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 */

View File

@@ -1,27 +1,66 @@
#define PyBytesObject PyStringObject // Bytes object interface
#define PyBytes_Type PyString_Type
#define PyBytes_Check PyString_Check #ifndef Py_BYTESOBJECT_H
#define PyBytes_CheckExact PyString_CheckExact #define Py_BYTESOBJECT_H
#define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED #ifdef __cplusplus
#define PyBytes_AS_STRING PyString_AS_STRING extern "C" {
#define PyBytes_GET_SIZE PyString_GET_SIZE #endif
#define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS
#define PyBytes_FromStringAndSize PyString_FromStringAndSize /*
#define PyBytes_FromString PyString_FromString Type PyBytesObject represents a byte string. An extra zero byte is
#define PyBytes_FromFormatV PyString_FromFormatV reserved at the end to ensure it is zero-terminated, but a size is
#define PyBytes_FromFormat PyString_FromFormat present so strings with null bytes in them can be represented. This
#define PyBytes_Size PyString_Size is an immutable object type.
#define PyBytes_AsString PyString_AsString
#define PyBytes_Repr PyString_Repr There are functions to create new bytes objects, to test
#define PyBytes_Concat PyString_Concat an object for bytes-ness, and to get the
#define PyBytes_ConcatAndDel PyString_ConcatAndDel byte string value. The latter function returns a null pointer
#define _PyBytes_Resize _PyString_Resize if the object is not of the proper type.
#define _PyBytes_Eq _PyString_Eq There is a variant that takes an explicit size as well as a
#define PyBytes_Format PyString_Format variant that assumes a zero-terminated string. Note that none of the
#define _PyBytes_FormatLong _PyString_FormatLong functions should be applied to NULL pointer.
#define PyBytes_DecodeEscape PyString_DecodeEscape */
#define _PyBytes_Join _PyString_Join
#define PyBytes_AsStringAndSize PyString_AsStringAndSize PyAPI_DATA(PyTypeObject) PyBytes_Type;
#define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping 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 */

View File

@@ -1,73 +0,0 @@
#ifndef Py_CSTRINGIO_H
#define Py_CSTRINGIO_H
#ifdef __cplusplus
extern "C" {
#endif
/*
This header provides access to cStringIO objects from C.
Functions are provided for calling cStringIO objects and
macros are provided for testing whether you have cStringIO
objects.
Before calling any of the functions or macros, you must initialize
the routines with:
PycString_IMPORT
This would typically be done in your init function.
*/
#define PycStringIO_CAPSULE_NAME "cStringIO.cStringIO_CAPI"
#define PycString_IMPORT \
PycStringIO = ((struct PycStringIO_CAPI*)PyCapsule_Import(\
PycStringIO_CAPSULE_NAME, 0))
/* Basic functions to manipulate cStringIO objects from C */
static struct PycStringIO_CAPI {
/* Read a string from an input object. If the last argument
is -1, the remainder will be read.
*/
int(*cread)(PyObject *, char **, Py_ssize_t);
/* Read a line from an input object. Returns the length of the read
line as an int and a pointer inside the object buffer as char** (so
the caller doesn't have to provide its own buffer as destination).
*/
int(*creadline)(PyObject *, char **);
/* Write a string to an output object*/
int(*cwrite)(PyObject *, const char *, Py_ssize_t);
/* Get the output object as a Python string (returns new reference). */
PyObject *(*cgetvalue)(PyObject *);
/* Create a new output object */
PyObject *(*NewOutput)(int);
/* Create an input object from a Python string
(copies the Python string reference).
*/
PyObject *(*NewInput)(PyObject *);
/* The Python types for cStringIO input and output objects.
Note that you can do input on an output object.
*/
PyTypeObject *InputType, *OutputType;
} *PycStringIO;
/* These can be used to test if you have one */
#define PycStringIO_InputCheck(O) \
(Py_TYPE(O)==PycStringIO->InputType)
#define PycStringIO_OutputCheck(O) \
(Py_TYPE(O)==PycStringIO->OutputType)
#ifdef __cplusplus
}
#endif
#endif /* !Py_CSTRINGIO_H */

View File

@@ -1,28 +0,0 @@
/* Cell object interface */
#ifndef Py_CELLOBJECT_H
#define Py_CELLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PyObject_HEAD
PyObject *ob_ref; /* Content of the cell or NULL when empty */
} PyCellObject;
PyAPI_DATA(PyTypeObject) PyCell_Type;
#define PyCell_Check(op) (Py_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) (((PyCellObject *)(op))->ob_ref = v)
#ifdef __cplusplus
}
#endif
#endif /* !Py_TUPLEOBJECT_H */

View File

@@ -1,3 +1,5 @@
/* Interface to random parts in ceval.c */
#ifndef Py_CEVAL_H #ifndef Py_CEVAL_H
#define Py_CEVAL_H #define Py_CEVAL_H
#ifdef __cplusplus #ifdef __cplusplus
@@ -5,69 +7,64 @@ extern "C" {
#endif #endif
/* Interface to random parts in ceval.c */ PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyObject *co,
PyObject *, PyObject *, PyObject *); PyObject *globals,
PyObject *locals,
/* Inline this */ PyObject *const *args, int argc,
#define PyEval_CallObject(func,arg) \ PyObject *const *kwds, int kwdc,
PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) PyObject *const *defs, int defc,
PyObject *kwdefs, PyObject *closure);
PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj,
const char *format, ...);
PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj,
const char *methodname,
const char *format, ...);
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
struct _frame; /* Avoid including frameobject.h */
PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void);
PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); PyAPI_FUNC(PyFrameObject *) PyEval_GetFrame(void);
PyAPI_FUNC(int) PyEval_GetRestricted(void);
/* Look at the current frame's (if any) code's co_flags, and turn on PyAPI_FUNC(PyObject *) PyEval_GetFrameBuiltins(void);
the corresponding compiler flags in cf->cf_flags. Return 1 if any PyAPI_FUNC(PyObject *) PyEval_GetFrameGlobals(void);
flag was set, else return 0. */ PyAPI_FUNC(PyObject *) PyEval_GetFrameLocals(void);
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
PyAPI_FUNC(int) Py_FlushLine(void);
PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg);
PyAPI_FUNC(int) Py_MakePendingCalls(void); PyAPI_FUNC(int) Py_MakePendingCalls(void);
/* Protection against deeply nested recursive calls */ /* 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 mistakenly 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(void) Py_SetRecursionLimit(int);
PyAPI_FUNC(int) Py_GetRecursionLimit(void); PyAPI_FUNC(int) Py_GetRecursionLimit(void);
#define Py_EnterRecursiveCall(where) \ PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where);
(_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ PyAPI_FUNC(void) Py_LeaveRecursiveCall(void);
_Py_CheckRecursiveCall(where))
#define Py_LeaveRecursiveCall() \
(--PyThreadState_GET()->recursion_depth)
PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where);
PyAPI_DATA(int) _Py_CheckRecursionLimit;
#ifdef USE_STACKCHECK
# define _Py_MakeRecCheck(x) (++(x) > --_Py_CheckRecursionLimit)
#else
# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit)
#endif
PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *);
PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *);
PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); PyAPI_FUNC(PyObject *) PyEval_EvalFrame(PyFrameObject *);
PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(PyFrameObject *f, int exc);
PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc);
/* this used to be handled on a per-thread basis - now just two globals */
PyAPI_DATA(volatile int) _Py_Ticker;
PyAPI_DATA(int) _Py_CheckInterval;
/* Interface for threads. /* Interface for threads.
@@ -88,7 +85,7 @@ PyAPI_DATA(int) _Py_CheckInterval;
if (...premature_exit...) { if (...premature_exit...) {
Py_BLOCK_THREADS Py_BLOCK_THREADS
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_OSError);
return NULL; return NULL;
} }
@@ -96,7 +93,7 @@ PyAPI_DATA(int) _Py_CheckInterval;
Py_BLOCK_THREADS Py_BLOCK_THREADS
if (...premature_exit...) { if (...premature_exit...) {
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_OSError);
return NULL; return NULL;
} }
Py_UNBLOCK_THREADS Py_UNBLOCK_THREADS
@@ -107,9 +104,6 @@ PyAPI_DATA(int) _Py_CheckInterval;
WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
Py_END_ALLOW_THREADS!!! Py_END_ALLOW_THREADS!!!
The function PyEval_InitThreads() should be called only from
initthread() in "threadmodule.c".
Note that not yet all candidates have been converted to use this Note that not yet all candidates have been converted to use this
mechanism! mechanism!
*/ */
@@ -117,15 +111,10 @@ PyAPI_DATA(int) _Py_CheckInterval;
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
#ifdef WITH_THREAD Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
PyAPI_FUNC(void) PyEval_InitThreads(void);
PyAPI_FUNC(void) PyEval_AcquireLock(void);
PyAPI_FUNC(void) PyEval_ReleaseLock(void);
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
PyAPI_FUNC(void) PyEval_ReInitThreads(void);
#define Py_BEGIN_ALLOW_THREADS { \ #define Py_BEGIN_ALLOW_THREADS { \
PyThreadState *_save; \ PyThreadState *_save; \
@@ -135,17 +124,20 @@ PyAPI_FUNC(void) PyEval_ReInitThreads(void);
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
} }
#else /* !WITH_THREAD */ /* Masks and values used by FORMAT_VALUE opcode. */
#define FVC_MASK 0x3
#define Py_BEGIN_ALLOW_THREADS { #define FVC_NONE 0x0
#define Py_BLOCK_THREADS #define FVC_STR 0x1
#define Py_UNBLOCK_THREADS #define FVC_REPR 0x2
#define Py_END_ALLOW_THREADS } #define FVC_ASCII 0x3
#define FVS_MASK 0x4
#endif /* !WITH_THREAD */ #define FVS_HAVE_SPEC 0x4
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
#ifndef Py_LIMITED_API
# define Py_CPYTHON_CEVAL_H
# include "cpython/ceval.h"
# undef Py_CPYTHON_CEVAL_H
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,83 +0,0 @@
/* Class object interface */
/* Revealing some structures (not for general use) */
#ifndef Py_CLASSOBJECT_H
#define Py_CLASSOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PyObject_HEAD
PyObject *cl_bases; /* A tuple of class objects */
PyObject *cl_dict; /* A dictionary */
PyObject *cl_name; /* A string */
/* The following three are functions or NULL */
PyObject *cl_getattr;
PyObject *cl_setattr;
PyObject *cl_delattr;
PyObject *cl_weakreflist; /* List of weak references */
} PyClassObject;
typedef struct {
PyObject_HEAD
PyClassObject *in_class; /* The class object */
PyObject *in_dict; /* A dictionary */
PyObject *in_weakreflist; /* List of weak references */
} PyInstanceObject;
typedef struct {
PyObject_HEAD
PyObject *im_func; /* The callable object implementing the method */
PyObject *im_self; /* The instance it is bound to, or NULL */
PyObject *im_class; /* The class that asked for the method */
PyObject *im_weakreflist; /* List of weak references */
} PyMethodObject;
PyAPI_DATA(PyTypeObject) PyClass_Type, PyInstance_Type, PyMethod_Type;
#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type)
#define PyInstance_Check(op) ((op)->ob_type == &PyInstance_Type)
#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type)
PyAPI_FUNC(PyObject *) PyClass_New(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyInstance_New(PyObject *, PyObject *,
PyObject *);
PyAPI_FUNC(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
/* Look up attribute with name (a string) on instance object pinst, using
* only the instance and base class dicts. If a descriptor is found in
* a class dict, the descriptor is returned without calling it.
* Returns NULL if nothing found, else a borrowed reference to the
* value associated with name in the dict in which name was found.
* The point of this routine is that it never calls arbitrary Python
* code, so is always "safe": all it does is dict lookups. The function
* can't fail, never sets an exception, and NULL is not an error (it just
* means "not found").
*/
PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
/* 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)
#define PyMethod_GET_CLASS(meth) \
(((PyMethodObject *)meth) -> im_class)
PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
PyAPI_FUNC(int) PyMethod_ClearFreeList(void);
#ifdef __cplusplus
}
#endif
#endif /* !Py_CLASSOBJECT_H */

View File

@@ -1,89 +0,0 @@
/*
CObjects are marked Pending Deprecation as of Python 2.7.
The full schedule for 2.x is as follows:
- CObjects are marked Pending Deprecation in Python 2.7.
- CObjects will be marked Deprecated in Python 2.8
(if there is one).
- CObjects will be removed in Python 2.9 (if there is one).
Additionally, for the Python 3.x series:
- CObjects were marked Deprecated in Python 3.1.
- CObjects will be removed in Python 3.2.
You should switch all use of CObjects to capsules. Capsules
have a safer and more consistent API. For more information,
see Include/pycapsule.h, or read the "Capsules" topic in
the "Python/C API Reference Manual".
Python 2.7 no longer uses CObjects itself; all objects which
were formerly CObjects are now capsules. Note that this change
does not by itself break binary compatibility with extensions
built for previous versions of Python--PyCObject_AsVoidPtr()
has been changed to also understand capsules.
*/
/* original file header comment follows: */
/* C objects to be exported from one extension module to another.
C objects are used for communication between extension modules.
They provide a way for an extension module to export a C interface
to other extension modules, so that extension modules can use the
Python import mechanism to link to one another.
*/
#ifndef Py_COBJECT_H
#define Py_COBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_DATA(PyTypeObject) PyCObject_Type;
#define PyCObject_Check(op) (Py_TYPE(op) == &PyCObject_Type)
/* Create a PyCObject from a pointer to a C object and an optional
destructor function. If the second argument is non-null, then it
will be called with the first argument if and when the PyCObject is
destroyed.
*/
PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr(
void *cobj, void (*destruct)(void*));
/* Create a PyCObject from a pointer to a C object, a description object,
and an optional destructor function. If the third argument is non-null,
then it will be called with the first and second arguments if and when
the PyCObject is destroyed.
*/
PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc(
void *cobj, void *desc, void (*destruct)(void*,void*));
/* Retrieve a pointer to a C object from a PyCObject. */
PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *);
/* Retrieve a pointer to a description object from a PyCObject. */
PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
/* Import a pointer to a C object from a module using a PyCObject. */
PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name);
/* Modify a C object. Fails (==0) if object has a destructor. */
PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
typedef struct {
PyObject_HEAD
void *cobject;
void *desc;
void (*destructor)(void *);
} PyCObject;
#ifdef __cplusplus
}
#endif
#endif /* !Py_COBJECT_H */

View File

@@ -1,107 +0,0 @@
/* Definitions for bytecode */
#ifndef Py_CODE_H
#define Py_CODE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Bytecode object */
typedef struct {
PyObject_HEAD
int co_argcount; /* #arguments, except *args */
int co_nlocals; /* #local variables */
int co_stacksize; /* #entries needed for evaluation stack */
int co_flags; /* CO_..., see below */
PyObject *co_code; /* instruction opcodes */
PyObject *co_consts; /* list (constants used) */
PyObject *co_names; /* list of strings (names used) */
PyObject *co_varnames; /* tuple of strings (local variable names) */
PyObject *co_freevars; /* tuple of strings (free variable names) */
PyObject *co_cellvars; /* tuple of strings (cell variable names) */
/* The rest doesn't count for hash/cmp */
PyObject *co_filename; /* string (where it was loaded from) */
PyObject *co_name; /* string (name, for reference) */
int co_firstlineno; /* first source line number */
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
PyObject *co_weakreflist; /* to support weakrefs to code objects */
} PyCodeObject;
/* Masks for co_flags above */
#define CO_OPTIMIZED 0x0001
#define CO_NEWLOCALS 0x0002
#define CO_VARARGS 0x0004
#define CO_VARKEYWORDS 0x0008
#define CO_NESTED 0x0010
#define CO_GENERATOR 0x0020
/* The CO_NOFREE flag is set if there are no free or cell variables.
This information is redundant, but it allows a single flag test
to determine whether there is any extra work to be done when the
call frame it setup.
*/
#define CO_NOFREE 0x0040
#if 0
/* This is no longer used. Stopped defining in 2.5, do not re-use. */
#define CO_GENERATOR_ALLOWED 0x1000
#endif
#define CO_FUTURE_DIVISION 0x2000
#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */
#define CO_FUTURE_WITH_STATEMENT 0x8000
#define CO_FUTURE_PRINT_FUNCTION 0x10000
#define CO_FUTURE_UNICODE_LITERALS 0x20000
/* This should be defined if a future statement modifies the syntax.
For example, when a keyword is added.
*/
#if 1
#define PY_PARSER_REQUIRES_FUTURE_KEYWORD
#endif
#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
PyAPI_DATA(PyTypeObject) PyCode_Type;
#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type)
#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars))
/* Public interface */
PyAPI_FUNC(PyCodeObject *) PyCode_New(
int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *);
/* same as struct above */
/* Creates a new empty code object with the specified source location. */
PyAPI_FUNC(PyCodeObject *)
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
/* Return the line number associated with the specified bytecode index
in this code object. If you just need the line number of a frame,
use PyFrame_GetLineNumber() instead. */
PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
/* for internal use only */
#define _PyCode_GETCODEPTR(co, pp) \
((*Py_TYPE((co)->co_code)->tp_as_buffer->bf_getreadbuffer) \
((co)->co_code, 0, (void **)(pp)))
typedef struct _addr_pair {
int ap_lower;
int ap_upper;
} PyAddrPair;
/* 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(PyCodeObject* co,
int lasti, PyAddrPair *bounds);
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
PyObject *names, PyObject *lineno_obj);
#ifdef __cplusplus
}
#endif
#endif /* !Py_CODE_H */

View File

@@ -27,25 +27,22 @@ PyAPI_FUNC(int) PyCodec_Register(
PyObject *search_function PyObject *search_function
); );
/* Codec register lookup API. /* 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. */
Looks up the given encoding and returns a CodecInfo object with PyAPI_FUNC(int) PyCodec_Unregister(
function attributes which implement the different aspects of PyObject *search_function
processing the encoding. );
The encoding string is looked up converted to all lower-case /* Codec registry encoding check API.
characters. This makes encodings looked up through this mechanism
effectively case-insensitive.
If no codec is found, a KeyError is set and NULL returned. Returns 1/0 depending on whether there is a registered codec for
the given encoding.
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.
*/ PyAPI_FUNC(int) PyCodec_KnownEncoding(
PyAPI_FUNC(PyObject *) _PyCodec_Lookup(
const char *encoding const char *encoding
); );
@@ -81,55 +78,58 @@ PyAPI_FUNC(PyObject *) PyCodec_Decode(
const char *errors const char *errors
); );
/* --- Codec Lookup APIs -------------------------------------------------- // --- Codec Lookup APIs --------------------------------------------------
All APIs return a codec object with incremented refcount and are /* Codec registry lookup API.
based on _PyCodec_Lookup(). The same comments w/r to the encoding
name also apply to these APIs.
*/ 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.
*/
/* Get an encoder function for the given encoding. */ /* Get an encoder function for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_Encoder( PyAPI_FUNC(PyObject *) PyCodec_Encoder(const char *encoding);
const char *encoding
);
/* Get a decoder function for the given encoding. */ /* Get a decoder function for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_Decoder( PyAPI_FUNC(PyObject *) PyCodec_Decoder(const char *encoding);
const char *encoding
);
/* Get a IncrementalEncoder object for the given encoding. */ /* Get an IncrementalEncoder object for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder(
const char *encoding, const char *encoding,
const char *errors const char *errors);
);
/* Get a IncrementalDecoder object function for the given encoding. */ /* Get an IncrementalDecoder object function for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder(
const char *encoding, const char *encoding,
const char *errors const char *errors);
);
/* Get a StreamReader factory function for the given encoding. */ /* Get a StreamReader factory function for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_StreamReader( PyAPI_FUNC(PyObject *) PyCodec_StreamReader(
const char *encoding, const char *encoding,
PyObject *stream, PyObject *stream,
const char *errors const char *errors);
);
/* Get a StreamWriter factory function for the given encoding. */ /* Get a StreamWriter factory function for the given encoding. */
PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( PyAPI_FUNC(PyObject *) PyCodec_StreamWriter(
const char *encoding, const char *encoding,
PyObject *stream, PyObject *stream,
const char *errors const char *errors);
);
/* Unicode encoding error handling callback registry API */ /* Unicode encoding error handling callback registry API */
@@ -161,6 +161,15 @@ PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc);
/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ /* replace the unicode encode error with backslash escapes (\x, \u and \U) */
PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,38 +1,20 @@
#ifndef Py_COMPILE_H #ifndef Py_COMPILE_H
#define Py_COMPILE_H #define Py_COMPILE_H
#include "code.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Public interface */ /* These definitions must match corresponding definitions in graminit.h. */
struct _node; /* Declare the existence of this type */ #define Py_single_input 256
PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); #define Py_file_input 257
#define Py_eval_input 258
/* Future feature support */ #define Py_func_type_input 345
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"
struct _mod; /* Declare the existence of this type */
PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,
PyCompilerFlags *, PyArena *);
PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *);
#ifndef Py_LIMITED_API
# define Py_CPYTHON_COMPILE_H
# include "cpython/compile.h"
# undef Py_CPYTHON_COMPILE_H
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -6,59 +6,23 @@
extern "C" { extern "C" {
#endif #endif
typedef struct {
double real;
double imag;
} Py_complex;
/* Operations on complex numbers from complexmodule.c */
#define c_sum _Py_c_sum
#define c_diff _Py_c_diff
#define c_neg _Py_c_neg
#define c_prod _Py_c_prod
#define c_quot _Py_c_quot
#define c_pow _Py_c_pow
#define c_abs _Py_c_abs
PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_neg(Py_complex);
PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex);
PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex);
PyAPI_FUNC(double) c_abs(Py_complex);
/* Complex object interface */ /* Complex object interface */
/*
PyComplexObject represents a complex number with double-precision
real and imaginary parts.
*/
typedef struct {
PyObject_HEAD
Py_complex cval;
} PyComplexObject;
PyAPI_DATA(PyTypeObject) PyComplex_Type; PyAPI_DATA(PyTypeObject) PyComplex_Type;
#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) #define PyComplex_Check(op) PyObject_TypeCheck((op), &PyComplex_Type)
#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) #define PyComplex_CheckExact(op) Py_IS_TYPE((op), &PyComplex_Type)
PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex);
PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag);
PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op);
PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op);
PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op);
/* Format the object based on the format_spec, as defined in PEP 3101 #ifndef Py_LIMITED_API
(Advanced String Formatting). */ # define Py_CPYTHON_COMPLEXOBJECT_H
PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj, # include "cpython/complexobject.h"
char *format_spec, # undef Py_CPYTHON_COMPLEXOBJECT_H
Py_ssize_t format_spec_len); #endif
#ifdef __cplusplus #ifdef __cplusplus
} }

104
extern/include/python/cpython/abstract.h vendored Normal file
View File

@@ -0,0 +1,104 @@
#ifndef Py_CPYTHON_ABSTRACTOBJECT_H
# error "this header file must not be included directly"
#endif
/* === Object Protocol ================================================== */
/* 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, ...);
/* 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);
/* === Vectorcall protocol (PEP 590) ============================= */
// PyVectorcall_NARGS() is exported as a function for the stable ABI.
// Here (when we are not using the stable ABI), the name is overridden to
// call a static inline function for best performance.
static inline Py_ssize_t
_PyVectorcall_NARGS(size_t n)
{
return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
}
#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n)
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
// Backwards compatibility aliases (PEP 590) 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);
PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg);
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);
}
/* 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)) )
/* 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)

8
extern/include/python/cpython/audit.h vendored Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _Py_CPYTHON_AUDIT_H
# error "this header file must not be included directly"
#endif
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *);
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*);

View File

@@ -0,0 +1,38 @@
#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;
}
#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
PyByteArrayObject *self = _PyByteArray_CAST(op);
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(self)->ob_size));
#else
return Py_SIZE(self);
#endif
}
#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))

View File

@@ -0,0 +1,42 @@
#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);
/* 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;
}
#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op))
static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) {
PyBytesObject *self = _PyBytes_CAST(op);
return Py_SIZE(self);
}
#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self))
PyAPI_FUNC(PyObject*) PyBytes_Join(PyObject *sep, PyObject *iterable);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline PyObject*
_PyBytes_Join(PyObject *sep, PyObject *iterable)
{
return PyBytes_Join(sep, iterable);
}

View File

@@ -0,0 +1,50 @@
/* 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 *);
static inline PyObject* PyCell_GET(PyObject *op) {
PyObject *res;
PyCellObject *cell;
assert(PyCell_Check(op));
cell = _Py_CAST(PyCellObject*, op);
Py_BEGIN_CRITICAL_SECTION(cell);
res = cell->ob_ref;
Py_END_CRITICAL_SECTION();
return res;
}
#define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op))
static inline void PyCell_SET(PyObject *op, PyObject *value) {
PyCellObject *cell;
assert(PyCell_Check(op));
cell = _Py_CAST(PyCellObject*, op);
Py_BEGIN_CRITICAL_SECTION(cell);
cell->ob_ref = value;
Py_END_CRITICAL_SECTION();
}
#define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value))
#ifdef __cplusplus
}
#endif
#endif /* !Py_TUPLEOBJECT_H */
#endif /* Py_LIMITED_API */

43
extern/include/python/cpython/ceval.h vendored Normal file
View File

@@ -0,0 +1,43 @@
#ifndef Py_CPYTHON_CEVAL_H
# error "this header file must not be included directly"
#endif
PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *);
PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *);
PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *);
PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *);
/* 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(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc);
// Old name -- remove when this API changes:
_Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t
_PyEval_RequestCodeExtraIndex(freefunc f) {
return PyUnstable_Eval_RequestCodeExtraIndex(f);
}
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
// Trampoline API
typedef struct {
FILE* perf_map;
PyThread_type_lock map_lock;
} PerfMapState;
PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void);
PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(
const void *code_addr,
unsigned int code_size,
const char *entry_name);
PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void);
PyAPI_FUNC(int) PyUnstable_CopyPerfMapFile(const char* parent_filename);
PyAPI_FUNC(int) PyUnstable_PerfTrampoline_CompileCode(PyCodeObject *);
PyAPI_FUNC(int) PyUnstable_PerfTrampoline_SetPersistAfterFork(int enable);

View File

@@ -0,0 +1,71 @@
/* 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 *);
#define _PyMethod_CAST(meth) \
(assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth))
/* Static inline functions for direct access to these values.
Type checks are *not* done, so use with care. */
static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) {
return _PyMethod_CAST(meth)->im_func;
}
#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth))
static inline PyObject* PyMethod_GET_SELF(PyObject *meth) {
return _PyMethod_CAST(meth)->im_self;
}
#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth))
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 *);
#define _PyInstanceMethod_CAST(meth) \
(assert(PyInstanceMethod_Check(meth)), \
_Py_CAST(PyInstanceMethodObject*, meth))
/* Static inline function for direct access to these values.
Type checks are *not* done, so use with care. */
static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) {
return _PyInstanceMethod_CAST(meth)->func;
}
#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth))
#ifdef __cplusplus
}
#endif
#endif // !Py_CLASSOBJECT_H
#endif // !Py_LIMITED_API

340
extern/include/python/cpython/code.h vendored Normal file
View File

@@ -0,0 +1,340 @@
/* Definitions for bytecode */
#ifndef Py_LIMITED_API
#ifndef Py_CODE_H
#define Py_CODE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
PyObject *_co_code;
PyObject *_co_varnames;
PyObject *_co_cellvars;
PyObject *_co_freevars;
} _PyCoCached;
typedef struct {
int size;
int capacity;
struct _PyExecutorObject *executors[1];
} _PyExecutorArray;
#ifdef Py_GIL_DISABLED
/* Each thread specializes a thread-local copy of the bytecode in free-threaded
* builds. These copies are stored on the code object in a `_PyCodeArray`. The
* first entry in the array always points to the "main" copy of the bytecode
* that is stored at the end of the code object.
*/
typedef struct {
Py_ssize_t size;
char *entries[1];
} _PyCodeArray;
#define _PyCode_DEF_THREAD_LOCAL_BYTECODE() \
_PyCodeArray *co_tlbc;
#else
#define _PyCode_DEF_THREAD_LOCAL_BYTECODE()
#endif
// 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 */ \
\
/* 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 spaces for holding local, cell, \
and free variables */ \
int co_framesize; /* Size of frame in words */ \
int co_nlocals; /* number of local variables */ \
int co_ncellvars; /* total number of cell variables */ \
int co_nfreevars; /* number of free variables */ \
uint32_t co_version; /* version number */ \
\
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 */ \
_PyExecutorArray *co_executors; /* executors from optimizer */ \
_PyCoCached *_co_cached; /* cached co_* attributes */ \
uintptr_t _co_instrumentation_version; /* current instrumentation version */ \
struct _PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \
Py_ssize_t _co_unique_id; /* ID used for per-thread refcounting */ \
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; \
_PyCode_DEF_THREAD_LOCAL_BYTECODE() \
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
#define CO_NO_MONITORING_EVENTS 0x2000000
/* Whether the code object has a docstring,
If so, it will be the first item in co_consts
*/
#define CO_HAS_DOCSTRING 0x4000000
/* A function defined in class scope */
#define CO_METHOD 0x8000000
/* 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 21 /* Max static block nesting within a function */
PyAPI_DATA(PyTypeObject) PyCode_Type;
#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type)
static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
assert(PyCode_Check(op));
return op->co_nfreevars;
}
static inline int PyUnstable_Code_GetFirstFree(PyCodeObject *op) {
assert(PyCode_Check(op));
return op->co_nlocalsplus - op->co_nfreevars;
}
Py_DEPRECATED(3.13) static inline int PyCode_GetFirstFree(PyCodeObject *op) {
return PyUnstable_Code_GetFirstFree(op);
}
/* Unstable public interface */
PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New(
int, int, int, int, int, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, int, PyObject *,
PyObject *);
PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs(
int, int, int, int, int, int, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, int, PyObject *,
PyObject *);
/* same as struct above */
// Old names -- remove when this API changes:
_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
PyCode_New(
int a, int b, int c, int d, int e, PyObject *f, PyObject *g,
PyObject *h, PyObject *i, PyObject *j, PyObject *k,
PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
PyObject *q)
{
return PyUnstable_Code_New(
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
}
_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
PyCode_NewWithPosOnlyArgs(
int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g,
PyObject *h, PyObject *i, PyObject *j, PyObject *k,
PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
PyObject *q)
{
return PyUnstable_Code_NewWithPosOnlyArgs(
a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
}
/* 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 *);
#define PY_FOREACH_CODE_EVENT(V) \
V(CREATE) \
V(DESTROY)
typedef enum {
#define PY_DEF_EVENT(op) PY_CODE_EVENT_##op,
PY_FOREACH_CODE_EVENT(PY_DEF_EVENT)
#undef PY_DEF_EVENT
} PyCodeEvent;
/*
* A callback that is invoked for different events in a code object's lifecycle.
*
* The callback is invoked with a borrowed reference to co, after it is
* created and before it is destroyed.
*
* If the callback sets an exception, it must return -1. Otherwise
* it should return 0.
*/
typedef int (*PyCode_WatchCallback)(
PyCodeEvent event,
PyCodeObject* co);
/*
* Register a per-interpreter callback that will be invoked for code object
* lifecycle events.
*
* Returns a handle that may be passed to PyCode_ClearWatcher on success,
* or -1 and sets an error if no more handles are available.
*/
PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback);
/*
* Clear the watcher associated with the watcher_id handle.
*
* Returns 0 on success or -1 if no watcher exists for the provided id.
*/
PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id);
/* 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) PyUnstable_Code_GetExtra(
PyObject *code, Py_ssize_t index, void **extra);
PyAPI_FUNC(int) PyUnstable_Code_SetExtra(
PyObject *code, Py_ssize_t index, void *extra);
// Old names -- remove when this API changes:
_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
{
return PyUnstable_Code_GetExtra(code, index, extra);
}
_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
{
return PyUnstable_Code_SetExtra(code, index, 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

50
extern/include/python/cpython/compile.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#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_OPTIMIZED_AST (0x8000 | PyCF_ONLY_AST)
#define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \
PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \
PyCF_ALLOW_INCOMPLETE_INPUT | PyCF_OPTIMIZED_AST)
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 */
#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);

View File

@@ -0,0 +1,33 @@
#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.
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);

107
extern/include/python/cpython/context.h vendored Normal file
View File

@@ -0,0 +1,107 @@
#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 *);
typedef enum {
/*
* The current context has switched to a different context. The object
* passed to the watch callback is the now-current contextvars.Context
* object, or None if no context is current.
*/
Py_CONTEXT_SWITCHED = 1,
} PyContextEvent;
/*
* Context object watcher callback function. The object passed to the callback
* is event-specific; see PyContextEvent for details.
*
* if the callback returns with an exception set, it must return -1. Otherwise
* it should return 0
*/
typedef int (*PyContext_WatchCallback)(PyContextEvent, PyObject *);
/*
* Register a per-interpreter callback that will be invoked for context object
* enter/exit events.
*
* Returns a handle that may be passed to PyContext_ClearWatcher on success,
* or -1 and sets and error if no more handles are available.
*/
PyAPI_FUNC(int) PyContext_AddWatcher(PyContext_WatchCallback callback);
/*
* Clear the watcher associated with the watcher_id handle.
*
* Returns 0 on success or -1 if no watcher exists for the provided id.
*/
PyAPI_FUNC(int) PyContext_ClearWatcher(int watcher_id);
/* 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);
#ifdef __cplusplus
}
#endif
#endif /* !Py_CONTEXT_H */
#endif /* !Py_LIMITED_API */

View File

@@ -0,0 +1,154 @@
#ifndef Py_CPYTHON_CRITICAL_SECTION_H
# error "this header file must not be included directly"
#endif
// Python critical sections
//
// Conceptually, critical sections are a deadlock avoidance layer on top of
// per-object locks. These helpers, in combination with those locks, replace
// our usage of the global interpreter lock to provide thread-safety for
// otherwise thread-unsafe objects, such as dict.
//
// NOTE: These APIs are no-ops in non-free-threaded builds.
//
// Straightforward per-object locking could introduce deadlocks that were not
// present when running with the GIL. Threads may hold locks for multiple
// objects simultaneously because Python operations can nest. If threads were
// to acquire the same locks in different orders, they would deadlock.
//
// One way to avoid deadlocks is to allow threads to hold only the lock (or
// locks) for a single operation at a time (typically a single lock, but some
// operations involve two locks). When a thread begins a nested operation it
// could suspend the locks for any outer operation: before beginning the nested
// operation, the locks for the outer operation are released and when the
// nested operation completes, the locks for the outer operation are
// reacquired.
//
// To improve performance, this API uses a variation of the above scheme.
// Instead of immediately suspending locks any time a nested operation begins,
// locks are only suspended if the thread would block. This reduces the number
// of lock acquisitions and releases for nested operations, while still
// avoiding deadlocks.
//
// Additionally, the locks for any active operation are suspended around
// other potentially blocking operations, such as I/O. This is because the
// interaction between locks and blocking operations can lead to deadlocks in
// the same way as the interaction between multiple locks.
//
// Each thread's critical sections and their corresponding locks are tracked in
// a stack in `PyThreadState.critical_section`. When a thread calls
// `_PyThreadState_Detach()`, such as before a blocking I/O operation or when
// waiting to acquire a lock, the thread suspends all of its active critical
// sections, temporarily releasing the associated locks. When the thread calls
// `_PyThreadState_Attach()`, it resumes the top-most (i.e., most recent)
// critical section by reacquiring the associated lock or locks. See
// `_PyCriticalSection_Resume()`.
//
// NOTE: Only the top-most critical section is guaranteed to be active.
// Operations that need to lock two objects at once must use
// `Py_BEGIN_CRITICAL_SECTION2()`. You *CANNOT* use nested critical sections
// to lock more than one object at once, because the inner critical section
// may suspend the outer critical sections. This API does not provide a way
// to lock more than two objects at once (though it could be added later
// if actually needed).
//
// NOTE: Critical sections implicitly behave like reentrant locks because
// attempting to acquire the same lock will suspend any outer (earlier)
// critical sections. However, they are less efficient for this use case than
// purposefully designed reentrant locks.
//
// Example usage:
// Py_BEGIN_CRITICAL_SECTION(op);
// ...
// Py_END_CRITICAL_SECTION();
//
// To lock two objects at once:
// Py_BEGIN_CRITICAL_SECTION2(op1, op2);
// ...
// Py_END_CRITICAL_SECTION2();
typedef struct PyCriticalSection PyCriticalSection;
typedef struct PyCriticalSection2 PyCriticalSection2;
PyAPI_FUNC(void)
PyCriticalSection_Begin(PyCriticalSection *c, PyObject *op);
PyAPI_FUNC(void)
PyCriticalSection_BeginMutex(PyCriticalSection *c, PyMutex *m);
PyAPI_FUNC(void)
PyCriticalSection_End(PyCriticalSection *c);
PyAPI_FUNC(void)
PyCriticalSection2_Begin(PyCriticalSection2 *c, PyObject *a, PyObject *b);
PyAPI_FUNC(void)
PyCriticalSection2_BeginMutex(PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2);
PyAPI_FUNC(void)
PyCriticalSection2_End(PyCriticalSection2 *c);
#ifndef Py_GIL_DISABLED
# define Py_BEGIN_CRITICAL_SECTION(op) \
{
# define Py_BEGIN_CRITICAL_SECTION_MUTEX(mutex) \
{
# define Py_END_CRITICAL_SECTION() \
}
# define Py_BEGIN_CRITICAL_SECTION2(a, b) \
{
# define Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2) \
{
# define Py_END_CRITICAL_SECTION2() \
}
#else /* !Py_GIL_DISABLED */
// NOTE: the contents of this struct are private and may change betweeen
// Python releases without a deprecation period.
struct PyCriticalSection {
// Tagged pointer to an outer active critical section (or 0).
uintptr_t _cs_prev;
// Mutex used to protect critical section
PyMutex *_cs_mutex;
};
// A critical section protected by two mutexes. Use
// Py_BEGIN_CRITICAL_SECTION2 and Py_END_CRITICAL_SECTION2.
// NOTE: the contents of this struct are private and may change betweeen
// Python releases without a deprecation period.
struct PyCriticalSection2 {
PyCriticalSection _cs_base;
PyMutex *_cs_mutex2;
};
# define Py_BEGIN_CRITICAL_SECTION(op) \
{ \
PyCriticalSection _py_cs; \
PyCriticalSection_Begin(&_py_cs, _PyObject_CAST(op))
# define Py_BEGIN_CRITICAL_SECTION_MUTEX(mutex) \
{ \
PyCriticalSection _py_cs; \
PyCriticalSection_BeginMutex(&_py_cs, mutex)
# define Py_END_CRITICAL_SECTION() \
PyCriticalSection_End(&_py_cs); \
}
# define Py_BEGIN_CRITICAL_SECTION2(a, b) \
{ \
PyCriticalSection2 _py_cs2; \
PyCriticalSection2_Begin(&_py_cs2, _PyObject_CAST(a), _PyObject_CAST(b))
# define Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2) \
{ \
PyCriticalSection2 _py_cs2; \
PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2)
# define Py_END_CRITICAL_SECTION2() \
PyCriticalSection2_End(&_py_cs2); \
}
#endif

View File

@@ -0,0 +1,62 @@
#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_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
struct wrapperbase *, void *);
PyAPI_FUNC(int) PyDescr_IsData(PyObject *);

View File

@@ -0,0 +1,105 @@
#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;
/* This is a private field for CPython's internal use.
* Bits 0-7 are for dict watchers.
* Bits 8-11 are for the watched mutation counter (used by tier2 optimization)
* Bits 12-31 are currently unused
* Bits 32-63 are a unique id in the free threading build (used for per-thread refcounting)
*/
uint64_t _ma_watcher_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);
// PyDict_GetItemStringRef() can be used instead
Py_DEPRECATED(3.14) PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
PyObject *mp, PyObject *key, PyObject *defaultobj);
// Inserts `key` with a value `default_value`, if `key` is not already present
// in the dictionary. If `result` is not NULL, then the value associated
// with `key` is returned in `*result` (either the existing value, or the now
// inserted `default_value`).
// Returns:
// -1 on error
// 0 if `key` was not present and `default_value` was inserted
// 1 if `key` was present and `default_value` was not inserted
PyAPI_FUNC(int) PyDict_SetDefaultRef(PyObject *mp, PyObject *key, PyObject *default_value, PyObject **result);
/* Get the number of items of a dictionary. */
static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
PyDictObject *mp;
assert(PyDict_Check(op));
mp = _Py_CAST(PyDictObject*, op);
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&mp->ma_used);
#else
return mp->ma_used;
#endif
}
#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
// Use PyDict_Pop() instead
Py_DEPRECATED(3.14) PyAPI_FUNC(PyObject *) _PyDict_Pop(
PyObject *dict,
PyObject *key,
PyObject *default_value);
/* Dictionary watchers */
#define PY_FOREACH_DICT_EVENT(V) \
V(ADDED) \
V(MODIFIED) \
V(DELETED) \
V(CLONED) \
V(CLEARED) \
V(DEALLOCATED)
typedef enum {
#define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT,
PY_FOREACH_DICT_EVENT(PY_DEF_EVENT)
#undef PY_DEF_EVENT
} PyDict_WatchEvent;
// Callback to be invoked when a watched dict is cleared, dealloced, or modified.
// In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the
// new value for key, NULL if key is being deleted.
typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value);
// Register/unregister a dict-watcher callback
PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback);
PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id);
// Mark given dictionary as "watched" (callback will be called if it is modified)
PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict);
PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict);

View File

@@ -0,0 +1,16 @@
#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);

View File

@@ -0,0 +1,16 @@
#ifndef Py_CPYTHON_FILEUTILS_H
# error "this header file must not be included directly"
#endif
PyAPI_FUNC(FILE*) Py_fopen(
PyObject *path,
const char *mode);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline FILE*
_Py_fopen_obj(PyObject *path, const char *mode)
{
return Py_fopen(path, mode);
}
PyAPI_FUNC(int) Py_fclose(FILE *file);

View File

@@ -0,0 +1,27 @@
#ifndef Py_CPYTHON_FLOATOBJECT_H
# error "this header file must not be included directly"
#endif
typedef struct {
PyObject_HEAD
double ob_fval;
} PyFloatObject;
#define _PyFloat_CAST(op) \
(assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op))
// Static inline version of PyFloat_AsDouble() trading safety for speed.
// It doesn't check if op is a double object.
static inline double PyFloat_AS_DOUBLE(PyObject *op) {
return _PyFloat_CAST(op)->ob_fval;
}
#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op))
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);

View File

@@ -0,0 +1,35 @@
/* 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 *);
typedef struct {
PyObject_HEAD
PyFrameObject* frame;
} PyFrameLocalsProxyObject;

View File

@@ -0,0 +1,185 @@
/* Function object interface */
#ifndef Py_LIMITED_API
#ifndef Py_FUNCOBJECT_H
#define Py_FUNCOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#define _Py_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 {
_Py_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
_Py_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 */
PyObject *func_annotate; /* Callable to fill the annotations dictionary */
PyObject *func_typeparams; /* Tuple of active type variables 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
* vectorcall function pointer */
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;
#undef _Py_COMMON_FIELDS
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(void) PyFunction_SetVectorcall(PyFunctionObject *, vectorcallfunc);
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 *);
#define _PyFunction_CAST(func) \
(assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func))
/* Static inline functions for direct access to these values.
Type checks are *not* done, so use with care. */
static inline PyObject* PyFunction_GET_CODE(PyObject *func) {
return _PyFunction_CAST(func)->func_code;
}
#define PyFunction_GET_CODE(func) PyFunction_GET_CODE(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_GLOBALS(PyObject *func) {
return _PyFunction_CAST(func)->func_globals;
}
#define PyFunction_GET_GLOBALS(func) PyFunction_GET_GLOBALS(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_MODULE(PyObject *func) {
return _PyFunction_CAST(func)->func_module;
}
#define PyFunction_GET_MODULE(func) PyFunction_GET_MODULE(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_DEFAULTS(PyObject *func) {
return _PyFunction_CAST(func)->func_defaults;
}
#define PyFunction_GET_DEFAULTS(func) PyFunction_GET_DEFAULTS(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_KW_DEFAULTS(PyObject *func) {
return _PyFunction_CAST(func)->func_kwdefaults;
}
#define PyFunction_GET_KW_DEFAULTS(func) PyFunction_GET_KW_DEFAULTS(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_CLOSURE(PyObject *func) {
return _PyFunction_CAST(func)->func_closure;
}
#define PyFunction_GET_CLOSURE(func) PyFunction_GET_CLOSURE(_PyObject_CAST(func))
static inline PyObject* PyFunction_GET_ANNOTATIONS(PyObject *func) {
return _PyFunction_CAST(func)->func_annotations;
}
#define PyFunction_GET_ANNOTATIONS(func) PyFunction_GET_ANNOTATIONS(_PyObject_CAST(func))
/* 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 *);
#define PY_FOREACH_FUNC_EVENT(V) \
V(CREATE) \
V(DESTROY) \
V(MODIFY_CODE) \
V(MODIFY_DEFAULTS) \
V(MODIFY_KWDEFAULTS)
typedef enum {
#define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT,
PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT)
#undef PY_DEF_EVENT
} PyFunction_WatchEvent;
/*
* A callback that is invoked for different events in a function's lifecycle.
*
* The callback is invoked with a borrowed reference to func, after it is
* created and before it is modified or destroyed. The callback should not
* modify func.
*
* When a function's code object, defaults, or kwdefaults are modified the
* callback will be invoked with the respective event and new_value will
* contain a borrowed reference to the new value that is about to be stored in
* the function. Otherwise the third argument is NULL.
*
* If the callback returns with an exception set, it must return -1. Otherwise
* it should return 0.
*/
typedef int (*PyFunction_WatchCallback)(
PyFunction_WatchEvent event,
PyFunctionObject *func,
PyObject *new_value);
/*
* Register a per-interpreter callback that will be invoked for function lifecycle
* events.
*
* Returns a handle that may be passed to PyFunction_ClearWatcher on success,
* or -1 and sets an error if no more handles are available.
*/
PyAPI_FUNC(int) PyFunction_AddWatcher(PyFunction_WatchCallback callback);
/*
* Clear the watcher associated with the watcher_id handle.
*
* Returns 0 on success or -1 if no watcher exists for the supplied id.
*/
PyAPI_FUNC(int) PyFunction_ClearWatcher(int watcher_id);
#ifdef __cplusplus
}
#endif
#endif /* !Py_FUNCOBJECT_H */
#endif /* Py_LIMITED_API */

View File

@@ -0,0 +1,56 @@
/* Generator object interface */
#ifndef Py_LIMITED_API
#ifndef Py_GENOBJECT_H
#define Py_GENOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
/* --- Generators --------------------------------------------------------- */
typedef struct _PyGenObject 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(PyCodeObject *) PyGen_GetCode(PyGenObject *gen);
/* --- PyCoroObject ------------------------------------------------------- */
typedef struct _PyCoroObject PyCoroObject;
PyAPI_DATA(PyTypeObject) PyCoro_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 _PyAsyncGenObject PyAsyncGenObject;
PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *,
PyObject *name, PyObject *qualname);
#define PyAsyncGen_CheckExact(op) Py_IS_TYPE((op), &PyAsyncGen_Type)
#define PyAsyncGenASend_CheckExact(op) Py_IS_TYPE((op), &_PyAsyncGenASend_Type)
#undef _PyGenObject_HEAD
#ifdef __cplusplus
}
#endif
#endif /* !Py_GENOBJECT_H */
#endif /* Py_LIMITED_API */

30
extern/include/python/cpython/import.h vendored Normal file
View File

@@ -0,0 +1,30 @@
#ifndef Py_CPYTHON_IMPORT_H
# error "this header file must not be included directly"
#endif
struct _inittab {
const char *name; /* ASCII encoded string */
PyObject* (*initfunc)(void);
};
// This is not used after Py_Initialize() is called.
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;
};
/* Embedding apps may change this pointer to point to their favorite
collection of frozen modules: */
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttr(
PyObject *mod_name,
PyObject *attr_name);
PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttrString(
const char *mod_name,
const char *attr_name);

View File

@@ -0,0 +1,334 @@
#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 perf_profiling;
int remote_debug;
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;
int int_max_str_digits;
int thread_inherit_context;
int context_aware_warnings;
#ifdef __APPLE__
int use_system_logger;
#endif
int cpu_count;
#ifdef Py_GIL_DISABLED
int enable_gil;
int tlbc_enabled;
#endif
/* --- 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;
/* --- Set by Py_Main() -------------------------- */
wchar_t *sys_path_0;
/* --- 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, we believe we're running from a source tree.
int _is_python_build;
#ifdef Py_STATS
// If non-zero, turns on statistics gathering.
int _pystats;
#endif
#ifdef Py_DEBUG
// If not empty, import a non-__main__ module before site.py is executed.
// PYTHON_PRESITE=package.module or -X presite=package.module
wchar_t *run_presite;
#endif
} 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);
/* --- PyConfig_Get() ----------------------------------------- */
PyAPI_FUNC(PyObject*) PyConfig_Get(const char *name);
PyAPI_FUNC(int) PyConfig_GetInt(const char *name, int *value);
PyAPI_FUNC(PyObject*) PyConfig_Names(void);
PyAPI_FUNC(int) PyConfig_Set(const char *name, PyObject *value);
/* --- 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);
// --- PyInitConfig ---------------------------------------------------------
typedef struct PyInitConfig PyInitConfig;
PyAPI_FUNC(PyInitConfig*) PyInitConfig_Create(void);
PyAPI_FUNC(void) PyInitConfig_Free(PyInitConfig *config);
PyAPI_FUNC(int) PyInitConfig_GetError(PyInitConfig* config,
const char **err_msg);
PyAPI_FUNC(int) PyInitConfig_GetExitCode(PyInitConfig* config,
int *exitcode);
PyAPI_FUNC(int) PyInitConfig_HasOption(PyInitConfig *config,
const char *name);
PyAPI_FUNC(int) PyInitConfig_GetInt(PyInitConfig *config,
const char *name,
int64_t *value);
PyAPI_FUNC(int) PyInitConfig_GetStr(PyInitConfig *config,
const char *name,
char **value);
PyAPI_FUNC(int) PyInitConfig_GetStrList(PyInitConfig *config,
const char *name,
size_t *length,
char ***items);
PyAPI_FUNC(void) PyInitConfig_FreeStrList(size_t length, char **items);
PyAPI_FUNC(int) PyInitConfig_SetInt(PyInitConfig *config,
const char *name,
int64_t value);
PyAPI_FUNC(int) PyInitConfig_SetStr(PyInitConfig *config,
const char *name,
const char *value);
PyAPI_FUNC(int) PyInitConfig_SetStrList(PyInitConfig *config,
const char *name,
size_t length,
char * const *items);
PyAPI_FUNC(int) PyInitConfig_AddModule(PyInitConfig *config,
const char *name,
PyObject* (*initfunc)(void));
PyAPI_FUNC(int) Py_InitializeFromInitConfig(PyInitConfig *config);
#ifdef __cplusplus
}
#endif
#endif /* !Py_LIMITED_API */
#endif /* !Py_PYCORECONFIG_H */

View File

@@ -0,0 +1,53 @@
#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;
/* 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);
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(list)->ob_size));
#else
return Py_SIZE(list);
#endif
}
#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op))
#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);
assert(0 <= index);
assert(index < list->allocated);
list->ob_item[index] = value;
}
#define PyList_SET_ITEM(op, index, value) \
PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))
PyAPI_FUNC(int) PyList_Extend(PyObject *self, PyObject *iterable);
PyAPI_FUNC(int) PyList_Clear(PyObject *self);

74
extern/include/python/cpython/lock.h vendored Normal file
View File

@@ -0,0 +1,74 @@
#ifndef Py_CPYTHON_LOCK_H
# error "this header file must not be included directly"
#endif
#define _Py_UNLOCKED 0
#define _Py_LOCKED 1
// A mutex that occupies one byte. The lock can be zero initialized to
// represent the unlocked state.
//
// Typical initialization:
// PyMutex m = (PyMutex){0};
//
// Or initialize as global variables:
// static PyMutex m;
//
// Typical usage:
// PyMutex_Lock(&m);
// ...
// PyMutex_Unlock(&m);
//
// The contents of the PyMutex are not part of the public API, but are
// described to aid in understanding the implementation and debugging. Only
// the two least significant bits are used. The remaining bits are always zero:
// 0b00: unlocked
// 0b01: locked
// 0b10: unlocked and has parked threads
// 0b11: locked and has parked threads
typedef struct PyMutex {
uint8_t _bits; // (private)
} PyMutex;
// exported function for locking the mutex
PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m);
// exported function for unlocking the mutex
PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m);
// exported function for checking if the mutex is locked
PyAPI_FUNC(int) PyMutex_IsLocked(PyMutex *m);
// Locks the mutex.
//
// If the mutex is currently locked, the calling thread will be parked until
// the mutex is unlocked. If the current thread holds the GIL, then the GIL
// will be released while the thread is parked.
static inline void
_PyMutex_Lock(PyMutex *m)
{
uint8_t expected = _Py_UNLOCKED;
if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) {
PyMutex_Lock(m);
}
}
#define PyMutex_Lock _PyMutex_Lock
// Unlocks the mutex.
static inline void
_PyMutex_Unlock(PyMutex *m)
{
uint8_t expected = _Py_LOCKED;
if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_UNLOCKED)) {
PyMutex_Unlock(m);
}
}
#define PyMutex_Unlock _PyMutex_Unlock
// Checks if the mutex is currently locked.
static inline int
_PyMutex_IsLocked(PyMutex *m)
{
return (_Py_atomic_load_uint8(&m->_bits) & _Py_LOCKED) != 0;
}
#define PyMutex_IsLocked _PyMutex_IsLocked

View File

@@ -0,0 +1,184 @@
#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.
Long integers are made up of a number of 30- or 15-bit digits, depending on
the platform. The number of digits (ndigits) is stored in the high bits of
the lv_tag field (lvtag >> _PyLong_NON_SIZE_BITS).
The absolute value of a number is equal to
SUM(for i=0 through ndigits-1) ob_digit[i] * 2**(PyLong_SHIFT*i)
The sign of the value is stored in the lower 2 bits of lv_tag.
- 0: Positive
- 1: Zero
- 2: Negative
The third lowest bit of lv_tag is
set to 1 for the small ints.
In a normalized number, ob_digit[ndigits-1] (the most significant
digit) is never zero. Also, in all cases, for all valid i,
0 <= ob_digit[i] <= PyLong_MASK.
The allocation function takes care of allocating extra memory
so that ob_digit[0] ... ob_digit[ndigits-1] are actually available.
We always allocate memory for at least one digit, so accessing ob_digit[0]
is always safe. However, in the case ndigits == 0, the contents of
ob_digit[0] may be undefined.
*/
typedef struct _PyLongValue {
uintptr_t lv_tag; /* Number of digits, sign and flags */
digit ob_digit[1];
} _PyLongValue;
struct _longobject {
PyObject_HEAD
_PyLongValue long_value;
};
Py_DEPRECATED(3.14) PyAPI_FUNC(PyLongObject*) _PyLong_New(Py_ssize_t);
// Return a copy of src.
PyAPI_FUNC(PyObject*) _PyLong_Copy(PyLongObject *src);
Py_DEPRECATED(3.14) PyAPI_FUNC(PyLongObject*) _PyLong_FromDigits(
int negative,
Py_ssize_t digit_count,
digit *digits);
/* Inline some internals for speed. These should be in pycore_long.h
* if user code didn't need them inlined. */
#define _PyLong_SIGN_MASK 3
#define _PyLong_NON_SIZE_BITS 3
static inline int
_PyLong_IsCompact(const PyLongObject* op) {
assert(PyType_HasFeature(op->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS));
return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS);
}
#define PyUnstable_Long_IsCompact _PyLong_IsCompact
static inline Py_ssize_t
_PyLong_CompactValue(const PyLongObject *op)
{
Py_ssize_t sign;
assert(PyType_HasFeature(op->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS));
assert(PyUnstable_Long_IsCompact(op));
sign = 1 - (op->long_value.lv_tag & _PyLong_SIGN_MASK);
return sign * (Py_ssize_t)op->long_value.ob_digit[0];
}
#define PyUnstable_Long_CompactValue _PyLong_CompactValue
/* --- Import/Export API -------------------------------------------------- */
typedef struct PyLongLayout {
uint8_t bits_per_digit;
uint8_t digit_size;
int8_t digits_order;
int8_t digit_endianness;
} PyLongLayout;
PyAPI_FUNC(const PyLongLayout*) PyLong_GetNativeLayout(void);
typedef struct PyLongExport {
int64_t value;
uint8_t negative;
Py_ssize_t ndigits;
const void *digits;
// Member used internally, must not be used for other purpose.
Py_uintptr_t _reserved;
} PyLongExport;
PyAPI_FUNC(int) PyLong_Export(
PyObject *obj,
PyLongExport *export_long);
PyAPI_FUNC(void) PyLong_FreeExport(
PyLongExport *export_long);
/* --- PyLongWriter API --------------------------------------------------- */
typedef struct PyLongWriter PyLongWriter;
PyAPI_FUNC(PyLongWriter*) PyLongWriter_Create(
int negative,
Py_ssize_t ndigits,
void **digits);
PyAPI_FUNC(PyObject*) PyLongWriter_Finish(PyLongWriter *writer);
PyAPI_FUNC(void) PyLongWriter_Discard(PyLongWriter *writer);
#ifdef __cplusplus
}
#endif
#endif /* !Py_LONGINTREPR_H */
#endif /* Py_LIMITED_API */

View File

@@ -0,0 +1,89 @@
#ifndef Py_CPYTHON_LONGOBJECT_H
# error "this header file must not be included directly"
#endif
#define _PyLong_CAST(op) \
(assert(PyLong_Check(op)), _Py_CAST(PyLongObject*, (op)))
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
/* PyLong_IsPositive. Check if the integer object is positive.
- On success, return 1 if *obj is positive, and 0 otherwise.
- On failure, set an exception, and return -1. */
PyAPI_FUNC(int) PyLong_IsPositive(PyObject *obj);
/* PyLong_IsNegative. Check if the integer object is negative.
- On success, return 1 if *obj is negative, and 0 otherwise.
- On failure, set an exception, and return -1. */
PyAPI_FUNC(int) PyLong_IsNegative(PyObject *obj);
/* PyLong_IsZero. Check if the integer object is zero.
- On success, return 1 if *obj is zero, and 0 if it is non-zero.
- On failure, set an exception, and return -1. */
PyAPI_FUNC(int) PyLong_IsZero(PyObject *obj);
/* PyLong_GetSign. Get the sign of an integer object:
0, -1 or +1 for zero, negative or positive integer, respectively.
- On success, set '*sign' to the integer sign, and return 0.
- On failure, set an exception, and return -1. */
PyAPI_FUNC(int) PyLong_GetSign(PyObject *v, int *sign);
Py_DEPRECATED(3.14) 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.
Always successful.
*/
PyAPI_FUNC(int64_t) _PyLong_NumBits(PyObject *v);
/* _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, int with_exceptions);
/* For use by the gcd function in mathmodule.c */
PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *);

View File

@@ -0,0 +1,50 @@
#ifndef Py_CPYTHON_MEMORYOBJECT_H
# error "this header file must not be included directly"
#endif
/* The structs are declared here so that macros can work, but they shouldn't
be considered public. Don't access their fields directly, use the macros
and functions instead! */
#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */
#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */
typedef struct {
PyObject_HEAD
int flags; /* state flags */
Py_ssize_t exports; /* number of direct memoryview exports */
Py_buffer master; /* snapshot buffer obtained from the original exporter */
} _PyManagedBufferObject;
/* memoryview state flags */
#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */
#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */
#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */
#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */
#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */
#define _Py_MEMORYVIEW_RESTRICTED 0x020 /* Disallow new references to the memoryview's buffer */
typedef struct {
PyObject_VAR_HEAD
_PyManagedBufferObject *mbuf; /* managed buffer */
Py_hash_t hash; /* hash value for read-only views */
int flags; /* state flags */
Py_ssize_t exports; /* number of buffer re-exports */
Py_buffer view; /* private copy of the exporter's view */
PyObject *weakreflist;
Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */
} PyMemoryViewObject;
#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op)
/* Get a pointer to the memoryview's private copy of the exporter's buffer. */
static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) {
return (&_PyMemoryView_CAST(op)->view);
}
#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op))
/* Get a pointer to the exporting object (this may be NULL!). */
static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) {
return _PyMemoryView_CAST(op)->view.obj;
}
#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op))

View File

@@ -0,0 +1,66 @@
#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;
}
#define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func))
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;
}
#define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func))
static inline int PyCFunction_GET_FLAGS(PyObject *func) {
return _PyCFunctionObject_CAST(func)->m_ml->ml_flags;
}
#define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func))
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;
}
#define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func))

View File

@@ -0,0 +1,26 @@
#ifndef Py_CPYTHON_MODSUPPORT_H
# error "this header file must not be included directly"
#endif
// A data structure that can be used to run initialization code once in a
// thread-safe manner. The C++11 equivalent is std::call_once.
typedef struct {
uint8_t v;
} _PyOnceFlag;
typedef struct _PyArg_Parser {
const char *format;
const char * const *keywords;
const char *fname;
const char *custom_msg;
_PyOnceFlag once; /* atomic one-time initialization flag */
int is_kwtuple_owned; /* does this parser own the kwtuple object? */
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;
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
struct _PyArg_Parser *, ...);

View File

@@ -0,0 +1,269 @@
#ifndef Py_CPYTHON_MONITORING_H
# error "this header file must not be included directly"
#endif
/* Local events.
* These require bytecode instrumentation */
#define PY_MONITORING_EVENT_PY_START 0
#define PY_MONITORING_EVENT_PY_RESUME 1
#define PY_MONITORING_EVENT_PY_RETURN 2
#define PY_MONITORING_EVENT_PY_YIELD 3
#define PY_MONITORING_EVENT_CALL 4
#define PY_MONITORING_EVENT_LINE 5
#define PY_MONITORING_EVENT_INSTRUCTION 6
#define PY_MONITORING_EVENT_JUMP 7
#define PY_MONITORING_EVENT_BRANCH_LEFT 8
#define PY_MONITORING_EVENT_BRANCH_RIGHT 9
#define PY_MONITORING_EVENT_STOP_ITERATION 10
#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \
((ev) < _PY_MONITORING_LOCAL_EVENTS)
/* Other events, mainly exceptions */
#define PY_MONITORING_EVENT_RAISE 11
#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 12
#define PY_MONITORING_EVENT_PY_UNWIND 13
#define PY_MONITORING_EVENT_PY_THROW 14
#define PY_MONITORING_EVENT_RERAISE 15
/* Ancillary events */
#define PY_MONITORING_EVENT_C_RETURN 16
#define PY_MONITORING_EVENT_C_RAISE 17
#define PY_MONITORING_EVENT_BRANCH 18
typedef struct _PyMonitoringState {
uint8_t active;
uint8_t opaque;
} PyMonitoringState;
PyAPI_FUNC(int)
PyMonitoring_EnterScope(PyMonitoringState *state_array, uint64_t *version,
const uint8_t *event_types, Py_ssize_t length);
PyAPI_FUNC(int)
PyMonitoring_ExitScope(void);
PyAPI_FUNC(int)
_PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval);
PyAPI_FUNC(int)
_PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval);
PyAPI_FUNC(int)
_PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject* callable, PyObject *arg0);
PyAPI_FUNC(int)
_PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
int lineno);
PyAPI_FUNC(int)
_PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
Py_DEPRECATED(3.14) PyAPI_FUNC(int)
_PyMonitoring_FireBranchEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
PyAPI_FUNC(int)
_PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
PyAPI_FUNC(int)
_PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset);
PyAPI_FUNC(int)
_PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval);
PyAPI_FUNC(int)
_PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset);
PyAPI_FUNC(int)
_PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value);
#define _PYMONITORING_IF_ACTIVE(STATE, X) \
if ((STATE)->active) { \
return (X); \
} \
else { \
return 0; \
}
static inline int
PyMonitoring_FirePyStartEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyStartEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FirePyResumeEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyResumeEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FirePyReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyReturnEvent(state, codelike, offset, retval));
}
static inline int
PyMonitoring_FirePyYieldEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyYieldEvent(state, codelike, offset, retval));
}
static inline int
PyMonitoring_FireCallEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject* callable, PyObject *arg0)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireCallEvent(state, codelike, offset, callable, arg0));
}
static inline int
PyMonitoring_FireLineEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
int lineno)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireLineEvent(state, codelike, offset, lineno));
}
static inline int
PyMonitoring_FireJumpEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireJumpEvent(state, codelike, offset, target_offset));
}
static inline int
PyMonitoring_FireBranchRightEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireBranchRightEvent(state, codelike, offset, target_offset));
}
static inline int
PyMonitoring_FireBranchLeftEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *target_offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireBranchLeftEvent(state, codelike, offset, target_offset));
}
static inline int
PyMonitoring_FireCReturnEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset,
PyObject *retval)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireCReturnEvent(state, codelike, offset, retval));
}
static inline int
PyMonitoring_FirePyThrowEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyThrowEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FireRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireRaiseEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FireReraiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireReraiseEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FireExceptionHandledEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireExceptionHandledEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FireCRaiseEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireCRaiseEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FirePyUnwindEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FirePyUnwindEvent(state, codelike, offset));
}
static inline int
PyMonitoring_FireStopIterationEvent(PyMonitoringState *state, PyObject *codelike, int32_t offset, PyObject *value)
{
_PYMONITORING_IF_ACTIVE(
state,
_PyMonitoring_FireStopIterationEvent(state, codelike, offset, value));
}
#undef _PYMONITORING_IF_ACTIVE

493
extern/include/python/cpython/object.h vendored Normal file
View File

@@ -0,0 +1,493 @@
#ifndef Py_CPYTHON_OBJECT_H
# error "this header file must not be included directly"
#endif
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op);
PyAPI_FUNC(void) _Py_ForgetReference(PyObject *op);
#ifdef Py_REF_DEBUG
/* These are useful as debugging aids when chasing down refleaks. */
PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void);
# define _Py_GetRefTotal() _Py_GetGlobalRefTotal()
PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void);
PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
#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;
// Hidden PyMutex struct for non free-threaded build.
struct {
uint8_t v;
} mutex;
} _Py_Identifier;
#ifndef 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 /* !Py_BUILD_CORE */
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; /* no longer used */
void *tp_subclasses; /* for static builtin types this is an index */
PyObject *tp_weaklist; /* not used for static builtin types */
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6.
* If zero, the cache is invalid and must be initialized.
*/
unsigned int tp_version_tag;
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
/* bitset of which type-watchers care about this type */
unsigned char tp_watched;
/* Number of tp_version_tag values used.
* Set to _Py_ATTR_CACHE_UNUSED if the attribute cache is
* disabled for this type (e.g. due to custom MRO entries).
* Otherwise, limited to MAX_VERSIONS_PER_CLASS (defined elsewhere).
*/
uint16_t tp_versions_used;
};
#define _Py_ATTR_CACHE_UNUSED (30000) // (see tp_versions_used)
/* This struct is used by the specializer
* It should be treated as an opaque blob
* by code other than the specializer and interpreter. */
struct _specialization_cache {
// In order to avoid bloating the bytecode with lots of inline caches, the
// members of this structure have a somewhat unique contract. They are set
// by the specialization machinery, and are invalidated by PyType_Modified.
// The rules for using them are as follows:
// - If getitem is non-NULL, then it is the same Python function that
// PyType_Lookup(cls, "__getitem__") would return.
// - If getitem is NULL, then getitem_version is meaningless.
// - If getitem->func_version == getitem_version, then getitem can be called
// with two positional arguments and no keyword arguments, and has neither
// *args nor **kwargs (as required by BINARY_OP_SUBSCR_GETITEM):
PyObject *getitem;
uint32_t getitem_version;
PyObject *init;
};
/* 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
void *ht_token; // Storage for the "Py_tp_token" slot
struct _specialization_cache _spec_cache; // For use by the specializer.
#ifdef Py_GIL_DISABLED
Py_ssize_t unique_id; // ID used for per-thread refcounting
#endif
/* 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_LookupRef(PyTypeObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void);
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
PyAPI_FUNC(void) PyUnstable_Object_ClearWeakRefsNoCallbacks(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 `dst` and set `dst` to `src`.
*
* As in case of Py_CLEAR "the obvious" code can be deadly:
*
* Py_DECREF(dst);
* dst = src;
*
* The safe way is:
*
* Py_SETREF(dst, src);
*
* That arranges to set `dst` to `src` _before_ decref'ing, so that any code
* triggered as a side-effect of `dst` getting torn down no longer believes
* `dst` points to a valid object.
*
* Temporary variables are used to only evaluate macro arguments once and so
* avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to
* avoid a miscompilation caused by type punning. See Py_CLEAR() comment for
* implementation details about type punning.
*
* The memcpy() implementation does not emit a compiler warning if 'src' has
* not the same type than 'src': any pointer type is accepted for 'src'.
*/
#ifdef _Py_TYPEOF
#define Py_SETREF(dst, src) \
do { \
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
*_tmp_dst_ptr = (src); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#else
#define Py_SETREF(dst, src) \
do { \
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
PyObject *_tmp_src = _PyObject_CAST(src); \
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#endif
/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of
* Py_DECREF().
*/
#ifdef _Py_TYPEOF
#define Py_XSETREF(dst, src) \
do { \
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
*_tmp_dst_ptr = (src); \
Py_XDECREF(_tmp_old_dst); \
} while (0)
#else
#define Py_XSETREF(dst, src) \
do { \
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
PyObject *_tmp_src = _PyObject_CAST(src); \
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
Py_XDECREF(_tmp_old_dst); \
} while (0)
#endif
/* 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);
PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op);
PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate);
PyAPI_FUNC(int) _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count);
/* For backwards compatibility with the old trashcan mechanism */
#define Py_TRASHCAN_BEGIN(op, dealloc)
#define Py_TRASHCAN_END
PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);
PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
PyAPI_FUNC(int) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict);
PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj);
typedef int(*PyType_WatchCallback)(PyTypeObject *);
PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback);
PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id);
PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type);
PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type);
/* Attempt to assign a version tag to the given type.
*
* Returns 1 if the type already had a valid version tag or a new one was
* assigned, or 0 if a new tag could not be assigned.
*/
PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type);
typedef enum {
PyRefTracer_CREATE = 0,
PyRefTracer_DESTROY = 1,
} PyRefTracerEvent;
typedef int (*PyRefTracer)(PyObject *, PyRefTracerEvent event, void *);
PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data);
PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**);
/* Enable PEP-703 deferred reference counting on the object.
*
* Returns 1 if deferred reference counting was successfully enabled, and
* 0 if the runtime ignored it. This function cannot fail.
*/
PyAPI_FUNC(int) PyUnstable_Object_EnableDeferredRefcount(PyObject *);
/* Determine if the object exists as a unique temporary variable on the
* topmost frame of the interpreter.
*/
PyAPI_FUNC(int) PyUnstable_Object_IsUniqueReferencedTemporary(PyObject *);
/* Check whether the object is immortal. This cannot fail. */
PyAPI_FUNC(int) PyUnstable_IsImmortal(PyObject *);
// Increments the reference count of the object, if it's not zero.
// PyUnstable_EnableTryIncRef() should be called on the object
// before calling this function in order to avoid spurious failures.
PyAPI_FUNC(int) PyUnstable_TryIncRef(PyObject *);
PyAPI_FUNC(void) PyUnstable_EnableTryIncRef(PyObject *);
PyAPI_FUNC(int) PyUnstable_Object_IsUniquelyReferenced(PyObject *);

104
extern/include/python/cpython/objimpl.h vendored Normal file
View File

@@ -0,0 +1,104 @@
#ifndef Py_CPYTHON_OBJIMPL_H
# error "this header file must not be included directly"
#endif
static inline size_t _PyObject_SIZE(PyTypeObject *type) {
return _Py_STATIC_CAST(size_t, type->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
static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) {
size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize);
size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize);
return _Py_SIZE_ROUND_UP(size, 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);
// Test if a type supports weak references
PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type);
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
PyAPI_FUNC(PyObject *) PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *,
size_t);
/* Visit all live GC-capable objects, similar to gc.get_objects(None). The
* supplied callback is called on every such object with the void* arg set
* to the supplied arg. Returning 0 from the callback ends iteration, returning
* 1 allows iteration to continue. Returning any other value may result in
* undefined behaviour.
*
* If new objects are (de)allocated by the callback it is undefined if they
* will be visited.
* Garbage collection is disabled during operation. Explicitly running a
* collection in the callback may lead to undefined behaviour e.g. visiting the
* same objects multiple times or not at all.
*/
typedef int (*gcvisitobjects_t)(PyObject*, void*);
PyAPI_FUNC(void) PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void* arg);

View File

@@ -0,0 +1,43 @@
#ifndef Py_ODICTOBJECT_H
#define Py_ODICTOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
/* OrderedDict */
/* This API is optional and mostly redundant. */
#ifndef Py_LIMITED_API
typedef struct _odictobject PyODictObject;
PyAPI_DATA(PyTypeObject) PyODict_Type;
PyAPI_DATA(PyTypeObject) PyODictIter_Type;
PyAPI_DATA(PyTypeObject) PyODictKeys_Type;
PyAPI_DATA(PyTypeObject) PyODictItems_Type;
PyAPI_DATA(PyTypeObject) PyODictValues_Type;
#define PyODict_Check(op) PyObject_TypeCheck((op), &PyODict_Type)
#define PyODict_CheckExact(op) Py_IS_TYPE((op), &PyODict_Type)
#define PyODict_SIZE(op) PyDict_GET_SIZE((op))
PyAPI_FUNC(PyObject *) PyODict_New(void);
PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key);
/* wrappers around PyDict* functions */
#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), (key))
#define PyODict_GetItemWithError(od, key) \
PyDict_GetItemWithError(_PyObject_CAST(od), (key))
#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), (key))
#define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od))
#define PyODict_GetItemString(od, key) \
PyDict_GetItemString(_PyObject_CAST(od), (key))
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_ODICTOBJECT_H */

View File

@@ -0,0 +1,31 @@
/* PickleBuffer object. This is built-in for ease of use from third-party
* C extensions.
*/
#ifndef Py_PICKLEBUFOBJECT_H
#define Py_PICKLEBUFOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_LIMITED_API
PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type;
#define PyPickleBuffer_Check(op) Py_IS_TYPE((op), &PyPickleBuffer_Type)
/* Create a PickleBuffer redirecting to the given buffer-enabled object */
PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *);
/* Get the PickleBuffer's underlying view to the original object
* (NULL if released)
*/
PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *);
/* Release the PickleBuffer. Returns 0 on success, -1 on error. */
PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *);
#endif /* !Py_LIMITED_API */
#ifdef __cplusplus
}
#endif
#endif /* !Py_PICKLEBUFOBJECT_H */

View File

@@ -0,0 +1,105 @@
#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.
//
// <sys/types.h> may also define these macros.
# ifndef __NEED_pthread_cond_t
# define __NEED_pthread_cond_t 1
# endif
# ifndef __NEED_pthread_condattr_t
# define __NEED_pthread_condattr_t 1
# endif
# ifndef __NEED_pthread_mutex_t
# define __NEED_pthread_mutex_t 1
# endif
# ifndef __NEED_pthread_mutexattr_t
# define __NEED_pthread_mutexattr_t 1
# endif
# ifndef __NEED_pthread_key_t
# define __NEED_pthread_key_t 1
# endif
# ifndef __NEED_pthread_t
# define __NEED_pthread_t 1
# endif
# ifndef __NEED_pthread_attr_t
# define __NEED_pthread_attr_t 1
# endif
# 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(int) pthread_join(pthread_t thread, void** value_ptr);
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

625
extern/include/python/cpython/pyatomic.h vendored Normal file
View File

@@ -0,0 +1,625 @@
// This header provides cross-platform low-level atomic operations
// similar to C11 atomics.
//
// Operations are sequentially consistent unless they have a suffix indicating
// otherwise. If in doubt, prefer the sequentially consistent operations.
//
// The "_relaxed" suffix for load and store operations indicates the "relaxed"
// memory order. They don't provide synchronization, but (roughly speaking)
// guarantee somewhat sane behavior for races instead of undefined behavior.
// In practice, they correspond to "normal" hardware load and store
// instructions, so they are almost as inexpensive as plain loads and stores
// in C.
//
// Note that atomic read-modify-write operations like _Py_atomic_add_* return
// the previous value of the atomic variable, not the new value.
//
// See https://en.cppreference.com/w/c/atomic for more information on C11
// atomics.
// See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf
// "A Relaxed Guide to memory_order_relaxed" for discussion of and common usage
// or relaxed atomics.
//
// Functions with pseudo Python code:
//
// def _Py_atomic_load(obj):
// return obj # sequential consistency
//
// def _Py_atomic_load_relaxed(obj):
// return obj # relaxed consistency
//
// def _Py_atomic_store(obj, value):
// obj = value # sequential consistency
//
// def _Py_atomic_store_relaxed(obj, value):
// obj = value # relaxed consistency
//
// def _Py_atomic_exchange(obj, value):
// # sequential consistency
// old_obj = obj
// obj = value
// return old_obj
//
// def _Py_atomic_compare_exchange(obj, expected, desired):
// # sequential consistency
// if obj == expected:
// obj = desired
// return True
// else:
// expected = obj
// return False
//
// def _Py_atomic_add(obj, value):
// # sequential consistency
// old_obj = obj
// obj += value
// return old_obj
//
// def _Py_atomic_and(obj, value):
// # sequential consistency
// old_obj = obj
// obj &= value
// return old_obj
//
// def _Py_atomic_or(obj, value):
// # sequential consistency
// old_obj = obj
// obj |= value
// return old_obj
//
// Other functions:
//
// def _Py_atomic_load_ptr_acquire(obj):
// return obj # acquire
//
// def _Py_atomic_store_ptr_release(obj):
// return obj # release
//
// def _Py_atomic_fence_seq_cst():
// # sequential consistency
// ...
//
// def _Py_atomic_fence_release():
// # release
// ...
#ifndef Py_CPYTHON_ATOMIC_H
# error "this header file must not be included directly"
#endif
// --- _Py_atomic_add --------------------------------------------------------
// Atomically adds `value` to `obj` and returns the previous value
static inline int
_Py_atomic_add_int(int *obj, int value);
static inline int8_t
_Py_atomic_add_int8(int8_t *obj, int8_t value);
static inline int16_t
_Py_atomic_add_int16(int16_t *obj, int16_t value);
static inline int32_t
_Py_atomic_add_int32(int32_t *obj, int32_t value);
static inline int64_t
_Py_atomic_add_int64(int64_t *obj, int64_t value);
static inline intptr_t
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value);
static inline unsigned int
_Py_atomic_add_uint(unsigned int *obj, unsigned int value);
static inline uint8_t
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value);
static inline uint16_t
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value);
static inline uint32_t
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value);
static inline uint64_t
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value);
static inline uintptr_t
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value);
static inline Py_ssize_t
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value);
// --- _Py_atomic_compare_exchange -------------------------------------------
// Performs an atomic compare-and-exchange.
//
// - If `*obj` and `*expected` are equal, store `desired` into `*obj`
// and return 1 (success).
// - Otherwise, store the `*obj` current value into `*expected`
// and return 0 (failure).
//
// These correspond to the C11 atomic_compare_exchange_strong() function.
static inline int
_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired);
static inline int
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired);
static inline int
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired);
static inline int
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired);
static inline int
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired);
static inline int
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired);
static inline int
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired);
static inline int
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired);
static inline int
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired);
static inline int
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired);
static inline int
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired);
static inline int
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired);
static inline int
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired);
// NOTE: `obj` and `expected` are logically `void**` types, but we use `void*`
// so that we can pass types like `PyObject**` without a cast.
static inline int
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *value);
// --- _Py_atomic_exchange ---------------------------------------------------
// Atomically replaces `*obj` with `value` and returns the previous value of `*obj`.
static inline int
_Py_atomic_exchange_int(int *obj, int value);
static inline int8_t
_Py_atomic_exchange_int8(int8_t *obj, int8_t value);
static inline int16_t
_Py_atomic_exchange_int16(int16_t *obj, int16_t value);
static inline int32_t
_Py_atomic_exchange_int32(int32_t *obj, int32_t value);
static inline int64_t
_Py_atomic_exchange_int64(int64_t *obj, int64_t value);
static inline intptr_t
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value);
static inline unsigned int
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value);
static inline uint8_t
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value);
static inline uint16_t
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value);
static inline uint32_t
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value);
static inline uint64_t
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value);
static inline uintptr_t
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value);
static inline Py_ssize_t
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value);
static inline void *
_Py_atomic_exchange_ptr(void *obj, void *value);
// --- _Py_atomic_and --------------------------------------------------------
// Performs `*obj &= value` atomically and returns the previous value of `*obj`.
static inline uint8_t
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value);
static inline uint16_t
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value);
static inline uint32_t
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value);
static inline uint64_t
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value);
static inline uintptr_t
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value);
// --- _Py_atomic_or ---------------------------------------------------------
// Performs `*obj |= value` atomically and returns the previous value of `*obj`.
static inline uint8_t
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value);
static inline uint16_t
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value);
static inline uint32_t
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value);
static inline uint64_t
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value);
static inline uintptr_t
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value);
// --- _Py_atomic_load -------------------------------------------------------
// Atomically loads `*obj` (sequential consistency)
static inline int
_Py_atomic_load_int(const int *obj);
static inline int8_t
_Py_atomic_load_int8(const int8_t *obj);
static inline int16_t
_Py_atomic_load_int16(const int16_t *obj);
static inline int32_t
_Py_atomic_load_int32(const int32_t *obj);
static inline int64_t
_Py_atomic_load_int64(const int64_t *obj);
static inline intptr_t
_Py_atomic_load_intptr(const intptr_t *obj);
static inline uint8_t
_Py_atomic_load_uint8(const uint8_t *obj);
static inline uint16_t
_Py_atomic_load_uint16(const uint16_t *obj);
static inline uint32_t
_Py_atomic_load_uint32(const uint32_t *obj);
static inline uint64_t
_Py_atomic_load_uint64(const uint64_t *obj);
static inline uintptr_t
_Py_atomic_load_uintptr(const uintptr_t *obj);
static inline unsigned int
_Py_atomic_load_uint(const unsigned int *obj);
static inline Py_ssize_t
_Py_atomic_load_ssize(const Py_ssize_t *obj);
static inline void *
_Py_atomic_load_ptr(const void *obj);
// --- _Py_atomic_load_relaxed -----------------------------------------------
// Loads `*obj` (relaxed consistency, i.e., no ordering)
static inline int
_Py_atomic_load_int_relaxed(const int *obj);
static inline char
_Py_atomic_load_char_relaxed(const char *obj);
static inline unsigned char
_Py_atomic_load_uchar_relaxed(const unsigned char *obj);
static inline short
_Py_atomic_load_short_relaxed(const short *obj);
static inline unsigned short
_Py_atomic_load_ushort_relaxed(const unsigned short *obj);
static inline long
_Py_atomic_load_long_relaxed(const long *obj);
static inline double
_Py_atomic_load_double_relaxed(const double *obj);
static inline long long
_Py_atomic_load_llong_relaxed(const long long *obj);
static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t *obj);
static inline int16_t
_Py_atomic_load_int16_relaxed(const int16_t *obj);
static inline int32_t
_Py_atomic_load_int32_relaxed(const int32_t *obj);
static inline int64_t
_Py_atomic_load_int64_relaxed(const int64_t *obj);
static inline intptr_t
_Py_atomic_load_intptr_relaxed(const intptr_t *obj);
static inline uint8_t
_Py_atomic_load_uint8_relaxed(const uint8_t *obj);
static inline uint16_t
_Py_atomic_load_uint16_relaxed(const uint16_t *obj);
static inline uint32_t
_Py_atomic_load_uint32_relaxed(const uint32_t *obj);
static inline uint64_t
_Py_atomic_load_uint64_relaxed(const uint64_t *obj);
static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj);
static inline unsigned int
_Py_atomic_load_uint_relaxed(const unsigned int *obj);
static inline Py_ssize_t
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj);
static inline void *
_Py_atomic_load_ptr_relaxed(const void *obj);
static inline unsigned long long
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj);
// --- _Py_atomic_store ------------------------------------------------------
// Atomically performs `*obj = value` (sequential consistency)
static inline void
_Py_atomic_store_int(int *obj, int value);
static inline void
_Py_atomic_store_int8(int8_t *obj, int8_t value);
static inline void
_Py_atomic_store_int16(int16_t *obj, int16_t value);
static inline void
_Py_atomic_store_int32(int32_t *obj, int32_t value);
static inline void
_Py_atomic_store_int64(int64_t *obj, int64_t value);
static inline void
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value);
static inline void
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value);
static inline void
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value);
static inline void
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value);
static inline void
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value);
static inline void
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value);
static inline void
_Py_atomic_store_uint(unsigned int *obj, unsigned int value);
static inline void
_Py_atomic_store_ptr(void *obj, void *value);
static inline void
_Py_atomic_store_ssize(Py_ssize_t* obj, Py_ssize_t value);
// --- _Py_atomic_store_relaxed ----------------------------------------------
// Stores `*obj = value` (relaxed consistency, i.e., no ordering)
static inline void
_Py_atomic_store_int_relaxed(int *obj, int value);
static inline void
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value);
static inline void
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value);
static inline void
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value);
static inline void
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value);
static inline void
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value);
static inline void
_Py_atomic_store_uint8_relaxed(uint8_t* obj, uint8_t value);
static inline void
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value);
static inline void
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value);
static inline void
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value);
static inline void
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value);
static inline void
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value);
static inline void
_Py_atomic_store_ptr_relaxed(void *obj, void *value);
static inline void
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value);
static inline void
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
unsigned long long value);
static inline void
_Py_atomic_store_char_relaxed(char *obj, char value);
static inline void
_Py_atomic_store_uchar_relaxed(unsigned char *obj, unsigned char value);
static inline void
_Py_atomic_store_short_relaxed(short *obj, short value);
static inline void
_Py_atomic_store_ushort_relaxed(unsigned short *obj, unsigned short value);
static inline void
_Py_atomic_store_long_relaxed(long *obj, long value);
static inline void
_Py_atomic_store_float_relaxed(float *obj, float value);
static inline void
_Py_atomic_store_double_relaxed(double *obj, double value);
static inline void
_Py_atomic_store_llong_relaxed(long long *obj, long long value);
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
// Loads `*obj` (acquire operation)
static inline void *
_Py_atomic_load_ptr_acquire(const void *obj);
static inline uintptr_t
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj);
// Stores `*obj = value` (release operation)
static inline void
_Py_atomic_store_ptr_release(void *obj, void *value);
static inline void
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value);
static inline void
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value);
static inline void
_Py_atomic_store_int_release(int *obj, int value);
static inline int
_Py_atomic_load_int_acquire(const int *obj);
static inline void
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value);
static inline void
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value);
static inline uint64_t
_Py_atomic_load_uint64_acquire(const uint64_t *obj);
static inline uint32_t
_Py_atomic_load_uint32_acquire(const uint32_t *obj);
static inline Py_ssize_t
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj);
// --- _Py_atomic_fence ------------------------------------------------------
// Sequential consistency fence. C11 fences have complex semantics. When
// possible, use the atomic operations on variables defined above, which
// generally do not require explicit use of a fence.
// See https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence
static inline void _Py_atomic_fence_seq_cst(void);
// Acquire fence
static inline void _Py_atomic_fence_acquire(void);
// Release fence
static inline void _Py_atomic_fence_release(void);
#ifndef _Py_USE_GCC_BUILTIN_ATOMICS
# if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
# define _Py_USE_GCC_BUILTIN_ATOMICS 1
# elif defined(__clang__)
# if __has_builtin(__atomic_load)
# define _Py_USE_GCC_BUILTIN_ATOMICS 1
# endif
# endif
#endif
#if _Py_USE_GCC_BUILTIN_ATOMICS
# define Py_ATOMIC_GCC_H
# include "pyatomic_gcc.h"
# undef Py_ATOMIC_GCC_H
#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
# define Py_ATOMIC_STD_H
# include "pyatomic_std.h"
# undef Py_ATOMIC_STD_H
#elif defined(_MSC_VER)
# define Py_ATOMIC_MSC_H
# include "pyatomic_msc.h"
# undef Py_ATOMIC_MSC_H
#else
# error "no available pyatomic implementation for this platform/compiler"
#endif
// --- aliases ---------------------------------------------------------------
// Compilers don't really support "consume" semantics, so we fake it. Use
// "acquire" with TSan to support false positives. Use "relaxed" otherwise,
// because CPUs on all platforms we support respect address dependencies without
// extra barriers.
// See 2.6.7 in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf
#if defined(_Py_THREAD_SANITIZER)
# define _Py_atomic_load_ptr_consume _Py_atomic_load_ptr_acquire
#else
# define _Py_atomic_load_ptr_consume _Py_atomic_load_ptr_relaxed
#endif
#if SIZEOF_LONG == 8
# define _Py_atomic_load_ulong(p) \
_Py_atomic_load_uint64((uint64_t *)p)
# define _Py_atomic_load_ulong_relaxed(p) \
_Py_atomic_load_uint64_relaxed((uint64_t *)p)
# define _Py_atomic_store_ulong(p, v) \
_Py_atomic_store_uint64((uint64_t *)p, v)
# define _Py_atomic_store_ulong_relaxed(p, v) \
_Py_atomic_store_uint64_relaxed((uint64_t *)p, v)
#elif SIZEOF_LONG == 4
# define _Py_atomic_load_ulong(p) \
_Py_atomic_load_uint32((uint32_t *)p)
# define _Py_atomic_load_ulong_relaxed(p) \
_Py_atomic_load_uint32_relaxed((uint32_t *)p)
# define _Py_atomic_store_ulong(p, v) \
_Py_atomic_store_uint32((uint32_t *)p, v)
# define _Py_atomic_store_ulong_relaxed(p, v) \
_Py_atomic_store_uint32_relaxed((uint32_t *)p, v)
#else
# error "long must be 4 or 8 bytes in size"
#endif // SIZEOF_LONG

View File

@@ -0,0 +1,615 @@
// This is the implementation of Python atomic operations using GCC's built-in
// functions that match the C+11 memory model. This implementation is preferred
// for GCC compatible compilers, such as Clang. These functions are available
// in GCC 4.8+ without needing to compile with --std=c11 or --std=gnu11.
#ifndef Py_ATOMIC_GCC_H
# error "this header file must not be included directly"
#endif
// --- _Py_atomic_add --------------------------------------------------------
static inline int
_Py_atomic_add_int(int *obj, int value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline int8_t
_Py_atomic_add_int8(int8_t *obj, int8_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline int16_t
_Py_atomic_add_int16(int16_t *obj, int16_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline int32_t
_Py_atomic_add_int32(int32_t *obj, int32_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline int64_t
_Py_atomic_add_int64(int64_t *obj, int64_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline intptr_t
_Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline unsigned int
_Py_atomic_add_uint(unsigned int *obj, unsigned int value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline uint8_t
_Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline uint16_t
_Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline uint32_t
_Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline uint64_t
_Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline uintptr_t
_Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
static inline Py_ssize_t
_Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
{ return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_compare_exchange -------------------------------------------
static inline int
_Py_atomic_compare_exchange_int(int *obj, int *expected, int desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired)
{ return __atomic_compare_exchange_n(obj, expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
static inline int
_Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired)
{ return __atomic_compare_exchange_n((void **)obj, (void **)expected, desired, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_exchange ---------------------------------------------------
static inline int
_Py_atomic_exchange_int(int *obj, int value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline int8_t
_Py_atomic_exchange_int8(int8_t *obj, int8_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline int16_t
_Py_atomic_exchange_int16(int16_t *obj, int16_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline int32_t
_Py_atomic_exchange_int32(int32_t *obj, int32_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline int64_t
_Py_atomic_exchange_int64(int64_t *obj, int64_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline intptr_t
_Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline unsigned int
_Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline uint8_t
_Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline uint16_t
_Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline uint32_t
_Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline uint64_t
_Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline uintptr_t
_Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline Py_ssize_t
_Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
{ return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void *
_Py_atomic_exchange_ptr(void *obj, void *value)
{ return __atomic_exchange_n((void **)obj, value, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_and --------------------------------------------------------
static inline uint8_t
_Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
static inline uint16_t
_Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
static inline uint32_t
_Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
static inline uint64_t
_Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
static inline uintptr_t
_Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
{ return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_or ---------------------------------------------------------
static inline uint8_t
_Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
static inline uint16_t
_Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
static inline uint32_t
_Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
static inline uint64_t
_Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
static inline uintptr_t
_Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
{ return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_load -------------------------------------------------------
static inline int
_Py_atomic_load_int(const int *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline int8_t
_Py_atomic_load_int8(const int8_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline int16_t
_Py_atomic_load_int16(const int16_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline int32_t
_Py_atomic_load_int32(const int32_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline int64_t
_Py_atomic_load_int64(const int64_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline intptr_t
_Py_atomic_load_intptr(const intptr_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline uint8_t
_Py_atomic_load_uint8(const uint8_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline uint16_t
_Py_atomic_load_uint16(const uint16_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline uint32_t
_Py_atomic_load_uint32(const uint32_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline uint64_t
_Py_atomic_load_uint64(const uint64_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline uintptr_t
_Py_atomic_load_uintptr(const uintptr_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline unsigned int
_Py_atomic_load_uint(const unsigned int *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline Py_ssize_t
_Py_atomic_load_ssize(const Py_ssize_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
static inline void *
_Py_atomic_load_ptr(const void *obj)
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_load_relaxed -----------------------------------------------
static inline int
_Py_atomic_load_int_relaxed(const int *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline char
_Py_atomic_load_char_relaxed(const char *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline unsigned char
_Py_atomic_load_uchar_relaxed(const unsigned char *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline short
_Py_atomic_load_short_relaxed(const short *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline unsigned short
_Py_atomic_load_ushort_relaxed(const unsigned short *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline long
_Py_atomic_load_long_relaxed(const long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline float
_Py_atomic_load_float_relaxed(const float *obj)
{ float ret; __atomic_load(obj, &ret, __ATOMIC_RELAXED); return ret; }
static inline double
_Py_atomic_load_double_relaxed(const double *obj)
{ double ret; __atomic_load(obj, &ret, __ATOMIC_RELAXED); return ret; }
static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline int16_t
_Py_atomic_load_int16_relaxed(const int16_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline int32_t
_Py_atomic_load_int32_relaxed(const int32_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline int64_t
_Py_atomic_load_int64_relaxed(const int64_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline intptr_t
_Py_atomic_load_intptr_relaxed(const intptr_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline uint8_t
_Py_atomic_load_uint8_relaxed(const uint8_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline uint16_t
_Py_atomic_load_uint16_relaxed(const uint16_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline uint32_t
_Py_atomic_load_uint32_relaxed(const uint32_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline uint64_t
_Py_atomic_load_uint64_relaxed(const uint64_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline unsigned int
_Py_atomic_load_uint_relaxed(const unsigned int *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline Py_ssize_t
_Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline void *
_Py_atomic_load_ptr_relaxed(const void *obj)
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_RELAXED); }
static inline unsigned long long
_Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
static inline long long
_Py_atomic_load_llong_relaxed(const long long *obj)
{ return __atomic_load_n(obj, __ATOMIC_RELAXED); }
// --- _Py_atomic_store ------------------------------------------------------
static inline void
_Py_atomic_store_int(int *obj, int value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_int8(int8_t *obj, int8_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_int16(int16_t *obj, int16_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_int32(int32_t *obj, int32_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_int64(int64_t *obj, int64_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_uint(unsigned int *obj, unsigned int value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_ptr(void *obj, void *value)
{ __atomic_store_n((void **)obj, value, __ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
{ __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
// --- _Py_atomic_store_relaxed ----------------------------------------------
static inline void
_Py_atomic_store_int_relaxed(int *obj, int value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_ptr_relaxed(void *obj, void *value)
{ __atomic_store_n((void **)obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_ullong_relaxed(unsigned long long *obj,
unsigned long long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_char_relaxed(char *obj, char value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_uchar_relaxed(unsigned char *obj, unsigned char value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_short_relaxed(short *obj, short value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_ushort_relaxed(unsigned short *obj, unsigned short value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_long_relaxed(long *obj, long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_float_relaxed(float *obj, float value)
{ __atomic_store(obj, &value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_double_relaxed(double *obj, double value)
{ __atomic_store(obj, &value, __ATOMIC_RELAXED); }
static inline void
_Py_atomic_store_llong_relaxed(long long *obj, long long value)
{ __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
// --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
static inline void *
_Py_atomic_load_ptr_acquire(const void *obj)
{ return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_ACQUIRE); }
static inline uintptr_t
_Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
{ return (uintptr_t)__atomic_load_n(obj, __ATOMIC_ACQUIRE); }
static inline void
_Py_atomic_store_ptr_release(void *obj, void *value)
{ __atomic_store_n((void **)obj, value, __ATOMIC_RELEASE); }
static inline void
_Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
static inline void
_Py_atomic_store_int_release(int *obj, int value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
static inline void
_Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
static inline int
_Py_atomic_load_int_acquire(const int *obj)
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
static inline void
_Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
static inline void
_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
static inline uint64_t
_Py_atomic_load_uint64_acquire(const uint64_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
static inline uint32_t
_Py_atomic_load_uint32_acquire(const uint32_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
static inline Py_ssize_t
_Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
// --- _Py_atomic_fence ------------------------------------------------------
static inline void
_Py_atomic_fence_seq_cst(void)
{ __atomic_thread_fence(__ATOMIC_SEQ_CST); }
static inline void
_Py_atomic_fence_acquire(void)
{ __atomic_thread_fence(__ATOMIC_ACQUIRE); }
static inline void
_Py_atomic_fence_release(void)
{ __atomic_thread_fence(__ATOMIC_RELEASE); }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,9 @@
#ifndef Py_LIMITED_API
#ifndef PYCTYPE_H #ifndef PYCTYPE_H
#define PYCTYPE_H #define PYCTYPE_H
#ifdef __cplusplus
extern "C" {
#endif
#define PY_CTF_LOWER 0x01 #define PY_CTF_LOWER 0x01
#define PY_CTF_UPPER 0x02 #define PY_CTF_UPPER 0x02
@@ -28,4 +32,8 @@ PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256];
#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) #define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)])
#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) #define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)])
#ifdef __cplusplus
}
#endif
#endif /* !PYCTYPE_H */ #endif /* !PYCTYPE_H */
#endif /* !Py_LIMITED_API */

38
extern/include/python/cpython/pydebug.h vendored Normal file
View File

@@ -0,0 +1,38 @@
#ifndef Py_LIMITED_API
#ifndef Py_PYDEBUG_H
#define Py_PYDEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DebugFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_VerboseFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_QuietFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InteractiveFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InspectFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_OptimizeFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_BytesWarningFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_FrozenFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoUserSiteDirectory;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UnbufferedStdioFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HashRandomizationFlag;
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IsolatedFlag;
#ifdef MS_WINDOWS
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag;
Py_DEPRECATED(3.12) 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_FUNC(char*) Py_GETENV(const char *name);
#ifdef __cplusplus
}
#endif
#endif /* !Py_PYDEBUG_H */
#endif /* Py_LIMITED_API */

132
extern/include/python/cpython/pyerrors.h vendored Normal file
View File

@@ -0,0 +1,132 @@
#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;
PyObject *metadata;
} PySyntaxErrorObject;
typedef struct {
PyException_HEAD
PyObject *msg;
PyObject *name;
PyObject *path;
PyObject *name_from;
} 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
/* Context manipulation (PEP 3134) */
PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *);
/* In exceptions.c */
PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar(
PyObject *orig,
PyObject *excs);
/* In signalmodule.c */
PyAPI_FUNC(int) PySignal_SetWakeupFd(int fd);
/* 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(void) _Py_NO_RETURN _Py_FatalErrorFunc(
const char *func,
const char *message);
PyAPI_FUNC(void) PyErr_FormatUnraisable(const char *, ...);
PyAPI_DATA(PyObject *) PyExc_PythonFinalizationError;
#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message))

15
extern/include/python/cpython/pyfpe.h vendored Normal file
View File

@@ -0,0 +1,15 @@
#ifndef Py_PYFPE_H
#define Py_PYFPE_H
/* Header excluded from the stable API */
#ifndef Py_LIMITED_API
/* These macros used to do something when Python was built with --with-fpectl,
* but support for that was dropped in 3.7. We continue to define them though,
* to avoid breaking API users.
*/
#define PyFPE_START_PROTECT(err_string, leave_stmt)
#define PyFPE_END_PROTECT(v)
#endif /* !defined(Py_LIMITED_API) */
#endif /* !Py_PYFPE_H */

45
extern/include/python/cpython/pyframe.h vendored Normal file
View File

@@ -0,0 +1,45 @@
#ifndef Py_CPYTHON_PYFRAME_H
# error "this header file must not be included directly"
#endif
PyAPI_DATA(PyTypeObject) PyFrame_Type;
PyAPI_DATA(PyTypeObject) PyFrameLocalsProxy_Type;
#define PyFrame_Check(op) Py_IS_TYPE((op), &PyFrame_Type)
#define PyFrameLocalsProxy_Check(op) Py_IS_TYPE((op), &PyFrameLocalsProxy_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);
PyAPI_FUNC(PyObject*) PyFrame_GetVar(PyFrameObject *frame, PyObject *name);
PyAPI_FUNC(PyObject*) PyFrame_GetVarString(PyFrameObject *frame, const char *name);
/* The following functions are for use by debuggers and other tools
* implementing custom frame evaluators with PEP 523. */
struct _PyInterpreterFrame;
/* Returns the code object of the frame (strong reference).
* Does not raise an exception. */
PyAPI_FUNC(PyObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame);
/* Returns a byte offset into the last executed instruction.
* Does not raise an exception. */
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame);
/* Returns the currently executing line number, or -1 if there is no line number.
* Does not raise an exception. */
PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame);
#define PyUnstable_EXECUTABLE_KIND_SKIP 0
#define PyUnstable_EXECUTABLE_KIND_PY_FUNCTION 1
#define PyUnstable_EXECUTABLE_KIND_BUILTIN_FUNCTION 3
#define PyUnstable_EXECUTABLE_KIND_METHOD_DESCRIPTOR 4
#define PyUnstable_EXECUTABLE_KINDS 5
PyAPI_DATA(const PyTypeObject *) const PyUnstable_ExecutableKinds[PyUnstable_EXECUTABLE_KINDS+1];

54
extern/include/python/cpython/pyhash.h vendored Normal file
View File

@@ -0,0 +1,54 @@
#ifndef Py_CPYTHON_HASH_H
# error "this header file must not be included directly"
#endif
/* Prime multiplier used in string and various other hashes. */
#define PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
/* Parameters used for the numeric hash implementation. See notes for
_Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
reduction modulo the prime 2**_PyHASH_BITS - 1. */
#if SIZEOF_VOID_P >= 8
# define PyHASH_BITS 61
#else
# define PyHASH_BITS 31
#endif
#define PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
#define PyHASH_INF 314159
#define PyHASH_IMAG PyHASH_MULTIPLIER
/* Aliases kept for backward compatibility with Python 3.12 */
#define _PyHASH_MULTIPLIER PyHASH_MULTIPLIER
#define _PyHASH_BITS PyHASH_BITS
#define _PyHASH_MODULUS PyHASH_MODULUS
#define _PyHASH_INF PyHASH_INF
#define _PyHASH_IMAG PyHASH_IMAG
/* Helpers for hash functions */
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double);
/* hash function definition */
typedef struct {
Py_hash_t (*const hash)(const void *, Py_ssize_t);
const char *name;
const int hash_bits;
const int seed_bits;
} PyHash_FuncDef;
PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);
PyAPI_FUNC(Py_hash_t) Py_HashPointer(const void *ptr);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline Py_hash_t
_Py_HashPointer(const void *ptr)
{
return Py_HashPointer(ptr);
}
PyAPI_FUNC(Py_hash_t) PyObject_GenericHash(PyObject *);
PyAPI_FUNC(Py_hash_t) Py_HashBuffer(const void *ptr, Py_ssize_t len);

View File

@@ -0,0 +1,89 @@
#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);
/* 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);
/* Initialization and finalization */
PyAPI_FUNC(PyStatus) Py_InitializeFromConfig(
const PyConfig *config);
PyAPI_FUNC(int) Py_RunMain(void);
PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err);
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
/* --- PyInterpreterConfig ------------------------------------ */
#define PyInterpreterConfig_DEFAULT_GIL (0)
#define PyInterpreterConfig_SHARED_GIL (1)
#define PyInterpreterConfig_OWN_GIL (2)
typedef struct {
// XXX "allow_object_sharing"? "own_objects"?
int use_main_obmalloc;
int allow_fork;
int allow_exec;
int allow_threads;
int allow_daemon_threads;
int check_multi_interp_extensions;
int gil;
} PyInterpreterConfig;
#define _PyInterpreterConfig_INIT \
{ \
.use_main_obmalloc = 0, \
.allow_fork = 0, \
.allow_exec = 0, \
.allow_threads = 1, \
.allow_daemon_threads = 0, \
.check_multi_interp_extensions = 1, \
.gil = PyInterpreterConfig_OWN_GIL, \
}
// gh-117649: The free-threaded build does not currently support single-phase
// init extensions in subinterpreters. For now, we ensure that
// `check_multi_interp_extensions` is always `1`, even in the legacy config.
#ifdef Py_GIL_DISABLED
# define _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS 1
#else
# define _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS 0
#endif
#define _PyInterpreterConfig_LEGACY_INIT \
{ \
.use_main_obmalloc = 1, \
.allow_fork = 1, \
.allow_exec = 1, \
.allow_threads = 1, \
.allow_daemon_threads = 1, \
.check_multi_interp_extensions = _PyInterpreterConfig_LEGACY_CHECK_MULTI_INTERP_EXTENSIONS, \
.gil = PyInterpreterConfig_SHARED_GIL, \
}
PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig(
PyThreadState **tstate_p,
const PyInterpreterConfig *config);
typedef void (*atexit_datacallbackfunc)(void *);
PyAPI_FUNC(int) PyUnstable_AtExit(
PyInterpreterState *, atexit_datacallbackfunc, void *);

84
extern/include/python/cpython/pymem.h vendored Normal file
View File

@@ -0,0 +1,84 @@
#ifndef Py_CPYTHON_PYMEM_H
# error "this header file must not be included directly"
#endif
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
#ifdef WITH_MIMALLOC
PYMEM_ALLOCATOR_MIMALLOC = 7,
PYMEM_ALLOCATOR_MIMALLOC_DEBUG = 8,
#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);

275
extern/include/python/cpython/pystate.h vendored Normal file
View File

@@ -0,0 +1,275 @@
#ifndef Py_CPYTHON_PYSTATE_H
# error "this header file must not be included directly"
#endif
/* private interpreter helpers */
PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *);
PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int);
/* 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
/* Remote debugger support */
#define _Py_MAX_SCRIPT_PATH_SIZE 512
typedef struct {
int32_t debugger_pending_call;
char debugger_script_path[_Py_MAX_SCRIPT_PATH_SIZE];
} _PyRemoteDebuggerSupport;
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;
/* Minimum size of data stack chunk */
#define _PY_DATA_STACK_CHUNK_SIZE (16*1024)
struct _ts {
/* See Python/ceval.c for comments explaining most fields */
PyThreadState *prev;
PyThreadState *next;
PyInterpreterState *interp;
/* The global instrumentation version in high bits, plus flags indicating
when to break out of the interpreter loop in lower bits. See details in
pycore_ceval.h. */
uintptr_t eval_breaker;
struct {
/* Has been initialized to a safe state.
In order to be effective, this must be set to 0 during or right
after allocation. */
unsigned int initialized:1;
/* Has been bound to an OS thread. */
unsigned int bound:1;
/* Has been unbound from its OS thread. */
unsigned int unbound:1;
/* Has been bound aa current for the GILState API. */
unsigned int bound_gilstate:1;
/* Currently in use (maybe holds the GIL). */
unsigned int active:1;
/* various stages of finalization */
unsigned int finalizing:1;
unsigned int cleared:1;
unsigned int finalized:1;
/* padding to align to 4 bytes */
unsigned int :24;
} _status;
#ifdef Py_BUILD_CORE
# define _PyThreadState_WHENCE_NOTSET -1
# define _PyThreadState_WHENCE_UNKNOWN 0
# define _PyThreadState_WHENCE_INIT 1
# define _PyThreadState_WHENCE_FINI 2
# define _PyThreadState_WHENCE_THREADING 3
# define _PyThreadState_WHENCE_GILSTATE 4
# define _PyThreadState_WHENCE_EXEC 5
#endif
/* Currently holds the GIL. Must be its own field to avoid data races */
int holds_gil;
int _whence;
/* Thread state (_Py_THREAD_ATTACHED, _Py_THREAD_DETACHED, _Py_THREAD_SUSPENDED).
See Include/internal/pycore_pystate.h for more details. */
int state;
int py_recursion_remaining;
int py_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 what_event; /* The event currently being monitored, if any. */
/* Pointer to currently executing frame. */
struct _PyInterpreterFrame *current_frame;
Py_tracefunc c_profilefunc;
Py_tracefunc c_tracefunc;
PyObject *c_profileobj;
PyObject *c_traceobj;
/* The exception currently being raised */
PyObject *current_exception;
/* 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;
PyObject *delete_later;
/* Tagged pointer to top-most critical section, or zero if there is no
* active critical section. Critical sections are only used in
* `--disable-gil` builds (i.e., when Py_GIL_DISABLED is defined to 1). In the
* default build, this field is always zero.
*/
uintptr_t critical_section;
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;
_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;
PyObject *current_executor;
uint64_t dict_global_version;
/* Used to store/retrieve `threading.local` keys/values for this thread */
PyObject *threading_local_key;
/* Used by `threading.local`s to be remove keys/values for dying threads.
The PyThreadObject must hold the only reference to this value.
*/
PyObject *threading_local_sentinel;
_PyRemoteDebuggerSupport remote_debugger_support;
};
/* other API */
/* Similar to PyThreadState_Get(), but don't issue a fatal error
* if it is NULL. */
PyAPI_FUNC(PyThreadState *) PyThreadState_GetUnchecked(void);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline PyThreadState*
_PyThreadState_UncheckedGet(void)
{
return PyThreadState_GetUnchecked();
}
// 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);
/* The implementation of sys._current_frames() Returns a dict mapping
thread id to that thread's current frame.
*/
PyAPI_FUNC(PyObject*) _PyThread_CurrentFrames(void);
// Set the stack protection start address and stack protection size
// of a Python thread state
PyAPI_FUNC(int) PyUnstable_ThreadState_SetStackProtection(
PyThreadState *tstate,
void *stack_start_addr, // Stack start address
size_t stack_size); // Stack size (in bytes)
// Reset the stack protection start address and stack protection size
// of a Python thread state
PyAPI_FUNC(void) PyUnstable_ThreadState_ResetStackProtection(
PyThreadState *tstate);
/* 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);

194
extern/include/python/cpython/pystats.h vendored Normal file
View File

@@ -0,0 +1,194 @@
// Statistics on Python performance.
//
// API:
//
// - _Py_INCREF_STAT_INC() and _Py_DECREF_STAT_INC() used by Py_INCREF()
// and Py_DECREF().
// - _Py_stats variable
//
// Functions of the sys module:
//
// - sys._stats_on()
// - sys._stats_off()
// - sys._stats_clear()
// - sys._stats_dump()
//
// Python must be built with ./configure --enable-pystats to define the
// Py_STATS macro.
//
// Define _PY_INTERPRETER macro to increment interpreter_increfs and
// interpreter_decrefs. Otherwise, increment increfs and decrefs.
//
// The number of incref operations counted by `incref` and
// `interpreter_incref` is the number of increment operations, which is
// not equal to the total of all reference counts. A single increment
// operation may increase the reference count of an object by more than
// one. For example, see `_Py_RefcntAdd`.
#ifndef Py_CPYTHON_PYSTATS_H
# error "this header file must not be included directly"
#endif
#define PYSTATS_MAX_UOP_ID 1024
#define SPECIALIZATION_FAILURE_KINDS 60
/* Stats for determining who is calling PyEval_EvalFrame */
#define EVAL_CALL_TOTAL 0
#define EVAL_CALL_VECTOR 1
#define EVAL_CALL_GENERATOR 2
#define EVAL_CALL_LEGACY 3
#define EVAL_CALL_FUNCTION_VECTORCALL 4
#define EVAL_CALL_BUILD_CLASS 5
#define EVAL_CALL_SLOT 6
#define EVAL_CALL_FUNCTION_EX 7
#define EVAL_CALL_API 8
#define EVAL_CALL_METHOD 9
#define EVAL_CALL_KINDS 10
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;
uint64_t eval_calls[EVAL_CALL_KINDS];
} CallStats;
typedef struct _object_stats {
uint64_t increfs;
uint64_t decrefs;
uint64_t interpreter_increfs;
uint64_t interpreter_decrefs;
uint64_t immortal_increfs;
uint64_t immortal_decrefs;
uint64_t interpreter_immortal_increfs;
uint64_t interpreter_immortal_decrefs;
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 inline_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;
uint64_t type_cache_hits;
uint64_t type_cache_misses;
uint64_t type_cache_dunder_hits;
uint64_t type_cache_dunder_misses;
uint64_t type_cache_collisions;
/* Temporary value used during GC */
uint64_t object_visits;
} ObjectStats;
typedef struct _gc_stats {
uint64_t collections;
uint64_t object_visits;
uint64_t objects_collected;
uint64_t objects_transitively_reachable;
uint64_t objects_not_transitively_reachable;
} GCStats;
typedef struct _uop_stats {
uint64_t execution_count;
uint64_t miss;
uint64_t pair_count[PYSTATS_MAX_UOP_ID + 1];
} UOpStats;
#define _Py_UOP_HIST_SIZE 32
typedef struct _optimization_stats {
uint64_t attempts;
uint64_t traces_created;
uint64_t traces_executed;
uint64_t uops_executed;
uint64_t trace_stack_overflow;
uint64_t trace_stack_underflow;
uint64_t trace_too_long;
uint64_t trace_too_short;
uint64_t inner_loop;
uint64_t recursive_call;
uint64_t low_confidence;
uint64_t unknown_callee;
uint64_t executors_invalidated;
UOpStats opcode[PYSTATS_MAX_UOP_ID + 1];
uint64_t unsupported_opcode[256];
uint64_t trace_length_hist[_Py_UOP_HIST_SIZE];
uint64_t trace_run_length_hist[_Py_UOP_HIST_SIZE];
uint64_t optimized_trace_length_hist[_Py_UOP_HIST_SIZE];
uint64_t optimizer_attempts;
uint64_t optimizer_successes;
uint64_t optimizer_failure_reason_no_memory;
uint64_t remove_globals_builtins_changed;
uint64_t remove_globals_incorrect_keys;
uint64_t error_in_opcode[PYSTATS_MAX_UOP_ID + 1];
// JIT memory stats
uint64_t jit_total_memory_size;
uint64_t jit_code_size;
uint64_t jit_trampoline_size;
uint64_t jit_data_size;
uint64_t jit_padding_size;
uint64_t jit_freed_memory_size;
uint64_t trace_total_memory_hist[_Py_UOP_HIST_SIZE];
} OptimizationStats;
typedef struct _rare_event_stats {
/* Setting an object's class, obj.__class__ = ... */
uint64_t set_class;
/* Setting the bases of a class, cls.__bases__ = ... */
uint64_t set_bases;
/* Setting the PEP 523 frame eval function, _PyInterpreterState_SetFrameEvalFunc() */
uint64_t set_eval_frame_func;
/* Modifying the builtins, __builtins__.__dict__[var] = ... */
uint64_t builtin_dict;
/* Modifying a function, e.g. func.__defaults__ = ..., etc. */
uint64_t func_modification;
/* Modifying a dict that is being watched */
uint64_t watched_dict_modification;
uint64_t watched_globals_modification;
} RareEventStats;
typedef struct _stats {
OpcodeStats opcode_stats[256];
CallStats call_stats;
ObjectStats object_stats;
OptimizationStats optimization_stats;
RareEventStats rare_event_stats;
GCStats *gc_stats;
} PyStats;
// Export for shared extensions like 'math'
PyAPI_DATA(PyStats*) _Py_stats;
#ifdef _PY_INTERPRETER
# define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_increfs++; } while (0)
# define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_decrefs++; } while (0)
# define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_increfs++; } while (0)
# define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.interpreter_immortal_decrefs++; } while (0)
#else
# define _Py_INCREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.increfs++; } while (0)
# define _Py_DECREF_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.decrefs++; } while (0)
# define _Py_INCREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_increfs++; } while (0)
# define _Py_DECREF_IMMORTAL_STAT_INC() do { if (_Py_stats) _Py_stats->object_stats.immortal_decrefs++; } while (0)
#endif

View File

@@ -0,0 +1,96 @@
#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_AnyFileExFlags(
FILE *fp,
const char *filename, /* decoded from the filesystem encoding */
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(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)
/* 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(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *);

View File

@@ -0,0 +1,43 @@
#ifndef Py_CPYTHON_PYTHREAD_H
# error "this header file must not be included directly"
#endif
// PY_TIMEOUT_MAX is the highest usable value (in microseconds) of PY_TIMEOUT_T
// type, and depends on the system threading API.
//
// NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread module
// exposes a higher-level API, with timeouts expressed in seconds and
// floating-point numbers allowed.
PyAPI_DATA(const long long) PY_TIMEOUT_MAX;
#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)
#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 "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}

27
extern/include/python/cpython/pytime.h vendored Normal file
View File

@@ -0,0 +1,27 @@
// PyTime_t C API: see Doc/c-api/time.rst for the documentation.
#ifndef Py_LIMITED_API
#ifndef Py_PYTIME_H
#define Py_PYTIME_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int64_t PyTime_t;
#define PyTime_MIN INT64_MIN
#define PyTime_MAX INT64_MAX
PyAPI_FUNC(double) PyTime_AsSecondsDouble(PyTime_t t);
PyAPI_FUNC(int) PyTime_Monotonic(PyTime_t *result);
PyAPI_FUNC(int) PyTime_PerfCounter(PyTime_t *result);
PyAPI_FUNC(int) PyTime_Time(PyTime_t *result);
PyAPI_FUNC(int) PyTime_MonotonicRaw(PyTime_t *result);
PyAPI_FUNC(int) PyTime_PerfCounterRaw(PyTime_t *result);
PyAPI_FUNC(int) PyTime_TimeRaw(PyTime_t *result);
#ifdef __cplusplus
}
#endif
#endif /* Py_PYTIME_H */
#endif /* Py_LIMITED_API */

View File

@@ -0,0 +1,71 @@
#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_CAST(so) \
(assert(PyAnySet_Check(so)), _Py_CAST(PySetObject*, so))
static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) {
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&(_PySet_CAST(so)->used));
#else
return _PySet_CAST(so)->used;
#endif
}
#define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so))

View File

@@ -0,0 +1,13 @@
#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;
};

View File

@@ -0,0 +1,32 @@
#ifndef Py_LIMITED_API
#ifndef Py_TRACEMALLOC_H
#define Py_TRACEMALLOC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Track an allocated memory block in the tracemalloc module.
Return 0 on success, return -1 on error (failed to allocate memory to store
the trace).
Return -2 if tracemalloc is disabled.
If memory block is already tracked, update the existing trace. */
PyAPI_FUNC(int) PyTraceMalloc_Track(
unsigned int domain,
uintptr_t ptr,
size_t size);
/* Untrack an allocated memory block in the tracemalloc module.
Do nothing if the block was not tracked.
Return -2 if tracemalloc is disabled, otherwise return 0. */
PyAPI_FUNC(int) PyTraceMalloc_Untrack(
unsigned int domain,
uintptr_t ptr);
#ifdef __cplusplus
}
#endif
#endif // !Py_TRACEMALLOC_H
#endif // !Py_LIMITED_API

View File

@@ -0,0 +1,40 @@
#ifndef Py_CPYTHON_TUPLEOBJECT_H
# error "this header file must not be included directly"
#endif
typedef struct {
PyObject_VAR_HEAD
/* Cached hash. Initially set to -1. */
Py_hash_t ob_hash;
/* 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);
/* 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);
}
#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op))
#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);
assert(0 <= index);
assert(index < Py_SIZE(tuple));
tuple->ob_item[index] = value;
}
#define PyTuple_SET_ITEM(op, index, value) \
PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value))

View File

@@ -0,0 +1,773 @@
#ifndef Py_CPYTHON_UNICODEOBJECT_H
# error "this header file must not be included directly"
#endif
/* Py_UNICODE was the native Unicode storage format (code unit) used by
Python and represents a single Unicode element in the Unicode type.
With PEP 393, Py_UNICODE is deprecated and replaced with a
typedef to wchar_t. */
Py_DEPRECATED(3.13) typedef wchar_t PY_UNICODE_TYPE;
Py_DEPRECATED(3.13) typedef wchar_t Py_UNICODE;
/* --- Internal Unicode Operations ---------------------------------------- */
// Static inline functions to work with surrogates
static inline int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) {
return (0xD800 <= ch && ch <= 0xDFFF);
}
static inline int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) {
return (0xD800 <= ch && ch <= 0xDBFF);
}
static inline int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) {
return (0xDC00 <= ch && ch <= 0xDFFF);
}
// Join two surrogate characters and return a single Py_UCS4 value.
static inline Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) {
assert(Py_UNICODE_IS_HIGH_SURROGATE(high));
assert(Py_UNICODE_IS_LOW_SURROGATE(low));
return 0x10000 + (((high & 0x03FF) << 10) | (low & 0x03FF));
}
// High surrogate = top 10 bits added to 0xD800.
// The character must be in the range [U+10000; U+10ffff].
static inline Py_UCS4 Py_UNICODE_HIGH_SURROGATE(Py_UCS4 ch) {
assert(0x10000 <= ch && ch <= 0x10ffff);
return (0xD800 - (0x10000 >> 10) + (ch >> 10));
}
// Low surrogate = bottom 10 bits added to 0xDC00.
// The character must be in the range [U+10000; U+10ffff].
static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) {
assert(0x10000 <= ch && ch <= 0x10ffff);
return (0xDC00 + (ch & 0x3FF));
}
/* --- Unicode Type ------------------------------------------------------- */
/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject
structure. state.ascii and state.compact are set, and the data
immediately follow the structure. utf8_length can be found
in the length field; the utf8 pointer is equal to the data pointer. */
typedef struct {
/* There are 4 forms of Unicode strings:
- compact ascii:
* structure = PyASCIIObject
* test: PyUnicode_IS_COMPACT_ASCII(op)
* kind = PyUnicode_1BYTE_KIND
* compact = 1
* ascii = 1
* (length is the length of the utf8)
* (data starts just after the structure)
* (since ASCII is decoded from UTF-8, the utf8 string are the data)
- compact:
* structure = PyCompactUnicodeObject
* test: PyUnicode_IS_COMPACT(op) && !PyUnicode_IS_ASCII(op)
* kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or
PyUnicode_4BYTE_KIND
* compact = 1
* ascii = 0
* utf8 is not shared with data
* utf8_length = 0 if utf8 is NULL
* (data starts just after the structure)
- legacy string:
* structure = PyUnicodeObject structure
* test: !PyUnicode_IS_COMPACT(op)
* kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or
PyUnicode_4BYTE_KIND
* compact = 0
* data.any is not NULL
* utf8 is shared and utf8_length = length with data.any if ascii = 1
* utf8_length = 0 if utf8 is NULL
Compact strings use only one memory block (structure + characters),
whereas legacy strings use one block for the structure and one block
for characters.
Legacy strings are created by subclasses of Unicode.
See also _PyUnicode_CheckConsistency().
*/
PyObject_HEAD
Py_ssize_t length; /* Number of code points in the string */
Py_hash_t hash; /* Hash value; -1 if not set */
#ifdef Py_GIL_DISABLED
/* Ensure 4 byte alignment for PyUnicode_DATA(), see gh-63736 on m68k.
In the non-free-threaded build, we'll use explicit padding instead */
_Py_ALIGN_AS(4)
#endif
struct {
/* If interned is non-zero, the two references from the
dictionary to this object are *not* counted in ob_refcnt.
The possible values here are:
0: Not Interned
1: Interned
2: Interned and Immortal
3: Interned, Immortal, and Static
This categorization allows the runtime to determine the right
cleanup mechanism at runtime shutdown. */
#ifdef Py_GIL_DISABLED
// Needs to be accessed atomically, so can't be a bit field.
unsigned char interned;
#else
unsigned int interned:2;
#endif
/* Character size:
- PyUnicode_1BYTE_KIND (1):
* character type = Py_UCS1 (8 bits, unsigned)
* all characters are in the range U+0000-U+00FF (latin1)
* if ascii is set, all characters are in the range U+0000-U+007F
(ASCII), otherwise at least one character is in the range
U+0080-U+00FF
- PyUnicode_2BYTE_KIND (2):
* character type = Py_UCS2 (16 bits, unsigned)
* all characters are in the range U+0000-U+FFFF (BMP)
* at least one character is in the range U+0100-U+FFFF
- PyUnicode_4BYTE_KIND (4):
* character type = Py_UCS4 (32 bits, unsigned)
* all characters are in the range U+0000-U+10FFFF
* at least one character is in the range U+10000-U+10FFFF
*/
unsigned int kind:3;
/* Compact is with respect to the allocation scheme. Compact unicode
objects only require one memory block while non-compact objects use
one block for the PyUnicodeObject struct and another for its data
buffer. */
unsigned int compact:1;
/* The string only contains characters in the range U+0000-U+007F (ASCII)
and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is
set, use the PyASCIIObject structure. */
unsigned int ascii:1;
/* The object is statically allocated. */
unsigned int statically_allocated:1;
#ifndef Py_GIL_DISABLED
/* Padding to ensure that PyUnicode_DATA() is always aligned to
4 bytes (see issue gh-63736 on m68k) */
unsigned int :24;
#endif
} state;
} PyASCIIObject;
/* Non-ASCII strings allocated through PyUnicode_New use the
PyCompactUnicodeObject structure. state.compact is set, and the data
immediately follow the structure. */
typedef struct {
PyASCIIObject _base;
Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the
* terminating \0. */
char *utf8; /* UTF-8 representation (null-terminated) */
} PyCompactUnicodeObject;
/* Object format for Unicode subclasses. */
typedef struct {
PyCompactUnicodeObject _base;
union {
void *any;
Py_UCS1 *latin1;
Py_UCS2 *ucs2;
Py_UCS4 *ucs4;
} data; /* Canonical, smallest-form Unicode buffer */
} PyUnicodeObject;
#define _PyASCIIObject_CAST(op) \
(assert(PyUnicode_Check(op)), \
_Py_CAST(PyASCIIObject*, (op)))
#define _PyCompactUnicodeObject_CAST(op) \
(assert(PyUnicode_Check(op)), \
_Py_CAST(PyCompactUnicodeObject*, (op)))
#define _PyUnicodeObject_CAST(op) \
(assert(PyUnicode_Check(op)), \
_Py_CAST(PyUnicodeObject*, (op)))
/* --- Flexible String Representation Helper Macros (PEP 393) -------------- */
/* Values for PyASCIIObject.state: */
/* Interning state. */
#define SSTATE_NOT_INTERNED 0
#define SSTATE_INTERNED_MORTAL 1
#define SSTATE_INTERNED_IMMORTAL 2
#define SSTATE_INTERNED_IMMORTAL_STATIC 3
/* Use only if you know it's a string */
static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) {
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_uint8_relaxed(&_PyASCIIObject_CAST(op)->state.interned);
#else
return _PyASCIIObject_CAST(op)->state.interned;
#endif
}
#define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op))
/* For backward compatibility. Soft-deprecated. */
static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) {
return 1;
}
#define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op))
/* Return true if the string contains only ASCII characters, or 0 if not. The
string may be compact (PyUnicode_IS_COMPACT_ASCII) or not. */
static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) {
return _PyASCIIObject_CAST(op)->state.ascii;
}
#define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op))
/* Return true if the string is compact or 0 if not.
No type checks are performed. */
static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) {
return _PyASCIIObject_CAST(op)->state.compact;
}
#define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op))
/* Return true if the string is a compact ASCII string (use PyASCIIObject
structure), or 0 if not. No type checks are performed. */
static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) {
return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op));
}
#define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op))
enum PyUnicode_Kind {
/* Return values of the PyUnicode_KIND() function: */
PyUnicode_1BYTE_KIND = 1,
PyUnicode_2BYTE_KIND = 2,
PyUnicode_4BYTE_KIND = 4
};
PyAPI_FUNC(int) PyUnicode_KIND(PyObject *op);
// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above.
//
// gh-89653: Converting this macro to a static inline function would introduce
// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and
// unsigned numbers) where kind type is an int or on
// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned).
#define PyUnicode_KIND(op) _Py_RVALUE(_PyASCIIObject_CAST(op)->state.kind)
/* Return a void pointer to the raw unicode buffer. */
static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) {
if (PyUnicode_IS_ASCII(op)) {
return _Py_STATIC_CAST(void*, (_PyASCIIObject_CAST(op) + 1));
}
return _Py_STATIC_CAST(void*, (_PyCompactUnicodeObject_CAST(op) + 1));
}
static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) {
void *data;
assert(!PyUnicode_IS_COMPACT(op));
data = _PyUnicodeObject_CAST(op)->data.any;
assert(data != NULL);
return data;
}
PyAPI_FUNC(void*) PyUnicode_DATA(PyObject *op);
static inline void* _PyUnicode_DATA(PyObject *op) {
if (PyUnicode_IS_COMPACT(op)) {
return _PyUnicode_COMPACT_DATA(op);
}
return _PyUnicode_NONCOMPACT_DATA(op);
}
#define PyUnicode_DATA(op) _PyUnicode_DATA(_PyObject_CAST(op))
/* Return pointers to the canonical representation cast to unsigned char,
Py_UCS2, or Py_UCS4 for direct character access.
No checks are performed, use PyUnicode_KIND() before to ensure
these will work correctly. */
#define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op))
#define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op))
#define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op))
/* Returns the length of the unicode string. */
static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) {
return _PyASCIIObject_CAST(op)->length;
}
#define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op))
/* Write into the canonical representation, this function does not do any sanity
checks and is intended for usage in loops. The caller should cache the
kind and data pointers obtained from other function calls.
index is the index in the string (starts at 0) and value is the new
code point value which should be written to that location. */
static inline void PyUnicode_WRITE(int kind, void *data,
Py_ssize_t index, Py_UCS4 value)
{
assert(index >= 0);
if (kind == PyUnicode_1BYTE_KIND) {
assert(value <= 0xffU);
_Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value);
}
else if (kind == PyUnicode_2BYTE_KIND) {
assert(value <= 0xffffU);
_Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value);
}
else {
assert(kind == PyUnicode_4BYTE_KIND);
assert(value <= 0x10ffffU);
_Py_STATIC_CAST(Py_UCS4*, data)[index] = value;
}
}
#define PyUnicode_WRITE(kind, data, index, value) \
PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \
(index), _Py_STATIC_CAST(Py_UCS4, value))
/* Read a code point from the string's canonical representation. No checks
are performed. */
static inline Py_UCS4 PyUnicode_READ(int kind,
const void *data, Py_ssize_t index)
{
assert(index >= 0);
if (kind == PyUnicode_1BYTE_KIND) {
return _Py_STATIC_CAST(const Py_UCS1*, data)[index];
}
if (kind == PyUnicode_2BYTE_KIND) {
return _Py_STATIC_CAST(const Py_UCS2*, data)[index];
}
assert(kind == PyUnicode_4BYTE_KIND);
return _Py_STATIC_CAST(const Py_UCS4*, data)[index];
}
#define PyUnicode_READ(kind, data, index) \
PyUnicode_READ(_Py_STATIC_CAST(int, kind), \
_Py_STATIC_CAST(const void*, data), \
(index))
/* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it
calls PyUnicode_KIND() and might call it twice. For single reads, use
PyUnicode_READ_CHAR, for multiple consecutive reads callers should
cache kind and use PyUnicode_READ instead. */
static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index)
{
int kind;
assert(index >= 0);
// Tolerate reading the NUL character at str[len(str)]
assert(index <= PyUnicode_GET_LENGTH(unicode));
kind = PyUnicode_KIND(unicode);
if (kind == PyUnicode_1BYTE_KIND) {
return PyUnicode_1BYTE_DATA(unicode)[index];
}
if (kind == PyUnicode_2BYTE_KIND) {
return PyUnicode_2BYTE_DATA(unicode)[index];
}
assert(kind == PyUnicode_4BYTE_KIND);
return PyUnicode_4BYTE_DATA(unicode)[index];
}
#define PyUnicode_READ_CHAR(unicode, index) \
PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index))
/* Return a maximum character value which is suitable for creating another
string based on op. This is always an approximation but more efficient
than iterating over the string. */
static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op)
{
int kind;
if (PyUnicode_IS_ASCII(op)) {
return 0x7fU;
}
kind = PyUnicode_KIND(op);
if (kind == PyUnicode_1BYTE_KIND) {
return 0xffU;
}
if (kind == PyUnicode_2BYTE_KIND) {
return 0xffffU;
}
assert(kind == PyUnicode_4BYTE_KIND);
return 0x10ffffU;
}
#define PyUnicode_MAX_CHAR_VALUE(op) \
PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op))
/* === Public API ========================================================= */
/* With PEP 393, this is the recommended way to allocate a new unicode object.
This function will allocate the object and its buffer in a single memory
block. Objects created using this function are not resizable. */
PyAPI_FUNC(PyObject*) PyUnicode_New(
Py_ssize_t size, /* Number of code points in the new string */
Py_UCS4 maxchar /* maximum code point value in the string */
);
/* For backward compatibility. Soft-deprecated. */
static inline int PyUnicode_READY(PyObject* Py_UNUSED(op))
{
return 0;
}
#define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op))
/* Copy character from one unicode object into another, this function performs
character conversion when necessary and falls back to memcpy() if possible.
Fail if to is too small (smaller than *how_many* or smaller than
len(from)-from_start), or if kind(from[from_start:from_start+how_many]) >
kind(to), or if *to* has more than 1 reference.
Return the number of written character, or return -1 and raise an exception
on error.
Pseudo-code:
how_many = min(how_many, len(from) - from_start)
to[to_start:to_start+how_many] = from[from_start:from_start+how_many]
return how_many
Note: The function doesn't write a terminating null character.
*/
PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters(
PyObject *to,
Py_ssize_t to_start,
PyObject *from,
Py_ssize_t from_start,
Py_ssize_t how_many
);
/* Fill a string with a character: write fill_char into
unicode[start:start+length].
Fail if fill_char is bigger than the string maximum character, or if the
string has more than 1 reference.
Return the number of written character, or return -1 and raise an exception
on error. */
PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill(
PyObject *unicode,
Py_ssize_t start,
Py_ssize_t length,
Py_UCS4 fill_char
);
/* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters.
Scan the string to find the maximum character. */
PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData(
int kind,
const void *buffer,
Py_ssize_t size);
/* --- Public PyUnicodeWriter API ----------------------------------------- */
typedef struct PyUnicodeWriter PyUnicodeWriter;
PyAPI_FUNC(PyUnicodeWriter*) PyUnicodeWriter_Create(Py_ssize_t length);
PyAPI_FUNC(void) PyUnicodeWriter_Discard(PyUnicodeWriter *writer);
PyAPI_FUNC(PyObject*) PyUnicodeWriter_Finish(PyUnicodeWriter *writer);
PyAPI_FUNC(int) PyUnicodeWriter_WriteChar(
PyUnicodeWriter *writer,
Py_UCS4 ch);
PyAPI_FUNC(int) PyUnicodeWriter_WriteUTF8(
PyUnicodeWriter *writer,
const char *str,
Py_ssize_t size);
PyAPI_FUNC(int) PyUnicodeWriter_WriteASCII(
PyUnicodeWriter *writer,
const char *str,
Py_ssize_t size);
PyAPI_FUNC(int) PyUnicodeWriter_WriteWideChar(
PyUnicodeWriter *writer,
const wchar_t *str,
Py_ssize_t size);
PyAPI_FUNC(int) PyUnicodeWriter_WriteUCS4(
PyUnicodeWriter *writer,
Py_UCS4 *str,
Py_ssize_t size);
PyAPI_FUNC(int) PyUnicodeWriter_WriteStr(
PyUnicodeWriter *writer,
PyObject *obj);
PyAPI_FUNC(int) PyUnicodeWriter_WriteRepr(
PyUnicodeWriter *writer,
PyObject *obj);
PyAPI_FUNC(int) PyUnicodeWriter_WriteSubstring(
PyUnicodeWriter *writer,
PyObject *str,
Py_ssize_t start,
Py_ssize_t end);
PyAPI_FUNC(int) PyUnicodeWriter_Format(
PyUnicodeWriter *writer,
const char *format,
...);
PyAPI_FUNC(int) PyUnicodeWriter_DecodeUTF8Stateful(
PyUnicodeWriter *writer,
const char *string, /* UTF-8 encoded string */
Py_ssize_t length, /* size of string */
const char *errors, /* error handling */
Py_ssize_t *consumed); /* bytes consumed */
/* --- Private _PyUnicodeWriter API --------------------------------------- */
typedef struct {
PyObject *buffer;
void *data;
int kind;
Py_UCS4 maxchar;
Py_ssize_t size;
Py_ssize_t pos;
/* minimum number of allocated characters (default: 0) */
Py_ssize_t min_length;
/* minimum character (default: 127, ASCII) */
Py_UCS4 min_char;
/* If non-zero, overallocate the buffer (default: 0). */
unsigned char overallocate;
/* If readonly is 1, buffer is a shared string (cannot be modified)
and size is set to 0. */
unsigned char readonly;
} _PyUnicodeWriter;
// Initialize a Unicode writer.
//
// By default, the minimum buffer size is 0 character and overallocation is
// disabled. Set min_length, min_char and overallocate attributes to control
// the allocation of the buffer.
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(void) _PyUnicodeWriter_Init(
_PyUnicodeWriter *writer);
/* Prepare the buffer to write 'length' characters
with the specified maximum character.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_Prepare(WRITER, LENGTH, MAXCHAR) \
(((MAXCHAR) <= (WRITER)->maxchar \
&& (LENGTH) <= (WRITER)->size - (WRITER)->pos) \
? 0 \
: (((LENGTH) == 0) \
? 0 \
: _PyUnicodeWriter_PrepareInternal((WRITER), (LENGTH), (MAXCHAR))))
/* Don't call this function directly, use the _PyUnicodeWriter_Prepare() macro
instead. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_PrepareInternal(
_PyUnicodeWriter *writer,
Py_ssize_t length,
Py_UCS4 maxchar);
/* Prepare the buffer to have at least the kind KIND.
For example, kind=PyUnicode_2BYTE_KIND ensures that the writer will
support characters in range U+000-U+FFFF.
Return 0 on success, raise an exception and return -1 on error. */
#define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \
((KIND) <= (WRITER)->kind \
? 0 \
: _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND)))
/* Don't call this function directly, use the _PyUnicodeWriter_PrepareKind()
macro instead. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_PrepareKindInternal(
_PyUnicodeWriter *writer,
int kind);
/* Append a Unicode character.
Return 0 on success, raise an exception and return -1 on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteChar(
_PyUnicodeWriter *writer,
Py_UCS4 ch);
/* Append a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteStr(
_PyUnicodeWriter *writer,
PyObject *str); /* Unicode string */
/* Append a substring of a Unicode string.
Return 0 on success, raise an exception and return -1 on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteSubstring(
_PyUnicodeWriter *writer,
PyObject *str, /* Unicode string */
Py_ssize_t start,
Py_ssize_t end);
/* Append an ASCII-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteASCIIString(
_PyUnicodeWriter *writer,
const char *str, /* ASCII-encoded byte string */
Py_ssize_t len); /* number of bytes, or -1 if unknown */
/* Append a latin1-encoded byte string.
Return 0 on success, raise an exception and return -1 on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(int) _PyUnicodeWriter_WriteLatin1String(
_PyUnicodeWriter *writer,
const char *str, /* latin1-encoded byte string */
Py_ssize_t len); /* length in bytes */
/* Get the value of the writer as a Unicode string. Clear the
buffer of the writer. Raise an exception and return NULL
on error. */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(PyObject *) _PyUnicodeWriter_Finish(
_PyUnicodeWriter *writer);
/* Deallocate memory of a writer (clear its internal buffer). */
_Py_DEPRECATED_EXTERNALLY(3.14) PyAPI_FUNC(void) _PyUnicodeWriter_Dealloc(
_PyUnicodeWriter *writer);
/* --- Manage the default encoding ---------------------------------------- */
/* Returns a pointer to the default encoding (UTF-8) of the
Unicode object unicode.
Like PyUnicode_AsUTF8AndSize(), this also caches the UTF-8 representation
in the unicodeobject.
_PyUnicode_AsString is a #define for PyUnicode_AsUTF8 to
support the previous internal function with the same behaviour.
Use of this API is DEPRECATED since no size information can be
extracted from the returned data.
*/
PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode);
// Deprecated alias kept for backward compatibility
Py_DEPRECATED(3.14) static inline const char*
_PyUnicode_AsString(PyObject *unicode)
{
return PyUnicode_AsUTF8(unicode);
}
/* === Characters Type APIs =============================================== */
/* These should not be used directly. Use the Py_UNICODE_IS* and
Py_UNICODE_TO* macros instead.
These APIs are implemented in Objects/unicodectype.c.
*/
PyAPI_FUNC(int) _PyUnicode_IsLowercase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsUppercase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsTitlecase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsWhitespace(
const Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsLinebreak(
const Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_ToDigit(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(double) _PyUnicode_ToNumeric(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsDigit(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsNumeric(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsPrintable(
Py_UCS4 ch /* Unicode character */
);
PyAPI_FUNC(int) _PyUnicode_IsAlpha(
Py_UCS4 ch /* Unicode character */
);
// Helper array used by Py_UNICODE_ISSPACE().
PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[];
// Since splitting on whitespace is an important use case, and
// whitespace in most situations is solely ASCII whitespace, we
// optimize for the common case by using a quick look-up table
// _Py_ascii_whitespace (see below) with an inlined check.
static inline int Py_UNICODE_ISSPACE(Py_UCS4 ch) {
if (ch < 128) {
return _Py_ascii_whitespace[ch];
}
return _PyUnicode_IsWhitespace(ch);
}
#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch)
#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch)
#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch)
#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch)
#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch)
#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch)
#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch)
#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch)
#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch)
static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) {
return (Py_UNICODE_ISALPHA(ch)
|| Py_UNICODE_ISDECIMAL(ch)
|| Py_UNICODE_ISDIGIT(ch)
|| Py_UNICODE_ISNUMERIC(ch));
}
/* === Misc functions ===================================================== */
// Return an interned Unicode object for an Identifier; may fail if there is no
// memory.
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);

View File

@@ -0,0 +1,20 @@
#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)

View File

@@ -0,0 +1,66 @@
#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;
#ifdef Py_GIL_DISABLED
/* Pointer to the lock used when clearing in free-threaded builds.
* Normally this can be derived from wr_object, but in some cases we need
* to lock after wr_object has been set to Py_None.
*/
PyMutex *weakrefs_lock;
#endif
};
PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
#define _PyWeakref_CAST(op) \
(assert(PyWeakref_Check(op)), _Py_CAST(PyWeakReference*, (op)))
// Test if a weak reference is dead.
PyAPI_FUNC(int) PyWeakref_IsDead(PyObject *ref);
Py_DEPRECATED(3.13) static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj)
{
PyWeakReference *ref = _PyWeakref_CAST(ref_obj);
PyObject *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;
}
#define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref))

View File

@@ -0,0 +1,16 @@
#ifndef Py_CRITICAL_SECTION_H
#define Py_CRITICAL_SECTION_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_LIMITED_API
# define Py_CPYTHON_CRITICAL_SECTION_H
# include "cpython/critical_section.h"
# undef Py_CPYTHON_CRITICAL_SECTION_H
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_CRITICAL_SECTION_H */

View File

@@ -1,6 +1,6 @@
/* datetime.h /* datetime.h
*/ */
#ifndef Py_LIMITED_API
#ifndef DATETIME_H #ifndef DATETIME_H
#define DATETIME_H #define DATETIME_H
#ifdef __cplusplus #ifdef __cplusplus
@@ -34,7 +34,7 @@ extern "C" {
typedef struct typedef struct
{ {
PyObject_HEAD PyObject_HEAD
long hashcode; /* -1 when unknown */ Py_hash_t hashcode; /* -1 when unknown */
int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
int seconds; /* 0 <= seconds < 24*3600 is invariant */ int seconds; /* 0 <= seconds < 24*3600 is invariant */
int microseconds; /* 0 <= microseconds < 1000000 is invariant */ int microseconds; /* 0 <= microseconds < 1000000 is invariant */
@@ -51,7 +51,7 @@ typedef struct
*/ */
#define _PyTZINFO_HEAD \ #define _PyTZINFO_HEAD \
PyObject_HEAD \ PyObject_HEAD \
long hashcode; \ Py_hash_t hashcode; \
char hastzinfo; /* boolean flag */ char hastzinfo; /* boolean flag */
/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something /* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
@@ -81,6 +81,7 @@ typedef struct
typedef struct typedef struct
{ {
_PyDateTime_TIMEHEAD _PyDateTime_TIMEHEAD
unsigned char fold;
PyObject *tzinfo; PyObject *tzinfo;
} PyDateTime_Time; /* hastzinfo true */ } PyDateTime_Time; /* hastzinfo true */
@@ -108,32 +109,49 @@ typedef struct
typedef struct typedef struct
{ {
_PyDateTime_DATETIMEHEAD _PyDateTime_DATETIMEHEAD
unsigned char fold;
PyObject *tzinfo; PyObject *tzinfo;
} PyDateTime_DateTime; /* hastzinfo true */ } PyDateTime_DateTime; /* hastzinfo true */
/* Apply for date and datetime instances. */ /* Apply for date and datetime instances. */
#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]) // o is a pointer to a time or a datetime object.
#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) #define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo)
#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6])
#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) \ #define PyDateTime_DATE_GET_MICROSECOND(o) \
((((PyDateTime_DateTime*)o)->data[7] << 16) | \ ((((PyDateTime_DateTime*)(o))->data[7] << 16) | \
(((PyDateTime_DateTime*)o)->data[8] << 8) | \ (((PyDateTime_DateTime*)(o))->data[8] << 8) | \
((PyDateTime_DateTime*)o)->data[9]) ((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. */ /* Apply for time instances. */
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) #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_MINUTE(o) (((PyDateTime_Time*)(o))->data[1])
#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) #define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)(o))->data[2])
#define PyDateTime_TIME_GET_MICROSECOND(o) \ #define PyDateTime_TIME_GET_MICROSECOND(o) \
((((PyDateTime_Time*)o)->data[3] << 16) | \ ((((PyDateTime_Time*)(o))->data[3] << 16) | \
(((PyDateTime_Time*)o)->data[4] << 8) | \ (((PyDateTime_Time*)(o))->data[4] << 8) | \
((PyDateTime_Time*)o)->data[5]) ((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. */ /* Define structure for C API. */
@@ -145,95 +163,105 @@ typedef struct {
PyTypeObject *DeltaType; PyTypeObject *DeltaType;
PyTypeObject *TZInfoType; PyTypeObject *TZInfoType;
/* singletons */
PyObject *TimeZone_UTC;
/* constructors */ /* constructors */
PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
PyObject*, PyTypeObject*); PyObject*, PyTypeObject*);
PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
PyObject *(*TimeZone_FromTimeZone)(PyObject *offset, PyObject *name);
/* constructors for the DB API */ /* constructors for the DB API */
PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
PyObject *(*Date_FromTimestamp)(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; } PyDateTime_CAPI;
#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI" #define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
/* "magic" constant used to partially protect against developer mistakes. */ /* This block is only used as part of the public API and should not be
#define DATETIME_API_MAGIC 0x414548d5 * included in _datetimemodule.c, which does not use the C API capsule.
* See bpo-35081 for more details.
#ifdef Py_BUILD_CORE * */
#ifndef _PY_DATETIME_IMPL
/* Macros for type checking when building the Python core. */
#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType)
#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType)
#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType)
#else
/* Define global variable for the C API and a macro for setting it. */ /* Define global variable for the C API and a macro for setting it. */
static PyDateTime_CAPI *PyDateTimeAPI = NULL; static PyDateTime_CAPI *PyDateTimeAPI = NULL;
#define PyDateTime_IMPORT \ #define PyDateTime_IMPORT \
PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) 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. */ /* Macros for type checking when not building the Python core. */
#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) #define PyDate_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateType)
#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) #define PyDate_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateType)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) #define PyDateTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateTimeType)
#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) #define PyDateTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateTimeType)
#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) #define PyTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->TimeType)
#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) #define PyTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->TimeType)
#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) #define PyDelta_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DeltaType)
#define PyDelta_CheckExact(op) (Py_TYPE(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)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType)
/* Macros for accessing constructors in a simplified fashion. */ /* Macros for accessing constructors in a simplified fashion. */
#define PyDate_FromDate(year, month, day) \ #define PyDate_FromDate(year, month, day) \
PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) PyDateTimeAPI->Date_FromDate((year), (month), (day), PyDateTimeAPI->DateType)
#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ #define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ PyDateTimeAPI->DateTime_FromDateAndTime((year), (month), (day), (hour), \
min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) (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) \ #define PyTime_FromTime(hour, minute, second, usecond) \
PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ PyDateTimeAPI->Time_FromTime((hour), (minute), (second), (usecond), \
Py_None, PyDateTimeAPI->TimeType) 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) \ #define PyDelta_FromDSU(days, seconds, useconds) \
PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ PyDateTimeAPI->Delta_FromDelta((days), (seconds), (useconds), 1, \
PyDateTimeAPI->DeltaType) 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. */ /* Macros supporting the DB API. */
#define PyDateTime_FromTimestamp(args) \ #define PyDateTime_FromTimestamp(args) \
PyDateTimeAPI->DateTime_FromTimestamp( \ PyDateTimeAPI->DateTime_FromTimestamp( \
(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) (PyObject*) (PyDateTimeAPI->DateTimeType), (args), NULL)
#define PyDate_FromTimestamp(args) \ #define PyDate_FromTimestamp(args) \
PyDateTimeAPI->Date_FromTimestamp( \ PyDateTimeAPI->Date_FromTimestamp( \
(PyObject*) (PyDateTimeAPI->DateType), args) (PyObject*) (PyDateTimeAPI->DateType), (args))
#endif /* Py_BUILD_CORE */ #endif /* !defined(_PY_DATETIME_IMPL) */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif
#endif /* !Py_LIMITED_API */

View File

@@ -8,87 +8,93 @@ extern "C" {
typedef PyObject *(*getter)(PyObject *, void *); typedef PyObject *(*getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *);
typedef struct PyGetSetDef { struct PyGetSetDef {
char *name; const char *name;
getter get; getter get;
setter set; setter set;
char *doc; const char *doc;
void *closure; void *closure;
} PyGetSetDef;
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
void *wrapped);
typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args,
void *wrapped, PyObject *kwds);
struct wrapperbase {
char *name;
int offset;
void *function;
wrapperfunc wrapper;
char *doc;
int flags;
PyObject *name_strobj;
}; };
/* Flags for above struct */ PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type;
#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */
/* Various kinds of descriptor objects */
#define PyDescr_COMMON \
PyObject_HEAD \
PyTypeObject *d_type; \
PyObject *d_name
typedef struct {
PyDescr_COMMON;
} PyDescrObject;
typedef struct {
PyDescr_COMMON;
PyMethodDef *d_method;
} PyMethodDescrObject;
typedef struct {
PyDescr_COMMON;
struct PyMemberDef *d_member;
} PyMemberDescrObject;
typedef struct {
PyDescr_COMMON;
PyGetSetDef *d_getset;
} PyGetSetDescrObject;
typedef struct {
PyDescr_COMMON;
struct wrapperbase *d_base;
void *d_wrapped; /* This can be any function pointer */
} PyWrapperDescrObject;
PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type;
PyAPI_DATA(PyTypeObject) PyDictProxy_Type;
PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type;
PyAPI_DATA(PyTypeObject) PyMemberDescr_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_NewMethod(PyTypeObject *, PyMethodDef *);
PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *);
PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, PyMemberDef *);
struct PyMemberDef *); PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, PyGetSetDef *);
PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
struct PyGetSetDef *);
PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
struct wrapperbase *, void *);
#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL)
PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *);
PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *);
PyAPI_DATA(PyTypeObject) PyProperty_Type; /* An array of PyMemberDef structures defines the name, type and offset
of selected members of a C structure. These can be read by
PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY
flag is set). The array must be terminated with an entry whose name
pointer is NULL. */
struct PyMemberDef {
const char *name;
int type;
Py_ssize_t offset;
int flags;
const char *doc;
};
// These constants used to be in structmember.h, not prefixed by Py_.
// (structmember.h now has aliases to the new names.)
/* Types */
#define Py_T_SHORT 0
#define Py_T_INT 1
#define Py_T_LONG 2
#define Py_T_FLOAT 3
#define Py_T_DOUBLE 4
#define Py_T_STRING 5
#define _Py_T_OBJECT 6 // Deprecated, use Py_T_OBJECT_EX instead
/* the ordering here is weird for binary compatibility */
#define Py_T_CHAR 7 /* 1-character string */
#define Py_T_BYTE 8 /* 8-bit signed int */
/* unsigned variants: */
#define Py_T_UBYTE 9
#define Py_T_USHORT 10
#define Py_T_UINT 11
#define Py_T_ULONG 12
/* Added by Jack: strings contained in the structure */
#define Py_T_STRING_INPLACE 13
/* Added by Lillo: bools contained in the structure (assumed char) */
#define Py_T_BOOL 14
#define Py_T_OBJECT_EX 16
#define Py_T_LONGLONG 17
#define Py_T_ULONGLONG 18
#define Py_T_PYSSIZET 19 /* Py_ssize_t */
#define _Py_T_NONE 20 // Deprecated. Value is always None.
/* Flags */
#define Py_READONLY 1
#define Py_AUDIT_READ 2 // Added in 3.10, harmless no-op before that
#define _Py_WRITE_RESTRICTED 4 // Deprecated, no-op. Do not reuse the value.
#define Py_RELATIVE_OFFSET 8
PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *);
PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *);
#ifndef Py_LIMITED_API
# define Py_CPYTHON_DESCROBJECT_H
# include "cpython/descrobject.h"
# undef Py_CPYTHON_DESCROBJECT_H
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* !Py_DESCROBJECT_H */ #endif /* !Py_DESCROBJECT_H */

View File

@@ -4,7 +4,6 @@
extern "C" { extern "C" {
#endif #endif
/* Dictionary object type -- mapping from hashable object to object */ /* Dictionary object type -- mapping from hashable object to object */
/* The distribution includes a separate file, Objects/dictnotes.txt, /* The distribution includes a separate file, Objects/dictnotes.txt,
@@ -13,117 +12,26 @@ extern "C" {
tuning dictionaries, and several ideas for possible optimizations. tuning dictionaries, and several ideas for possible optimizations.
*/ */
/*
There are three kinds of slots in the table:
1. Unused. me_key == me_value == NULL
Does not hold an active (key, value) pair now and never did. Unused can
transition to Active upon key insertion. This is the only case in which
me_key is NULL, and is each slot's initial state.
2. Active. me_key != NULL and me_key != dummy and me_value != NULL
Holds an active (key, value) pair. Active can transition to Dummy upon
key deletion. This is the only case in which me_value != NULL.
3. Dummy. me_key == dummy and me_value == NULL
Previously held an active (key, value) pair, but that was deleted and an
active pair has not yet overwritten the slot. Dummy can transition to
Active upon key insertion. Dummy slots cannot be made Unused again
(cannot have me_key set to NULL), else the probe sequence in case of
collision would have no way to know they were once active.
Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to
hold a search finger. The me_hash field of Unused or Dummy slots has no
meaning otherwise.
*/
/* PyDict_MINSIZE is the minimum size of a dictionary. This many slots are
* allocated directly in the dict object (in the ma_smalltable member).
* It must be a power of 2, and at least 4. 8 allows dicts with no more
* than 5 active entries to live in ma_smalltable (and so avoid an
* additional malloc); instrumentation suggested this suffices for the
* majority of dicts (consisting mostly of usually-small instance dicts and
* usually-small dicts created to pass keyword arguments).
*/
#define PyDict_MINSIZE 8
typedef struct {
/* Cached hash code of me_key. Note that hash codes are C longs.
* We have to use Py_ssize_t instead because dict_popitem() abuses
* me_hash to hold a search finger.
*/
Py_ssize_t me_hash;
PyObject *me_key;
PyObject *me_value;
} PyDictEntry;
/*
To ensure the lookup algorithm terminates, there must be at least one Unused
slot (NULL key) in the table.
The value ma_fill is the number of non-NULL keys (sum of Active and Dummy);
ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL
values == the number of Active items).
To avoid slowing down lookups on a near-full table, we resize the table when
it's two-thirds full.
*/
typedef struct _dictobject PyDictObject;
struct _dictobject {
PyObject_HEAD
Py_ssize_t ma_fill; /* # Active + # Dummy */
Py_ssize_t ma_used; /* # Active */
/* The table contains ma_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 ma_mask;
/* ma_table points to ma_smalltable for small tables, else to
* additional malloc'ed memory. ma_table is never NULL! This rule
* saves repeated runtime null-tests in the workhorse getitem and
* setitem calls.
*/
PyDictEntry *ma_table;
PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
PyDictEntry ma_smalltable[PyDict_MINSIZE];
};
PyAPI_DATA(PyTypeObject) PyDict_Type; PyAPI_DATA(PyTypeObject) PyDict_Type;
PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
PyAPI_DATA(PyTypeObject) PyDictItems_Type;
PyAPI_DATA(PyTypeObject) PyDictValues_Type;
#define PyDict_Check(op) \ #define PyDict_Check(op) \
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) #define PyDict_CheckExact(op) Py_IS_TYPE((op), &PyDict_Type)
#define PyDictKeys_Check(op) (Py_TYPE(op) == &PyDictKeys_Type)
#define PyDictItems_Check(op) (Py_TYPE(op) == &PyDictItems_Type)
#define PyDictValues_Check(op) (Py_TYPE(op) == &PyDictValues_Type)
/* This excludes Values, since they are not sets. */
# define PyDictViewSet_Check(op) \
(PyDictKeys_Check(op) || PyDictItems_Check(op))
PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_New(void);
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); 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_SetItem(PyObject *mp, PyObject *key, PyObject *item);
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
PyAPI_FUNC(int) PyDict_Next( PyAPI_FUNC(int) PyDict_Next(
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
PyAPI_FUNC(int) _PyDict_Next(
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash);
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
@@ -134,8 +42,8 @@ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
*/ */
PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
PyObject *other, PyObject *other,
int override); int override);
/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing /* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
iterable objects of length 2. If override is true, the last occurrence iterable objects of length 2. If override is true, the last occurrence
@@ -143,13 +51,57 @@ PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
*/ */
PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
PyObject *seq2, PyObject *seq2,
int override); int override);
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); 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_SetItemString(PyObject *dp, const char *key, PyObject *item);
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030D0000
// Return the object from dictionary *op* which has a key *key*.
// - If the key is present, set *result to a new strong reference to the value
// and return 1.
// - If the key is missing, set *result to NULL and return 0 .
// - On error, raise an exception and return -1.
PyAPI_FUNC(int) PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result);
PyAPI_FUNC(int) PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result);
#endif
#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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,15 +0,0 @@
#ifndef PY_NO_SHORT_FLOAT_REPR
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr);
PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits,
int *decpt, int *sign, char **rve);
PyAPI_FUNC(void) _Py_dg_freedtoa(char *s);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,499 @@
/* Copyright (c) 2008-2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ---
* Author: Kostya Serebryany
* Copied to CPython by Jeffrey Yasskin, with all macros renamed to
* start with _Py_ to avoid colliding with users embedding Python, and
* with deprecated macros removed.
*/
/* This file defines dynamic annotations for use with dynamic analysis
tool such as valgrind, PIN, etc.
Dynamic annotation is a source code annotation that affects
the generated code (that is, the annotation is not a comment).
Each such annotation is attached to a particular
instruction and/or to a particular object (address) in the program.
The annotations that should be used by users are macros in all upper-case
(e.g., _Py_ANNOTATE_NEW_MEMORY).
Actual implementation of these macros may differ depending on the
dynamic analysis tool being used.
See https://code.google.com/p/data-race-test/ for more information.
This file supports the following dynamic analysis tools:
- None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).
Macros are defined empty.
- ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).
Macros are defined as calls to non-inlinable empty functions
that are intercepted by Valgrind. */
#ifndef __DYNAMIC_ANNOTATIONS_H__
#define __DYNAMIC_ANNOTATIONS_H__
#ifndef DYNAMIC_ANNOTATIONS_ENABLED
# define DYNAMIC_ANNOTATIONS_ENABLED 0
#endif
#if DYNAMIC_ANNOTATIONS_ENABLED != 0
/* -------------------------------------------------------------
Annotations useful when implementing condition variables such as CondVar,
using conditional critical sections (Await/LockWhen) and when constructing
user-defined synchronization mechanisms.
The annotations _Py_ANNOTATE_HAPPENS_BEFORE() and
_Py_ANNOTATE_HAPPENS_AFTER() can be used to define happens-before arcs in
user-defined synchronization mechanisms: the race detector will infer an
arc from the former to the latter when they share the same argument
pointer.
Example 1 (reference counting):
void Unref() {
_Py_ANNOTATE_HAPPENS_BEFORE(&refcount_);
if (AtomicDecrementByOne(&refcount_) == 0) {
_Py_ANNOTATE_HAPPENS_AFTER(&refcount_);
delete this;
}
}
Example 2 (message queue):
void MyQueue::Put(Type *e) {
MutexLock lock(&mu_);
_Py_ANNOTATE_HAPPENS_BEFORE(e);
PutElementIntoMyQueue(e);
}
Type *MyQueue::Get() {
MutexLock lock(&mu_);
Type *e = GetElementFromMyQueue();
_Py_ANNOTATE_HAPPENS_AFTER(e);
return e;
}
Note: when possible, please use the existing reference counting and message
queue implementations instead of inventing new ones. */
/* Report that wait on the condition variable at address "cv" has succeeded
and the lock at address "lock" is held. */
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \
AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)
/* Report that wait on the condition variable at "cv" has succeeded. Variant
w/o lock. */
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) \
AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)
/* Report that we are about to signal on the condition variable at address
"cv". */
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) \
AnnotateCondVarSignal(__FILE__, __LINE__, cv)
/* Report that we are about to signal_all on the condition variable at "cv". */
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \
AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)
/* Annotations for user-defined synchronization mechanisms. */
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) _Py_ANNOTATE_CONDVAR_SIGNAL(obj)
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) _Py_ANNOTATE_CONDVAR_WAIT(obj)
/* Report that the bytes in the range [pointer, pointer+size) are about
to be published safely. The race checker will create a happens-before
arc from the call _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to
subsequent accesses to this memory.
Note: this annotation may not work properly if the race detector uses
sampling, i.e. does not observe all memory accesses.
*/
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \
AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)
/* Instruct the tool to create a happens-before arc between mu->Unlock() and
mu->Lock(). This annotation may slow down the race detector and hide real
races. Normally it is used only when it would be difficult to annotate each
of the mutex's critical sections individually using the annotations above.
This annotation makes sense only for hybrid race detectors. For pure
happens-before detectors this is a no-op. For more details see
https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \
AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)
/* -------------------------------------------------------------
Annotations useful when defining memory allocators, or when memory that
was protected in one way starts to be protected in another. */
/* Report that a new memory at "address" of size "size" has been allocated.
This might be used when the memory has been retrieved from a free list and
is about to be reused, or when the locking discipline for a variable
changes. */
#define _Py_ANNOTATE_NEW_MEMORY(address, size) \
AnnotateNewMemory(__FILE__, __LINE__, address, size)
/* -------------------------------------------------------------
Annotations useful when defining FIFO queues that transfer data between
threads. */
/* Report that the producer-consumer queue (such as ProducerConsumerQueue) at
address "pcq" has been created. The _Py_ANNOTATE_PCQ_* annotations should
be used only for FIFO queues. For non-FIFO queues use
_Py_ANNOTATE_HAPPENS_BEFORE (for put) and _Py_ANNOTATE_HAPPENS_AFTER (for
get). */
#define _Py_ANNOTATE_PCQ_CREATE(pcq) \
AnnotatePCQCreate(__FILE__, __LINE__, pcq)
/* Report that the queue at address "pcq" is about to be destroyed. */
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) \
AnnotatePCQDestroy(__FILE__, __LINE__, pcq)
/* Report that we are about to put an element into a FIFO queue at address
"pcq". */
#define _Py_ANNOTATE_PCQ_PUT(pcq) \
AnnotatePCQPut(__FILE__, __LINE__, pcq)
/* Report that we've just got an element from a FIFO queue at address "pcq". */
#define _Py_ANNOTATE_PCQ_GET(pcq) \
AnnotatePCQGet(__FILE__, __LINE__, pcq)
/* -------------------------------------------------------------
Annotations that suppress errors. It is usually better to express the
program's synchronization using the other annotations, but these can
be used when all else fails. */
/* Report that we may have a benign race at "pointer", with size
"sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the
point where "pointer" has been allocated, preferably close to the point
where the race happens. See also _Py_ANNOTATE_BENIGN_RACE_STATIC. */
#define _Py_ANNOTATE_BENIGN_RACE(pointer, description) \
AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
sizeof(*(pointer)), description)
/* Same as _Py_ANNOTATE_BENIGN_RACE(address, description), but applies to
the memory range [address, address+size). */
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
/* Request the analysis tool to ignore all reads in the current thread
until _Py_ANNOTATE_IGNORE_READS_END is called.
Useful to ignore intentional racey reads, while still checking
other reads and all writes.
See also _Py_ANNOTATE_UNPROTECTED_READ. */
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() \
AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
/* Stop ignoring reads. */
#define _Py_ANNOTATE_IGNORE_READS_END() \
AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() \
AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
/* Stop ignoring writes. */
#define _Py_ANNOTATE_IGNORE_WRITES_END() \
AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
/* Start ignoring all memory accesses (reads and writes). */
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
do {\
_Py_ANNOTATE_IGNORE_READS_BEGIN();\
_Py_ANNOTATE_IGNORE_WRITES_BEGIN();\
}while(0)\
/* Stop ignoring all memory accesses. */
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() \
do {\
_Py_ANNOTATE_IGNORE_WRITES_END();\
_Py_ANNOTATE_IGNORE_READS_END();\
}while(0)\
/* Similar to _Py_ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events:
RWLOCK* and CONDVAR*. */
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() \
AnnotateIgnoreSyncBegin(__FILE__, __LINE__)
/* Stop ignoring sync events. */
#define _Py_ANNOTATE_IGNORE_SYNC_END() \
AnnotateIgnoreSyncEnd(__FILE__, __LINE__)
/* Enable (enable!=0) or disable (enable==0) race detection for all threads.
This annotation could be useful if you want to skip expensive race analysis
during some period of program execution, e.g. during initialization. */
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) \
AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
/* -------------------------------------------------------------
Annotations useful for debugging. */
/* Request to trace every access to "address". */
#define _Py_ANNOTATE_TRACE_MEMORY(address) \
AnnotateTraceMemory(__FILE__, __LINE__, address)
/* Report the current thread name to a race detector. */
#define _Py_ANNOTATE_THREAD_NAME(name) \
AnnotateThreadName(__FILE__, __LINE__, name)
/* -------------------------------------------------------------
Annotations useful when implementing locks. They are not
normally needed by modules that merely use locks.
The "lock" argument is a pointer to the lock object. */
/* Report that a lock has been created at address "lock". */
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) \
AnnotateRWLockCreate(__FILE__, __LINE__, lock)
/* Report that the lock at address "lock" is about to be destroyed. */
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) \
AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
/* Report that the lock at address "lock" has been acquired.
is_w=1 for writer lock, is_w=0 for reader lock. */
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
/* Report that the lock at address "lock" is about to be released. */
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
/* -------------------------------------------------------------
Annotations useful when implementing barriers. They are not
normally needed by modules that merely use barriers.
The "barrier" argument is a pointer to the barrier object. */
/* Report that the "barrier" has been initialized with initial "count".
If 'reinitialization_allowed' is true, initialization is allowed to happen
multiple times w/o calling barrier_destroy() */
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \
reinitialization_allowed)
/* Report that we are about to enter barrier_wait("barrier"). */
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)
/* Report that we just exited barrier_wait("barrier"). */
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)
/* Report that the "barrier" has been destroyed. */
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) \
AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)
/* -------------------------------------------------------------
Annotations useful for testing race detectors. */
/* Report that we expect a race on the variable at "address".
Use only in unit tests for a race detector. */
#define _Py_ANNOTATE_EXPECT_RACE(address, description) \
AnnotateExpectRace(__FILE__, __LINE__, address, description)
/* A no-op. Insert where you like to test the interceptors. */
#define _Py_ANNOTATE_NO_OP(arg) \
AnnotateNoOp(__FILE__, __LINE__, arg)
/* Force the race detector to flush its state. The actual effect depends on
* the implementation of the detector. */
#define _Py_ANNOTATE_FLUSH_STATE() \
AnnotateFlushState(__FILE__, __LINE__)
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
#define _Py_ANNOTATE_RWLOCK_CREATE(lock) /* empty */
#define _Py_ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
#define _Py_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
#define _Py_ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
#define _Py_ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */
#define _Py_ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */
#define _Py_ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */
#define _Py_ANNOTATE_BARRIER_DESTROY(barrier) /* empty */
#define _Py_ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */
#define _Py_ANNOTATE_CONDVAR_WAIT(cv) /* empty */
#define _Py_ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */
#define _Py_ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */
#define _Py_ANNOTATE_HAPPENS_BEFORE(obj) /* empty */
#define _Py_ANNOTATE_HAPPENS_AFTER(obj) /* empty */
#define _Py_ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */
#define _Py_ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */
#define _Py_ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */
#define _Py_ANNOTATE_PCQ_CREATE(pcq) /* empty */
#define _Py_ANNOTATE_PCQ_DESTROY(pcq) /* empty */
#define _Py_ANNOTATE_PCQ_PUT(pcq) /* empty */
#define _Py_ANNOTATE_PCQ_GET(pcq) /* empty */
#define _Py_ANNOTATE_NEW_MEMORY(address, size) /* empty */
#define _Py_ANNOTATE_EXPECT_RACE(address, description) /* empty */
#define _Py_ANNOTATE_BENIGN_RACE(address, description) /* empty */
#define _Py_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
#define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */
#define _Py_ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */
#define _Py_ANNOTATE_TRACE_MEMORY(arg) /* empty */
#define _Py_ANNOTATE_THREAD_NAME(name) /* empty */
#define _Py_ANNOTATE_IGNORE_READS_BEGIN() /* empty */
#define _Py_ANNOTATE_IGNORE_READS_END() /* empty */
#define _Py_ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */
#define _Py_ANNOTATE_IGNORE_WRITES_END() /* empty */
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */
#define _Py_ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */
#define _Py_ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */
#define _Py_ANNOTATE_IGNORE_SYNC_END() /* empty */
#define _Py_ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
#define _Py_ANNOTATE_NO_OP(arg) /* empty */
#define _Py_ANNOTATE_FLUSH_STATE() /* empty */
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
/* Use the macros above rather than using these functions directly. */
#ifdef __cplusplus
extern "C" {
#endif
void AnnotateRWLockCreate(const char *file, int line,
const volatile void *lock);
void AnnotateRWLockDestroy(const char *file, int line,
const volatile void *lock);
void AnnotateRWLockAcquired(const char *file, int line,
const volatile void *lock, long is_w);
void AnnotateRWLockReleased(const char *file, int line,
const volatile void *lock, long is_w);
void AnnotateBarrierInit(const char *file, int line,
const volatile void *barrier, long count,
long reinitialization_allowed);
void AnnotateBarrierWaitBefore(const char *file, int line,
const volatile void *barrier);
void AnnotateBarrierWaitAfter(const char *file, int line,
const volatile void *barrier);
void AnnotateBarrierDestroy(const char *file, int line,
const volatile void *barrier);
void AnnotateCondVarWait(const char *file, int line,
const volatile void *cv,
const volatile void *lock);
void AnnotateCondVarSignal(const char *file, int line,
const volatile void *cv);
void AnnotateCondVarSignalAll(const char *file, int line,
const volatile void *cv);
void AnnotatePublishMemoryRange(const char *file, int line,
const volatile void *address,
long size);
void AnnotateUnpublishMemoryRange(const char *file, int line,
const volatile void *address,
long size);
void AnnotatePCQCreate(const char *file, int line,
const volatile void *pcq);
void AnnotatePCQDestroy(const char *file, int line,
const volatile void *pcq);
void AnnotatePCQPut(const char *file, int line,
const volatile void *pcq);
void AnnotatePCQGet(const char *file, int line,
const volatile void *pcq);
void AnnotateNewMemory(const char *file, int line,
const volatile void *address,
long size);
void AnnotateExpectRace(const char *file, int line,
const volatile void *address,
const char *description);
void AnnotateBenignRace(const char *file, int line,
const volatile void *address,
const char *description);
void AnnotateBenignRaceSized(const char *file, int line,
const volatile void *address,
long size,
const char *description);
void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
const volatile void *mu);
void AnnotateTraceMemory(const char *file, int line,
const volatile void *arg);
void AnnotateThreadName(const char *file, int line,
const char *name);
void AnnotateIgnoreReadsBegin(const char *file, int line);
void AnnotateIgnoreReadsEnd(const char *file, int line);
void AnnotateIgnoreWritesBegin(const char *file, int line);
void AnnotateIgnoreWritesEnd(const char *file, int line);
void AnnotateEnableRaceDetection(const char *file, int line, int enable);
void AnnotateNoOp(const char *file, int line,
const volatile void *arg);
void AnnotateFlushState(const char *file, int line);
/* Return non-zero value if running under valgrind.
If "valgrind.h" is included into dynamic_annotations.c,
the regular valgrind mechanism will be used.
See http://valgrind.org/docs/manual/manual-core-adv.html about
RUNNING_ON_VALGRIND and other valgrind "client requests".
The file "valgrind.h" may be obtained by doing
svn co svn://svn.valgrind.org/valgrind/trunk/include
If for some reason you can't use "valgrind.h" or want to fake valgrind,
there are two ways to make this function return non-zero:
- Use environment variable: export RUNNING_ON_VALGRIND=1
- Make your tool intercept the function RunningOnValgrind() and
change its return value.
*/
int RunningOnValgrind(void);
#ifdef __cplusplus
}
#endif
#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
/* _Py_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
Instead of doing
_Py_ANNOTATE_IGNORE_READS_BEGIN();
... = x;
_Py_ANNOTATE_IGNORE_READS_END();
one can use
... = _Py_ANNOTATE_UNPROTECTED_READ(x); */
template <class T>
inline T _Py_ANNOTATE_UNPROTECTED_READ(const volatile T &x) {
_Py_ANNOTATE_IGNORE_READS_BEGIN();
T res = x;
_Py_ANNOTATE_IGNORE_READS_END();
return res;
}
/* Apply _Py_ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
namespace { \
class static_var ## _annotator { \
public: \
static_var ## _annotator() { \
_Py_ANNOTATE_BENIGN_RACE_SIZED(&static_var, \
sizeof(static_var), \
# static_var ": " description); \
} \
}; \
static static_var ## _annotator the ## static_var ## _annotator;\
}
#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
#define _Py_ANNOTATE_UNPROTECTED_READ(x) (x)
#define _Py_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */
#endif /* DYNAMIC_ANNOTATIONS_ENABLED */
#endif /* __DYNAMIC_ANNOTATIONS_H__ */

View File

@@ -1,34 +1,43 @@
// 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.
//
// The public PyRun_InteractiveOneObjectEx() function can return E_EOF,
// same as its variants:
//
// * PyRun_InteractiveOneObject()
// * PyRun_InteractiveOneFlags()
// * PyRun_InteractiveOne()
#ifndef Py_ERRCODE_H #ifndef Py_ERRCODE_H
#define Py_ERRCODE_H #define Py_ERRCODE_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define E_OK 10 /* No error */
/* Error codes passed around between file input, tokenizer, parser and #define E_EOF 11 /* End Of File */
interpreter. This is necessary so we can turn them into Python #define E_INTR 12 /* Interrupted */
exceptions at a higher level. Note that some errors have a #define E_TOKEN 13 /* Bad token */
slightly different meaning when passed from the tokenizer to the #define E_SYNTAX 14 /* Syntax error */
parser than when passed from the parser to the interpreter; e.g. #define E_NOMEM 15 /* Ran out of memory */
the parser only returns E_EOF when it hits EOF immediately, and it #define E_DONE 16 /* Parsing complete */
never returns E_OK. */ #define E_ERROR 17 /* Execution error */
#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */
#define E_OK 10 /* No error */ #define E_OVERFLOW 19 /* Node had too many children */
#define E_EOF 11 /* End Of File */ #define E_TOODEEP 20 /* Too many indentation levels */
#define E_INTR 12 /* Interrupted */ #define E_DEDENT 21 /* No matching outer block for dedent */
#define E_TOKEN 13 /* Bad token */ #define E_DECODE 22 /* Error in decoding into Unicode */
#define E_SYNTAX 14 /* Syntax error */ #define E_EOFS 23 /* EOF in triple-quoted string */
#define E_NOMEM 15 /* Ran out of memory */ #define E_EOLS 24 /* EOL in single-quoted string */
#define E_DONE 16 /* Parsing complete */ #define E_LINECONT 25 /* Unexpected characters after a line continuation */
#define E_ERROR 17 /* Execution error */ #define E_BADSINGLE 27 /* Ill-formed single statement input */
#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ #define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */
#define E_OVERFLOW 19 /* Node had too many children */ #define E_COLUMNOVERFLOW 29 /* Column offset overflow */
#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 */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,25 +0,0 @@
/* Interface to execute compiled code */
#ifndef Py_EVAL_H
#define Py_EVAL_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co,
PyObject *globals,
PyObject *locals,
PyObject **args, int argc,
PyObject **kwds, int kwdc,
PyObject **defs, int defc,
PyObject *closure);
PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args);
#ifdef __cplusplus
}
#endif
#endif /* !Py_EVAL_H */

105
extern/include/python/exports.h vendored Normal file
View File

@@ -0,0 +1,105 @@
#ifndef Py_EXPORTS_H
#define Py_EXPORTS_H
/* Declarations for symbol visibility.
PyAPI_FUNC(type): Declares a public Python API function and return type
PyAPI_DATA(type): Declares public Python data and its type
PyMODINIT_FUNC: A Python module init function. If these functions are
inside the Python core, they are private to the core.
If in an extension module, it may be declared with
external linkage depending on the platform.
As a number of platforms support/require "__declspec(dllimport/dllexport)",
we support a HAVE_DECLSPEC_DLL macro to save duplication.
*/
/*
All windows ports, except cygwin, are handled in PC/pyconfig.h.
Cygwin is the only other autoconf platform requiring special
linkage handling and it uses __declspec().
*/
#if defined(__CYGWIN__)
# define HAVE_DECLSPEC_DLL
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(Py_ENABLE_SHARED)
#define Py_IMPORTED_SYMBOL __declspec(dllimport)
#define Py_EXPORTED_SYMBOL __declspec(dllexport)
#define Py_LOCAL_SYMBOL
#else
#define Py_IMPORTED_SYMBOL
#define Py_EXPORTED_SYMBOL
#define Py_LOCAL_SYMBOL
#endif
#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.
*/
#if (defined(__GNUC__) && (__GNUC__ >= 4)) ||\
(defined(__clang__) && _Py__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
/* only get special linkage if built as shared or platform is Cygwin */
#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
# if defined(HAVE_DECLSPEC_DLL)
# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
/* module init functions inside the core need no external linkage */
/* except for Cygwin to handle embedding */
# if defined(__CYGWIN__)
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
# else /* __CYGWIN__ */
# define PyMODINIT_FUNC PyObject*
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
/* Building an extension module, or an embedded situation */
/* public Python functions and data are imported */
/* Under Cygwin, auto-import functions to prevent compilation */
/* failures similar to those described at the bottom of 4.1: */
/* http://docs.python.org/extending/windows.html#a-cookbook-approach */
# if !defined(__CYGWIN__)
# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
/* module init functions outside the core must be exported */
# if defined(__cplusplus)
# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
# else /* __cplusplus */
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
# endif /* __cplusplus */
# endif /* Py_BUILD_CORE */
# endif /* HAVE_DECLSPEC_DLL */
#endif /* Py_ENABLE_SHARED */
/* If no external linkage macros defined by now, create defaults */
#ifndef PyAPI_FUNC
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
#endif
#ifndef PyAPI_DATA
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
#endif
#ifndef PyMODINIT_FUNC
# if defined(__cplusplus)
# define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
# else /* __cplusplus */
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
# endif /* __cplusplus */
#endif
#endif /* Py_EXPORTS_H */

View File

@@ -1,5 +1,4 @@
/* File object interface (what's left of it -- see io.py) */
/* File object interface */
#ifndef Py_FILEOBJECT_H #ifndef Py_FILEOBJECT_H
#define Py_FILEOBJECT_H #define Py_FILEOBJECT_H
@@ -7,89 +6,34 @@
extern "C" { extern "C" {
#endif #endif
typedef struct { #define PY_STDIOTEXTMODE "b"
PyObject_HEAD
FILE *f_fp;
PyObject *f_name;
PyObject *f_mode;
int (*f_close)(FILE *);
int f_softspace; /* Flag used by 'print' command */
int f_binary; /* Flag which indicates whether the file is
open in binary (1) or text (0) mode */
char* f_buf; /* Allocated readahead buffer */
char* f_bufend; /* Points after last occupied position */
char* f_bufptr; /* Current buffer position */
char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */
int f_univ_newline; /* Handle any newline convention */
int f_newlinetypes; /* Types of newlines seen */
int f_skipnextlf; /* Skip next \n */
PyObject *f_encoding;
PyObject *f_errors;
PyObject *weakreflist; /* List of weak references */
int unlocked_count; /* Num. currently running sections of code
using f_fp with the GIL released. */
int readable;
int writable;
} PyFileObject;
PyAPI_DATA(PyTypeObject) PyFile_Type; PyAPI_FUNC(PyObject *) PyFile_FromFd(int, const char *, const char *, int,
const char *, const char *,
#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type) const char *, int);
#define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type)
PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);
PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);
PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *);
PyAPI_FUNC(int) PyFile_SetEncodingAndErrors(PyObject *, const char *, char *errors);
PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *,
int (*)(FILE *));
PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *);
PyAPI_FUNC(void) PyFile_IncUseCount(PyFileObject *);
PyAPI_FUNC(void) PyFile_DecUseCount(PyFileObject *);
PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *);
PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int);
PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
/* The default encoding used by the platform file system APIs /* The default encoding used by the platform file system APIs
If non-NULL, this is different than the default encoding for strings If non-NULL, this is different than the default encoding for strings
*/ */
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors;
#endif
Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
/* Routines to replace fread() and fgets() which accept any of \r, \n #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
or \r\n as line terminators. Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UTF8Mode;
*/
#define PY_STDIOTEXTMODE "b"
char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
/* A routine to do sanity checking on the file mode string. returns
non-zero on if an exception occurred
*/
int _PyFile_SanitizeMode(char *mode);
#if defined _MSC_VER && _MSC_VER >= 1400
/* A routine to check if a file descriptor is valid on Windows. Returns 0
* and sets errno to EBADF if it isn't. This is to avoid Assertions
* from various functions in the Windows CRT beginning with
* Visual Studio 2005
*/
int _PyVerify_fd(int fd);
#elif defined _MSC_VER && _MSC_VER >= 1200
/* fdopen doesn't set errno EBADF and crashes for large fd on debug build */
#define _PyVerify_fd(fd) (_get_osfhandle(fd) >= 0)
#else
#define _PyVerify_fd(A) (1) /* dummy */
#endif #endif
/* A routine to check if a file descriptor can be select()-ed. */ #ifndef Py_LIMITED_API
#ifdef HAVE_SELECT # define Py_CPYTHON_FILEOBJECT_H
#define _PyIsSelectable_fd(FD) (((FD) >= 0) && ((FD) < FD_SETSIZE)) # include "cpython/fileobject.h"
#else # undef Py_CPYTHON_FILEOBJECT_H
#define _PyIsSelectable_fd(FD) (1) #endif
#endif /* HAVE_SELECT */
#ifdef __cplusplus #ifdef __cplusplus
} }

62
extern/include/python/fileutils.h vendored Normal file
View File

@@ -0,0 +1,62 @@
#ifndef Py_FILEUTILS_H
#define Py_FILEUTILS_H
/*******************************
* stat() and fstat() fiddling *
*******************************/
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h> // S_ISREG()
#elif defined(HAVE_STAT_H)
# include <stat.h> // S_ISREG()
#endif
#ifndef S_IFMT
// VisualAge C/C++ Failed to Define MountType Field in sys/stat.h.
# define S_IFMT 0170000
#endif
#ifndef S_IFLNK
// Windows doesn't define S_IFLNK, but posixmodule.c maps
// IO_REPARSE_TAG_SYMLINK to S_IFLNK.
# define S_IFLNK 0120000
#endif
#ifndef S_ISREG
# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISCHR
# define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR)
#endif
#ifndef S_ISLNK
# define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
#endif
// Move this down here since some C++ #include's don't like to be included
// inside an extern "C".
#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 */

View File

@@ -2,7 +2,7 @@
/* Float object interface */ /* Float object interface */
/* /*
PyFloatObject represents a (double precision) floating point number. PyFloatObject represents a (double precision) floating-point number.
*/ */
#ifndef Py_FLOATOBJECT_H #ifndef Py_FLOATOBJECT_H
@@ -11,128 +11,42 @@ PyFloatObject represents a (double precision) floating point number.
extern "C" { extern "C" {
#endif #endif
typedef struct {
PyObject_HEAD
double ob_fval;
} PyFloatObject;
PyAPI_DATA(PyTypeObject) PyFloat_Type; PyAPI_DATA(PyTypeObject) PyFloat_Type;
#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) #define PyFloat_CheckExact(op) Py_IS_TYPE((op), &PyFloat_Type)
/* The str() precision PyFloat_STR_PRECISION is chosen so that in most cases,
the rounding noise created by various operations is suppressed, while
giving plenty of precision for practical use. */
#define PyFloat_STR_PRECISION 12
#ifdef Py_NAN
#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) #define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN)
#endif
#define Py_RETURN_INF(sign) do \ #define Py_RETURN_INF(sign) \
if (copysign(1., sign) == 1.) { \ do { \
return PyFloat_FromDouble(Py_HUGE_VAL); \ if (copysign(1., sign) == 1.) { \
} else { \ return PyFloat_FromDouble(Py_INFINITY); \
return PyFloat_FromDouble(-Py_HUGE_VAL); \ } \
} while(0) else { \
return PyFloat_FromDouble(-Py_INFINITY); \
} \
} while(0)
PyAPI_FUNC(double) PyFloat_GetMax(void); PyAPI_FUNC(double) PyFloat_GetMax(void);
PyAPI_FUNC(double) PyFloat_GetMin(void); PyAPI_FUNC(double) PyFloat_GetMin(void);
PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void); PyAPI_FUNC(PyObject*) PyFloat_GetInfo(void);
/* Return Python float from string PyObject. Second argument ignored on /* Return Python float from string PyObject. */
input, and, if non-NULL, NULL is stored into *junk (this tried to serve a PyAPI_FUNC(PyObject*) PyFloat_FromString(PyObject*);
purpose once but can't be made to work as intended). */
PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*, char** junk);
/* Return Python float from C double. */ /* Return Python float from C double. */
PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double); PyAPI_FUNC(PyObject*) PyFloat_FromDouble(double);
/* Extract C double from Python float. The macro version trades safety for /* Extract C double from Python float. The macro version trades safety for
speed. */ speed. */
PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); PyAPI_FUNC(double) PyFloat_AsDouble(PyObject*);
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
/* Write repr(v) into the char buffer argument, followed by null byte. The
buffer must be "big enough"; >= 100 is very safe.
PyFloat_AsReprString(buf, x) strives to print enough digits so that
PyFloat_FromString(buf) then reproduces x exactly. */
PyAPI_FUNC(void) PyFloat_AsReprString(char*, PyFloatObject *v);
/* Write str(v) into the char buffer argument, followed by null byte. The
buffer must be "big enough"; >= 100 is very safe. Note that it's
unusual to be able to get back the float you started with from
PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to
preserve precision across conversions. */
PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v);
/* _PyFloat_{Pack,Unpack}{4,8}
*
* The struct and pickle (at least) modules need an efficient platform-
* independent way to store floating-point values as byte strings.
* The Pack routines produce a string from a C double, and the Unpack
* routines produce a C double from such a string. The suffix (4 or 8)
* specifies the number of bytes in the string.
*
* On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats
* these functions work by copying bits. On other platforms, the formats the
* 4- byte format is identical to the IEEE-754 single precision format, and
* the 8-byte format to the IEEE-754 double precision format, although the
* packing of INFs and NaNs (if such things exist on the platform) isn't
* handled correctly, and attempting to unpack a string containing an IEEE
* INF or NaN will raise an exception.
*
* On non-IEEE platforms with more precision, or larger dynamic range, than
* 754 supports, not all values can be packed; on non-IEEE platforms with less
* precision, or smaller dynamic range, not all values can be unpacked. What
* happens in such cases is partly accidental (alas).
*/
/* The pack routines write 4 or 8 bytes, starting at p. le is a bool
* argument, true if you want the string in little-endian format (exponent
* last, at p+3 or p+7), false if you want big-endian format (exponent
* first, at p).
* Return value: 0 if all is OK, -1 if error (and an exception is
* set, most likely OverflowError).
* There are two problems on non-IEEE platforms:
* 1): What this does is undefined if x is a NaN or infinity.
* 2): -0.0 and +0.0 produce the same string.
*/
PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le);
PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
/* Used to get the important decimal digits of a double */
PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum);
PyAPI_FUNC(void) _PyFloat_DigitsInit(void);
/* The unpack routines read 4 or 8 bytes, starting at p. le is a bool
* argument, true if the string is in little-endian format (exponent
* last, at p+3 or p+7), false if big-endian (exponent first, at p).
* Return value: The unpacked double. On error, this is -1.0 and
* PyErr_Occurred() is true (and an exception is set, most likely
* OverflowError). Note that on a non-IEEE platform this will refuse
* to unpack a string that represents a NaN or infinity.
*/
PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le);
PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
/* free list api */
PyAPI_FUNC(int) PyFloat_ClearFreeList(void);
/* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */
PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj,
char *format_spec,
Py_ssize_t format_spec_len);
/* Round a C double x to the closest multiple of 10**-ndigits. Returns a
Python float on success, or NULL (with an appropriate exception set) on
failure. Used in builtin_round in bltinmodule.c. */
PyAPI_FUNC(PyObject *) _Py_double_round(double x, int ndigits);
#ifndef Py_LIMITED_API
# define Py_CPYTHON_FLOATOBJECT_H
# include "cpython/floatobject.h"
# undef Py_CPYTHON_FLOATOBJECT_H
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,4 +1,3 @@
/* Frame object interface */ /* Frame object interface */
#ifndef Py_FRAMEOBJECT_H #ifndef Py_FRAMEOBJECT_H
@@ -7,81 +6,13 @@
extern "C" { extern "C" {
#endif #endif
typedef struct { #include "pyframe.h"
int b_type; /* what kind of block this is */
int b_handler; /* where to jump to find handler */
int b_level; /* value stack level to pop to */
} PyTryBlock;
typedef struct _frame { #ifndef Py_LIMITED_API
PyObject_VAR_HEAD # define Py_CPYTHON_FRAMEOBJECT_H
struct _frame *f_back; /* previous frame, or NULL */ # include "cpython/frameobject.h"
PyCodeObject *f_code; /* code segment */ # undef Py_CPYTHON_FRAMEOBJECT_H
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ #endif
PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (any mapping) */
PyObject **f_valuestack; /* points after the last local */
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
Frame evaluation usually NULLs it, but a frame that yields sets it
to the current stack top. */
PyObject **f_stacktop;
PyObject *f_trace; /* Trace function */
/* If an exception is raised in this frame, the next three are used to
* record the exception info (if any) originally in the thread state. See
* comments before set_exc_info() -- it's not obvious.
* Invariant: if _type is NULL, then so are _value and _traceback.
* Desired invariant: all three are NULL, or all three are non-NULL. That
* one isn't currently true, but "should be".
*/
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
PyThreadState *f_tstate;
int f_lasti; /* Last instruction if called */
/* Call PyFrame_GetLineNumber() instead of reading this field
directly. As of 2.3 f_lineno is only valid when tracing is
active (i.e. when f_trace is set). At other times we use
PyCode_Addr2Line to calculate the line from the current
bytecode index. */
int f_lineno; /* Current line number */
int f_iblock; /* index in f_blockstack */
PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
} PyFrameObject;
/* Standard object interface */
PyAPI_DATA(PyTypeObject) PyFrame_Type;
#define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type)
#define PyFrame_IsRestricted(f) \
((f)->f_builtins != (f)->f_tstate->interp->builtins)
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
PyObject *, PyObject *);
/* The rest of the interface is specific for frame objects */
/* Block management functions */
PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int);
PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *);
/* Extend the value stack */
PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int);
/* Conversions between "fast locals" and locals in dictionary */
PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
/* Return the line of code the frame is currently executing. */
PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *);
#ifdef __cplusplus #ifdef __cplusplus
} }

Some files were not shown because too many files have changed in this diff Show More