Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r3243:272b53198be9 Date: 2019-03-16 08:00 +0100 http://bitbucket.org/cffi/cffi/changeset/272b53198be9/
Log: py3.8 fixes diff --git a/cffi/_embedding.h b/cffi/_embedding.h --- a/cffi/_embedding.h +++ b/cffi/_embedding.h @@ -169,8 +169,10 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - if (PyDict_SetItemString(global_dict, "__builtins__", - PyThreadState_GET()->interp->builtins) < 0) + PyObject *builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) goto error; x = PyEval_EvalCode( #if PY_MAJOR_VERSION < 3 @@ -263,23 +265,33 @@ So we use a global variable as a simple spin lock. This global variable must be from 'libpythonX.Y.so', not from this cffi-based extension module, because it must be shared from - different cffi-based extension modules. We choose + different cffi-based extension modules. + + In Python < 3.8, we choose _PyParser_TokenNames[0] as a completely arbitrary pointer value that is never written to. The default is to point to the string "ENDMARKER". We change it temporarily to point to the next character in that string. (Yes, I know it's REALLY obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. */ #ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 char *volatile *lock = (char *volatile *)_PyParser_TokenNames; - char *old_value; + char *old_value, *locked_value; while (1) { /* spin loop */ old_value = *lock; + locked_value = old_value + 1; if (old_value[0] == 'E') { assert(old_value[1] == 'N'); - if (cffi_compare_and_swap(lock, old_value, old_value + 1)) + if (cffi_compare_and_swap(lock, old_value, locked_value)) break; } else { @@ -290,6 +302,27 @@ this is only run at start-up anyway. */ } } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif #endif /* call Py_InitializeEx() */ @@ -306,7 +339,7 @@ #ifdef WITH_THREAD /* release the lock */ - while (!cffi_compare_and_swap(lock, old_value + 1, old_value)) + while (!cffi_compare_and_swap(lock, locked_value, old_value)) ; #endif diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -20,7 +20,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -22,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error diff --git a/testing/embedding/test_basic.py b/testing/embedding/test_basic.py --- a/testing/embedding/test_basic.py +++ b/testing/embedding/test_basic.py @@ -172,7 +172,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit