137 lines
4.9 KiB
Diff
137 lines
4.9 KiB
Diff
# HG changeset patch
|
|
# User Armin Rigo <arigo@tunes.org>
|
|
# Date 1552719624 -3600
|
|
# Node ID 272b53198be984719f29748f998504d1e0634e21
|
|
# Parent ff25b4e68195de3034253a1b35e096f8b616aa73
|
|
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
|
|
|
|
|