@@ -140,23 +140,58 @@ struct type_info {
140
140
// / Tracks the `internals` and `type_info` ABI version independent of the main library version
141
141
#define PYBIND11_INTERNALS_VERSION 3
142
142
143
- #if defined(_DEBUG)
143
+ // / On MSVC, debug and release builds are not ABI-compatible!
144
+ #if defined(_MSC_VER) && defined(_DEBUG)
144
145
# define PYBIND11_BUILD_TYPE " _debug"
145
146
#else
146
147
# define PYBIND11_BUILD_TYPE " "
147
148
#endif
148
149
150
+ // / Let's assume that different compilers are ABI-incompatible.
151
+ #if defined(_MSC_VER)
152
+ # define PYBIND11_COMPILER_TYPE " _msvc"
153
+ #elif defined(__INTEL_COMPILER)
154
+ # define PYBIND11_COMPILER_TYPE " _icc"
155
+ #elif defined(__clang__)
156
+ # define PYBIND11_COMPILER_TYPE " _clang"
157
+ #elif defined(__PGI)
158
+ # define PYBIND11_COMPILER_TYPE " _pgi"
159
+ #elif defined(__MINGW32__)
160
+ # define PYBIND11_COMPILER_TYPE " _mingw"
161
+ #elif defined(__CYGWIN__)
162
+ # define PYBIND11_COMPILER_TYPE " _gcc_cygwin"
163
+ #elif defined(__GNUC__)
164
+ # define PYBIND11_COMPILER_TYPE " _gcc"
165
+ #else
166
+ # define PYBIND11_COMPILER_TYPE " _unknown"
167
+ #endif
168
+
169
+ #if defined(_LIBCPP_VERSION)
170
+ # define PYBIND11_STDLIB " _libcpp"
171
+ #elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
172
+ # define PYBIND11_STDLIB " _libstdcpp"
173
+ #else
174
+ # define PYBIND11_STDLIB " "
175
+ #endif
176
+
177
+ // / On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
178
+ #if defined(__GXX_ABI_VERSION)
179
+ # define PYBIND11_BUILD_ABI " _cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
180
+ #else
181
+ # define PYBIND11_BUILD_ABI " "
182
+ #endif
183
+
149
184
#if defined(WITH_THREAD)
150
185
# define PYBIND11_INTERNALS_KIND " "
151
186
#else
152
187
# define PYBIND11_INTERNALS_KIND " _without_thread"
153
188
#endif
154
189
155
190
#define PYBIND11_INTERNALS_ID " __pybind11_internals_v" \
156
- PYBIND11_TOSTRING (PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_BUILD_TYPE "__"
191
+ PYBIND11_TOSTRING (PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI PYBIND11_BUILD_TYPE "__"
157
192
158
193
#define PYBIND11_MODULE_LOCAL_ID " __pybind11_module_local_v" \
159
- PYBIND11_TOSTRING (PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_BUILD_TYPE "__"
194
+ PYBIND11_TOSTRING (PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI PYBIND11_BUILD_TYPE "__"
160
195
161
196
// / Each module locally stores a pointer to the `internals` data. The data
162
197
// / itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
@@ -165,12 +200,48 @@ inline internals **&get_internals_pp() {
165
200
return internals_pp;
166
201
}
167
202
203
+ inline void translate_exception (std::exception_ptr p) {
204
+ try {
205
+ if (p) std::rethrow_exception (p);
206
+ } catch (error_already_set &e) { e.restore (); return ;
207
+ } catch (const builtin_exception &e) { e.set_error (); return ;
208
+ } catch (const std::bad_alloc &e) { PyErr_SetString (PyExc_MemoryError, e.what ()); return ;
209
+ } catch (const std::domain_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
210
+ } catch (const std::invalid_argument &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
211
+ } catch (const std::length_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
212
+ } catch (const std::out_of_range &e) { PyErr_SetString (PyExc_IndexError, e.what ()); return ;
213
+ } catch (const std::range_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
214
+ } catch (const std::exception &e) { PyErr_SetString (PyExc_RuntimeError, e.what ()); return ;
215
+ } catch (...) {
216
+ PyErr_SetString (PyExc_RuntimeError, " Caught an unknown exception!" );
217
+ return ;
218
+ }
219
+ }
220
+
221
+ #if !defined(__GLIBCXX__)
222
+ inline void translate_local_exception (std::exception_ptr p) {
223
+ try {
224
+ if (p) std::rethrow_exception (p);
225
+ } catch (error_already_set &e) { e.restore (); return ;
226
+ } catch (const builtin_exception &e) { e.set_error (); return ;
227
+ }
228
+ }
229
+ #endif
230
+
168
231
// / Return a reference to the current `internals` data
169
232
PYBIND11_NOINLINE inline internals &get_internals () {
170
233
auto **&internals_pp = get_internals_pp ();
171
234
if (internals_pp && *internals_pp)
172
235
return **internals_pp;
173
236
237
+ // Ensure that the GIL is held since we will need to make Python calls.
238
+ // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
239
+ struct gil_scoped_acquire_local {
240
+ gil_scoped_acquire_local () : state (PyGILState_Ensure()) {}
241
+ ~gil_scoped_acquire_local () { PyGILState_Release (state); }
242
+ const PyGILState_STATE state;
243
+ } gil;
244
+
174
245
constexpr auto *id = PYBIND11_INTERNALS_ID;
175
246
auto builtins = handle (PyEval_GetBuiltins ());
176
247
if (builtins.contains (id) && isinstance<capsule>(builtins[id])) {
@@ -182,15 +253,7 @@ PYBIND11_NOINLINE inline internals &get_internals() {
182
253
//
183
254
// libstdc++ doesn't require this (types there are identified only by name)
184
255
#if !defined(__GLIBCXX__)
185
- (*internals_pp)->registered_exception_translators .push_front (
186
- [](std::exception_ptr p) -> void {
187
- try {
188
- if (p) std::rethrow_exception (p);
189
- } catch (error_already_set &e) { e.restore (); return ;
190
- } catch (const builtin_exception &e) { e.set_error (); return ;
191
- }
192
- }
193
- );
256
+ (*internals_pp)->registered_exception_translators .push_front (&translate_local_exception);
194
257
#endif
195
258
} else {
196
259
if (!internals_pp) internals_pp = new internals*();
@@ -213,25 +276,7 @@ PYBIND11_NOINLINE inline internals &get_internals() {
213
276
internals_ptr->istate = tstate->interp ;
214
277
#endif
215
278
builtins[id] = capsule (internals_pp);
216
- internals_ptr->registered_exception_translators .push_front (
217
- [](std::exception_ptr p) -> void {
218
- try {
219
- if (p) std::rethrow_exception (p);
220
- } catch (error_already_set &e) { e.restore (); return ;
221
- } catch (const builtin_exception &e) { e.set_error (); return ;
222
- } catch (const std::bad_alloc &e) { PyErr_SetString (PyExc_MemoryError, e.what ()); return ;
223
- } catch (const std::domain_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
224
- } catch (const std::invalid_argument &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
225
- } catch (const std::length_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
226
- } catch (const std::out_of_range &e) { PyErr_SetString (PyExc_IndexError, e.what ()); return ;
227
- } catch (const std::range_error &e) { PyErr_SetString (PyExc_ValueError, e.what ()); return ;
228
- } catch (const std::exception &e) { PyErr_SetString (PyExc_RuntimeError, e.what ()); return ;
229
- } catch (...) {
230
- PyErr_SetString (PyExc_RuntimeError, " Caught an unknown exception!" );
231
- return ;
232
- }
233
- }
234
- );
279
+ internals_ptr->registered_exception_translators .push_front (&translate_exception);
235
280
internals_ptr->static_property_type = make_static_property_type ();
236
281
internals_ptr->default_metaclass = make_default_metaclass ();
237
282
internals_ptr->instance_base = make_object_base_type (internals_ptr->default_metaclass );
0 commit comments