Mercurial > vim
comparison src/if_python3.c @ 33452:ed8db57d1034 v9.0.1980
patch 9.0.1980: win32: issues with stable python ABI
Commit: https://github.com/vim/vim/commit/119fdd9293f63614ed2ca60a78993466435db639
Author: Ken Takata <kentkt@csc.jp>
Date: Wed Oct 4 20:05:05 2023 +0200
patch 9.0.1980: win32: issues with stable python ABI
Problem: win32: issues with stable python ABI
Solution: if_python3,win32: Fix Python3 stable ABI
There were some issues in current stable ABI implementation on Windows:
* Python DLL name should be `python3.dll` instead of `python311.dll` and
so on. (See: https://docs.python.org/3/c-api/stable.html)
* Some non-stable API functions were used:
- `_PyObject_NextNotImplemented`
- `PyStdPrinter_Type`
* `reset_stdin()` and `hook_py_exit()` didn't work with `python3.dll`.
`python3.dll` is a special type of DLL called forwarder DLL.
It just forwards the functions to other DLL (e.g. `python311.dll`).
There were two issues regarding these functions:
- `python3.dll` doesn't have import tables. This caused a crash in
`get_imported_func_info()`. Add a check whether the specified DLL
has an import table.
- `reset_stdin()` and `hook_py_exit()` should be applied to the
forwarded DLL (e.g. `python311.dll`), not to `python3.dll`.
Check the export directory of `python3.dll` to find the forwarded
DLL and apply the functions to it.
closes: #13260
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Ken Takata <kentkt@csc.jp>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 04 Oct 2023 20:15:03 +0200 |
parents | 9b35b4c6df4c |
children | e6c00b4c3ee5 |
comparison
equal
deleted
inserted
replaced
33451:843d48139b56 | 33452:ed8db57d1034 |
---|---|
240 # define PySys_SetArgv py3_PySys_SetArgv | 240 # define PySys_SetArgv py3_PySys_SetArgv |
241 # define PyType_Ready py3_PyType_Ready | 241 # define PyType_Ready py3_PyType_Ready |
242 # if PY_VERSION_HEX >= 0x03040000 | 242 # if PY_VERSION_HEX >= 0x03040000 |
243 # define PyType_GetFlags py3_PyType_GetFlags | 243 # define PyType_GetFlags py3_PyType_GetFlags |
244 # endif | 244 # endif |
245 #undef Py_BuildValue | 245 # undef Py_BuildValue |
246 # define Py_BuildValue py3_Py_BuildValue | 246 # define Py_BuildValue py3_Py_BuildValue |
247 # define Py_SetPythonHome py3_Py_SetPythonHome | 247 # define Py_SetPythonHome py3_Py_SetPythonHome |
248 # define Py_Initialize py3_Py_Initialize | 248 # define Py_Initialize py3_Py_Initialize |
249 # define Py_Finalize py3_Py_Finalize | 249 # define Py_Finalize py3_Py_Finalize |
250 # define Py_IsInitialized py3_Py_IsInitialized | 250 # define Py_IsInitialized py3_Py_IsInitialized |
251 # define _Py_NoneStruct (*py3__Py_NoneStruct) | 251 # define _Py_NoneStruct (*py3__Py_NoneStruct) |
252 # define _Py_FalseStruct (*py3__Py_FalseStruct) | 252 # define _Py_FalseStruct (*py3__Py_FalseStruct) |
253 # define _Py_TrueStruct (*py3__Py_TrueStruct) | 253 # define _Py_TrueStruct (*py3__Py_TrueStruct) |
254 # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented) | 254 # ifndef USE_LIMITED_API |
255 # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented) | |
256 # endif | |
255 # define PyModule_AddObject py3_PyModule_AddObject | 257 # define PyModule_AddObject py3_PyModule_AddObject |
256 # define PyImport_AppendInittab py3_PyImport_AppendInittab | 258 # define PyImport_AppendInittab py3_PyImport_AppendInittab |
257 # define PyImport_AddModule py3_PyImport_AddModule | 259 # define PyImport_AddModule py3_PyImport_AddModule |
258 # ifdef USE_LIMITED_API | 260 # ifdef USE_LIMITED_API |
259 # if Py_LIMITED_API >= 0x030a0000 | 261 # if Py_LIMITED_API >= 0x030a0000 |
286 # endif | 288 # endif |
287 # define PyFloat_FromDouble py3_PyFloat_FromDouble | 289 # define PyFloat_FromDouble py3_PyFloat_FromDouble |
288 # define PyFloat_AsDouble py3_PyFloat_AsDouble | 290 # define PyFloat_AsDouble py3_PyFloat_AsDouble |
289 # define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr | 291 # define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr |
290 # define PyType_Type (*py3_PyType_Type) | 292 # define PyType_Type (*py3_PyType_Type) |
291 # define PyStdPrinter_Type (*py3_PyStdPrinter_Type) | 293 # ifndef USE_LIMITED_API |
294 # define PyStdPrinter_Type (*py3_PyStdPrinter_Type) | |
295 # endif | |
292 # define PySlice_Type (*py3_PySlice_Type) | 296 # define PySlice_Type (*py3_PySlice_Type) |
293 # define PyFloat_Type (*py3_PyFloat_Type) | 297 # define PyFloat_Type (*py3_PyFloat_Type) |
294 # define PyNumber_Check (*py3_PyNumber_Check) | 298 # define PyNumber_Check (*py3_PyNumber_Check) |
295 # define PyNumber_Long (*py3_PyNumber_Long) | 299 # define PyNumber_Long (*py3_PyNumber_Long) |
296 # define PyErr_NewException py3_PyErr_NewException | 300 # define PyErr_NewException py3_PyErr_NewException |
447 static int (*py3_Py_IsInitialized)(void); | 451 static int (*py3_Py_IsInitialized)(void); |
448 static void (*py3_PyErr_Clear)(void); | 452 static void (*py3_PyErr_Clear)(void); |
449 static PyObject* (*py3_PyErr_Format)(PyObject *, const char *, ...); | 453 static PyObject* (*py3_PyErr_Format)(PyObject *, const char *, ...); |
450 static void (*py3_PyErr_PrintEx)(int); | 454 static void (*py3_PyErr_PrintEx)(int); |
451 static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *); | 455 static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *); |
456 # ifndef USE_LIMITED_API | |
452 static iternextfunc py3__PyObject_NextNotImplemented; | 457 static iternextfunc py3__PyObject_NextNotImplemented; |
458 # endif | |
453 static PyObject* py3__Py_NoneStruct; | 459 static PyObject* py3__Py_NoneStruct; |
454 static PyObject* py3__Py_FalseStruct; | 460 static PyObject* py3__Py_FalseStruct; |
455 static PyObject* py3__Py_TrueStruct; | 461 static PyObject* py3__Py_TrueStruct; |
456 static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o); | 462 static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o); |
457 static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void)); | 463 static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void)); |
483 static double (*py3_PyFloat_AsDouble)(PyObject *); | 489 static double (*py3_PyFloat_AsDouble)(PyObject *); |
484 static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name); | 490 static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name); |
485 static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems); | 491 static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems); |
486 static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds); | 492 static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds); |
487 static PyTypeObject* py3_PyType_Type; | 493 static PyTypeObject* py3_PyType_Type; |
494 # ifndef USE_LIMITED_API | |
488 static PyTypeObject* py3_PyStdPrinter_Type; | 495 static PyTypeObject* py3_PyStdPrinter_Type; |
496 # endif | |
489 static PyTypeObject* py3_PySlice_Type; | 497 static PyTypeObject* py3_PySlice_Type; |
490 static PyTypeObject* py3_PyFloat_Type; | 498 static PyTypeObject* py3_PyFloat_Type; |
491 PyTypeObject* py3_PyBool_Type; | 499 PyTypeObject* py3_PyBool_Type; |
492 # if PY_VERSION_HEX >= 0x030c00b0 | 500 # if PY_VERSION_HEX >= 0x030c00b0 |
493 PyTypeObject* py3_PyLong_Type; | 501 PyTypeObject* py3_PyLong_Type; |
631 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads}, | 639 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads}, |
632 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread}, | 640 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread}, |
633 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread}, | 641 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread}, |
634 {"_PyArg_Parse_SizeT", (PYTHON_PROC*)&py3_PyArg_Parse}, | 642 {"_PyArg_Parse_SizeT", (PYTHON_PROC*)&py3_PyArg_Parse}, |
635 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized}, | 643 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized}, |
644 # ifndef USE_LIMITED_API | |
636 {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented}, | 645 {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented}, |
646 # endif | |
637 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct}, | 647 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct}, |
638 {"_Py_FalseStruct", (PYTHON_PROC*)&py3__Py_FalseStruct}, | 648 {"_Py_FalseStruct", (PYTHON_PROC*)&py3__Py_FalseStruct}, |
639 {"_Py_TrueStruct", (PYTHON_PROC*)&py3__Py_TrueStruct}, | 649 {"_Py_TrueStruct", (PYTHON_PROC*)&py3__Py_TrueStruct}, |
640 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear}, | 650 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear}, |
641 {"PyErr_Format", (PYTHON_PROC*)&py3_PyErr_Format}, | 651 {"PyErr_Format", (PYTHON_PROC*)&py3_PyErr_Format}, |
679 {"PyFloat_AsDouble", (PYTHON_PROC*)&py3_PyFloat_AsDouble}, | 689 {"PyFloat_AsDouble", (PYTHON_PROC*)&py3_PyFloat_AsDouble}, |
680 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr}, | 690 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr}, |
681 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc}, | 691 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc}, |
682 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew}, | 692 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew}, |
683 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type}, | 693 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type}, |
694 # ifndef USE_LIMITED_API | |
684 {"PyStdPrinter_Type", (PYTHON_PROC*)&py3_PyStdPrinter_Type}, | 695 {"PyStdPrinter_Type", (PYTHON_PROC*)&py3_PyStdPrinter_Type}, |
696 # endif | |
685 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type}, | 697 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type}, |
686 {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type}, | 698 {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type}, |
687 # if PY_VERSION_HEX < 0x030c00b0 | 699 # if PY_VERSION_HEX < 0x030c00b0 |
688 {"PyBool_Type", (PYTHON_PROC*)&py3_PyBool_Type}, | 700 {"PyBool_Type", (PYTHON_PROC*)&py3_PyBool_Type}, |
689 # endif | 701 # endif |
1165 static void | 1177 static void |
1166 reset_stdin(void) | 1178 reset_stdin(void) |
1167 { | 1179 { |
1168 FILE *(*py__acrt_iob_func)(unsigned) = NULL; | 1180 FILE *(*py__acrt_iob_func)(unsigned) = NULL; |
1169 FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL; | 1181 FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL; |
1170 HINSTANCE hinst = hinstPy3; | 1182 HINSTANCE hinst = get_forwarded_dll(hinstPy3); |
1171 | 1183 |
1172 if (hinst == NULL || is_stdin_readable()) | 1184 if (hinst == NULL || is_stdin_readable()) |
1173 return; | 1185 return; |
1174 | 1186 |
1175 // Get "freopen" and "stdin" which are used in the python DLL. | 1187 // Get "freopen" and "stdin" which are used in the python DLL. |
1217 * Install a hook to python dll's exit(). | 1229 * Install a hook to python dll's exit(). |
1218 */ | 1230 */ |
1219 static void | 1231 static void |
1220 hook_py_exit(void) | 1232 hook_py_exit(void) |
1221 { | 1233 { |
1222 HINSTANCE hinst = hinstPy3; | 1234 HINSTANCE hinst = get_forwarded_dll(hinstPy3); |
1223 | 1235 |
1224 if (hinst == NULL || orig_exit != NULL) | 1236 if (hinst == NULL || orig_exit != NULL) |
1225 return; | 1237 return; |
1226 | 1238 |
1227 orig_exit = hook_dll_import_func(hinst, "exit", (void *)hooked_exit); | 1239 orig_exit = hook_dll_import_func(hinst, "exit", (void *)hooked_exit); |