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);