From a2739f072fd1ad959f5c5a2f755bd25c53a0dbd0 Mon Sep 17 00:00:00 2001 From: Florian Angerer Date: Fri, 3 Feb 2023 08:23:52 +0100 Subject: [PATCH 1/5] Move check of HPy_TypeCheck's 2nd arg to debug mode --- hpy/debug/src/autogen_debug_wrappers.c | 5 ----- hpy/debug/src/debug_ctx.c | 18 ++++++++++++++++++ hpy/devel/src/runtime/ctx_object.c | 23 +++++------------------ hpy/tools/autogen/debug.py | 3 ++- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/hpy/debug/src/autogen_debug_wrappers.c b/hpy/debug/src/autogen_debug_wrappers.c index b5c7014ca..4b5fc35f4 100644 --- a/hpy/debug/src/autogen_debug_wrappers.c +++ b/hpy/debug/src/autogen_debug_wrappers.c @@ -457,11 +457,6 @@ DHPy debug_ctx_Type(HPyContext *dctx, DHPy obj) return DHPy_open(dctx, HPy_Type(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); } -int debug_ctx_TypeCheck(HPyContext *dctx, DHPy obj, DHPy type) -{ - return HPy_TypeCheck(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, type)); -} - int debug_ctx_Is(HPyContext *dctx, DHPy obj, DHPy other) { return HPy_Is(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, other)); diff --git a/hpy/debug/src/debug_ctx.c b/hpy/debug/src/debug_ctx.c index 4105ee01e..8340f0c8e 100644 --- a/hpy/debug/src/debug_ctx.c +++ b/hpy/debug/src/debug_ctx.c @@ -399,3 +399,21 @@ void debug_ctx_TupleBuilder_Cancel(HPyContext *dctx, HPyTupleBuilder dh_builder) DHPy_builder_handle_close(dctx, handle); } +/* + However, we don't want to raise an exception if you pass a non-type, + because the CPython version (PyObject_TypeCheck) always succeed and it + would be too easy to forget to check the return value. We just raise a + fatal error instead. + */ +int debug_ctx_TypeCheck(HPyContext *dctx, DHPy obj, DHPy type) +{ + HPyContext *uctx = get_info(dctx)->uctx; + UHPy uh_obj = DHPy_unwrap(dctx, obj); + UHPy uh_type = DHPy_unwrap(dctx, type); + assert(!HPy_IsNull(uh_obj)); + assert(!HPy_IsNull(uh_type)); + if (!HPy_TypeCheck(uctx, uh_type, uctx->h_TypeType)) { + HPy_FatalError(uctx, "HPy_TypeCheck arg 2 must be a type"); + } + return HPy_TypeCheck(uctx, uh_obj, uh_type); +} diff --git a/hpy/devel/src/runtime/ctx_object.c b/hpy/devel/src/runtime/ctx_object.c index 88358f833..dc6ee2b2b 100644 --- a/hpy/devel/src/runtime/ctx_object.c +++ b/hpy/devel/src/runtime/ctx_object.c @@ -15,28 +15,15 @@ ctx_Dump(HPyContext *ctx, HPy h) _PyObject_Dump(_h2py(h)); } -/* NOTE: contrarily to CPython, the HPy have to check that h_type is a - type. On CPython it's not necessarily because it passes a PyTypeObject*, - but here we can only receive an HPy. - - However, we can't/don't want to raise an exception if you pass a non-type, - because the CPython version (PyObject_TypeCheck) always succeed and it - would be too easy to forget to check the return value. We just raise a - fatal error instead. - - Hopefully the slowdown is not too much. If it proves to be too much, we - could say that the function is allowed to crash if you pass a non-type, and - do the check only in debug mode. +/* NOTE: In contrast to CPython, HPy has to check that 'h_type' is a type. This + is not necessary on CPython because it requires C type 'PyTypeObject *' but + here we can only receive an HPy handle. Appropriate checking of the argument + will be done in the debug mode. */ _HPy_HIDDEN int ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type) { - PyObject *type= _h2py(h_type); - assert(type != NULL); - if (!PyType_Check(type)) { - Py_FatalError("HPy_TypeCheck arg 2 must be a type"); - } - return PyObject_TypeCheck(_h2py(h_obj), (PyTypeObject*)type); + return PyObject_TypeCheck(_h2py(h_obj), (PyTypeObject*)_h2py(h_type)); } _HPy_HIDDEN int diff --git a/hpy/tools/autogen/debug.py b/hpy/tools/autogen/debug.py index 06f414746..b9b516065 100644 --- a/hpy/tools/autogen/debug.py +++ b/hpy/tools/autogen/debug.py @@ -87,7 +87,8 @@ class autogen_debug_wrappers(AutoGenFile): 'HPyListBuilder_New', 'HPyListBuilder_Set', 'HPyListBuilder_Build', - 'HPyListBuilder_Cancel' + 'HPyListBuilder_Cancel', + 'HPy_TypeCheck' } def generate(self): From 31eab76ee0956bcc5d81cef4ac860e4956fa976a Mon Sep 17 00:00:00 2001 From: Florian Angerer Date: Fri, 3 Feb 2023 08:22:17 +0100 Subject: [PATCH 2/5] Test invalid type arg for HPy_TypeCheck --- .../debug/{test_as_struct.py => test_misc.py} | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) rename test/debug/{test_as_struct.py => test_misc.py} (58%) diff --git a/test/debug/test_as_struct.py b/test/debug/test_misc.py similarity index 58% rename from test/debug/test_as_struct.py rename to test/debug/test_misc.py index 2989b3c9a..a55b303b3 100644 --- a/test/debug/test_as_struct.py +++ b/test/debug/test_misc.py @@ -38,3 +38,24 @@ def test_use_invalid_as_struct(compiler, python_subprocess): assert "Invalid usage of _HPy_AsStruct_Object" in result.stderr.decode("utf-8") +@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") +def test_typecheck(compiler, python_subprocess): + mod = compiler.compile_module(""" + HPyDef_METH(f, "f", HPyFunc_VARARGS) + static HPy f_impl(HPyContext *ctx, HPy self, HPy *args, HPy_ssize_t nargs) + { + if (nargs != 2) { + HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 2 arguments"); + return HPy_NULL; + } + int res = HPy_TypeCheck(ctx, args[0], args[1]); + return HPyBool_FromLong(ctx, res); + } + @EXPORT(f) + @INIT + """) + code = "assert mod.f(mod.f('hello', 2)) == 0" + result = python_subprocess.run(mod, code) + assert result.returncode != 0 + assert "HPy_TypeCheck arg 2 must be a type" in result.stderr.decode("utf-8") + From ff48f7e8cb264e4cec5d4a8d912a13cbf26f9f37 Mon Sep 17 00:00:00 2001 From: Florian Angerer Date: Fri, 3 Feb 2023 10:56:30 +0100 Subject: [PATCH 3/5] Add doc for HPy_Type and HPy_TypeCheck --- docs/api-reference/hpy-object.rst | 5 +++++ docs/api-reference/index.rst | 1 + hpy/tools/autogen/public_api.h | 33 ++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 docs/api-reference/hpy-object.rst diff --git a/docs/api-reference/hpy-object.rst b/docs/api-reference/hpy-object.rst new file mode 100644 index 000000000..6d0e68ddf --- /dev/null +++ b/docs/api-reference/hpy-object.rst @@ -0,0 +1,5 @@ +HPy Object +========== + +.. autocmodule:: autogen/public_api.h + :members: HPy_IsTrue,HPy_GetAttr,HPy_GetAttr_s,HPy_HasAttr,HPy_HasAttr_s,HPy_SetAttr,HPy_SetAttr_s,HPy_GetItem,HPy_GetItem_s,HPy_GetItem_i,HPy_SetItem,HPy_SetItem_s,HPy_SetItem_i,HPy_DelItem,HPy_DelItem_s,HPy_DelItem_i,HPy_Type,HPy_TypeCheck,HPy_Is,HPy_Repr,HPy_Str,HPy_ASCII,HPy_Bytes,HPy_RichCompare,HPy_RichCompareBool,HPy_Hash diff --git a/docs/api-reference/index.rst b/docs/api-reference/index.rst index 1dc0e7771..bb50e29a0 100644 --- a/docs/api-reference/index.rst +++ b/docs/api-reference/index.rst @@ -26,6 +26,7 @@ between the modes. function-index hpy-ctx + hpy-object hpy-type hpy-field hpy-global diff --git a/hpy/tools/autogen/public_api.h b/hpy/tools/autogen/public_api.h index 8dee35940..263980c75 100644 --- a/hpy/tools/autogen/public_api.h +++ b/hpy/tools/autogen/public_api.h @@ -365,9 +365,40 @@ int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); HPy_ID(237) int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *utf8_key); +/** + * Returns the type of the given object ``obj``. + * + * On failure, raises ``SystemError`` and returns ``HPy_NULL``. This is + * equivalent to the Python expression``type(obj)``. + * + * :param ctx: + * The execution context. + * :param obj: + * a Python object (must not be ``HPy_NULL``) + * + * :returns: + * The type of ``obj`` or ``HPy_NULL`` in case of errors. + */ HPy_ID(165) HPy HPy_Type(HPyContext *ctx, HPy obj); -// WARNING: HPy_TypeCheck could be tweaked/removed in the future, see issue #160 + +/** + * Checks if ``ob`` is an instance of ``type`` or any subtype of ``type``. + * + * :param ctx: + * The execution context. + * :param obj: + * a Python object (must not be ``HPy_NULL``) + * :param type: + * A Python type object. This argument must not be ``HPy_NULL`` and must be + * a type (i.e. it must inherit from Python ``type``). If this is not the + * case, the behavior is undefined (verification of the argument is only + * done in debug mode). + * + * :returns: + * Non-zero if object ``obj`` is an instance of type ``type`` or an instance + * of a subtype of ``type``, and ``0`` otherwise. + */ HPy_ID(166) int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type); From 95a61887004f92798d36b530d1c99c74a84d978e Mon Sep 17 00:00:00 2001 From: Nico Rittinghaus Date: Wed, 21 Sep 2022 13:19:46 +0200 Subject: [PATCH 4/5] Debug context: enforce usage of correct context instance Co-authored-by: Stepan Sindelar --- hpy/debug/src/autogen_debug_ctx_call.i | 362 ++++++- hpy/debug/src/autogen_debug_wrappers.c | 1230 +++++++++++++++++++++--- hpy/debug/src/debug_ctx.c | 118 ++- hpy/debug/src/debug_ctx_cpython.c | 142 ++- hpy/debug/src/debug_internal.h | 44 +- hpy/tools/autogen/debug.py | 46 +- test/debug/test_context_reuse.py | 102 ++ 7 files changed, 1861 insertions(+), 183 deletions(-) create mode 100644 test/debug/test_context_reuse.py diff --git a/hpy/debug/src/autogen_debug_ctx_call.i b/hpy/debug/src/autogen_debug_ctx_call.i index f03b48e2f..44cbbca52 100644 --- a/hpy/debug/src/autogen_debug_ctx_call.i +++ b/hpy/debug/src/autogen_debug_ctx_call.i @@ -14,7 +14,19 @@ HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -25,7 +37,19 @@ _HPyFunc_args_BINARYFUNC *a = (_HPyFunc_args_BINARYFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -38,7 +62,19 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -50,7 +86,19 @@ HPyFunc_inquiry f = (HPyFunc_inquiry)func; _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - a->result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); return; } @@ -58,7 +106,19 @@ HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - a->result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); return; } @@ -66,7 +126,19 @@ HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0, a->arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -76,7 +148,19 @@ HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0, a->arg1, a->arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1, a->arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -87,7 +171,19 @@ _HPyFunc_args_SSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZEOBJARGPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - a->result = f(dctx, dh_arg0, a->arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg2); return; @@ -97,7 +193,19 @@ _HPyFunc_args_SSIZESSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZESSIZEOBJARGPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg3 = _py2dh(dctx, a->arg3); - a->result = f(dctx, dh_arg0, a->arg1, a->arg2, dh_arg3); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, a->arg1, a->arg2, dh_arg3); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg3); return; @@ -108,7 +216,19 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - a->result = f(dctx, dh_arg0, dh_arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -117,14 +237,37 @@ case HPyFunc_FREEFUNC: { HPyFunc_freefunc f = (HPyFunc_freefunc)func; _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; - f(dctx, a->arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + f(next_dctx, a->arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; return; } case HPyFunc_GETATTRFUNC: { HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)func; _HPyFunc_args_GETATTRFUNC *a = (_HPyFunc_args_GETATTRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0, a->arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -135,7 +278,19 @@ _HPyFunc_args_GETATTROFUNC *a = (_HPyFunc_args_GETATTROFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -147,7 +302,19 @@ _HPyFunc_args_SETATTRFUNC *a = (_HPyFunc_args_SETATTRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - a->result = f(dctx, dh_arg0, a->arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg2); return; @@ -158,7 +325,19 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - a->result = f(dctx, dh_arg0, dh_arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -168,7 +347,19 @@ HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -178,7 +369,19 @@ HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - a->result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); return; } @@ -187,7 +390,19 @@ _HPyFunc_args_RICHCMPFUNC *a = (_HPyFunc_args_RICHCMPFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, a->arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -198,7 +413,19 @@ HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -208,7 +435,19 @@ HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -220,7 +459,19 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - DHPy dh_result = f(dctx, dh_arg0, dh_arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -234,7 +485,19 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - a->result = f(dctx, dh_arg0, dh_arg1, dh_arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -244,7 +507,19 @@ HPyFunc_getter f = (HPyFunc_getter)func; _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_result = f(dctx, dh_arg0, a->arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -255,7 +530,19 @@ _HPyFunc_args_SETTER *a = (_HPyFunc_args_SETTER*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - a->result = f(dctx, dh_arg0, dh_arg1, a->arg2); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); return; @@ -265,7 +552,19 @@ _HPyFunc_args_OBJOBJPROC *a = (_HPyFunc_args_OBJOBJPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - a->result = f(dctx, dh_arg0, dh_arg1); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = f(next_dctx, dh_arg0, dh_arg1); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); return; @@ -274,7 +573,18 @@ HPyFunc_destructor f = (HPyFunc_destructor)func; _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - f(dctx, dh_arg0); + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + f(next_dctx, dh_arg0); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; DHPy_close_and_check(dctx, dh_arg0); return; } diff --git a/hpy/debug/src/autogen_debug_wrappers.c b/hpy/debug/src/autogen_debug_wrappers.c index 4b5fc35f4..964919988 100644 --- a/hpy/debug/src/autogen_debug_wrappers.c +++ b/hpy/debug/src/autogen_debug_wrappers.c @@ -14,681 +14,1647 @@ DHPy debug_ctx_Dup(HPyContext *dctx, DHPy h) { - return DHPy_open(dctx, HPy_Dup(get_info(dctx)->uctx, DHPy_unwrap(dctx, h))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Dup(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromInt32_t(HPyContext *dctx, int32_t value) { - return DHPy_open(dctx, HPyLong_FromInt32_t(get_info(dctx)->uctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromInt32_t(get_info(dctx)->uctx, value); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromUInt32_t(HPyContext *dctx, uint32_t value) { - return DHPy_open(dctx, HPyLong_FromUInt32_t(get_info(dctx)->uctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromUInt32_t(get_info(dctx)->uctx, value); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromInt64_t(HPyContext *dctx, int64_t v) { - return DHPy_open(dctx, HPyLong_FromInt64_t(get_info(dctx)->uctx, v)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromInt64_t(get_info(dctx)->uctx, v); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromUInt64_t(HPyContext *dctx, uint64_t v) { - return DHPy_open(dctx, HPyLong_FromUInt64_t(get_info(dctx)->uctx, v)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromUInt64_t(get_info(dctx)->uctx, v); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromSize_t(HPyContext *dctx, size_t value) { - return DHPy_open(dctx, HPyLong_FromSize_t(get_info(dctx)->uctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromSize_t(get_info(dctx)->uctx, value); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long_FromSsize_t(HPyContext *dctx, HPy_ssize_t value) { - return DHPy_open(dctx, HPyLong_FromSsize_t(get_info(dctx)->uctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyLong_FromSsize_t(get_info(dctx)->uctx, value); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int32_t debug_ctx_Long_AsInt32_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsInt32_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int32_t universal_result = HPyLong_AsInt32_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } uint32_t debug_ctx_Long_AsUInt32_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsUInt32_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + uint32_t universal_result = HPyLong_AsUInt32_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } uint32_t debug_ctx_Long_AsUInt32_tMask(HPyContext *dctx, DHPy h) { - return HPyLong_AsUInt32_tMask(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + uint32_t universal_result = HPyLong_AsUInt32_tMask(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int64_t debug_ctx_Long_AsInt64_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsInt64_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int64_t universal_result = HPyLong_AsInt64_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } uint64_t debug_ctx_Long_AsUInt64_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsUInt64_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + uint64_t universal_result = HPyLong_AsUInt64_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } uint64_t debug_ctx_Long_AsUInt64_tMask(HPyContext *dctx, DHPy h) { - return HPyLong_AsUInt64_tMask(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + uint64_t universal_result = HPyLong_AsUInt64_tMask(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } size_t debug_ctx_Long_AsSize_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsSize_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + size_t universal_result = HPyLong_AsSize_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } HPy_ssize_t debug_ctx_Long_AsSsize_t(HPyContext *dctx, DHPy h) { - return HPyLong_AsSsize_t(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy_ssize_t universal_result = HPyLong_AsSsize_t(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } void *debug_ctx_Long_AsVoidPtr(HPyContext *dctx, DHPy h) { - return HPyLong_AsVoidPtr(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + void * universal_result = HPyLong_AsVoidPtr(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } double debug_ctx_Long_AsDouble(HPyContext *dctx, DHPy h) { - return HPyLong_AsDouble(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + double universal_result = HPyLong_AsDouble(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Float_FromDouble(HPyContext *dctx, double v) { - return DHPy_open(dctx, HPyFloat_FromDouble(get_info(dctx)->uctx, v)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyFloat_FromDouble(get_info(dctx)->uctx, v); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } double debug_ctx_Float_AsDouble(HPyContext *dctx, DHPy h) { - return HPyFloat_AsDouble(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + double universal_result = HPyFloat_AsDouble(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Bool_FromBool(HPyContext *dctx, bool v) { - return DHPy_open(dctx, HPyBool_FromBool(get_info(dctx)->uctx, v)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyBool_FromBool(get_info(dctx)->uctx, v); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } HPy_ssize_t debug_ctx_Length(HPyContext *dctx, DHPy h) { - return HPy_Length(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy_ssize_t universal_result = HPy_Length(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Number_Check(HPyContext *dctx, DHPy h) { - return HPyNumber_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyNumber_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Add(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Add(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Add(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Subtract(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Subtract(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Subtract(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Multiply(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Multiply(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Multiply(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_MatrixMultiply(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_MatrixMultiply(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_MatrixMultiply(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_FloorDivide(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_FloorDivide(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_FloorDivide(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_TrueDivide(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_TrueDivide(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_TrueDivide(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Remainder(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Remainder(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Remainder(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Divmod(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Divmod(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Divmod(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Power(HPyContext *dctx, DHPy h1, DHPy h2, DHPy h3) { - return DHPy_open(dctx, HPy_Power(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2), DHPy_unwrap(dctx, h3))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + HPy dh_h3 = DHPy_unwrap(dctx, h3); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Power(get_info(dctx)->uctx, dh_h1, dh_h2, dh_h3); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Negative(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Negative(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Negative(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Positive(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Positive(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Positive(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Absolute(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Absolute(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Absolute(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Invert(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Invert(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Invert(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Lshift(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Lshift(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Lshift(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Rshift(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Rshift(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Rshift(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_And(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_And(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_And(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Xor(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Xor(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Xor(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Or(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_Or(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Or(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Index(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Index(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Index(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Long(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Long(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Long(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Float(HPyContext *dctx, DHPy h1) { - return DHPy_open(dctx, HPy_Float(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Float(get_info(dctx)->uctx, dh_h1); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceAdd(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceAdd(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceAdd(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceSubtract(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceSubtract(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceSubtract(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceMultiply(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceMultiply(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceMultiply(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceMatrixMultiply(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceMatrixMultiply(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceMatrixMultiply(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceFloorDivide(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceFloorDivide(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceFloorDivide(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceTrueDivide(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceTrueDivide(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceTrueDivide(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceRemainder(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceRemainder(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceRemainder(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlacePower(HPyContext *dctx, DHPy h1, DHPy h2, DHPy h3) { - return DHPy_open(dctx, HPy_InPlacePower(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2), DHPy_unwrap(dctx, h3))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + HPy dh_h3 = DHPy_unwrap(dctx, h3); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlacePower(get_info(dctx)->uctx, dh_h1, dh_h2, dh_h3); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceLshift(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceLshift(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceLshift(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceRshift(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceRshift(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceRshift(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceAnd(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceAnd(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceAnd(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceXor(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceXor(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceXor(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_InPlaceOr(HPyContext *dctx, DHPy h1, DHPy h2) { - return DHPy_open(dctx, HPy_InPlaceOr(get_info(dctx)->uctx, DHPy_unwrap(dctx, h1), DHPy_unwrap(dctx, h2))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h1 = DHPy_unwrap(dctx, h1); + HPy dh_h2 = DHPy_unwrap(dctx, h2); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_InPlaceOr(get_info(dctx)->uctx, dh_h1, dh_h2); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Callable_Check(HPyContext *dctx, DHPy h) { - return HPyCallable_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyCallable_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_CallTupleDict(HPyContext *dctx, DHPy callable, DHPy args, DHPy kw) { - return DHPy_open(dctx, HPy_CallTupleDict(get_info(dctx)->uctx, DHPy_unwrap(dctx, callable), DHPy_unwrap(dctx, args), DHPy_unwrap(dctx, kw))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_callable = DHPy_unwrap(dctx, callable); + HPy dh_args = DHPy_unwrap(dctx, args); + HPy dh_kw = DHPy_unwrap(dctx, kw); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_CallTupleDict(get_info(dctx)->uctx, dh_callable, dh_args, dh_kw); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } void debug_ctx_FatalError(HPyContext *dctx, const char *message) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; HPy_FatalError(get_info(dctx)->uctx, message); + get_ctx_info(dctx)->is_valid = true; } void debug_ctx_Err_SetString(HPyContext *dctx, DHPy h_type, const char *utf8_message) { - HPyErr_SetString(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type), utf8_message); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + get_ctx_info(dctx)->is_valid = false; + HPyErr_SetString(get_info(dctx)->uctx, dh_h_type, utf8_message); + get_ctx_info(dctx)->is_valid = true; } void debug_ctx_Err_SetObject(HPyContext *dctx, DHPy h_type, DHPy h_value) { - HPyErr_SetObject(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type), DHPy_unwrap(dctx, h_value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + HPy dh_h_value = DHPy_unwrap(dctx, h_value); + get_ctx_info(dctx)->is_valid = false; + HPyErr_SetObject(get_info(dctx)->uctx, dh_h_type, dh_h_value); + get_ctx_info(dctx)->is_valid = true; } DHPy debug_ctx_Err_SetFromErrnoWithFilename(HPyContext *dctx, DHPy h_type, const char *filename_fsencoded) { - return DHPy_open(dctx, HPyErr_SetFromErrnoWithFilename(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type), filename_fsencoded)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyErr_SetFromErrnoWithFilename(get_info(dctx)->uctx, dh_h_type, filename_fsencoded); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } void debug_ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *dctx, DHPy h_type, DHPy filename1, DHPy filename2) { - HPyErr_SetFromErrnoWithFilenameObjects(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type), DHPy_unwrap(dctx, filename1), DHPy_unwrap(dctx, filename2)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + HPy dh_filename1 = DHPy_unwrap(dctx, filename1); + HPy dh_filename2 = DHPy_unwrap(dctx, filename2); + get_ctx_info(dctx)->is_valid = false; + HPyErr_SetFromErrnoWithFilenameObjects(get_info(dctx)->uctx, dh_h_type, dh_filename1, dh_filename2); + get_ctx_info(dctx)->is_valid = true; } int debug_ctx_Err_Occurred(HPyContext *dctx) { - return HPyErr_Occurred(get_info(dctx)->uctx); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyErr_Occurred(get_info(dctx)->uctx); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Err_ExceptionMatches(HPyContext *dctx, DHPy exc) { - return HPyErr_ExceptionMatches(get_info(dctx)->uctx, DHPy_unwrap(dctx, exc)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_exc = DHPy_unwrap(dctx, exc); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyErr_ExceptionMatches(get_info(dctx)->uctx, dh_exc); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } void debug_ctx_Err_NoMemory(HPyContext *dctx) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; HPyErr_NoMemory(get_info(dctx)->uctx); + get_ctx_info(dctx)->is_valid = true; } void debug_ctx_Err_Clear(HPyContext *dctx) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; HPyErr_Clear(get_info(dctx)->uctx); + get_ctx_info(dctx)->is_valid = true; } DHPy debug_ctx_Err_NewException(HPyContext *dctx, const char *utf8_name, DHPy base, DHPy dict) { - return DHPy_open(dctx, HPyErr_NewException(get_info(dctx)->uctx, utf8_name, DHPy_unwrap(dctx, base), DHPy_unwrap(dctx, dict))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_base = DHPy_unwrap(dctx, base); + HPy dh_dict = DHPy_unwrap(dctx, dict); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyErr_NewException(get_info(dctx)->uctx, utf8_name, dh_base, dh_dict); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Err_NewExceptionWithDoc(HPyContext *dctx, const char *utf8_name, const char *utf8_doc, DHPy base, DHPy dict) { - return DHPy_open(dctx, HPyErr_NewExceptionWithDoc(get_info(dctx)->uctx, utf8_name, utf8_doc, DHPy_unwrap(dctx, base), DHPy_unwrap(dctx, dict))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_base = DHPy_unwrap(dctx, base); + HPy dh_dict = DHPy_unwrap(dctx, dict); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyErr_NewExceptionWithDoc(get_info(dctx)->uctx, utf8_name, utf8_doc, dh_base, dh_dict); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Err_WarnEx(HPyContext *dctx, DHPy category, const char *utf8_message, HPy_ssize_t stack_level) { - return HPyErr_WarnEx(get_info(dctx)->uctx, DHPy_unwrap(dctx, category), utf8_message, stack_level); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_category = DHPy_unwrap(dctx, category); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyErr_WarnEx(get_info(dctx)->uctx, dh_category, utf8_message, stack_level); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } void debug_ctx_Err_WriteUnraisable(HPyContext *dctx, DHPy obj) { - HPyErr_WriteUnraisable(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPyErr_WriteUnraisable(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; } int debug_ctx_IsTrue(HPyContext *dctx, DHPy h) { - return HPy_IsTrue(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_IsTrue(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_GetAttr(HPyContext *dctx, DHPy obj, DHPy name) { - return DHPy_open(dctx, HPy_GetAttr(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, name))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_name = DHPy_unwrap(dctx, name); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetAttr(get_info(dctx)->uctx, dh_obj, dh_name); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_GetAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name) { - return DHPy_open(dctx, HPy_GetAttr_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_name)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetAttr_s(get_info(dctx)->uctx, dh_obj, utf8_name); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_HasAttr(HPyContext *dctx, DHPy obj, DHPy name) { - return HPy_HasAttr(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, name)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_name = DHPy_unwrap(dctx, name); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_HasAttr(get_info(dctx)->uctx, dh_obj, dh_name); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_HasAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name) { - return HPy_HasAttr_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_name); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_HasAttr_s(get_info(dctx)->uctx, dh_obj, utf8_name); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_SetAttr(HPyContext *dctx, DHPy obj, DHPy name, DHPy value) { - return HPy_SetAttr(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, name), DHPy_unwrap(dctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_name = DHPy_unwrap(dctx, name); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetAttr(get_info(dctx)->uctx, dh_obj, dh_name, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_SetAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name, DHPy value) { - return HPy_SetAttr_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_name, DHPy_unwrap(dctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetAttr_s(get_info(dctx)->uctx, dh_obj, utf8_name, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_GetItem(HPyContext *dctx, DHPy obj, DHPy key) { - return DHPy_open(dctx, HPy_GetItem(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, key))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_key = DHPy_unwrap(dctx, key); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetItem(get_info(dctx)->uctx, dh_obj, dh_key); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_GetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx) { - return DHPy_open(dctx, HPy_GetItem_i(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), idx)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetItem_i(get_info(dctx)->uctx, dh_obj, idx); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_GetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key) { - return DHPy_open(dctx, HPy_GetItem_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_key)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_GetItem_s(get_info(dctx)->uctx, dh_obj, utf8_key); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Contains(HPyContext *dctx, DHPy container, DHPy key) { - return HPy_Contains(get_info(dctx)->uctx, DHPy_unwrap(dctx, container), DHPy_unwrap(dctx, key)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_container = DHPy_unwrap(dctx, container); + HPy dh_key = DHPy_unwrap(dctx, key); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_Contains(get_info(dctx)->uctx, dh_container, dh_key); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_SetItem(HPyContext *dctx, DHPy obj, DHPy key, DHPy value) { - return HPy_SetItem(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, key), DHPy_unwrap(dctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_key = DHPy_unwrap(dctx, key); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetItem(get_info(dctx)->uctx, dh_obj, dh_key, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_SetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx, DHPy value) { - return HPy_SetItem_i(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), idx, DHPy_unwrap(dctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetItem_i(get_info(dctx)->uctx, dh_obj, idx, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_SetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key, DHPy value) { - return HPy_SetItem_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_key, DHPy_unwrap(dctx, value)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_value = DHPy_unwrap(dctx, value); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_SetItem_s(get_info(dctx)->uctx, dh_obj, utf8_key, dh_value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_DelItem(HPyContext *dctx, DHPy obj, DHPy key) { - return HPy_DelItem(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, key)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_key = DHPy_unwrap(dctx, key); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_DelItem(get_info(dctx)->uctx, dh_obj, dh_key); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_DelItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx) { - return HPy_DelItem_i(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), idx); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_DelItem_i(get_info(dctx)->uctx, dh_obj, idx); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_DelItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key) { - return HPy_DelItem_s(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), utf8_key); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_DelItem_s(get_info(dctx)->uctx, dh_obj, utf8_key); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Type(HPyContext *dctx, DHPy obj) { - return DHPy_open(dctx, HPy_Type(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Type(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Is(HPyContext *dctx, DHPy obj, DHPy other) { - return HPy_Is(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj), DHPy_unwrap(dctx, other)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + HPy dh_other = DHPy_unwrap(dctx, other); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_Is(get_info(dctx)->uctx, dh_obj, dh_other); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } HPyType_BuiltinShape debug_ctx_Type_GetBuiltinShape(HPyContext *dctx, DHPy h_type) { - return _HPyType_GetBuiltinShape(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + get_ctx_info(dctx)->is_valid = false; + HPyType_BuiltinShape universal_result = _HPyType_GetBuiltinShape(get_info(dctx)->uctx, dh_h_type); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_New(HPyContext *dctx, DHPy h_type, void **data) { - return DHPy_open(dctx, _HPy_New(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_type), data)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_type = DHPy_unwrap(dctx, h_type); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = _HPy_New(get_info(dctx)->uctx, dh_h_type, data); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Repr(HPyContext *dctx, DHPy obj) { - return DHPy_open(dctx, HPy_Repr(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Repr(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Str(HPyContext *dctx, DHPy obj) { - return DHPy_open(dctx, HPy_Str(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Str(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_ASCII(HPyContext *dctx, DHPy obj) { - return DHPy_open(dctx, HPy_ASCII(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_ASCII(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Bytes(HPyContext *dctx, DHPy obj) { - return DHPy_open(dctx, HPy_Bytes(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_Bytes(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_RichCompare(HPyContext *dctx, DHPy v, DHPy w, int op) { - return DHPy_open(dctx, HPy_RichCompare(get_info(dctx)->uctx, DHPy_unwrap(dctx, v), DHPy_unwrap(dctx, w), op)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_v = DHPy_unwrap(dctx, v); + HPy dh_w = DHPy_unwrap(dctx, w); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_RichCompare(get_info(dctx)->uctx, dh_v, dh_w, op); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_RichCompareBool(HPyContext *dctx, DHPy v, DHPy w, int op) { - return HPy_RichCompareBool(get_info(dctx)->uctx, DHPy_unwrap(dctx, v), DHPy_unwrap(dctx, w), op); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_v = DHPy_unwrap(dctx, v); + HPy dh_w = DHPy_unwrap(dctx, w); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPy_RichCompareBool(get_info(dctx)->uctx, dh_v, dh_w, op); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } HPy_hash_t debug_ctx_Hash(HPyContext *dctx, DHPy obj) { - return HPy_Hash(get_info(dctx)->uctx, DHPy_unwrap(dctx, obj)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_obj = DHPy_unwrap(dctx, obj); + get_ctx_info(dctx)->is_valid = false; + HPy_hash_t universal_result = HPy_Hash(get_info(dctx)->uctx, dh_obj); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Bytes_Check(HPyContext *dctx, DHPy h) { - return HPyBytes_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyBytes_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } HPy_ssize_t debug_ctx_Bytes_Size(HPyContext *dctx, DHPy h) { - return HPyBytes_Size(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy_ssize_t universal_result = HPyBytes_Size(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } HPy_ssize_t debug_ctx_Bytes_GET_SIZE(HPyContext *dctx, DHPy h) { - return HPyBytes_GET_SIZE(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy_ssize_t universal_result = HPyBytes_GET_SIZE(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Bytes_FromString(HPyContext *dctx, const char *bytes) { - return DHPy_open(dctx, HPyBytes_FromString(get_info(dctx)->uctx, bytes)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyBytes_FromString(get_info(dctx)->uctx, bytes); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Bytes_FromStringAndSize(HPyContext *dctx, const char *bytes, HPy_ssize_t len) { - return DHPy_open(dctx, HPyBytes_FromStringAndSize(get_info(dctx)->uctx, bytes, len)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyBytes_FromStringAndSize(get_info(dctx)->uctx, bytes, len); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_FromString(HPyContext *dctx, const char *utf8) { - return DHPy_open(dctx, HPyUnicode_FromString(get_info(dctx)->uctx, utf8)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_FromString(get_info(dctx)->uctx, utf8); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Unicode_Check(HPyContext *dctx, DHPy h) { - return HPyUnicode_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyUnicode_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Unicode_AsASCIIString(HPyContext *dctx, DHPy h) { - return DHPy_open(dctx, HPyUnicode_AsASCIIString(get_info(dctx)->uctx, DHPy_unwrap(dctx, h))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_AsASCIIString(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_AsLatin1String(HPyContext *dctx, DHPy h) { - return DHPy_open(dctx, HPyUnicode_AsLatin1String(get_info(dctx)->uctx, DHPy_unwrap(dctx, h))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_AsLatin1String(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_AsUTF8String(HPyContext *dctx, DHPy h) { - return DHPy_open(dctx, HPyUnicode_AsUTF8String(get_info(dctx)->uctx, DHPy_unwrap(dctx, h))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_AsUTF8String(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_FromWideChar(HPyContext *dctx, const wchar_t *w, HPy_ssize_t size) { - return DHPy_open(dctx, HPyUnicode_FromWideChar(get_info(dctx)->uctx, w, size)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_FromWideChar(get_info(dctx)->uctx, w, size); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_DecodeFSDefault(HPyContext *dctx, const char *v) { - return DHPy_open(dctx, HPyUnicode_DecodeFSDefault(get_info(dctx)->uctx, v)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_DecodeFSDefault(get_info(dctx)->uctx, v); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *dctx, const char *v, HPy_ssize_t size) { - return DHPy_open(dctx, HPyUnicode_DecodeFSDefaultAndSize(get_info(dctx)->uctx, v, size)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_DecodeFSDefaultAndSize(get_info(dctx)->uctx, v, size); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_EncodeFSDefault(HPyContext *dctx, DHPy h) { - return DHPy_open(dctx, HPyUnicode_EncodeFSDefault(get_info(dctx)->uctx, DHPy_unwrap(dctx, h))); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_EncodeFSDefault(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } HPy_UCS4 debug_ctx_Unicode_ReadChar(HPyContext *dctx, DHPy h, HPy_ssize_t index) { - return HPyUnicode_ReadChar(get_info(dctx)->uctx, DHPy_unwrap(dctx, h), index); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPy_UCS4 universal_result = HPyUnicode_ReadChar(get_info(dctx)->uctx, dh_h, index); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Unicode_DecodeASCII(HPyContext *dctx, const char *ascii, HPy_ssize_t size, const char *errors) { - return DHPy_open(dctx, HPyUnicode_DecodeASCII(get_info(dctx)->uctx, ascii, size, errors)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_DecodeASCII(get_info(dctx)->uctx, ascii, size, errors); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Unicode_DecodeLatin1(HPyContext *dctx, const char *latin1, HPy_ssize_t size, const char *errors) { - return DHPy_open(dctx, HPyUnicode_DecodeLatin1(get_info(dctx)->uctx, latin1, size, errors)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyUnicode_DecodeLatin1(get_info(dctx)->uctx, latin1, size, errors); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_List_Check(HPyContext *dctx, DHPy h) { - return HPyList_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyList_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_List_New(HPyContext *dctx, HPy_ssize_t len) { - return DHPy_open(dctx, HPyList_New(get_info(dctx)->uctx, len)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyList_New(get_info(dctx)->uctx, len); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_List_Append(HPyContext *dctx, DHPy h_list, DHPy h_item) { - return HPyList_Append(get_info(dctx)->uctx, DHPy_unwrap(dctx, h_list), DHPy_unwrap(dctx, h_item)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h_list = DHPy_unwrap(dctx, h_list); + HPy dh_h_item = DHPy_unwrap(dctx, h_item); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyList_Append(get_info(dctx)->uctx, dh_h_list, dh_h_item); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Dict_Check(HPyContext *dctx, DHPy h) { - return HPyDict_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyDict_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Dict_New(HPyContext *dctx) { - return DHPy_open(dctx, HPyDict_New(get_info(dctx)->uctx)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyDict_New(get_info(dctx)->uctx); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } int debug_ctx_Tuple_Check(HPyContext *dctx, DHPy h) { - return HPyTuple_Check(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyTuple_Check(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_Import_ImportModule(HPyContext *dctx, const char *utf8_name) { - return DHPy_open(dctx, HPyImport_ImportModule(get_info(dctx)->uctx, utf8_name)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyImport_ImportModule(get_info(dctx)->uctx, utf8_name); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } DHPy debug_ctx_Capsule_New(HPyContext *dctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) { - return DHPy_open(dctx, HPyCapsule_New(get_info(dctx)->uctx, pointer, utf8_name, destructor)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyCapsule_New(get_info(dctx)->uctx, pointer, utf8_name, destructor); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } void *debug_ctx_Capsule_Get(HPyContext *dctx, DHPy capsule, _HPyCapsule_key key, const char *utf8_name) { - return HPyCapsule_Get(get_info(dctx)->uctx, DHPy_unwrap(dctx, capsule), key, utf8_name); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_capsule = DHPy_unwrap(dctx, capsule); + get_ctx_info(dctx)->is_valid = false; + void * universal_result = HPyCapsule_Get(get_info(dctx)->uctx, dh_capsule, key, utf8_name); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Capsule_IsValid(HPyContext *dctx, DHPy capsule, const char *utf8_name) { - return HPyCapsule_IsValid(get_info(dctx)->uctx, DHPy_unwrap(dctx, capsule), utf8_name); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_capsule = DHPy_unwrap(dctx, capsule); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyCapsule_IsValid(get_info(dctx)->uctx, dh_capsule, utf8_name); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } int debug_ctx_Capsule_Set(HPyContext *dctx, DHPy capsule, _HPyCapsule_key key, void *value) { - return HPyCapsule_Set(get_info(dctx)->uctx, DHPy_unwrap(dctx, capsule), key, value); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_capsule = DHPy_unwrap(dctx, capsule); + get_ctx_info(dctx)->is_valid = false; + int universal_result = HPyCapsule_Set(get_info(dctx)->uctx, dh_capsule, key, value); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } DHPy debug_ctx_FromPyObject(HPyContext *dctx, cpy_PyObject *obj) { - return DHPy_open(dctx, HPy_FromPyObject(get_info(dctx)->uctx, obj)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPy_FromPyObject(get_info(dctx)->uctx, obj); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } cpy_PyObject *debug_ctx_AsPyObject(HPyContext *dctx, DHPy h) { - return HPy_AsPyObject(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + cpy_PyObject * universal_result = HPy_AsPyObject(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } void debug_ctx_Field_Store(HPyContext *dctx, DHPy target_object, HPyField *target_field, DHPy h) { - HPyField_Store(get_info(dctx)->uctx, DHPy_unwrap(dctx, target_object), target_field, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_target_object = DHPy_unwrap(dctx, target_object); + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPyField_Store(get_info(dctx)->uctx, dh_target_object, target_field, dh_h); + get_ctx_info(dctx)->is_valid = true; } DHPy debug_ctx_Field_Load(HPyContext *dctx, DHPy source_object, HPyField source_field) { - return DHPy_open(dctx, HPyField_Load(get_info(dctx)->uctx, DHPy_unwrap(dctx, source_object), source_field)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_source_object = DHPy_unwrap(dctx, source_object); + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyField_Load(get_info(dctx)->uctx, dh_source_object, source_field); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } void debug_ctx_ReenterPythonExecution(HPyContext *dctx, HPyThreadState state) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; HPy_ReenterPythonExecution(get_info(dctx)->uctx, state); + get_ctx_info(dctx)->is_valid = true; } HPyThreadState debug_ctx_LeavePythonExecution(HPyContext *dctx) { - return HPy_LeavePythonExecution(get_info(dctx)->uctx); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPyThreadState universal_result = HPy_LeavePythonExecution(get_info(dctx)->uctx); + get_ctx_info(dctx)->is_valid = true; + return universal_result; } void debug_ctx_Global_Store(HPyContext *dctx, HPyGlobal *global, DHPy h) { - HPyGlobal_Store(get_info(dctx)->uctx, global, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + HPyGlobal_Store(get_info(dctx)->uctx, global, dh_h); + get_ctx_info(dctx)->is_valid = true; } DHPy debug_ctx_Global_Load(HPyContext *dctx, HPyGlobal global) { - return DHPy_open(dctx, HPyGlobal_Load(get_info(dctx)->uctx, global)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + get_ctx_info(dctx)->is_valid = false; + HPy universal_result = HPyGlobal_Load(get_info(dctx)->uctx, global); + get_ctx_info(dctx)->is_valid = true; + return DHPy_open(dctx, universal_result); } void debug_ctx_Dump(HPyContext *dctx, DHPy h) { - _HPy_Dump(get_info(dctx)->uctx, DHPy_unwrap(dctx, h)); + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } + HPy dh_h = DHPy_unwrap(dctx, h); + get_ctx_info(dctx)->is_valid = false; + _HPy_Dump(get_info(dctx)->uctx, dh_h); + get_ctx_info(dctx)->is_valid = true; } diff --git a/hpy/debug/src/debug_ctx.c b/hpy/debug/src/debug_ctx.c index 8340f0c8e..4c6af4e70 100644 --- a/hpy/debug/src/debug_ctx.c +++ b/hpy/debug/src/debug_ctx.c @@ -13,6 +13,42 @@ static struct _HPyContext_s g_debug_ctx = { .abi_version = HPY_ABI_VERSION, }; +static HPyDebugCtxInfo *init_ctx_info(HPyContext *dctx, HPyContext *uctx) { + HPyDebugCtxInfo *ctx_info = (HPyDebugCtxInfo*) malloc(sizeof(HPyDebugCtxInfo)); + if (ctx_info == NULL) { + HPyErr_NoMemory(uctx); + return NULL; + } + dctx->_private = ctx_info; + ctx_info->magic_number = HPY_DEBUG_CTX_INFO_MAGIC; + ctx_info->is_valid = false; + return ctx_info; +} + +static HPyContext *copy_debug_context(HPyContext *dctx) { + HPyDebugInfo *info = get_info(dctx); + HPyContext *new_dcxt = (HPyContext *) malloc(sizeof(struct _HPyContext_s)); + memcpy(new_dcxt, dctx, sizeof(struct _HPyContext_s)); + HPyDebugCtxInfo *ctx_info = init_ctx_info(new_dcxt, info->uctx); + if (ctx_info == NULL) { + return NULL; + } + ctx_info->info = info; + return new_dcxt; +} + +static int init_dctx_cache(HPyContext *dctx, HPyDebugInfo *info) { + // We prefill the context cache to keep it simple + for (size_t i = 0; i < HPY_DEBUG_CTX_CACHE_SIZE; ++i) { + info->dctx_cache[i] = copy_debug_context(dctx); + if (info->dctx_cache[i] == NULL) { + return -1; + } + } + info->dctx_cache_current_index = 0; + return 0; +} + // NOTE: at the moment this function assumes that uctx is always the // same. If/when we migrate to a system in which we can have multiple // independent contexts, this function should ensure to create a different @@ -25,13 +61,19 @@ int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) return 0; } // initialize debug_info - // XXX: currently we never free this malloc - HPyDebugInfo *info = malloc(sizeof(HPyDebugInfo)); + // XXX: currently we never free this malloc and + // the allocations of the cached debug contexts + HPyDebugCtxInfo *ctx_info = init_ctx_info(dctx, uctx); + if (ctx_info == NULL) { + return -1; + } + ctx_info->is_valid = true; + HPyDebugInfo *info = ctx_info->info = malloc(sizeof(HPyDebugInfo)); if (info == NULL) { HPyErr_NoMemory(uctx); return -1; } - info->magic_number = HPY_DEBUG_MAGIC; + info->magic_number = HPY_DEBUG_INFO_MAGIC; info->uctx = uctx; info->current_generation = 0; info->uh_on_invalid_handle = HPy_NULL; @@ -42,8 +84,10 @@ int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) DHQueue_init(&info->open_handles); DHQueue_init(&info->closed_handles); DHQueue_init(&info->closed_builder); - dctx->_private = info; debug_ctx_init_fields(dctx, uctx); + if (init_dctx_cache(dctx, info) != 0) { + return -1; + } return 0; } @@ -113,13 +157,38 @@ static void hpy_magic_dump(HPy h) } } +HPyContext* hpy_debug_get_next_dctx_from_cache(HPyContext *dctx) { + HPyDebugInfo *info = get_info(dctx); + HPyContext *result = info->dctx_cache[info->dctx_cache_current_index]; + info->dctx_cache_current_index = + (info->dctx_cache_current_index + 1) % HPY_DEBUG_CTX_CACHE_SIZE; + return result; +} + +void report_invalid_debug_context() { + fputs("Error: Wrong HPy Context!\n", stderr); + char *stacktrace; + create_stacktrace(&stacktrace, HPY_DEBUG_DEFAULT_STACKTRACE_LIMIT); + if (stacktrace != NULL) { + fputs(stacktrace, stderr); + } + fflush(stderr); + abort(); +} + /* ~~~~~~~~~~ manually written wrappers ~~~~~~~~~~ */ void debug_ctx_Close(HPyContext *dctx, DHPy dh) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } UHPy uh = DHPy_unwrap(dctx, dh); DHPy_close(dctx, dh); + // Note: this may run __del__ + get_ctx_info(dctx)->is_valid = false; HPy_Close(get_info(dctx)->uctx, uh); + get_ctx_info(dctx)->is_valid = true; } static void * @@ -144,6 +213,9 @@ protect_and_associate_data_ptr(DHPy h, void *ptr, HPy_ssize_t data_size) const char *debug_ctx_Unicode_AsUTF8AndSize(HPyContext *dctx, DHPy h, HPy_ssize_t *size) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } const char *ptr = HPyUnicode_AsUTF8AndSize(get_info(dctx)->uctx, DHPy_unwrap(dctx, h), size); HPy_ssize_t data_size = 0; if (ptr != NULL) { @@ -154,6 +226,9 @@ const char *debug_ctx_Unicode_AsUTF8AndSize(HPyContext *dctx, DHPy h, HPy_ssize_ const char *debug_ctx_Bytes_AsString(HPyContext *dctx, DHPy h) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } HPyContext *uctx = get_info(dctx)->uctx; UHPy uh = DHPy_unwrap(dctx, h); const char *ptr = HPyBytes_AsString(uctx, uh); @@ -167,6 +242,9 @@ const char *debug_ctx_Bytes_AsString(HPyContext *dctx, DHPy h) const char *debug_ctx_Bytes_AS_STRING(HPyContext *dctx, DHPy h) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } HPyContext *uctx = get_info(dctx)->uctx; UHPy uh = DHPy_unwrap(dctx, h); const char *ptr = HPyBytes_AS_STRING(uctx, uh); @@ -180,6 +258,9 @@ const char *debug_ctx_Bytes_AS_STRING(HPyContext *dctx, DHPy h) DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, DHPy dh_items[], HPy_ssize_t n) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } UHPy *uh_items = (UHPy *)alloca(n * sizeof(UHPy)); for(int i=0; iis_valid) { + report_invalid_debug_context(); + } UHPy uh_type = DHPy_unwrap(dctx, dh_type); UHPy uh_kw = DHPy_unwrap(dctx, dh_kw); UHPy *uh_args = (UHPy *)alloca(nargs * sizeof(UHPy)); for(int i=0; iuctx, uh_type, uh_args, - nargs, uh_kw)); + get_ctx_info(dctx)->is_valid = false; + HPy uh_result = HPyType_GenericNew(get_info(dctx)->uctx, uh_type, uh_args, + nargs, uh_kw); + DHPy dh_result = DHPy_open(dctx, uh_result); + get_ctx_info(dctx)->is_valid = true; + return dh_result; } DHPy debug_ctx_Type_FromSpec(HPyContext *dctx, HPyType_Spec *spec, HPyType_SpecParam *dparams) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } // dparams might contain some hidden DHPy: we need to manually unwrap them. if (dparams != NULL) { // count the params @@ -245,6 +336,9 @@ static const char *get_builtin_shape_name(HPyType_BuiltinShape shape) #define MAKE_debug_ctx_AsStruct(SHAPE) \ void *debug_ctx_AsStruct_##SHAPE(HPyContext *dctx, DHPy dh) \ { \ + if (!get_ctx_info(dctx)->is_valid) { \ + report_invalid_debug_context(); \ + } \ HPyContext *uctx = get_info(dctx)->uctx; \ UHPy uh = DHPy_unwrap(dctx, dh); \ UHPy uh_type = HPy_Type(uctx, uh); \ @@ -315,21 +409,33 @@ MAKE_debug_ctx_AsStruct(List) HPyTracker debug_ctx_Tracker_New(HPyContext *dctx, HPy_ssize_t size) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } return ctx_Tracker_New(dctx, size); } int debug_ctx_Tracker_Add(HPyContext *dctx, HPyTracker ht, DHPy dh) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } return ctx_Tracker_Add(dctx, ht, dh); } void debug_ctx_Tracker_ForgetAll(HPyContext *dctx, HPyTracker ht) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } ctx_Tracker_ForgetAll(dctx, ht); } void debug_ctx_Tracker_Close(HPyContext *dctx, HPyTracker ht) { + if (!get_ctx_info(dctx)->is_valid) { + report_invalid_debug_context(); + } // note: ctx_Tracker_Close internally calls HPy_Close() to close each // handle: since we are calling it with the dctx, it will end up calling // debug_ctx_Close, which is exactly what we need to properly record that diff --git a/hpy/debug/src/debug_ctx_cpython.c b/hpy/debug/src/debug_ctx_cpython.c index e26d16d14..a49fa7b4e 100644 --- a/hpy/debug/src/debug_ctx_cpython.c +++ b/hpy/debug/src/debug_ctx_cpython.c @@ -80,8 +80,24 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPyFunc_noargs f = (HPyFunc_noargs)func; _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; DHPy dh_self = _py2dh(dctx, a->self); - DHPy dh_result = f(dctx, dh_self); - DHPy_close_and_check(dctx, dh_self); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + DHPy dh_result = f(next_dctx, dh_self); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + + DHPy_close_and_check(dctx, dh_self); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); return; @@ -91,7 +107,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, _HPyFunc_args_O *a = (_HPyFunc_args_O*)args; DHPy dh_self = _py2dh(dctx, a->self); DHPy dh_arg = _py2dh(dctx, a->arg); - DHPy dh_result = f(dctx, dh_self, dh_arg); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + DHPy dh_result = f(next_dctx, dh_self, dh_arg); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); DHPy_close_and_check(dctx, dh_arg); a->result = _dh2py(dctx, dh_result); @@ -106,7 +138,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, for (HPy_ssize_t i = 0; i < a->nargs; i++) { dh_args[i] = _py2dh(dctx, a->args[i]); } - DHPy dh_result = f(dctx, dh_self, dh_args, a->nargs); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + DHPy dh_result = f(next_dctx, dh_self, dh_args, a->nargs); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); for (HPy_ssize_t i = 0; i < a->nargs; i++) { DHPy_close_and_check(dctx, dh_args[i]); @@ -125,7 +173,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); } DHPy dh_kw = _py2dh(dctx, a->kw); - DHPy dh_result = f(dctx, dh_self, dh_args, nargs, dh_kw); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = NULL; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); for (Py_ssize_t i = 0; i < nargs; i++) { DHPy_close_and_check(dctx, dh_args[i]); @@ -145,7 +209,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); } DHPy dh_kw = _py2dh(dctx, a->kw); - a->result = f(dctx, dh_self, dh_args, nargs, dh_kw); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + a->result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); for (Py_ssize_t i = 0; i < nargs; i++) { DHPy_close_and_check(dctx, dh_args[i]); @@ -158,7 +238,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, _HPyFunc_args_GETBUFFERPROC *a = (_HPyFunc_args_GETBUFFERPROC*)args; HPy_buffer hbuf; DHPy dh_self = _py2dh(dctx, a->self); - a->result = f(dctx, dh_self, &hbuf, a->flags); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + a->result = f(next_dctx, dh_self, &hbuf, a->flags); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); if (a->result < 0) { a->view->obj = NULL; @@ -174,7 +270,22 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPy_buffer hbuf; _buffer_py2h(dctx, a->view, &hbuf); DHPy dh_self = _py2dh(dctx, a->self); - f(dctx, dh_self, &hbuf); + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + + f(next_dctx, dh_self, &hbuf); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + DHPy_close_and_check(dctx, dh_self); // XXX: copy back from hbuf? HPy_Close(dctx, hbuf.obj); @@ -183,8 +294,23 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, case HPyFunc_TRAVERSEPROC: { HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; + + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(dctx); + a->result = -1; + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; + return; + } + get_ctx_info(dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + a->result = call_traverseproc_from_trampoline(f, a->self, a->visit, a->arg); + + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(dctx)->is_valid = true; return; } case HPyFunc_CAPSULE_DESTRUCTOR: { diff --git a/hpy/debug/src/debug_internal.h b/hpy/debug/src/debug_internal.h index 816678bb2..af21732c7 100644 --- a/hpy/debug/src/debug_internal.h +++ b/hpy/debug/src/debug_internal.h @@ -8,7 +8,8 @@ #include "hpy.h" #include "hpy_debug.h" -#define HPY_DEBUG_MAGIC 0xDEB00FF +#define HPY_DEBUG_INFO_MAGIC 0xDEB00FF +#define HPY_DEBUG_CTX_INFO_MAGIC 0xDDA003F /* === DHQueue === */ @@ -277,13 +278,31 @@ BUILDER_UNWRAP(HPyListBuilder, list_builder) static const HPy_ssize_t DEFAULT_CLOSED_HANDLES_QUEUE_MAX_SIZE = 1024; static const HPy_ssize_t DEFAULT_PROTECTED_RAW_DATA_MAX_SIZE = 1024 * 1024 * 10; +static const HPy_ssize_t HPY_DEBUG_DEFAULT_STACKTRACE_LIMIT = 16; +#define HPY_DEBUG_CTX_CACHE_SIZE 16 // Keep in sync with test_context_reuse.py + +// We intentionally create multiple HPyContext instances to check that +// the extension is not relying on the HPyContext identity. Before bouncing +// to HPy function in the CallRealFunctionFromTrampoline, we take next debug +// context copy from a circular buffer and mark the current one as invalid. +// +// HPyDebugInfo: represents meta-data shared between all the copies of the +// debug context. +// +// HPyDebugCtxInfo represents meta-data specific to each debug context +// instance. At this point it is main flag is_valid that is checked by all +// the context functions as the first thing. typedef struct { long magic_number; // used just for sanity checks HPyContext *uctx; long current_generation; - // the following should be an HPyField, but it's complicated: + // Array of cached debug contexts used as a circular buffer + HPyContext *dctx_cache[HPY_DEBUG_CTX_CACHE_SIZE]; + size_t dctx_cache_current_index; + + // the following should be an HPyField, but it's complicate: // HPyFields should be used only on memory which is known by the GC, which // happens automatically if you use e.g. HPy_New, but currently // HPy_DebugInfo is malloced(). We need either: @@ -305,14 +324,31 @@ typedef struct { DHQueue closed_builder; } HPyDebugInfo; +typedef struct { + long magic_number; // used just for sanity checks + bool is_valid; + HPyDebugInfo *info; +} HPyDebugCtxInfo; + +static inline HPyDebugCtxInfo *get_ctx_info(HPyContext *dctx) +{ + HPyDebugCtxInfo *info = (HPyDebugCtxInfo*)dctx->_private; + assert(info->magic_number == HPY_DEBUG_CTX_INFO_MAGIC); // sanity check + return info; +} + static inline HPyDebugInfo *get_info(HPyContext *dctx) { - HPyDebugInfo *info = (HPyDebugInfo*)dctx->_private; - assert(info->magic_number == HPY_DEBUG_MAGIC); // sanity check + HPyDebugInfo *info = get_ctx_info(dctx)->info; + assert(info->magic_number == HPY_DEBUG_INFO_MAGIC); // sanity check return info; } +HPyContext* hpy_debug_get_next_dctx_from_cache(HPyContext *dctx); + +void report_invalid_debug_context(); + void *raw_data_copy(const void* data, HPy_ssize_t size, bool write_protect); void raw_data_protect(void* data, HPy_ssize_t size); /* Return value: 0 indicates success, any different value indicates an error */ diff --git a/hpy/tools/autogen/debug.py b/hpy/tools/autogen/debug.py index b9b516065..a13319477 100644 --- a/hpy/tools/autogen/debug.py +++ b/hpy/tools/autogen/debug.py @@ -115,31 +115,44 @@ def gen_debug_wrapper(self, func): signature = toC(node) rettype = get_context_return_type(node, const_return) # - def get_params(): + def get_params_and_decls(): lst = [] + decls = [] for p in node.type.args.params: if p.name == 'ctx': lst.append('get_info(dctx)->uctx') elif toC(p.type) == 'DHPy': - lst.append('DHPy_unwrap(dctx, %s)' % p.name) + decls.append(' HPy dh_%s = DHPy_unwrap(dctx, %s);' % (p.name, p.name)) + lst.append('dh_%s' % p.name) elif toC(p.type) in ('DHPy *', 'DHPy []'): assert False, ('C type %s not supported, please write the wrapper ' 'for %s by hand' % (toC(p.type), func.name)) else: lst.append(p.name) - return ', '.join(lst) - params = get_params() + return (', '.join(lst), '\n'.join(decls)) + (params, param_decls) = get_params_and_decls() # lines = [] w = lines.append w(signature) w('{') + w(' if (!get_ctx_info(dctx)->is_valid) {') + w(' report_invalid_debug_context();') + w(' }') + if param_decls: + w(param_decls) + w(' get_ctx_info(dctx)->is_valid = false;') if rettype == 'void': w(f' {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') elif rettype == 'DHPy': - w(f' return DHPy_open(dctx, {func.name}({params}));') + w(f' HPy universal_result = {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') + w(' return DHPy_open(dctx, universal_result);') else: - w(f' return {func.name}({params});') + w(f' {rettype} universal_result = {func.name}({params});') + w(' get_ctx_info(dctx)->is_valid = true;') + w(' return universal_result;') w('}') return '\n'.join(lines) @@ -157,7 +170,7 @@ def generate(self): continue # c_ret_type = toC(hpyfunc.return_type()) - args = ['dctx'] + args = ['next_dctx'] dhpys = [] for i, param in enumerate(hpyfunc.params()[1:]): pname = param.name @@ -176,6 +189,22 @@ def generate(self): for pname in dhpys: w(f' DHPy dh_{pname} = _py2dh(dctx, a->{pname});') # + w(' HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx);') + w(' if (next_dctx == NULL) {') + w(' HPyErr_NoMemory(dctx);') + if c_ret_type == 'HPy': + w(' a->result = NULL;') + elif c_ret_type == 'int' or c_ret_type == 'HPy_ssize_t' or c_ret_type == 'HPy_hash_t': + w(' a->result = -1;') + else: + assert c_ret_type == 'void', c_ret_type + " not implemented" + w(' get_ctx_info(next_dctx)->is_valid = false;') + w(' get_ctx_info(dctx)->is_valid = true;') + w(' return;') + w(' }') + w(' get_ctx_info(dctx)->is_valid = false;') + w(' get_ctx_info(next_dctx)->is_valid = true;') + # if c_ret_type == 'void': w(f' f({args});') elif c_ret_type == 'HPy': @@ -183,6 +212,9 @@ def generate(self): else: w(f' a->result = f({args});') # + w(' get_ctx_info(next_dctx)->is_valid = false;') + w(' get_ctx_info(dctx)->is_valid = true;') + # for pname in dhpys: w(f' DHPy_close_and_check(dctx, dh_{pname});') # diff --git a/test/debug/test_context_reuse.py b/test/debug/test_context_reuse.py new file mode 100644 index 000000000..e3a57d316 --- /dev/null +++ b/test/debug/test_context_reuse.py @@ -0,0 +1,102 @@ +import pytest + +@pytest.fixture +def hpy_abi(): + return "debug" + + +def test_reuse_context_from_global_variable(compiler, python_subprocess): + mod = compiler.compile_module(""" + #include + + HPyContext *keep; + + HPyDef_METH(f, "f", HPyFunc_NOARGS) + static HPy f_impl(HPyContext *ctx, HPy self) + { + // We wrongly save the context to a global variable + keep = ctx; + return HPy_Dup(ctx, ctx->h_None); + } + + HPyDef_METH(g, "g", HPyFunc_NOARGS) + static HPy g_impl(HPyContext *ctx, HPy self) + { + HPy t = HPy_Dup(ctx, ctx->h_True); + // just checking if the correct context works + if (!HPy_TypeCheck(ctx, t, ctx->h_BoolType)) { + // if the correct context gives us bogus result, + // this will make the test fail + HPy_Close(ctx, t); + return HPy_Dup(ctx, ctx->h_None); + } + HPy_Close(ctx, t); + fprintf(stdout, "Heavy Marmelade\\n"); + fflush(stdout); + // Here we wrongly use "keep" instead of "ctx" + return HPy_Dup(keep, ctx->h_None); + } + + HPyDef_METH(bounce, "bounce", HPyFunc_O) + static HPy bounce_impl(HPyContext *ctx, HPy self, HPy trampoline) + { + fprintf(stdout, "Bouncing...\\n"); + fflush(stdout); + return HPy_CallTupleDict(ctx, trampoline, HPy_NULL, HPy_NULL); + } + + HPyDef_METH(keep_and_bounce, "keep_and_bounce", HPyFunc_O) + static HPy keep_and_bounce_impl(HPyContext *ctx, HPy self, HPy trampoline) + { + fprintf(stdout, "Bouncing differently...\\n"); + fflush(stdout); + keep = ctx; + return HPy_CallTupleDict(ctx, trampoline, HPy_NULL, HPy_NULL); + } + + @EXPORT(f) + @EXPORT(g) + @EXPORT(bounce) + @EXPORT(keep_and_bounce) + @INIT + """) + + code = "mod.f(); mod.g()" + result = python_subprocess.run(mod, code) + assert result.returncode != 0 + assert b"Error: Wrong HPy Context!" in result.stderr + assert result.stdout == b"Heavy Marmelade\n" + + code = "mod.f(); mod.bounce(lambda: mod.g())" + result = python_subprocess.run(mod, code) + assert result.returncode != 0 + assert b"Error: Wrong HPy Context!" in result.stderr + assert result.stdout == b"Bouncing...\nHeavy Marmelade\n" + + # checks the situation when the context cache runs out, + # and we start reusing cached contexts + code = "mod.f(); bounce_cnt = {};\n" \ + "def trampoline():\n" \ + " global bounce_cnt\n" \ + " bounce_cnt -= 1\n" \ + " return mod.bounce(trampoline) if bounce_cnt > 0 else mod.g()\n" \ + "mod.bounce(trampoline)" + + # With the reference HPy debug context implementation if we happen to run + # the usage of 'keep' on the same recycled context as when we saved 'keep', + # then ctx == keep, and it will not fail. + # To keep the test implementation agnostic, we just stress test it with + # different numbers and check that it either crashes with the right error + # or it does not crash and gives the correct result. + HPY_DEBUG_CTX_CACHE_SIZE = 16 + for size in range(HPY_DEBUG_CTX_CACHE_SIZE-1, HPY_DEBUG_CTX_CACHE_SIZE+2): + result = python_subprocess.run(mod, code.format(size)) + assert result.stdout == (b"Bouncing...\n" * size) + b"Heavy Marmelade\n" + if result.returncode != 0: + assert b"Error: Wrong HPy Context!" in result.stderr + + code = 'mod.keep_and_bounce(lambda: mod.g())' + result = python_subprocess.run(mod, code) + assert result.returncode != 0 + assert b"Error: Wrong HPy Context!" in result.stderr + assert result.stdout == b"Bouncing differently...\n" + b"Heavy Marmelade\n" From 96fe05838d8f1229ff191f4b67a849d2701e77bf Mon Sep 17 00:00:00 2001 From: stepan Date: Tue, 6 Dec 2022 12:02:24 +0100 Subject: [PATCH 5/5] Factor out common code in debug_ctx_cpython.c --- hpy/debug/src/autogen_debug_ctx_call.i | 260 +++++-------------------- hpy/debug/src/debug_ctx_cpython.c | 98 ++++------ hpy/tools/autogen/debug.py | 10 +- 3 files changed, 88 insertions(+), 280 deletions(-) diff --git a/hpy/debug/src/autogen_debug_ctx_call.i b/hpy/debug/src/autogen_debug_ctx_call.i index 44cbbca52..e2d910305 100644 --- a/hpy/debug/src/autogen_debug_ctx_call.i +++ b/hpy/debug/src/autogen_debug_ctx_call.i @@ -14,19 +14,13 @@ HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -37,19 +31,13 @@ _HPyFunc_args_BINARYFUNC *a = (_HPyFunc_args_BINARYFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -62,19 +50,13 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -86,19 +68,13 @@ HPyFunc_inquiry f = (HPyFunc_inquiry)func; _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); return; } @@ -106,19 +82,13 @@ HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); return; } @@ -126,19 +96,13 @@ HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -148,19 +112,13 @@ HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, a->arg1, a->arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -171,19 +129,13 @@ _HPyFunc_args_SSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZEOBJARGPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg2); return; @@ -193,19 +145,13 @@ _HPyFunc_args_SSIZESSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZESSIZEOBJARGPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg3 = _py2dh(dctx, a->arg3); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, a->arg1, a->arg2, dh_arg3); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg3); return; @@ -216,19 +162,13 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -237,37 +177,25 @@ case HPyFunc_FREEFUNC: { HPyFunc_freefunc f = (HPyFunc_freefunc)func; _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; f(next_dctx, a->arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); return; } case HPyFunc_GETATTRFUNC: { HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)func; _HPyFunc_args_GETATTRFUNC *a = (_HPyFunc_args_GETATTRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -278,19 +206,13 @@ _HPyFunc_args_GETATTROFUNC *a = (_HPyFunc_args_GETATTROFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -302,19 +224,13 @@ _HPyFunc_args_SETATTRFUNC *a = (_HPyFunc_args_SETATTRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg2); return; @@ -325,19 +241,13 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -347,19 +257,13 @@ HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -369,19 +273,13 @@ HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); return; } @@ -390,19 +288,13 @@ _HPyFunc_args_RICHCMPFUNC *a = (_HPyFunc_args_RICHCMPFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); a->result = _dh2py(dctx, dh_result); @@ -413,19 +305,13 @@ HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -435,19 +321,13 @@ HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -459,19 +339,13 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -485,19 +359,13 @@ DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); DHPy_close_and_check(dctx, dh_arg2); @@ -507,19 +375,13 @@ HPyFunc_getter f = (HPyFunc_getter)func; _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); a->result = _dh2py(dctx, dh_result); DHPy_close(dctx, dh_result); @@ -530,19 +392,13 @@ _HPyFunc_args_SETTER *a = (_HPyFunc_args_SETTER*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); return; @@ -552,19 +408,13 @@ _HPyFunc_args_OBJOBJPROC *a = (_HPyFunc_args_OBJOBJPROC*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); DHPy dh_arg1 = _py2dh(dctx, a->arg1); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_arg0, dh_arg1); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); DHPy_close_and_check(dctx, dh_arg1); return; @@ -573,18 +423,12 @@ HPyFunc_destructor f = (HPyFunc_destructor)func; _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; f(next_dctx, dh_arg0); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_arg0); return; } diff --git a/hpy/debug/src/debug_ctx_cpython.c b/hpy/debug/src/debug_ctx_cpython.c index a49fa7b4e..1e8f63a2c 100644 --- a/hpy/debug/src/debug_ctx_cpython.c +++ b/hpy/debug/src/debug_ctx_cpython.c @@ -71,6 +71,24 @@ static void _buffer_py2h(HPyContext *dctx, const Py_buffer *src, HPy_buffer *des dest->internal = src->internal; } +static HPyContext* _switch_to_next_dctx_from_cache(HPyContext *current_dctx) { + HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(current_dctx); + if (next_dctx == NULL) { + HPyErr_NoMemory(current_dctx); + get_ctx_info(current_dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return NULL; + } + get_ctx_info(current_dctx)->is_valid = false; + get_ctx_info(next_dctx)->is_valid = true; + return next_dctx; +} + +static void _switch_back_to_original_dctx(HPyContext *original_dctx, HPyContext *next_dctx) { + get_ctx_info(next_dctx)->is_valid = false; + get_ctx_info(original_dctx)->is_valid = true; +} + void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPyFunc_Signature sig, void *func, void *args) @@ -81,21 +99,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; DHPy dh_self = _py2dh(dctx, a->self); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_self); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); a->result = _dh2py(dctx, dh_result); @@ -108,21 +120,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, DHPy dh_self = _py2dh(dctx, a->self); DHPy dh_arg = _py2dh(dctx, a->arg); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_self, dh_arg); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); DHPy_close_and_check(dctx, dh_arg); @@ -139,21 +145,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, dh_args[i] = _py2dh(dctx, a->args[i]); } - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_self, dh_args, a->nargs); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); for (HPy_ssize_t i = 0; i < a->nargs; i++) { @@ -174,21 +174,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, } DHPy dh_kw = _py2dh(dctx, a->kw); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = NULL; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); for (Py_ssize_t i = 0; i < nargs; i++) { @@ -210,21 +204,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, } DHPy dh_kw = _py2dh(dctx, a->kw); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); for (Py_ssize_t i = 0; i < nargs; i++) { @@ -239,21 +227,15 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPy_buffer hbuf; DHPy dh_self = _py2dh(dctx, a->self); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = f(next_dctx, dh_self, &hbuf, a->flags); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); if (a->result < 0) { @@ -271,20 +253,14 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, _buffer_py2h(dctx, a->view, &hbuf); DHPy dh_self = _py2dh(dctx, a->self); - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; f(next_dctx, dh_self, &hbuf); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); DHPy_close_and_check(dctx, dh_self); // XXX: copy back from hbuf? @@ -295,22 +271,16 @@ void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; - HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx); + HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); if (next_dctx == NULL) { - HPyErr_NoMemory(dctx); a->result = -1; - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; return; } - get_ctx_info(dctx)->is_valid = false; - get_ctx_info(next_dctx)->is_valid = true; a->result = call_traverseproc_from_trampoline(f, a->self, a->visit, a->arg); - get_ctx_info(next_dctx)->is_valid = false; - get_ctx_info(dctx)->is_valid = true; + _switch_back_to_original_dctx(dctx, next_dctx); return; } case HPyFunc_CAPSULE_DESTRUCTOR: { diff --git a/hpy/tools/autogen/debug.py b/hpy/tools/autogen/debug.py index a13319477..f5c835b90 100644 --- a/hpy/tools/autogen/debug.py +++ b/hpy/tools/autogen/debug.py @@ -189,21 +189,16 @@ def generate(self): for pname in dhpys: w(f' DHPy dh_{pname} = _py2dh(dctx, a->{pname});') # - w(' HPyContext *next_dctx = hpy_debug_get_next_dctx_from_cache(dctx);') + w(' HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx);') w(' if (next_dctx == NULL) {') - w(' HPyErr_NoMemory(dctx);') if c_ret_type == 'HPy': w(' a->result = NULL;') elif c_ret_type == 'int' or c_ret_type == 'HPy_ssize_t' or c_ret_type == 'HPy_hash_t': w(' a->result = -1;') else: assert c_ret_type == 'void', c_ret_type + " not implemented" - w(' get_ctx_info(next_dctx)->is_valid = false;') - w(' get_ctx_info(dctx)->is_valid = true;') w(' return;') w(' }') - w(' get_ctx_info(dctx)->is_valid = false;') - w(' get_ctx_info(next_dctx)->is_valid = true;') # if c_ret_type == 'void': w(f' f({args});') @@ -212,8 +207,7 @@ def generate(self): else: w(f' a->result = f({args});') # - w(' get_ctx_info(next_dctx)->is_valid = false;') - w(' get_ctx_info(dctx)->is_valid = true;') + w(' _switch_back_to_original_dctx(dctx, next_dctx);') # for pname in dhpys: w(f' DHPy_close_and_check(dctx, dh_{pname});')