From 110b86383fab96614e159391063d3781fc18caf2 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Fri, 29 Mar 2019 18:15:59 -0700 Subject: [PATCH 1/3] rebase PR on libffi PR only use optimizer workaround on old compilers enable ctypes for ARM in configuration manager --- Include/pyport.h | 2 +- Include/pythonrun.h | 2 +- Modules/_ctypes/callbacks.c | 2 +- Modules/_ctypes/callproc.c | 11 ++++++++--- Modules/_ctypes/malloc_closure.c | 5 +++++ PC/layout/main.py | 16 ++-------------- PCbuild/pcbuild.sln | 2 ++ PCbuild/prepare_libffi.bat | 15 +++++++++++++-- Python/ceval.c | 9 +++++++++ 9 files changed, 42 insertions(+), 22 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 4971a493ccee22..d94e03f1efa453 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -406,7 +406,7 @@ extern "C" { #endif /* get and set x87 control word for VisualStudio/x86 */ -#if defined(_MSC_VER) && defined(_M_IX86) /* x87 only supported in x86 */ +#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) /* x87 not supported in 64-bit or ARM */ #define HAVE_PY_SET_53BIT_PRECISION 1 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned int old_387controlword, new_387controlword, out_387controlword diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 6f0c6fc6554379..e83846add981cd 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -165,7 +165,7 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; to an 8k margin. */ #define PYOS_STACK_MARGIN 2048 -#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300 +#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 /* Enable stack checking under Microsoft C */ #define USE_STACKCHECK #endif diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 2b7cb06ea8a95b..9f793c2771bfb9 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -380,7 +380,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) +#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) && !defined(_M_ARM) if ((flags & FUNCFLAG_CDECL) == 0) cc = FFI_STDCALL; #endif diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 5a943d3c37081e..1ad842eb3d4098 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -737,12 +737,17 @@ of 1, 2, 4, 8, 16, 32, or 64 bits */ int can_return_struct_as_int(size_t s) { - return s == 1 || s == 2 || s == 4; + return s == 1 || s == 2 || s == 4; } int can_return_struct_as_sint64(size_t s) { - return s == 8; +#ifdef _M_ARM + // 8 byte structs cannot be returned in a register on ARM32 + return 0; +#else + return s == 8; +#endif } #endif @@ -807,7 +812,7 @@ static int _call_function_pointer(int flags, } cc = FFI_DEFAULT_ABI; -#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) +#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) && !defined(_M_ARM) if ((flags & FUNCFLAG_CDECL) == 0) cc = FFI_STDCALL; #endif diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 8ad76497c7b3f2..f9cdb336958c6f 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -106,6 +106,11 @@ void *ffi_closure_alloc(size_t ignored, void** codeloc) return NULL; item = free_list; free_list = item->next; +#ifdef _M_ARM + // set Thumb bit so that blx is called correctly + *codeloc = (ITEM*)((uintptr_t)item | 1); +#else *codeloc = (void *)item; +#endif return (void *)item; } diff --git a/PC/layout/main.py b/PC/layout/main.py index 624033e721b73a..185e6498e1bc38 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -66,18 +66,6 @@ TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") -def copy_if_modified(src, dest): - try: - dest_stat = os.stat(dest) - except FileNotFoundError: - do_copy = True - else: - src_stat = os.stat(src) - do_copy = (src_stat.st_mtime != dest_stat.st_mtime or - src_stat.st_size != dest_stat.st_size) - - if do_copy: - shutil.copy2(src, dest) def get_lib_layout(ns): def _c(f): @@ -438,7 +426,7 @@ def copy_files(files, ns): need_compile.append((dest, ns.copy / dest)) else: (ns.temp / "Lib" / dest).parent.mkdir(parents=True, exist_ok=True) - copy_if_modified(src, ns.temp / "Lib" / dest) + shutil.copy2(src, ns.temp / "Lib" / dest) need_compile.append((dest, ns.temp / "Lib" / dest)) if src not in EXCLUDE_FROM_CATALOG: @@ -448,7 +436,7 @@ def copy_files(files, ns): log_debug("Copy {} -> {}", src, ns.copy / dest) (ns.copy / dest).parent.mkdir(parents=True, exist_ok=True) try: - copy_if_modified(src, ns.copy / dest) + shutil.copy2(src, ns.copy / dest) except shutil.SameFileError: pass diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 1bbfd180df14a0..e9239365b5c1af 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -238,6 +238,7 @@ Global {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.ActiveCfg = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.Build.0 = Debug|ARM {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 @@ -255,6 +256,7 @@ Global {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.ActiveCfg = Release|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.Build.0 = Release|ARM {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 diff --git a/PCbuild/prepare_libffi.bat b/PCbuild/prepare_libffi.bat index 3df85130f48adb..307739d874a213 100644 --- a/PCbuild/prepare_libffi.bat +++ b/PCbuild/prepare_libffi.bat @@ -24,6 +24,7 @@ echo. echo.Available flags: echo. -x64 build for x64 echo. -x86 build for x86 +echo. -arm32 build for arm32 echo. -? this help echo. --install-cygwin install cygwin to c:\cygwin exit /b 127 @@ -32,12 +33,14 @@ exit /b 127 set BUILD_X64= set BUILD_X86= +set BUILD_ARM32= set INSTALL_CYGWIN= :CheckOpts if "%1"=="" goto :CheckOptsDone if /I "%1"=="-x64" (set BUILD_X64=1) & shift & goto :CheckOpts if /I "%1"=="-x86" (set BUILD_X86=1) & shift & goto :CheckOpts +if /I "%1"=="-arm32" (set BUILD_ARM32=1) & shift & goto :CheckOpts if /I "%1"=="-?" goto :Usage if /I "%1"=="--install-cygwin" (set INSTALL_CYGWIN=1) & shift & goto :CheckOpts goto :Usage @@ -47,6 +50,7 @@ goto :Usage if NOT DEFINED BUILD_X64 if NOT DEFINED BUILD_X86 if NOT DEFINED BUILD_ARM32 ( set BUILD_X64=1 set BUILD_X86=1 + set BUILD_ARM32=1 ) if "%INSTALL_CYGWIN%"=="1" call :InstallCygwin @@ -83,8 +87,9 @@ echo. if not exist Makefile.in (%SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)") -call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin -call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin +if "%BUILD_X64%"=="1" call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin +if "%BUILD_X86%"=="1" call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin +if "%BUILD_ARM32%"=="1" call :BuildOne x86_arm i686-pc-cygwin arm-w32-cygwin popd endlocal @@ -118,6 +123,12 @@ if /I "%VCVARS_PLATFORM%" EQU "x86" ( set ASSEMBLER= set SRC_ARCHITECTURE=x86 ) +if /I "%VCVARS_PLATFORM%" EQU "x86_arm" ( + set ARCH=arm32 + set ARTIFACTS=%LIBFFI_SOURCE%\arm-w32-cygwin + set ASSEMBLER=-marm + set SRC_ARCHITECTURE=ARM +) if NOT DEFINED LIBFFI_OUT set LIBFFI_OUT=%~dp0\..\externals\libffi set _LIBFFI_OUT=%LIBFFI_OUT%\%ARCH% diff --git a/Python/ceval.c b/Python/ceval.c index 28e923219d389c..108cd3892003e3 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1733,6 +1733,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) exc = POP(); /* exc */ /* fall through */ case 0: +#if defined(_M_ARM) && !defined(DEBUG) && (_MSC_VER < 1915) + // Workaround only required before version 15.8 of Visual Studio + // work around optimizer problem on windows arm32 + if (oparg == 2) + { + exc = stack_pointer[0]; + cause = stack_pointer[1]; + } +#endif if (do_raise(exc, cause)) { goto exception_unwind; } From 6fc12f8bb9b7cd528633a465197e6a2a7e77f54f Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Mon, 15 Apr 2019 10:37:11 -0700 Subject: [PATCH 2/3] fix pc/layout rebase merge error --- PC/layout/main.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/PC/layout/main.py b/PC/layout/main.py index 185e6498e1bc38..624033e721b73a 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -66,6 +66,18 @@ TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") +def copy_if_modified(src, dest): + try: + dest_stat = os.stat(dest) + except FileNotFoundError: + do_copy = True + else: + src_stat = os.stat(src) + do_copy = (src_stat.st_mtime != dest_stat.st_mtime or + src_stat.st_size != dest_stat.st_size) + + if do_copy: + shutil.copy2(src, dest) def get_lib_layout(ns): def _c(f): @@ -426,7 +438,7 @@ def copy_files(files, ns): need_compile.append((dest, ns.copy / dest)) else: (ns.temp / "Lib" / dest).parent.mkdir(parents=True, exist_ok=True) - shutil.copy2(src, ns.temp / "Lib" / dest) + copy_if_modified(src, ns.temp / "Lib" / dest) need_compile.append((dest, ns.temp / "Lib" / dest)) if src not in EXCLUDE_FROM_CATALOG: @@ -436,7 +448,7 @@ def copy_files(files, ns): log_debug("Copy {} -> {}", src, ns.copy / dest) (ns.copy / dest).parent.mkdir(parents=True, exist_ok=True) try: - shutil.copy2(src, ns.copy / dest) + copy_if_modified(src, ns.copy / dest) except shutil.SameFileError: pass From 0ea6f8b8106226b3edf48dc2d229448e823bead7 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Mon, 15 Apr 2019 10:38:40 -0700 Subject: [PATCH 3/3] remove compiler workaround --- Python/ceval.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 108cd3892003e3..28e923219d389c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1733,15 +1733,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) exc = POP(); /* exc */ /* fall through */ case 0: -#if defined(_M_ARM) && !defined(DEBUG) && (_MSC_VER < 1915) - // Workaround only required before version 15.8 of Visual Studio - // work around optimizer problem on windows arm32 - if (oparg == 2) - { - exc = stack_pointer[0]; - cause = stack_pointer[1]; - } -#endif if (do_raise(exc, cause)) { goto exception_unwind; }