From dbd8cfc818a3d318ac1766eb1584575155a284b9 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 30 Jul 2026 11:35:31 +0200 Subject: [PATCH] [GR-21590] Remove vendored HPy project --- THIRD_PARTY_LICENSE.txt | 26 - ci.jsonnet | 3 - ci/python-gate.libsonnet | 2 +- docs/contributor/DEV_TASKS.md | 10 - .../cext/PythonAbstractNativeObject.java | 3 - .../python/lib/PyMemoryViewFromObject.java | 4 +- graalpython/hpy/.gitattributes | 1 - graalpython/hpy/.github/FUNDING.yml | 1 - graalpython/hpy/.github/workflows/ci.yml | 427 --- .../hpy/.github/workflows/release-pypi.yml | 136 - .../hpy/.github/workflows/valgrind-tests.yml | 38 - graalpython/hpy/.gitignore | 92 - graalpython/hpy/.readthedocs.yml | 10 - graalpython/hpy/AUTHORS | 38 - graalpython/hpy/CONTRIBUTING.md | 55 - graalpython/hpy/LICENSE | 21 - graalpython/hpy/MANIFEST.in | 1 - graalpython/hpy/Makefile | 86 - graalpython/hpy/README-gdb.md | 207 -- graalpython/hpy/README.md | 81 - graalpython/hpy/build.py | 91 - graalpython/hpy/c_test/Makefile | 16 - graalpython/hpy/c_test/acutest.h | 1794 ------------ graalpython/hpy/c_test/test_debug_handles.c | 99 - graalpython/hpy/c_test/test_stacktrace.c | 22 - graalpython/hpy/docs/Makefile | 28 - graalpython/hpy/docs/_static/README.txt | 1 - graalpython/hpy/docs/_templates/README.txt | 1 - .../docs/api-reference/argument-parsing.rst | 5 - .../hpy/docs/api-reference/build-value.rst | 5 - .../hpy/docs/api-reference/formatting.rst | 5 - .../hpy/docs/api-reference/function-index.rst | 187 -- .../hpy/docs/api-reference/helpers.rst | 5 - .../hpy/docs/api-reference/hpy-call.rst | 5 - .../hpy/docs/api-reference/hpy-ctx.rst | 9 - .../hpy/docs/api-reference/hpy-dict.rst | 5 - .../hpy/docs/api-reference/hpy-err.rst | 5 - .../hpy/docs/api-reference/hpy-eval.rst | 8 - .../hpy/docs/api-reference/hpy-field.rst | 5 - .../hpy/docs/api-reference/hpy-gil.rst | 5 - .../hpy/docs/api-reference/hpy-global.rst | 5 - .../hpy/docs/api-reference/hpy-object.rst | 5 - .../hpy/docs/api-reference/hpy-sequence.rst | 23 - .../hpy/docs/api-reference/hpy-type.rst | 50 - graalpython/hpy/docs/api-reference/index.rst | 69 - .../hpy/docs/api-reference/inline-helpers.rst | 14 - .../hpy/docs/api-reference/public-api.rst | 9 - .../hpy/docs/api-reference/structseq.rst | 15 - graalpython/hpy/docs/api.rst | 581 ---- graalpython/hpy/docs/changelog.rst | 235 -- graalpython/hpy/docs/conf.py | 134 - graalpython/hpy/docs/contributing/index.rst | 33 - graalpython/hpy/docs/debug-mode.rst | 169 -- .../hpy/docs/examples/debug-example.py | 10 - .../examples/hpytype-example/builtin_type.c | 106 - .../docs/examples/hpytype-example/setup.py | 11 - .../examples/hpytype-example/simple_type.c | 102 - .../examples/hpytype-example/simple_type.rst | 8 - .../hpy/docs/examples/mixed-example/mixed.c | 49 - .../hpy/docs/examples/mixed-example/setup.py | 10 - .../hpy/docs/examples/quickstart/quickstart.c | 39 - .../hpy/docs/examples/quickstart/setup.py | 13 - .../hpy/docs/examples/simple-example/setup.py | 10 - .../hpy/docs/examples/simple-example/simple.c | 43 - .../hpy/docs/examples/snippets/hpycall.c | 196 -- .../hpy/docs/examples/snippets/hpyinit.c | 22 - .../hpy/docs/examples/snippets/hpyvarargs.c | 45 - .../hpy/docs/examples/snippets/legacyinit.c | 20 - .../hpy/docs/examples/snippets/setup.py | 16 - .../hpy/docs/examples/snippets/snippets.c | 81 - graalpython/hpy/docs/examples/tests.py | 124 - .../hpy/docs/examples/trace-example.py | 9 - graalpython/hpy/docs/index.rst | 80 - .../hpy/docs/leysin-2020-design-decisions.md | 295 -- graalpython/hpy/docs/misc/embedding.rst | 46 - graalpython/hpy/docs/misc/index.rst | 7 - graalpython/hpy/docs/module-state.txt | 44 - graalpython/hpy/docs/overview.rst | 444 --- .../hpy/docs/porting-example/index.rst | 356 --- .../hpy/docs/porting-example/steps/.gitignore | 1 - .../docs/porting-example/steps/conftest.py | 35 - .../hpy/docs/porting-example/steps/setup00.py | 12 - .../hpy/docs/porting-example/steps/setup01.py | 13 - .../hpy/docs/porting-example/steps/setup02.py | 13 - .../hpy/docs/porting-example/steps/setup03.py | 14 - .../porting-example/steps/step_00_c_api.c | 165 -- .../porting-example/steps/step_00_c_api.rst | 8 - .../steps/step_01_hpy_legacy.c | 189 -- .../steps/step_01_hpy_legacy.rst | 8 - .../steps/step_02_hpy_legacy.c | 169 -- .../steps/step_02_hpy_legacy.rst | 8 - .../porting-example/steps/step_03_hpy_final.c | 153 -- .../steps/step_03_hpy_final.rst | 8 - .../steps/test_porting_example.py | 60 - graalpython/hpy/docs/porting-guide.rst | 569 ---- graalpython/hpy/docs/quickstart.rst | 55 - graalpython/hpy/docs/requirements.txt | 8 - graalpython/hpy/docs/trace-mode.rst | 64 - graalpython/hpy/docs/xxx-unsorted-notes.txt | 91 - graalpython/hpy/gdb-py.test | 3 - graalpython/hpy/hpy/debug/__init__.py | 11 - graalpython/hpy/hpy/debug/leakdetector.py | 43 - graalpython/hpy/hpy/debug/pytest.py | 31 - graalpython/hpy/hpy/debug/src/_debugmod.c | 432 --- .../hpy/debug/src/autogen_debug_ctx_call.i | 468 ---- .../hpy/debug/src/autogen_debug_ctx_init.h | 478 ---- .../hpy/debug/src/autogen_debug_wrappers.c | 1870 ------------- graalpython/hpy/hpy/debug/src/debug_ctx.c | 687 ----- .../hpy/hpy/debug/src/debug_ctx_cpython.c | 299 -- .../hpy/hpy/debug/src/debug_ctx_not_cpython.c | 16 - graalpython/hpy/hpy/debug/src/debug_handles.c | 298 -- .../hpy/hpy/debug/src/debug_internal.h | 359 --- graalpython/hpy/hpy/debug/src/dhqueue.c | 121 - .../hpy/hpy/debug/src/include/hpy_debug.h | 57 - graalpython/hpy/hpy/debug/src/memprotect.c | 94 - graalpython/hpy/hpy/debug/src/stacktrace.c | 94 - graalpython/hpy/hpy/devel/__init__.py | 464 ---- graalpython/hpy/hpy/devel/abitag.py | 66 - graalpython/hpy/hpy/devel/include/hpy.h | 292 -- .../include/hpy/autogen_hpyfunc_declare.h | 87 - .../hpy/devel/include/hpy/autogen_hpyslot.h | 137 - .../hpy/hpy/devel/include/hpy/cpy_types.h | 49 - .../include/hpy/cpython/autogen_api_impl.h | 616 ----- .../devel/include/hpy/cpython/autogen_ctx.h | 100 - .../hpy/cpython/autogen_hpyfunc_trampolines.h | 203 -- .../include/hpy/cpython/hpyfunc_trampolines.h | 120 - .../hpy/hpy/devel/include/hpy/cpython/misc.h | 575 ---- .../include/hpy/forbid_python_h/Python.h | 6 - .../hpy/hpy/devel/include/hpy/hpydef.h | 461 ---- .../hpy/hpy/devel/include/hpy/hpyexports.h | 13 - .../hpy/hpy/devel/include/hpy/hpyfunc.h | 125 - .../hpy/hpy/devel/include/hpy/hpymodule.h | 164 -- .../hpy/hpy/devel/include/hpy/hpytype.h | 303 -- .../hpy/devel/include/hpy/inline_helpers.h | 537 ---- .../hpy/hpy/devel/include/hpy/macros.h | 70 - .../hpy/devel/include/hpy/runtime/argparse.h | 26 - .../devel/include/hpy/runtime/buildvalue.h | 9 - .../hpy/devel/include/hpy/runtime/ctx_funcs.h | 124 - .../devel/include/hpy/runtime/ctx_module.h | 25 - .../hpy/devel/include/hpy/runtime/ctx_type.h | 16 - .../hpy/devel/include/hpy/runtime/format.h | 18 - .../hpy/devel/include/hpy/runtime/helpers.h | 15 - .../hpy/devel/include/hpy/runtime/structseq.h | 108 - .../devel/include/hpy/universal/autogen_ctx.h | 290 -- .../universal/autogen_hpyfunc_trampolines.h | 416 --- .../hpy/universal/autogen_trampolines.h | 760 ------ .../hpy/universal/hpyfunc_trampolines.h | 177 -- .../include/hpy/universal/misc_trampolines.h | 86 - .../hpy/hpy/devel/src/runtime/argparse.c | 819 ------ .../hpy/hpy/devel/src/runtime/buildvalue.c | 431 --- .../hpy/hpy/devel/src/runtime/ctx_bytes.c | 25 - .../hpy/hpy/devel/src/runtime/ctx_call.c | 119 - .../hpy/hpy/devel/src/runtime/ctx_capsule.c | 81 - .../hpy/devel/src/runtime/ctx_contextvar.c | 16 - .../hpy/hpy/devel/src/runtime/ctx_err.c | 13 - .../hpy/hpy/devel/src/runtime/ctx_eval.c | 23 - .../hpy/devel/src/runtime/ctx_listbuilder.c | 58 - .../hpy/hpy/devel/src/runtime/ctx_long.c | 119 - .../hpy/hpy/devel/src/runtime/ctx_module.c | 152 -- .../hpy/hpy/devel/src/runtime/ctx_object.c | 105 - .../hpy/hpy/devel/src/runtime/ctx_tracker.c | 155 -- .../hpy/hpy/devel/src/runtime/ctx_tuple.c | 22 - .../hpy/devel/src/runtime/ctx_tuplebuilder.c | 65 - .../hpy/hpy/devel/src/runtime/ctx_type.c | 1633 ----------- .../hpy/hpy/devel/src/runtime/format.c | 737 ----- .../hpy/hpy/devel/src/runtime/helpers.c | 154 -- .../hpy/hpy/devel/src/runtime/structseq.c | 271 -- graalpython/hpy/hpy/tools/autogen/__init__.py | 21 - graalpython/hpy/hpy/tools/autogen/__main__.py | 67 - graalpython/hpy/hpy/tools/autogen/autogen.h | 40 - .../hpy/hpy/tools/autogen/autogenfile.py | 43 - graalpython/hpy/hpy/tools/autogen/conf.py | 211 -- graalpython/hpy/hpy/tools/autogen/ctx.py | 106 - graalpython/hpy/hpy/tools/autogen/debug.py | 228 -- graalpython/hpy/hpy/tools/autogen/doc.py | 174 -- graalpython/hpy/hpy/tools/autogen/hpyfunc.py | 204 -- graalpython/hpy/hpy/tools/autogen/hpyslot.py | 18 - graalpython/hpy/hpy/tools/autogen/parse.py | 278 -- .../hpy/hpy/tools/autogen/public_api.h | 1557 ----------- graalpython/hpy/hpy/tools/autogen/pypy.py | 40 - .../hpy/hpy/tools/autogen/testing/__init__.py | 0 .../hpy/tools/autogen/testing/test_autogen.py | 223 -- .../hpy/tools/autogen/testing/test_hpyfunc.py | 145 - graalpython/hpy/hpy/tools/autogen/trace.py | 182 -- .../hpy/hpy/tools/autogen/trampolines.py | 140 - graalpython/hpy/hpy/tools/include_path.py | 4 - graalpython/hpy/hpy/tools/valgrind/hpy.supp | 44 - .../hpy/hpy/tools/valgrind/python.supp | 389 --- graalpython/hpy/hpy/trace/__init__.py | 6 - graalpython/hpy/hpy/trace/src/_tracemod.c | 207 -- .../hpy/trace/src/autogen_trace_ctx_init.h | 495 ---- .../hpy/trace/src/autogen_trace_func_table.c | 306 --- .../hpy/trace/src/autogen_trace_wrappers.c | 2428 ----------------- .../hpy/hpy/trace/src/include/hpy_trace.h | 42 - graalpython/hpy/hpy/trace/src/trace_ctx.c | 147 - .../hpy/hpy/trace/src/trace_internal.h | 72 - graalpython/hpy/hpy/universal/src/api.h | 18 - .../hpy/hpy/universal/src/autogen_ctx_call.i | 180 -- .../hpy/hpy/universal/src/autogen_ctx_def.h | 207 -- .../hpy/hpy/universal/src/autogen_ctx_impl.h | 612 ----- graalpython/hpy/hpy/universal/src/ctx.c | 10 - graalpython/hpy/hpy/universal/src/ctx_meth.c | 136 - graalpython/hpy/hpy/universal/src/ctx_meth.h | 6 - graalpython/hpy/hpy/universal/src/ctx_misc.c | 83 - graalpython/hpy/hpy/universal/src/ctx_misc.h | 20 - graalpython/hpy/hpy/universal/src/handles.h | 58 - graalpython/hpy/hpy/universal/src/hpymodule.c | 688 ----- .../hpy/hpy/universal/src/misc_win32.h | 55 - graalpython/hpy/microbench/README.md | 29 - graalpython/hpy/microbench/_valgrind_build.py | 29 - graalpython/hpy/microbench/conftest.py | 124 - graalpython/hpy/microbench/pytest_valgrind.sh | 3 - graalpython/hpy/microbench/setup.py | 17 - graalpython/hpy/microbench/src/cpy_simple.c | 174 -- graalpython/hpy/microbench/src/hpy_simple.c | 135 - graalpython/hpy/microbench/test_microbench.py | 226 -- graalpython/hpy/proof-of-concept/pof.c | 109 - graalpython/hpy/proof-of-concept/pofcpp.cpp | 117 - .../hpy/proof-of-concept/pofpackage/bar.cpp | 45 - .../hpy/proof-of-concept/pofpackage/foo.c | 20 - .../hpy/proof-of-concept/requirements.txt | 1 - graalpython/hpy/proof-of-concept/setup.py | 36 - graalpython/hpy/proof-of-concept/test_pof.py | 44 - graalpython/hpy/proof-of-concept/test_pof.sh | 177 -- graalpython/hpy/pyproject.toml | 3 - graalpython/hpy/requirements-autogen.txt | 3 - graalpython/hpy/setup.py | 269 -- graalpython/hpy/test/__init__.py | 0 graalpython/hpy/test/check_py27_compat.py | 90 - graalpython/hpy/test/conftest.py | 112 - graalpython/hpy/test/debug/__init__.py | 0 .../hpy/test/debug/test_builder_invalid.py | 148 - graalpython/hpy/test/debug/test_charptr.py | 300 -- .../hpy/test/debug/test_context_reuse.py | 107 - .../hpy/test/debug/test_handles_invalid.py | 216 -- .../hpy/test/debug/test_handles_leak.py | 280 -- graalpython/hpy/test/debug/test_misc.py | 179 -- graalpython/hpy/test/hpy_devel/__init__.py | 0 graalpython/hpy/test/hpy_devel/test_abitag.py | 25 - .../hpy/test/hpy_devel/test_distutils.py | 364 --- graalpython/hpy/test/support.py | 601 ---- graalpython/hpy/test/test_00_basic.py | 580 ---- graalpython/hpy/test/test_argparse.py | 678 ----- graalpython/hpy/test/test_call.py | 329 --- graalpython/hpy/test/test_capsule.py | 471 ---- graalpython/hpy/test/test_capsule_legacy.py | 86 - graalpython/hpy/test/test_contextvar.py | 52 - graalpython/hpy/test/test_cpy_compat.py | 221 -- graalpython/hpy/test/test_eval.py | 87 - graalpython/hpy/test/test_helpers.py | 144 - graalpython/hpy/test/test_hpybuildvalue.py | 218 -- graalpython/hpy/test/test_hpybytes.py | 131 - graalpython/hpy/test/test_hpydict.py | 121 - graalpython/hpy/test/test_hpyerr.py | 711 ----- graalpython/hpy/test/test_hpyfield.py | 429 --- graalpython/hpy/test/test_hpyglobal.py | 38 - graalpython/hpy/test/test_hpyimport.py | 24 - graalpython/hpy/test/test_hpyiter.py | 90 - graalpython/hpy/test/test_hpylist.py | 112 - graalpython/hpy/test/test_hpylong.py | 440 --- graalpython/hpy/test/test_hpymodule.py | 287 -- graalpython/hpy/test/test_hpyslice.py | 138 - graalpython/hpy/test/test_hpystructseq.py | 123 - graalpython/hpy/test/test_hpytuple.py | 81 - graalpython/hpy/test/test_hpytype.py | 1685 ------------ graalpython/hpy/test/test_hpytype_legacy.py | 399 --- graalpython/hpy/test/test_hpyunicode.py | 977 ------- graalpython/hpy/test/test_importing.py | 55 - graalpython/hpy/test/test_legacy_forbidden.py | 74 - graalpython/hpy/test/test_number.py | 235 -- graalpython/hpy/test/test_object.py | 1040 ------- graalpython/hpy/test/test_slots.py | 833 ------ graalpython/hpy/test/test_slots_legacy.py | 265 -- graalpython/hpy/test/test_support.py | 50 - graalpython/hpy/test/test_tracker.py | 120 - graalpython/hpy/test/trace/test_trace.py | 127 - mx.graalpython/copyrights/hpy.copyright.hash | 23 - .../copyrights/hpy.copyright.hash.regex | 23 - mx.graalpython/copyrights/hpy.copyright.star | 24 - .../copyrights/hpy.copyright.star.regex | 24 - mx.graalpython/downstream_tests.py | 44 - mx.graalpython/mx_graalpython.py | 25 - mx.graalpython/suite.py | 21 - 283 files changed, 3 insertions(+), 51036 deletions(-) delete mode 100644 graalpython/hpy/.gitattributes delete mode 100644 graalpython/hpy/.github/FUNDING.yml delete mode 100644 graalpython/hpy/.github/workflows/ci.yml delete mode 100644 graalpython/hpy/.github/workflows/release-pypi.yml delete mode 100644 graalpython/hpy/.github/workflows/valgrind-tests.yml delete mode 100644 graalpython/hpy/.gitignore delete mode 100644 graalpython/hpy/.readthedocs.yml delete mode 100644 graalpython/hpy/AUTHORS delete mode 100644 graalpython/hpy/CONTRIBUTING.md delete mode 100644 graalpython/hpy/LICENSE delete mode 100644 graalpython/hpy/MANIFEST.in delete mode 100644 graalpython/hpy/Makefile delete mode 100644 graalpython/hpy/README-gdb.md delete mode 100644 graalpython/hpy/README.md delete mode 100644 graalpython/hpy/build.py delete mode 100644 graalpython/hpy/c_test/Makefile delete mode 100644 graalpython/hpy/c_test/acutest.h delete mode 100644 graalpython/hpy/c_test/test_debug_handles.c delete mode 100644 graalpython/hpy/c_test/test_stacktrace.c delete mode 100644 graalpython/hpy/docs/Makefile delete mode 100644 graalpython/hpy/docs/_static/README.txt delete mode 100644 graalpython/hpy/docs/_templates/README.txt delete mode 100644 graalpython/hpy/docs/api-reference/argument-parsing.rst delete mode 100644 graalpython/hpy/docs/api-reference/build-value.rst delete mode 100644 graalpython/hpy/docs/api-reference/formatting.rst delete mode 100644 graalpython/hpy/docs/api-reference/function-index.rst delete mode 100644 graalpython/hpy/docs/api-reference/helpers.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-call.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-ctx.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-dict.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-err.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-eval.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-field.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-gil.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-global.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-object.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-sequence.rst delete mode 100644 graalpython/hpy/docs/api-reference/hpy-type.rst delete mode 100644 graalpython/hpy/docs/api-reference/index.rst delete mode 100644 graalpython/hpy/docs/api-reference/inline-helpers.rst delete mode 100644 graalpython/hpy/docs/api-reference/public-api.rst delete mode 100644 graalpython/hpy/docs/api-reference/structseq.rst delete mode 100644 graalpython/hpy/docs/api.rst delete mode 100644 graalpython/hpy/docs/changelog.rst delete mode 100644 graalpython/hpy/docs/conf.py delete mode 100644 graalpython/hpy/docs/contributing/index.rst delete mode 100644 graalpython/hpy/docs/debug-mode.rst delete mode 100644 graalpython/hpy/docs/examples/debug-example.py delete mode 100644 graalpython/hpy/docs/examples/hpytype-example/builtin_type.c delete mode 100644 graalpython/hpy/docs/examples/hpytype-example/setup.py delete mode 100644 graalpython/hpy/docs/examples/hpytype-example/simple_type.c delete mode 100644 graalpython/hpy/docs/examples/hpytype-example/simple_type.rst delete mode 100644 graalpython/hpy/docs/examples/mixed-example/mixed.c delete mode 100644 graalpython/hpy/docs/examples/mixed-example/setup.py delete mode 100644 graalpython/hpy/docs/examples/quickstart/quickstart.c delete mode 100644 graalpython/hpy/docs/examples/quickstart/setup.py delete mode 100644 graalpython/hpy/docs/examples/simple-example/setup.py delete mode 100644 graalpython/hpy/docs/examples/simple-example/simple.c delete mode 100644 graalpython/hpy/docs/examples/snippets/hpycall.c delete mode 100644 graalpython/hpy/docs/examples/snippets/hpyinit.c delete mode 100644 graalpython/hpy/docs/examples/snippets/hpyvarargs.c delete mode 100644 graalpython/hpy/docs/examples/snippets/legacyinit.c delete mode 100644 graalpython/hpy/docs/examples/snippets/setup.py delete mode 100644 graalpython/hpy/docs/examples/snippets/snippets.c delete mode 100644 graalpython/hpy/docs/examples/tests.py delete mode 100644 graalpython/hpy/docs/examples/trace-example.py delete mode 100644 graalpython/hpy/docs/index.rst delete mode 100644 graalpython/hpy/docs/leysin-2020-design-decisions.md delete mode 100644 graalpython/hpy/docs/misc/embedding.rst delete mode 100644 graalpython/hpy/docs/misc/index.rst delete mode 100644 graalpython/hpy/docs/module-state.txt delete mode 100644 graalpython/hpy/docs/overview.rst delete mode 100644 graalpython/hpy/docs/porting-example/index.rst delete mode 100644 graalpython/hpy/docs/porting-example/steps/.gitignore delete mode 100644 graalpython/hpy/docs/porting-example/steps/conftest.py delete mode 100644 graalpython/hpy/docs/porting-example/steps/setup00.py delete mode 100644 graalpython/hpy/docs/porting-example/steps/setup01.py delete mode 100644 graalpython/hpy/docs/porting-example/steps/setup02.py delete mode 100644 graalpython/hpy/docs/porting-example/steps/setup03.py delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_00_c_api.c delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c delete mode 100644 graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst delete mode 100644 graalpython/hpy/docs/porting-example/steps/test_porting_example.py delete mode 100644 graalpython/hpy/docs/porting-guide.rst delete mode 100644 graalpython/hpy/docs/quickstart.rst delete mode 100644 graalpython/hpy/docs/requirements.txt delete mode 100644 graalpython/hpy/docs/trace-mode.rst delete mode 100644 graalpython/hpy/docs/xxx-unsorted-notes.txt delete mode 100755 graalpython/hpy/gdb-py.test delete mode 100644 graalpython/hpy/hpy/debug/__init__.py delete mode 100644 graalpython/hpy/hpy/debug/leakdetector.py delete mode 100644 graalpython/hpy/hpy/debug/pytest.py delete mode 100644 graalpython/hpy/hpy/debug/src/_debugmod.c delete mode 100644 graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i delete mode 100644 graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h delete mode 100644 graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c delete mode 100644 graalpython/hpy/hpy/debug/src/debug_ctx.c delete mode 100644 graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c delete mode 100644 graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c delete mode 100644 graalpython/hpy/hpy/debug/src/debug_handles.c delete mode 100644 graalpython/hpy/hpy/debug/src/debug_internal.h delete mode 100644 graalpython/hpy/hpy/debug/src/dhqueue.c delete mode 100644 graalpython/hpy/hpy/debug/src/include/hpy_debug.h delete mode 100644 graalpython/hpy/hpy/debug/src/memprotect.c delete mode 100644 graalpython/hpy/hpy/debug/src/stacktrace.c delete mode 100644 graalpython/hpy/hpy/devel/__init__.py delete mode 100644 graalpython/hpy/hpy/devel/abitag.py delete mode 100644 graalpython/hpy/hpy/devel/include/hpy.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpy_types.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/hpydef.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/hpyexports.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/hpymodule.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/hpytype.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/macros.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/format.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/argparse.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/buildvalue.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_call.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_err.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_long.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_module.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_object.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_tuplebuilder.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/ctx_type.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/format.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/helpers.c delete mode 100644 graalpython/hpy/hpy/devel/src/runtime/structseq.c delete mode 100644 graalpython/hpy/hpy/tools/autogen/__init__.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/__main__.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/autogen.h delete mode 100644 graalpython/hpy/hpy/tools/autogen/autogenfile.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/conf.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/ctx.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/debug.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/doc.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/hpyfunc.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/hpyslot.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/parse.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/public_api.h delete mode 100644 graalpython/hpy/hpy/tools/autogen/pypy.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/testing/__init__.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/trace.py delete mode 100644 graalpython/hpy/hpy/tools/autogen/trampolines.py delete mode 100644 graalpython/hpy/hpy/tools/include_path.py delete mode 100644 graalpython/hpy/hpy/tools/valgrind/hpy.supp delete mode 100644 graalpython/hpy/hpy/tools/valgrind/python.supp delete mode 100644 graalpython/hpy/hpy/trace/__init__.py delete mode 100644 graalpython/hpy/hpy/trace/src/_tracemod.c delete mode 100644 graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h delete mode 100644 graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c delete mode 100644 graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c delete mode 100644 graalpython/hpy/hpy/trace/src/include/hpy_trace.h delete mode 100644 graalpython/hpy/hpy/trace/src/trace_ctx.c delete mode 100644 graalpython/hpy/hpy/trace/src/trace_internal.h delete mode 100644 graalpython/hpy/hpy/universal/src/api.h delete mode 100644 graalpython/hpy/hpy/universal/src/autogen_ctx_call.i delete mode 100644 graalpython/hpy/hpy/universal/src/autogen_ctx_def.h delete mode 100644 graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h delete mode 100644 graalpython/hpy/hpy/universal/src/ctx.c delete mode 100644 graalpython/hpy/hpy/universal/src/ctx_meth.c delete mode 100644 graalpython/hpy/hpy/universal/src/ctx_meth.h delete mode 100644 graalpython/hpy/hpy/universal/src/ctx_misc.c delete mode 100644 graalpython/hpy/hpy/universal/src/ctx_misc.h delete mode 100644 graalpython/hpy/hpy/universal/src/handles.h delete mode 100644 graalpython/hpy/hpy/universal/src/hpymodule.c delete mode 100644 graalpython/hpy/hpy/universal/src/misc_win32.h delete mode 100644 graalpython/hpy/microbench/README.md delete mode 100644 graalpython/hpy/microbench/_valgrind_build.py delete mode 100644 graalpython/hpy/microbench/conftest.py delete mode 100755 graalpython/hpy/microbench/pytest_valgrind.sh delete mode 100644 graalpython/hpy/microbench/setup.py delete mode 100644 graalpython/hpy/microbench/src/cpy_simple.c delete mode 100644 graalpython/hpy/microbench/src/hpy_simple.c delete mode 100644 graalpython/hpy/microbench/test_microbench.py delete mode 100644 graalpython/hpy/proof-of-concept/pof.c delete mode 100644 graalpython/hpy/proof-of-concept/pofcpp.cpp delete mode 100644 graalpython/hpy/proof-of-concept/pofpackage/bar.cpp delete mode 100644 graalpython/hpy/proof-of-concept/pofpackage/foo.c delete mode 100644 graalpython/hpy/proof-of-concept/requirements.txt delete mode 100644 graalpython/hpy/proof-of-concept/setup.py delete mode 100644 graalpython/hpy/proof-of-concept/test_pof.py delete mode 100755 graalpython/hpy/proof-of-concept/test_pof.sh delete mode 100644 graalpython/hpy/pyproject.toml delete mode 100644 graalpython/hpy/requirements-autogen.txt delete mode 100644 graalpython/hpy/setup.py delete mode 100644 graalpython/hpy/test/__init__.py delete mode 100644 graalpython/hpy/test/check_py27_compat.py delete mode 100644 graalpython/hpy/test/conftest.py delete mode 100644 graalpython/hpy/test/debug/__init__.py delete mode 100644 graalpython/hpy/test/debug/test_builder_invalid.py delete mode 100644 graalpython/hpy/test/debug/test_charptr.py delete mode 100644 graalpython/hpy/test/debug/test_context_reuse.py delete mode 100644 graalpython/hpy/test/debug/test_handles_invalid.py delete mode 100644 graalpython/hpy/test/debug/test_handles_leak.py delete mode 100644 graalpython/hpy/test/debug/test_misc.py delete mode 100644 graalpython/hpy/test/hpy_devel/__init__.py delete mode 100644 graalpython/hpy/test/hpy_devel/test_abitag.py delete mode 100644 graalpython/hpy/test/hpy_devel/test_distutils.py delete mode 100644 graalpython/hpy/test/support.py delete mode 100644 graalpython/hpy/test/test_00_basic.py delete mode 100644 graalpython/hpy/test/test_argparse.py delete mode 100644 graalpython/hpy/test/test_call.py delete mode 100644 graalpython/hpy/test/test_capsule.py delete mode 100644 graalpython/hpy/test/test_capsule_legacy.py delete mode 100644 graalpython/hpy/test/test_contextvar.py delete mode 100644 graalpython/hpy/test/test_cpy_compat.py delete mode 100644 graalpython/hpy/test/test_eval.py delete mode 100644 graalpython/hpy/test/test_helpers.py delete mode 100644 graalpython/hpy/test/test_hpybuildvalue.py delete mode 100644 graalpython/hpy/test/test_hpybytes.py delete mode 100644 graalpython/hpy/test/test_hpydict.py delete mode 100644 graalpython/hpy/test/test_hpyerr.py delete mode 100644 graalpython/hpy/test/test_hpyfield.py delete mode 100644 graalpython/hpy/test/test_hpyglobal.py delete mode 100644 graalpython/hpy/test/test_hpyimport.py delete mode 100644 graalpython/hpy/test/test_hpyiter.py delete mode 100644 graalpython/hpy/test/test_hpylist.py delete mode 100644 graalpython/hpy/test/test_hpylong.py delete mode 100644 graalpython/hpy/test/test_hpymodule.py delete mode 100644 graalpython/hpy/test/test_hpyslice.py delete mode 100644 graalpython/hpy/test/test_hpystructseq.py delete mode 100644 graalpython/hpy/test/test_hpytuple.py delete mode 100644 graalpython/hpy/test/test_hpytype.py delete mode 100644 graalpython/hpy/test/test_hpytype_legacy.py delete mode 100644 graalpython/hpy/test/test_hpyunicode.py delete mode 100644 graalpython/hpy/test/test_importing.py delete mode 100644 graalpython/hpy/test/test_legacy_forbidden.py delete mode 100644 graalpython/hpy/test/test_number.py delete mode 100644 graalpython/hpy/test/test_object.py delete mode 100644 graalpython/hpy/test/test_slots.py delete mode 100644 graalpython/hpy/test/test_slots_legacy.py delete mode 100644 graalpython/hpy/test/test_support.py delete mode 100644 graalpython/hpy/test/test_tracker.py delete mode 100644 graalpython/hpy/test/trace/test_trace.py delete mode 100644 mx.graalpython/copyrights/hpy.copyright.hash delete mode 100644 mx.graalpython/copyrights/hpy.copyright.hash.regex delete mode 100644 mx.graalpython/copyrights/hpy.copyright.star delete mode 100644 mx.graalpython/copyrights/hpy.copyright.star.regex diff --git a/THIRD_PARTY_LICENSE.txt b/THIRD_PARTY_LICENSE.txt index e27628c4ee..e754ee0c8e 100644 --- a/THIRD_PARTY_LICENSE.txt +++ b/THIRD_PARTY_LICENSE.txt @@ -11,32 +11,6 @@ The following software may be included in this product: -================================================================================ - -hpy ef4faf0 - -MIT License - -Copyright (c) 2019 pyhandle - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ================================================================================ Bouncy Castle Crypto API 1.84 diff --git a/ci.jsonnet b/ci.jsonnet index 80b8f9b50b..63093e44c2 100644 --- a/ci.jsonnet +++ b/ci.jsonnet @@ -189,9 +189,6 @@ "linux:aarch64:jdk-latest" : daily + t("00:30:00") + require(GPY_JVM_STANDALONE), "darwin:aarch64:jdk-latest" : daily + t("00:30:00") + require(GPY_JVM_STANDALONE), }), - "python-unittest-hpy": gpgate + require(GPY_NATIVE_STANDALONE) + platform_spec(no_jobs) + platform_spec({ - "linux:amd64:jdk-latest" : tier3, - }), "python-unittest-arrow-storage": gpgate + require(GPY_JVM_STANDALONE) + platform_spec(no_jobs) + platform_spec({ "linux:amd64:jdk-latest" : tier2, }), diff --git a/ci/python-gate.libsonnet b/ci/python-gate.libsonnet index 737107887e..917a74f716 100644 --- a/ci/python-gate.libsonnet +++ b/ci/python-gate.libsonnet @@ -554,7 +554,7 @@ "python-unittest", "python-unittest-multi-context", "python-unittest-jython", - ] + if self.os != 'windows' then ["python-unittest-hpy"] else [], + ], }), cov_truffle_gate:: $.coverage_gate + task_spec({ coverage_args:: ["truffle"], diff --git a/docs/contributor/DEV_TASKS.md b/docs/contributor/DEV_TASKS.md index da569c4a5b..821ba046ed 100644 --- a/docs/contributor/DEV_TASKS.md +++ b/docs/contributor/DEV_TASKS.md @@ -35,13 +35,3 @@ release tag commit and then it should change the CI overlay version to point to the head of branch `graalpy-patch-branch` in order to disable unnecessary gates on it. The GitHub sync needs to be manually enabled in the mirroring service configuration. - -### Updating hpy - -1. Switch to the `hpy-import` branch -2. Delete `graalpython/hpy` -3. Copy the sources from the hpy repo into `graalpython/hpy` (e.g git clone - them there, then delete the `graalpython/hpy/.git` folder) -4. Go back to your previous branch and merge hpy-import. -5. Go to `graalpython/hpy/build.py` and update the `VERSION` constant to - whatever you updated to. diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java index 7923249fed..b79b75fab8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java @@ -101,9 +101,6 @@ public final class PythonAbstractNativeObject extends PythonAbstractObject imple private Object[] replicatedNativeReferences; public PythonAbstractNativeObject(long pointer) { - // GR-50245 - // Fails in - // graalpython/com.oracle.graal.python.hpy.test/src/hpytest/test_slots_legacy.py::TestCustomLegacySlotsFeatures::test_legacy_slots_getsets[hybrid] assert pointer != UNINITIALIZED; this.pointer = pointer; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java index da5db1690a..3a6856f470 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -154,7 +154,7 @@ static PMemoryView fromManaged(VirtualFrame frame, Object object, } Object getBufferAttr = readGetBufferNode.execute(inliningTarget, type, HiddenAttr.GETBUFFER, null); if (hasSlotProfile.profile(inliningTarget, getBufferAttr != null)) { - // HPy object with buffer slot + // Native object with buffer slot Object result = callNode.execute(frame, getBufferAttr, object, BufferFlags.PyBUF_FULL_RO); if (!(result instanceof CExtPyBuffer)) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/graalpython/hpy/.gitattributes b/graalpython/hpy/.gitattributes deleted file mode 100644 index 1c5f632434..0000000000 --- a/graalpython/hpy/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -**/autogen_* linguist-generated=true diff --git a/graalpython/hpy/.github/FUNDING.yml b/graalpython/hpy/.github/FUNDING.yml deleted file mode 100644 index 950b3021c6..0000000000 --- a/graalpython/hpy/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -open_collective: hpy diff --git a/graalpython/hpy/.github/workflows/ci.yml b/graalpython/hpy/.github/workflows/ci.yml deleted file mode 100644 index 0ec548c068..0000000000 --- a/graalpython/hpy/.github/workflows/ci.yml +++ /dev/null @@ -1,427 +0,0 @@ ---- -name: tests - -on: [pull_request] - -jobs: - main_tests: - name: Main tests ${{ matrix.os }} ${{ matrix.python-version }} ${{ matrix.compiler }} - runs-on: ${{ matrix.os }} - continue-on-error: true - strategy: - # Duplicate changes to this matrix to 'poc_tests' - matrix: - os: [ubuntu-latest, macos-13, windows-latest] - python-version: ['3.9', '3.10'] - compiler: [""] - include: - - os: ubuntu-latest - python-version: '3.8' - - os: ubuntu-latest - python-version: '3.10' - compiler: 'g++' - - os: ubuntu-latest - python-version: '3.11' - - os: ubuntu-latest - python-version: '3.12' - - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/ccache.yml - # parameters: - # pythonVersion: $(python.version) - # - template: azure-templates/python.yml - # parameters: - # pythonVersion: $(python.version) - - - name: Set up Python - uses: actions/setup-python@v5.4 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel 'setuptools>=60.2' - - - name: Build - run: | - make - python -m pip install . - - - if: ${{ matrix.compiler }} - # Only set the compiler for the tests, not for the build - run: echo "CC=${{ matrix.compiler }}" >> $GITHUB_ENV - - - name: Run tests - run: | - python -m pip install pytest pytest-xdist filelock - python -m pytest --basetemp=.tmpdir --durations=16 -n auto test/ - - main_tests_debug: - name: Main tests on CPython debug builds - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - # Cannot install 3.12 on ubuntu-latest - python-version: ['3.11', '3.10', '3.9', '3.8'] - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python from deadsnakes - uses: deadsnakes/action@v3.2.0 - with: - python-version: ${{ matrix.python-version }} - debug: true - - - name: Check Python debug build - run: python -c "import sys; print(hasattr(sys, 'gettotalrefcount'))" - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - - - name: Build - run: | - make - python -m pip install . - - - name: Run tests - run: | - python -m pip install pytest pytest-xdist filelock - python -m pytest --durations=16 -n auto test/ - - poc_tests: - name: Proof of concept tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-13, windows-latest] - python-version: ['3.10'] - include: - - os: ubuntu-latest - python-version: '3.8' - - os: ubuntu-latest - python-version: '3.9' - - os: ubuntu-latest - python-version: '3.11' - - os: ubuntu-latest - python-version: '3.12' - - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/ccache.yml - # parameters: - # pythonVersion: $(python.version) - # - template: azure-templates/python.yml - # parameters: - # pythonVersion: $(python.version) - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - shell: bash - - - name: 'Test setup.py --hpy-abi=cpython bdist_wheel' - run: proof-of-concept/test_pof.sh wheel cpython - shell: bash - - - name: 'Test setup.py --hpy-abi=universal bdist_wheel' - run: proof-of-concept/test_pof.sh wheel universal - shell: bash - - - name: 'Test setup.py --hpy-abi=cpython install' - run: proof-of-concept/test_pof.sh setup_py_install cpython - shell: bash - - - name: 'Test setup.py --hpy-abi=universal install' - run: proof-of-concept/test_pof.sh setup_py_install universal - shell: bash - - - name: 'Test setup.py --hpy-abi=cpython build_ext --inplace' - run: proof-of-concept/test_pof.sh setup_py_build_ext_inplace cpython - shell: bash - - - name: 'Test setup.py --hpy-abi=universal build_ext --inplace' - run: proof-of-concept/test_pof.sh setup_py_build_ext_inplace universal - shell: bash - - - porting_example_tests: - name: Porting example tests - runs-on: ${{ matrix.os }} - continue-on-error: true - strategy: - matrix: - os: [ubuntu-latest, macos-13, windows-latest] - python-version: ['3.9'] - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - shell: bash - - - name: Install HPy - run: python -m pip install . - - - name: Install pytest - run: | - python -m pip install pytest - - - name: Run tests - run: make porting-example-tests - shell: bash - - - name: Run tests of completed port in debug mode - env: - HPY_DEBUG: "1" - TEST_ARGS: "-s -k hpy_final" - run: make porting-example-tests - shell: bash - - - valgrind_tests_1: - name: 'Valgrind tests (1/3)' - uses: ./.github/workflows/valgrind-tests.yml - with: - portion: '1/3' - - - valgrind_tests_2: - name: 'Valgrind tests (2/3)' - uses: ./.github/workflows/valgrind-tests.yml - with: - portion: '2/3' - - - valgrind_tests_3: - name: 'Valgrind tests (3/3)' - uses: ./.github/workflows/valgrind-tests.yml - with: - portion: '3/3' - - - docs_examples_tests: - name: Documentation examples tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-13, windows-latest] - python-version: ['3.10'] - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - shell: bash - - - name: Install HPy - run: python -m pip install . - - - name: Install pytest - run: | - python -m pip install pytest pytest-xdist filelock - - name: Run tests - run: make docs-examples-tests - shell: bash - - build_docs: - name: Build documentation - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/python.yml - - - name: Install / Upgrade system requirements - run: sudo apt update && sudo apt install -y libclang-17-dev - - - name: Install / Upgrade Python requirements - run: | - python -m pip install --upgrade pip - python -m pip install -r docs/requirements.txt - - - name: Build docs - run: | - cd docs; - python -m sphinx -T -W -E -b html -d _build/doctrees -D language=en . _build/html - - - name: Upload built HTML files - uses: actions/upload-artifact@v4 - with: - name: hpy_html_docs - path: docs/_build/html/* - if-no-files-found: error - retention-days: 5 - - c_tests: - name: C tests - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - run: make -C c_test - - - check_autogen: - name: Check autogen - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/python.yml - - - name: Set up Python - uses: actions/setup-python@v5 - with: - # autogen needs distutils - python-version: '3.11' - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - - - name: Install autogen dependencies - run: pip install -r requirements-autogen.txt - - - name: make autogen - run: | - make autogen - if [ -z "$(git status --porcelain)" ]; then - # clean working copy - echo "Working copy is clean, everything ok" - else - # Uncommitted changes - echo "ERROR: uncommitted changes after running make autogen" - echo "git status" - git status - echo - echo "git diff" - git diff - exit 1 - fi - - - check_py27_compat: - name: Check Python 2.7 compatibility - runs-on: 'ubuntu-20.04' - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/python.yml - # parameters: - # pythonVersion: "2.7" - - - name: Set up Python2 - # Copied from cython's ci.yml - run: | - sudo ln -fs python2 /usr/bin/python - sudo apt-get update - sudo apt-get install python-setuptools python2.7 python2.7-dev - curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py - sudo python2 get-pip.py - ls -l /usr/bin/pip* /usr/local/bin/pip* - which pip - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - - - name: check_py27_compat.py - run: | - python -m pip install pytest pytest-xdist filelock pathlib - python test/check_py27_compat.py - - - cpp_check: - name: Cppcheck static analysis - runs-on: 'ubuntu-22.04' - continue-on-error: true - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Install Cppcheck - run: sudo apt-get -qq -y install cppcheck=2.7-1 - - - name: Run Cppcheck - run: make cppcheck - - - infer: - name: Infer static analysis - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - # - template: azure-templates/python.yml - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel - - - name: Install Infer - run: | - python -m pip install compiledb wheel; - VERSION=1.1.0; \ - curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \ - | sudo tar -C /opt -xJ && \ - echo "/opt/infer-linux64-v$VERSION/bin" >> $GITHUB_PATH - - - name: Run Infer - run: make infer - - check_microbench: - name: Check micro benchmarks - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install / Upgrade system dependencies - run: sudo apt update && sudo apt install -y valgrind - - - name: Install / Upgrade Python requirements - run: | - python -m pip install --upgrade pip wheel 'setuptools>=60.2' - python -m pip install pytest cffi - - - name: Build and install HPy - run: | - make - python -m pip install . - - - name: Run microbenchmarks - run: | - cd microbench - python setup.py build_ext -i - python -m pytest -v diff --git a/graalpython/hpy/.github/workflows/release-pypi.yml b/graalpython/hpy/.github/workflows/release-pypi.yml deleted file mode 100644 index 959a779170..0000000000 --- a/graalpython/hpy/.github/workflows/release-pypi.yml +++ /dev/null @@ -1,136 +0,0 @@ ---- -name: Publish to PyPI - -# manually trigger this workflow -on: - workflow_dispatch: - inputs: - tag: - description: 'The Git tag to create or test a release for. Official releases should always be made from an existing tag.' - required: true - type: string - official: - description: 'If true, publish to official PyPI and create GitHub release. Otherwise publish only to test PyPI.' - default: false - type: boolean - -jobs: - build_sdist: - name: Build source package - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ inputs.tag }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - # HPy requires at least Python 3.8; we mostly work with >=3.10 - python-version: '>=3.10' - - - name: Install/Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel 'setuptools>=60.2' - - - name: Build and install Python source package - run: | - python setup.py sdist - python -m pip install dist/*.tar.gz - - - name: Run tests - run: | - make - pip install pytest pytest-xdist filelock - pytest -n auto test/ - - - uses: actions/upload-artifact@v3 - with: - path: dist/*.tar.gz - retention-days: 5 - - - build_bdist: - name: Build binary wheels - runs-on: ${{ matrix.os }} - strategy: - matrix: - # Windows tests fail when built as a binary wheel for some reason - # 'macos-12' doesn't pass the tests - os: [ubuntu-latest, macos-11] # windows-latest - - steps: - - uses: actions/checkout@v3 - with: - ref: ${{ inputs.tag }} - - # setup Python for cibuildwheel - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - # for other architectures, see: https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation - - name: Build wheels for CPython - uses: pypa/cibuildwheel@v2.12.3 - env: - # cibuildwheel automatically reads 'python_requires' from 'setup.py' - CIBW_BUILD: 'cp*' # no PyPy builds - CIBW_ARCHS_LINUX: "x86_64" # only Intel 64-bit - CIBW_ARCHS_MACOS: "x86_64" # only Intel 64-bit - CIBW_TEST_REQUIRES: pytest pytest-xdist filelock setuptools>=60.2 - # only copy test dir to current working dir - CIBW_TEST_COMMAND: cp -R {project}/test ./ && pytest --basetemp=.tmpdir --ignore=test/hpy_devel -n auto ./test/ - - - uses: actions/upload-artifact@v3 - with: - path: ./wheelhouse/*.whl - retention-days: 5 - - upload_pypi: - name: Publish packages to (Test) PyPI - needs: [build_sdist, build_bdist] - runs-on: ubuntu-latest - # don't do this action on forks by default - if: github.repository == 'hpyproject/hpy' - steps: - - uses: actions/download-artifact@v3 - with: - name: artifact - path: dist - - - name: Upload to Test PyPI - uses: pypa/gh-action-pypi-publish@v1.8.5 - if: ${{ !inputs.official }} - with: - verbose: true - user: __token__ - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository-url: https://test.pypi.org/legacy/ - - - name: Upload to PyPI - uses: pypa/gh-action-pypi-publish@v1.8.5 - if: ${{ inputs.official }} - with: - verbose: true - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} - - create_gh_release: - needs: [upload_pypi] - runs-on: ubuntu-latest - # don't do this action on forks by default - if: github.repository == 'hpyproject/hpy' - steps: - - uses: actions/download-artifact@v3 - with: - name: artifact - path: dist - - - name: Release - uses: softprops/action-gh-release@v1 - with: - files: dist/* - # consider tags in form '*.*.*rc*' to indicate a pre-release - prerelease: ${{ contains(inputs.tag, 'rc') }} - draft: ${{ !inputs.official }} - tag_name: ${{ inputs.tag }} diff --git a/graalpython/hpy/.github/workflows/valgrind-tests.yml b/graalpython/hpy/.github/workflows/valgrind-tests.yml deleted file mode 100644 index ab739252eb..0000000000 --- a/graalpython/hpy/.github/workflows/valgrind-tests.yml +++ /dev/null @@ -1,38 +0,0 @@ -on: - workflow_call: - inputs: - portion: - description: 'Select portion of tests to run under Valgrind (default runs all)' - default: '' - type: string - required: false - -jobs: - valgrind_tests: - # name: Valgrind tests - runs-on: 'ubuntu-latest' - steps: - - uses: actions/checkout@v4 - - - name: Install / Upgrade system dependencies - run: sudo apt update && sudo apt install -y valgrind - - - name: Set up Python - uses: actions/setup-python@v5.4 - with: - python-version: 3.9 - - - name: Install / Upgrade Python dependencies - run: python -m pip install --upgrade pip wheel setuptools - - - name: Build - run: | - make - python -m pip install . - - - name: Run tests - env: - HPY_TEST_PORTION: ${{ inputs.portion }} - run: | - python -m pip install pytest pytest-valgrind pytest-portion filelock - make valgrind diff --git a/graalpython/hpy/.gitignore b/graalpython/hpy/.gitignore deleted file mode 100644 index 2877066982..0000000000 --- a/graalpython/hpy/.gitignore +++ /dev/null @@ -1,92 +0,0 @@ -# HPy autogen -hpy/tools/autogen/autogen_pypy.txt - -# generated by setup.py:get_scm_config() -hpy/devel/include/hpy/version.h -hpy/devel/version.py - -# stubs created by setup.py when doing build_ext --inplace -proof-of-concept/pof.py -proof-of-concept/pofpackage/foo.py - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions and static libs -*.so -*.o -*.a -*.lib -vc140.pdb -c_test/test_debug_handles - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -test-output.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -.hpy.lock - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# cppcheck -.cppcheck - -# Sphinx -docs/_build/ - -# vscode -.vscode diff --git a/graalpython/hpy/.readthedocs.yml b/graalpython/hpy/.readthedocs.yml deleted file mode 100644 index 7ee9eedb2e..0000000000 --- a/graalpython/hpy/.readthedocs.yml +++ /dev/null @@ -1,10 +0,0 @@ -# readthedocs.org configuration - -version: 2 -sphinx: - configuration: docs/conf.py -formats: all -python: - version: 3.7 - install: - - requirements: docs/requirements.txt diff --git a/graalpython/hpy/AUTHORS b/graalpython/hpy/AUTHORS deleted file mode 100644 index 707ed38f94..0000000000 --- a/graalpython/hpy/AUTHORS +++ /dev/null @@ -1,38 +0,0 @@ -# This is the list of HPy's significant contributors. -# -# This does not necessarily list everyone who has contributed code, -# especially since many employees of one corporation may be contributing. -# To see the full list of contributors, see the revision history in -# source control. -Alexander Schremmer -Ammar Askar -Ankith (ankith26) -Antonio Cuni -Armin Rigo -Charlie Hayden -Christian Klein -Daniel Alley -Dominic Davis-Foster -Jaime Resano Aísa -Joachim Trouverie -Julian Berman -Krish Patel -Kyle Lawlor-Bagcal -Mathieu Dupuy -Matti Picus -Max Horn -Maxwell Bernstein -Mohamed Koubaa -Nico Rittinghaus -Omer Katz -Oracle and/or its affiliates -Paul Prescod -Pierre Augier -Robert O'Shea -Ronan Lamy -Simon Cross -Stefan Behnel -Stefano Rivera -Victor Stinner -Vytautas Liuolia -Łukasz Langa diff --git a/graalpython/hpy/CONTRIBUTING.md b/graalpython/hpy/CONTRIBUTING.md deleted file mode 100644 index 7178db511c..0000000000 --- a/graalpython/hpy/CONTRIBUTING.md +++ /dev/null @@ -1,55 +0,0 @@ -Contributing -============ - -Contributions are welcome, and they are greatly appreciated! Every -little bit helps. - -You can contribute in many ways: - -Types of Contributions ----------------------- - -### Report Bugs - -Report bugs at . - -When reporting a bug, please include: - -- Your operating system name and version. -- Any details about your local setup that might be helpful in - troubleshooting. -- Detailed steps to reproduce the bug. - -### Donate to HPy - -Become a financial contributor and help us sustain the HPy community: [Contribute to HPy](https://opencollective.com/hpy/contribute). - -### Fix Bugs or Implement Features - -Look through the GitHub issues for bugs or proposals being discussed -or ready for implementation. - -### Write Documentation - -HPy could always use more documentation, whether as part of the -official HPy docs, in docstrings, or even on the web in blog -posts, articles, and such. - -Get Started! ------------- - -You can test your environment by running - -```bash -proof-of-concept/test_pof.sh wheel universal -``` - -This should build HPy and a proof of concept (demo) extension and -then run a pytest that validates both. - -Until we get around to more comprehensive documentation, you -can reverse engineer how the system works by looking at these -files: - -- `proof-of-concept/test_pof.sh` -- `proof-of-concept/setup.py` diff --git a/graalpython/hpy/LICENSE b/graalpython/hpy/LICENSE deleted file mode 100644 index a5b403aa3f..0000000000 --- a/graalpython/hpy/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 The HPy Authors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/graalpython/hpy/MANIFEST.in b/graalpython/hpy/MANIFEST.in deleted file mode 100644 index 7a4b248c98..0000000000 --- a/graalpython/hpy/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -recursive-include hpy/devel/include *.h diff --git a/graalpython/hpy/Makefile b/graalpython/hpy/Makefile deleted file mode 100644 index 6d0f1c0db8..0000000000 --- a/graalpython/hpy/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -.PHONY: all -all: hpy.universal - -.PHONY: hpy.universal -hpy.universal: - python3 setup.py build_clib -f build_ext -if - -.PHONY: dist-info -dist-info: - python3 setup.py dist_info - -debug: - HPY_DEBUG_BUILD=1 make all - -autogen: - python3 -m hpy.tools.autogen . - -cppcheck-build-dir: - mkdir -p $(or ${CPPCHECK_BUILD_DIR}, .cppcheck) - -.PHONY: cppcheck -cppcheck: cppcheck-build-dir - # azure pipelines doesn't show stderr, so we write the errors to a file and cat it later :( - $(eval PYTHON_INC = $(shell python3 -q -c "from sysconfig import get_paths as gp; print(gp()['include'])")) - $(eval PYTHON_PLATINC = $(shell python3 -q -c "from sysconfig import get_paths as gp; print(gp()['platinclude'])")) - cppcheck --version - cppcheck \ - -v \ - --error-exitcode=1 \ - --cppcheck-build-dir=$(or ${CPPCHECK_BUILD_DIR}, .cppcheck) \ - --enable=warning,performance,portability,information,missingInclude \ - --inline-suppr \ - --suppress=syntaxError \ - -I /usr/local/include/ \ - -I /usr/include/ \ - -I ${PYTHON_INC} \ - -I ${PYTHON_PLATINC} \ - -I . \ - -I hpy/devel/include/ \ - -I hpy/devel/include/hpy/ \ - -I hpy/devel/include/hpy/cpython/ \ - -I hpy/devel/include/hpy/universal/ \ - -I hpy/devel/include/hpy/runtime/ \ - -I hpy/universal/src/ \ - -I hpy/debug/src/ \ - -I hpy/debug/src/include \ - -I hpy/trace/src/ \ - -I hpy/trace/src/include \ - --force \ - -D NULL=0 \ - -D HPY_ABI_CPYTHON \ - -D __linux__=1 \ - -D __x86_64__=1 \ - -D __LP64__=1 \ - . - -infer: - python3 setup.py build_ext -if -U NDEBUG | compiledb - # see commit cd8cd6e for why we need to ignore debug_ctx.c - @infer --fail-on-issue --compilation-database compile_commands.json --report-blacklist-path-regex "hpy/debug/src/debug_ctx.c" - -valgrind_args = --suppressions=hpy/tools/valgrind/python.supp --suppressions=hpy/tools/valgrind/hpy.supp --leak-check=full --show-leak-kinds=definite,indirect --log-file=/tmp/valgrind-output -python_args = -m pytest --valgrind --valgrind-log=/tmp/valgrind-output - -.PHONY: valgrind -valgrind: -ifeq ($(HPY_TEST_PORTION),) - PYTHONMALLOC=malloc valgrind $(valgrind_args) python3 $(python_args) test/ -else - PYTHONMALLOC=malloc valgrind $(valgrind_args) python3 $(python_args) --portion $(HPY_TEST_PORTION) test/ -endif - -porting-example-tests: - cd docs/porting-example/steps && python3 setup00.py build_ext -i - cd docs/porting-example/steps && python3 setup01.py build_ext -i - cd docs/porting-example/steps && python3 setup02.py build_ext -i - cd docs/porting-example/steps && python3 setup03.py --hpy-abi=universal build_ext -i - python3 -m pytest docs/porting-example/steps/ ${TEST_ARGS} - -docs-examples-tests: - cd docs/examples/simple-example && python3 setup.py --hpy-abi=universal install - cd docs/examples/mixed-example && python3 setup.py install - cd docs/examples/snippets && python3 setup.py --hpy-abi=universal install - cd docs/examples/quickstart && python3 setup.py --hpy-abi=universal install - cd docs/examples/hpytype-example && python3 setup.py --hpy-abi=universal install - python3 -m pytest docs/examples/tests.py ${TEST_ARGS} diff --git a/graalpython/hpy/README-gdb.md b/graalpython/hpy/README-gdb.md deleted file mode 100644 index c1bacca196..0000000000 --- a/graalpython/hpy/README-gdb.md +++ /dev/null @@ -1,207 +0,0 @@ -How to debug HPy on CPython -============================ - -This document describes how to make debugging easier when running HPy on -CPython. At the moment it is structured as a collection of notes, PRs to make -it more structured are welcome. - -**NOTE**: this document is **not** about the HPy debug mode, but it's about -debugging HPy itself. - - -Build a debug version of CPython ---------------------------------- - -This is highly recommended. It takes only few minutes and helps a lot during -debugging for two reasons: - -1. You can easily view CPython's source code inside GDB - -2. CPython is compiled with `-Og`, which means it will be easier to follow the - code step-by-step and to inspect variables - -3. The `py-*` GDB commands work out of the box. - -``` -$ cd /path/to/cpython -$ git checkout v3.8.2 -$ ./configure --with-pydebug --prefix=/opt/python-debug/ -$ make install -``` - -Enable `python-gdb.py` ----------------------- - -`python-gdb.py` is a GDB script to make it easier to inspect the state of a -Python process from whitin GDB. It is documented -[in the CPython's dev guide](https://devguide.python.org/gdb/). - -The script add a series of GBD commands such as: - - - `py-bt`: prints the Python-level traceback of the current function - - - `py-up`, `py-down`: navigate up and down the Python function stack by - going to the previous/next occurrence of `_PyEval_EvalFrameDefault`. They - are more or less equivalent to `up` and `down` inside `pdb`. - - - `py-print`: print the value of a Python-level variable - -**WARNING**: the CPython's dev guide suggests to add `add-auto-load-safe-path` -to your `~/.gdbinit`, but it doesn't work for me. What works for me is the -following: - -``` -# add this to your ~/.gdbinit -source /path/to/cpython/python-gdb.py -``` - -To check that the `py-*` commands work as expected, you can do the following: - -``` -$ gdb --args /opt/python-debug/bin/python3 -c 'for i in range(10000000): pass' -GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2 -... -(gdb) run # start the python process -... - -^C -... -(gdb) py-bt -Traceback (most recent call first): - File "", line 1, in -(gdb) py-print i -global 'i' = 9657683 -``` - -Inspect `PyObject *` and `HPy` inside GDB ------------------------------------------- - -**WARNING**: `py-dump` and `hpy-dump` prints to stderr, and this interacts -badly with pytest's capturing. Make sure to run `py.test -s`, else you might -not see the output. The included script `gdb-py.test` automatically pass `-s`. - -`python-gdb.py` installs a GDB pretty-printer for `PyObject *` variables, -which sometimes can be confusing: often, it prints the Python repr of the -variable: - -``` -(gdb) set $x = PyLong_FromLong(42) -(gdb) p $x -$5 = 42 -(gdb) p (void*)$x -$7 = (void *) 0x555555903ca0 -(gdb) p *$x -$6 = {ob_refcnt = 10, ob_type = 0x5555558d5560 } -``` - -For some reason which is unknown to me, sometimes it prints a rather obscure -string: here, `type` is the Python type of the object, and `0x5555558ce88` is -its address: - -``` -(gdb) p PyExc_ValueError -$12 = -(gdb) p (void*)PyExc_ValueError -$13 = (void *) 0x5555558ce880 <_PyExc_ValueError> -``` - -Another useful trick is to define these two custom GDB commands in your -`~/.gdbinit`: - -``` -# put this in your ~/.gdbinit -define py-dump -call _PyObject_Dump($arg0) -end - -# NOTE: -# 1. this assumes that you have a variable called "ctx" available -# 2. this assumes that it's a debug version of HPy, which was compiled with -# -fkeep-inline-functions -# 3. if you don't have _HPy_Dump available, you can call manually -# ctx->ctx_Dump (but only in universal mode) -define hpy-dump -call _HPy_Dump(ctx, $arg0) -end -``` - -Example of usage: - -``` -(gdb) set $x = PyLong_FromLong(42) -(gdb) py-dump $x -object address : 0x555555903ca0 -object refcount : 11 -object type : 0x5555558d5560 -object type name: int -object repr : 42 - -(gdb) py-dump PyExc_ValueError -object address : 0x5555558ce880 -object refcount : 14 -object type : 0x5555558dd8e0 -object type name: type -object repr : - -(gdb) set $h = ctx->ctx_Long_FromLong(ctx, 1234) -(gdb) p $h -$2 = {_i = 77} -(gdb) hpy-dump $h -object address : 0x7ffff64b0580 -object refcount : 1 -object type : 0x5555558d5560 -object type name: int -object repr : 1234 -``` - - - -Create a venv for python-debug and install hpy ------------------------------------------------ - -The following commands create a `venv` based on the newly built -`python-debug`, and installs `hpy` in "editable mode". - -``` -$ cd /path/to/hpy -$ /opt/python-debug/bin/python3 -m venv venv/hpy-debug -$ . venv/hpy-debug/bin/activate -$ python setup.py develop -``` - -Once hpy is installed this way, you can edit the C files and rebuild it easily -by using `make`: - -``` -$ make # build normally -$ make debug # build HPY with -O0 -g -``` - -Run a specific HPy test under GDB ---------------------------------- - -To run `py.test` under GDB, use the script `./gdb-py.test`. - -**Tip:** most HPy tests export a Python function called `f`. You can easily -put a breakpoint into it by using `b f_impl`: - -``` -$ ./gdb-py.test -s test/test_00_basic.py -k 'test_float_asdouble and universal' -... -(gdb) b f_impl -Breakpoint 1 at 0x7ffff63a0284: file /tmp/pytest-of-antocuni/pytest-219/test_float_asdouble_universal_0/mytest.c, line 5. -(gdb) run -... -Breakpoint 1, f_impl (ctx=0x7ffff64191d0, self=..., arg=...) at /tmp/pytest-of-antocuni/pytest-220/test_float_asdouble_universal_0/mytest.c:5 -5 { -(gdb) next -6 double a = HPyFloat_AsDouble(ctx, arg); -(gdb) p arg -$1 = {_i = 75} -(gdb) hpy-dump arg -object address : 0x7ffff7017700 -object refcount : 3 -object type : 0x5555558d3400 -object type name: float -object repr : 1.0 -``` diff --git a/graalpython/hpy/README.md b/graalpython/hpy/README.md deleted file mode 100644 index 311199e6bc..0000000000 --- a/graalpython/hpy/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# HPy: a better API for Python - -[![Build](https://github.com/hpyproject/hpy/actions/workflows/ci.yml/badge.svg)](https://github.com/hpyproject/hpy/actions/workflows/ci.yml) -[![Documentation](https://readthedocs.org/projects/hpy/badge/)](https://hpy.readthedocs.io/) -[![Join the discord server at https://discord.gg/xSzxUbPkTQ](https://img.shields.io/discord/1077164940906995813.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square)](https://discord.gg/xSzxUbPkTQ) - -**Website**: [hpyproject.org](https://hpyproject.org/) \ -**Community**: [HPy Discord server](https://discord.gg/xSzxUbPkTQ) \ -**Mailing list**: [hpy-dev@python.org](https://mail.python.org/mailman3/lists/hpy-dev.python.org/) - -## Summary - -HPy is a better API for extending Python -in C. The old C API is specific to the current implementation of CPython. -It exposes a lot of internal details which makes it hard to: - - - implement it for other Python implementations (e.g. PyPy, GraalPy, - Jython, IronPython, etc.). - - experiment with new things inside CPython itself: e.g. using a GC - instead of refcounting, or to remove the GIL - - guarantee binary stability - -HPy is a specification of a new API and ABI for extending Python that is -Python implementation agnostic and designed to hide and abstract internal -details such that it: - - - can stay binary compatible even if the underlying Python internals change significantly - - does not hinder internal progress of CPython and other Pythons - -Please read the [documentation](https://docs.hpyproject.org/en/latest/overview.html) -for more details on HPy motivation, goals, and features, for example: - - - debug mode for better developer experience - - support for incremental porting from CPython API to HPy - - CPython ABI for raw performance on CPython - - and others - -Do you want to see how HPy API looks in code? Check out -our [quickstart example](https://docs.hpyproject.org/en/latest/quickstart.html). - -You may also be interested in HPy's -[API reference](https://docs.hpyproject.org/en/latest/api-reference/index.html). - -This repository contains the API and ABI specification and implementation -for the CPython interpreter. Other interpreters that support HPy natively: GraalPy -and PyPy, provide their own builtin HPy implementations. - - -## Why should I care about this stuff? - - - the existing C API is becoming a problem for CPython and for the - evolution of the language itself: this project makes it possible to make - experiments which might be "officially" adopted in the future - - - for PyPy, it will give obvious speed benefits: for example, data - scientists will be able to get the benefit of fast C libraries *and* fast - Python code at the same time, something which is hard to achieve now - - - the current implementation is too tied to CPython and proved to be a - problem for almost all the other alternative implementations. Having an - API which is designed to work well on two different implementations will - make the job much easier for future ones: going from 2 to N is much easier - than going from 1 to 2 - - - arguably, it will be easier to learn and understand than the massive - CPython C API - -See also [Python Performance: Past, Present, -Future](https://github.com/vstinner/talks/raw/main/2019-EuroPython/python_performance.pdf) -by Victor Stinner. - - -## What does `HPy` mean? - -The "H" in `HPy` stands for "handle": one of the key idea of the new API is to -use fully opaque handles to represent and pass around Python objects. - - -## Donate to HPy - -Become a financial contributor and help us sustain the HPy community: [Contribute to HPy](https://opencollective.com/hpy/contribute). diff --git a/graalpython/hpy/build.py b/graalpython/hpy/build.py deleted file mode 100644 index 43eb5c3d69..0000000000 --- a/graalpython/hpy/build.py +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright (c) 2025, Oracle and/or its affiliates. -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this list of -# conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other materials provided -# with the distribution. -# 3. Neither the name of the copyright holder nor the names of its contributors may be used to -# endorse or promote products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -# OF THE POSSIBILITY OF SUCH DAMAGE. -# - -VERSION = "0.9.0" - -import argparse -import os -import shlex -import subprocess -import sys -import tempfile -import venv - -from pathlib import Path - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--out", required=True) - parser.add_argument("--cflags", required=True) - parsed_args = parser.parse_args() - - setup = Path(__file__).parent.absolute() / "setup.py" - build = Path(parsed_args.out).absolute() - build.mkdir(parents=True, exist_ok=True) - - if sys.platform != "win32": - executable = " ".join(map(shlex.quote, __graalpython__.executable_list)) - with open(build / "graalpy", "w") as f: - p = Path(f.name).absolute() - f.write(f"""#!/bin/bash - exec {executable} -B --DisableFrozenModules --Executable="$0" "$@" - """) - p.chmod(0o777) - sys._base_executable = sys.executable = str(p) - else: - # win32 works because venv generates a venvlauncher there - pass - - venv.main(args=[str(build / "venv")]) - if sys.platform == "win32": - exe = build / "venv" / "Scripts" / "graalpy.exe" - else: - exe = build / "venv" / "bin" / "graalpy" - - subprocess.run( - map(str, [ - exe, - setup, - "build", - "--build-lib", - build / "build", - "--build-temp", - build / "temp", - "install", - "--single-version-externally-managed", - "--root=/", - ]), - cwd=setup.parent, - check=True, - env=os.environ.copy() | { - "SETUPTOOLS_SCM_PRETEND_VERSION": VERSION, - "CFLAGS": os.environ.get("CFLAGS", "") + f" {parsed_args.cflags}" - }, - ) diff --git a/graalpython/hpy/c_test/Makefile b/graalpython/hpy/c_test/Makefile deleted file mode 100644 index 2e93170d4c..0000000000 --- a/graalpython/hpy/c_test/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -CC ?= gcc -INCLUDE=-I.. -I../hpy/devel/include -I../hpy/debug/src/include -CFLAGS = -O0 -UNDEBUG -g -Wall -Werror -Wfatal-errors $(INCLUDE) -DHPY_ABI_UNIVERSAL - -test: test_debug_handles test_stacktrace - ./test_debug_handles - ./test_stacktrace - -test_debug_handles: test_debug_handles.o ../hpy/debug/src/dhqueue.o - $(CC) -o $@ $^ - -test_stacktrace: test_stacktrace.o ../hpy/debug/src/stacktrace.o - $(CC) -o $@ $^ - -%.o : %.c - $(CC) -c $(CFLAGS) $< -o $@ diff --git a/graalpython/hpy/c_test/acutest.h b/graalpython/hpy/c_test/acutest.h deleted file mode 100644 index a05eb41cd0..0000000000 --- a/graalpython/hpy/c_test/acutest.h +++ /dev/null @@ -1,1794 +0,0 @@ -/* - * Acutest -- Another C/C++ Unit Test facility - * - * - * Copyright 2013-2020 Martin Mitas - * Copyright 2019 Garrett D'Amore - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef ACUTEST_H -#define ACUTEST_H - - -/************************ - *** Public interface *** - ************************/ - -/* By default, "acutest.h" provides the main program entry point (function - * main()). However, if the test suite is composed of multiple source files - * which include "acutest.h", then this causes a problem of multiple main() - * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all - * compilation units but one. - */ - -/* Macro to specify list of unit tests in the suite. - * The unit test implementation MUST provide list of unit tests it implements - * with this macro: - * - * TEST_LIST = { - * { "test1_name", test1_func_ptr }, - * { "test2_name", test2_func_ptr }, - * ... - * { NULL, NULL } // zeroed record marking the end of the list - * }; - * - * The list specifies names of each test (must be unique) and pointer to - * a function implementing it. The function does not take any arguments - * and has no return values, i.e. every test function has to be compatible - * with this prototype: - * - * void test_func(void); - * - * Note the list has to be ended with a zeroed record. - */ -#define TEST_LIST const struct acutest_test_ acutest_list_[] - - -/* Macros for testing whether an unit test succeeds or fails. These macros - * can be used arbitrarily in functions implementing the unit tests. - * - * If any condition fails throughout execution of a test, the test fails. - * - * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows - * also to specify an error message to print out if the condition fails. - * (It expects printf-like format string and its parameters). The macros - * return non-zero (condition passes) or 0 (condition fails). - * - * That can be useful when more conditions should be checked only if some - * preceding condition passes, as illustrated in this code snippet: - * - * SomeStruct* ptr = allocate_some_struct(); - * if(TEST_CHECK(ptr != NULL)) { - * TEST_CHECK(ptr->member1 < 100); - * TEST_CHECK(ptr->member2 > 200); - * } - */ -#define TEST_CHECK_(cond,...) acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__) -#define TEST_CHECK(cond) acutest_check_((cond), __FILE__, __LINE__, "%s", #cond) - - -/* These macros are the same as TEST_CHECK_ and TEST_CHECK except that if the - * condition fails, the currently executed unit test is immediately aborted. - * - * That is done either by calling abort() if the unit test is executed as a - * child process; or via longjmp() if the unit test is executed within the - * main Acutest process. - * - * As a side effect of such abortion, your unit tests may cause memory leaks, - * unflushed file descriptors, and other phenomena caused by the abortion. - * - * Therefore you should not use these as a general replacement for TEST_CHECK. - * Use it with some caution, especially if your test causes some other side - * effects to the outside world (e.g. communicating with some server, inserting - * into a database etc.). - */ -#define TEST_ASSERT_(cond,...) \ - do { \ - if(!acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__)) \ - acutest_abort_(); \ - } while(0) -#define TEST_ASSERT(cond) \ - do { \ - if(!acutest_check_((cond), __FILE__, __LINE__, "%s", #cond)) \ - acutest_abort_(); \ - } while(0) - - -#ifdef __cplusplus -/* Macros to verify that the code (the 1st argument) throws exception of given - * type (the 2nd argument). (Note these macros are only available in C++.) - * - * TEST_EXCEPTION_ is like TEST_EXCEPTION but accepts custom printf-like - * message. - * - * For example: - * - * TEST_EXCEPTION(function_that_throw(), ExpectedExceptionType); - * - * If the function_that_throw() throws ExpectedExceptionType, the check passes. - * If the function throws anything incompatible with ExpectedExceptionType - * (or if it does not thrown an exception at all), the check fails. - */ -#define TEST_EXCEPTION(code, exctype) \ - do { \ - bool exc_ok_ = false; \ - const char *msg_ = NULL; \ - try { \ - code; \ - msg_ = "No exception thrown."; \ - } catch(exctype const&) { \ - exc_ok_= true; \ - } catch(...) { \ - msg_ = "Unexpected exception thrown."; \ - } \ - acutest_check_(exc_ok_, __FILE__, __LINE__, #code " throws " #exctype);\ - if(msg_ != NULL) \ - acutest_message_("%s", msg_); \ - } while(0) -#define TEST_EXCEPTION_(code, exctype, ...) \ - do { \ - bool exc_ok_ = false; \ - const char *msg_ = NULL; \ - try { \ - code; \ - msg_ = "No exception thrown."; \ - } catch(exctype const&) { \ - exc_ok_= true; \ - } catch(...) { \ - msg_ = "Unexpected exception thrown."; \ - } \ - acutest_check_(exc_ok_, __FILE__, __LINE__, __VA_ARGS__); \ - if(msg_ != NULL) \ - acutest_message_("%s", msg_); \ - } while(0) -#endif /* #ifdef __cplusplus */ - - -/* Sometimes it is useful to split execution of more complex unit tests to some - * smaller parts and associate those parts with some names. - * - * This is especially handy if the given unit test is implemented as a loop - * over some vector of multiple testing inputs. Using these macros allow to use - * sort of subtitle for each iteration of the loop (e.g. outputting the input - * itself or a name associated to it), so that if any TEST_CHECK condition - * fails in the loop, it can be easily seen which iteration triggers the - * failure, without the need to manually output the iteration-specific data in - * every single TEST_CHECK inside the loop body. - * - * TEST_CASE allows to specify only single string as the name of the case, - * TEST_CASE_ provides all the power of printf-like string formatting. - * - * Note that the test cases cannot be nested. Starting a new test case ends - * implicitly the previous one. To end the test case explicitly (e.g. to end - * the last test case after exiting the loop), you may use TEST_CASE(NULL). - */ -#define TEST_CASE_(...) acutest_case_(__VA_ARGS__) -#define TEST_CASE(name) acutest_case_("%s", name) - - -/* Maximal output per TEST_CASE call. Longer messages are cut. - * You may define another limit prior including "acutest.h" - */ -#ifndef TEST_CASE_MAXSIZE - #define TEST_CASE_MAXSIZE 64 -#endif - - -/* printf-like macro for outputting an extra information about a failure. - * - * Intended use is to output some computed output versus the expected value, - * e.g. like this: - * - * if(!TEST_CHECK(produced == expected)) { - * TEST_MSG("Expected: %d", expected); - * TEST_MSG("Produced: %d", produced); - * } - * - * Note the message is only written down if the most recent use of any checking - * macro (like e.g. TEST_CHECK or TEST_EXCEPTION) in the current test failed. - * This means the above is equivalent to just this: - * - * TEST_CHECK(produced == expected); - * TEST_MSG("Expected: %d", expected); - * TEST_MSG("Produced: %d", produced); - * - * The macro can deal with multi-line output fairly well. It also automatically - * adds a final new-line if there is none present. - */ -#define TEST_MSG(...) acutest_message_(__VA_ARGS__) - - -/* Maximal output per TEST_MSG call. Longer messages are cut. - * You may define another limit prior including "acutest.h" - */ -#ifndef TEST_MSG_MAXSIZE - #define TEST_MSG_MAXSIZE 1024 -#endif - - -/* Macro for dumping a block of memory. - * - * Its intended use is very similar to what TEST_MSG is for, but instead of - * generating any printf-like message, this is for dumping raw block of a - * memory in a hexadecimal form: - * - * TEST_CHECK(size_produced == size_expected && - * memcmp(addr_produced, addr_expected, size_produced) == 0); - * TEST_DUMP("Expected:", addr_expected, size_expected); - * TEST_DUMP("Produced:", addr_produced, size_produced); - */ -#define TEST_DUMP(title, addr, size) acutest_dump_(title, addr, size) - -/* Maximal output per TEST_DUMP call (in bytes to dump). Longer blocks are cut. - * You may define another limit prior including "acutest.h" - */ -#ifndef TEST_DUMP_MAXSIZE - #define TEST_DUMP_MAXSIZE 1024 -#endif - - -/* Common test initialization/clean-up - * - * In some test suites, it may be needed to perform some sort of the same - * initialization and/or clean-up in all the tests. - * - * Such test suites may use macros TEST_INIT and/or TEST_FINI prior including - * this header. The expansion of the macro is then used as a body of helper - * function called just before executing every single (TEST_INIT) or just after - * it ends (TEST_FINI). - * - * Examples of various ways how to use the macro TEST_INIT: - * - * #define TEST_INIT my_init_func(); - * #define TEST_INIT my_init_func() // Works even without the semicolon - * #define TEST_INIT setlocale(LC_ALL, NULL); - * #define TEST_INIT { setlocale(LC_ALL, NULL); my_init_func(); } - * - * TEST_FINI is to be used in the same way. - */ - - -/********************** - *** Implementation *** - **********************/ - -/* The unit test files should not rely on anything below. */ - -#include -#include -#include -#include -#include -#include - -#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) - #define ACUTEST_UNIX_ 1 - #include - #include - #include - #include - #include - #include - #include - - #if defined CLOCK_PROCESS_CPUTIME_ID && defined CLOCK_MONOTONIC - #define ACUTEST_HAS_POSIX_TIMER_ 1 - #endif -#endif - -#if defined(_gnu_linux_) || defined(__linux__) - #define ACUTEST_LINUX_ 1 - #include - #include -#endif - -#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) - #define ACUTEST_WIN_ 1 - #include - #include -#endif - -#ifdef __cplusplus - #include -#endif - -#ifdef __has_include - #if __has_include() - #include - #endif -#endif - -/* Enable the use of the non-standard keyword __attribute__ to silence warnings under some compilers */ -#if defined(__GNUC__) || defined(__clang__) - #define ACUTEST_ATTRIBUTE_(attr) __attribute__((attr)) -#else - #define ACUTEST_ATTRIBUTE_(attr) -#endif - -/* Note our global private identifiers end with '_' to mitigate risk of clash - * with the unit tests implementation. */ - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef _MSC_VER - /* In the multi-platform code like ours, we cannot use the non-standard - * "safe" functions from Microsoft C lib like e.g. sprintf_s() instead of - * standard sprintf(). Hence, lets disable the warning C4996. */ - #pragma warning(push) - #pragma warning(disable: 4996) -#endif - - -struct acutest_test_ { - const char* name; - void (*func)(void); -}; - -struct acutest_test_data_ { - unsigned char flags; - double duration; -}; - -enum { - ACUTEST_FLAG_RUN_ = 1 << 0, - ACUTEST_FLAG_SUCCESS_ = 1 << 1, - ACUTEST_FLAG_FAILURE_ = 1 << 2, -}; - -extern const struct acutest_test_ acutest_list_[]; - -int acutest_check_(int cond, const char* file, int line, const char* fmt, ...); -void acutest_case_(const char* fmt, ...); -void acutest_message_(const char* fmt, ...); -void acutest_dump_(const char* title, const void* addr, size_t size); -void acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn); - - -#ifndef TEST_NO_MAIN - -static char* acutest_argv0_ = NULL; -static size_t acutest_list_size_ = 0; -static struct acutest_test_data_* acutest_test_data_ = NULL; -static size_t acutest_count_ = 0; -static int acutest_no_exec_ = -1; -static int acutest_no_summary_ = 0; -static int acutest_tap_ = 0; -static int acutest_skip_mode_ = 0; -static int acutest_worker_ = 0; -static int acutest_worker_index_ = 0; -static int acutest_cond_failed_ = 0; -static int acutest_was_aborted_ = 0; -static FILE *acutest_xml_output_ = NULL; - -static int acutest_stat_failed_units_ = 0; -static int acutest_stat_run_units_ = 0; - -static const struct acutest_test_* acutest_current_test_ = NULL; -static int acutest_current_index_ = 0; -static char acutest_case_name_[TEST_CASE_MAXSIZE] = ""; -static int acutest_test_already_logged_ = 0; -static int acutest_case_already_logged_ = 0; -static int acutest_verbose_level_ = 2; -static int acutest_test_failures_ = 0; -static int acutest_colorize_ = 0; -static int acutest_timer_ = 0; - -static int acutest_abort_has_jmp_buf_ = 0; -static jmp_buf acutest_abort_jmp_buf_; - - -static void -acutest_cleanup_(void) -{ - free((void*) acutest_test_data_); -} - -static void ACUTEST_ATTRIBUTE_(noreturn) -acutest_exit_(int exit_code) -{ - acutest_cleanup_(); - exit(exit_code); -} - -#if defined ACUTEST_WIN_ - typedef LARGE_INTEGER acutest_timer_type_; - static LARGE_INTEGER acutest_timer_freq_; - static acutest_timer_type_ acutest_timer_start_; - static acutest_timer_type_ acutest_timer_end_; - - static void - acutest_timer_init_(void) - { - QueryPerformanceFrequency(´st_timer_freq_); - } - - static void - acutest_timer_get_time_(LARGE_INTEGER* ts) - { - QueryPerformanceCounter(ts); - } - - static double - acutest_timer_diff_(LARGE_INTEGER start, LARGE_INTEGER end) - { - double duration = (double)(end.QuadPart - start.QuadPart); - duration /= (double)acutest_timer_freq_.QuadPart; - return duration; - } - - static void - acutest_timer_print_diff_(void) - { - printf("%.6lf secs", acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); - } -#elif defined ACUTEST_HAS_POSIX_TIMER_ - static clockid_t acutest_timer_id_; - typedef struct timespec acutest_timer_type_; - static acutest_timer_type_ acutest_timer_start_; - static acutest_timer_type_ acutest_timer_end_; - - static void - acutest_timer_init_(void) - { - if(acutest_timer_ == 1) - acutest_timer_id_ = CLOCK_MONOTONIC; - else if(acutest_timer_ == 2) - acutest_timer_id_ = CLOCK_PROCESS_CPUTIME_ID; - } - - static void - acutest_timer_get_time_(struct timespec* ts) - { - clock_gettime(acutest_timer_id_, ts); - } - - static double - acutest_timer_diff_(struct timespec start, struct timespec end) - { - double endns; - double startns; - - endns = end.tv_sec; - endns *= 1e9; - endns += end.tv_nsec; - - startns = start.tv_sec; - startns *= 1e9; - startns += start.tv_nsec; - - return ((endns - startns)/ 1e9); - } - - static void - acutest_timer_print_diff_(void) - { - printf("%.6lf secs", - acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_)); - } -#else - typedef int acutest_timer_type_; - static acutest_timer_type_ acutest_timer_start_; - static acutest_timer_type_ acutest_timer_end_; - - void - acutest_timer_init_(void) - {} - - static void - acutest_timer_get_time_(int* ts) - { - (void) ts; - } - - static double - acutest_timer_diff_(int start, int end) - { - (void) start; - (void) end; - return 0.0; - } - - static void - acutest_timer_print_diff_(void) - {} -#endif - -#define ACUTEST_COLOR_DEFAULT_ 0 -#define ACUTEST_COLOR_GREEN_ 1 -#define ACUTEST_COLOR_RED_ 2 -#define ACUTEST_COLOR_DEFAULT_INTENSIVE_ 3 -#define ACUTEST_COLOR_GREEN_INTENSIVE_ 4 -#define ACUTEST_COLOR_RED_INTENSIVE_ 5 - -static int ACUTEST_ATTRIBUTE_(format (printf, 2, 3)) -acutest_colored_printf_(int color, const char* fmt, ...) -{ - va_list args; - char buffer[256]; - int n; - - va_start(args, fmt); - vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - buffer[sizeof(buffer)-1] = '\0'; - - if(!acutest_colorize_) { - return printf("%s", buffer); - } - -#if defined ACUTEST_UNIX_ - { - const char* col_str; - switch(color) { - case ACUTEST_COLOR_GREEN_: col_str = "\033[0;32m"; break; - case ACUTEST_COLOR_RED_: col_str = "\033[0;31m"; break; - case ACUTEST_COLOR_GREEN_INTENSIVE_: col_str = "\033[1;32m"; break; - case ACUTEST_COLOR_RED_INTENSIVE_: col_str = "\033[1;31m"; break; - case ACUTEST_COLOR_DEFAULT_INTENSIVE_: col_str = "\033[1m"; break; - default: col_str = "\033[0m"; break; - } - printf("%s", col_str); - n = printf("%s", buffer); - printf("\033[0m"); - return n; - } -#elif defined ACUTEST_WIN_ - { - HANDLE h; - CONSOLE_SCREEN_BUFFER_INFO info; - WORD attr; - - h = GetStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(h, &info); - - switch(color) { - case ACUTEST_COLOR_GREEN_: attr = FOREGROUND_GREEN; break; - case ACUTEST_COLOR_RED_: attr = FOREGROUND_RED; break; - case ACUTEST_COLOR_GREEN_INTENSIVE_: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; - case ACUTEST_COLOR_RED_INTENSIVE_: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break; - case ACUTEST_COLOR_DEFAULT_INTENSIVE_: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break; - default: attr = 0; break; - } - if(attr != 0) - SetConsoleTextAttribute(h, attr); - n = printf("%s", buffer); - SetConsoleTextAttribute(h, info.wAttributes); - return n; - } -#else - n = printf("%s", buffer); - return n; -#endif -} - -static void -acutest_begin_test_line_(const struct acutest_test_* test) -{ - if(!acutest_tap_) { - if(acutest_verbose_level_ >= 3) { - acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s:\n", test->name); - acutest_test_already_logged_++; - } else if(acutest_verbose_level_ >= 1) { - int n; - char spaces[48]; - - n = acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Test %s... ", test->name); - memset(spaces, ' ', sizeof(spaces)); - if(n < (int) sizeof(spaces)) - printf("%.*s", (int) sizeof(spaces) - n, spaces); - } else { - acutest_test_already_logged_ = 1; - } - } -} - -static void -acutest_finish_test_line_(int result) -{ - if(acutest_tap_) { - const char* str = (result == 0) ? "ok" : "not ok"; - - printf("%s %d - %s\n", str, acutest_current_index_ + 1, acutest_current_test_->name); - - if(result == 0 && acutest_timer_) { - printf("# Duration: "); - acutest_timer_print_diff_(); - printf("\n"); - } - } else { - int color = (result == 0) ? ACUTEST_COLOR_GREEN_INTENSIVE_ : ACUTEST_COLOR_RED_INTENSIVE_; - const char* str = (result == 0) ? "OK" : "FAILED"; - printf("[ "); - acutest_colored_printf_(color, "%s", str); - printf(" ]"); - - if(result == 0 && acutest_timer_) { - printf(" "); - acutest_timer_print_diff_(); - } - - printf("\n"); - } -} - -static void -acutest_line_indent_(int level) -{ - static const char spaces[] = " "; - int n = level * 2; - - if(acutest_tap_ && n > 0) { - n--; - printf("#"); - } - - while(n > 16) { - printf("%s", spaces); - n -= 16; - } - printf("%.*s", n, spaces); -} - -int ACUTEST_ATTRIBUTE_(format (printf, 4, 5)) -acutest_check_(int cond, const char* file, int line, const char* fmt, ...) -{ - const char *result_str; - int result_color; - int verbose_level; - - if(cond) { - result_str = "ok"; - result_color = ACUTEST_COLOR_GREEN_; - verbose_level = 3; - } else { - if(!acutest_test_already_logged_ && acutest_current_test_ != NULL) - acutest_finish_test_line_(-1); - - result_str = "failed"; - result_color = ACUTEST_COLOR_RED_; - verbose_level = 2; - acutest_test_failures_++; - acutest_test_already_logged_++; - } - - if(acutest_verbose_level_ >= verbose_level) { - va_list args; - - if(!acutest_case_already_logged_ && acutest_case_name_[0]) { - acutest_line_indent_(1); - acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); - acutest_test_already_logged_++; - acutest_case_already_logged_++; - } - - acutest_line_indent_(acutest_case_name_[0] ? 2 : 1); - if(file != NULL) { -#ifdef ACUTEST_WIN_ - const char* lastsep1 = strrchr(file, '\\'); - const char* lastsep2 = strrchr(file, '/'); - if(lastsep1 == NULL) - lastsep1 = file-1; - if(lastsep2 == NULL) - lastsep2 = file-1; - file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1; -#else - const char* lastsep = strrchr(file, '/'); - if(lastsep != NULL) - file = lastsep+1; -#endif - printf("%s:%d: Check ", file, line); - } - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - printf("... "); - acutest_colored_printf_(result_color, "%s", result_str); - printf("\n"); - acutest_test_already_logged_++; - } - - acutest_cond_failed_ = (cond == 0); - return !acutest_cond_failed_; -} - -void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) -acutest_case_(const char* fmt, ...) -{ - va_list args; - - if(acutest_verbose_level_ < 2) - return; - - if(acutest_case_name_[0]) { - acutest_case_already_logged_ = 0; - acutest_case_name_[0] = '\0'; - } - - if(fmt == NULL) - return; - - va_start(args, fmt); - vsnprintf(acutest_case_name_, sizeof(acutest_case_name_) - 1, fmt, args); - va_end(args); - acutest_case_name_[sizeof(acutest_case_name_) - 1] = '\0'; - - if(acutest_verbose_level_ >= 3) { - acutest_line_indent_(1); - acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Case %s:\n", acutest_case_name_); - acutest_test_already_logged_++; - acutest_case_already_logged_++; - } -} - -void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) -acutest_message_(const char* fmt, ...) -{ - char buffer[TEST_MSG_MAXSIZE]; - char* line_beg; - char* line_end; - va_list args; - - if(acutest_verbose_level_ < 2) - return; - - /* We allow extra message only when something is already wrong in the - * current test. */ - if(acutest_current_test_ == NULL || !acutest_cond_failed_) - return; - - va_start(args, fmt); - vsnprintf(buffer, TEST_MSG_MAXSIZE, fmt, args); - va_end(args); - buffer[TEST_MSG_MAXSIZE-1] = '\0'; - - line_beg = buffer; - while(1) { - line_end = strchr(line_beg, '\n'); - if(line_end == NULL) - break; - acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); - printf("%.*s\n", (int)(line_end - line_beg), line_beg); - line_beg = line_end + 1; - } - if(line_beg[0] != '\0') { - acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); - printf("%s\n", line_beg); - } -} - -void -acutest_dump_(const char* title, const void* addr, size_t size) -{ - static const size_t BYTES_PER_LINE = 16; - size_t line_beg; - size_t truncate = 0; - - if(acutest_verbose_level_ < 2) - return; - - /* We allow extra message only when something is already wrong in the - * current test. */ - if(acutest_current_test_ == NULL || !acutest_cond_failed_) - return; - - if(size > TEST_DUMP_MAXSIZE) { - truncate = size - TEST_DUMP_MAXSIZE; - size = TEST_DUMP_MAXSIZE; - } - - acutest_line_indent_(acutest_case_name_[0] ? 3 : 2); - printf((title[strlen(title)-1] == ':') ? "%s\n" : "%s:\n", title); - - for(line_beg = 0; line_beg < size; line_beg += BYTES_PER_LINE) { - size_t line_end = line_beg + BYTES_PER_LINE; - size_t off; - - acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); - printf("%08lx: ", (unsigned long)line_beg); - for(off = line_beg; off < line_end; off++) { - if(off < size) - printf(" %02x", ((const unsigned char*)addr)[off]); - else - printf(" "); - } - - printf(" "); - for(off = line_beg; off < line_end; off++) { - unsigned char byte = ((const unsigned char*)addr)[off]; - if(off < size) - printf("%c", (iscntrl(byte) ? '.' : byte)); - else - break; - } - - printf("\n"); - } - - if(truncate > 0) { - acutest_line_indent_(acutest_case_name_[0] ? 4 : 3); - printf(" ... (and more %u bytes)\n", (unsigned) truncate); - } -} - -/* This is called just before each test */ -static void -acutest_init_(const char *test_name) -{ -#ifdef TEST_INIT - TEST_INIT - ; /* Allow for a single unterminated function call */ -#endif - - /* Suppress any warnings about unused variable. */ - (void) test_name; -} - -/* This is called after each test */ -static void -acutest_fini_(const char *test_name) -{ -#ifdef TEST_FINI - TEST_FINI - ; /* Allow for a single unterminated function call */ -#endif - - /* Suppress any warnings about unused variable. */ - (void) test_name; -} - -void -acutest_abort_(void) -{ - if(acutest_abort_has_jmp_buf_) { - longjmp(acutest_abort_jmp_buf_, 1); - } else { - if(acutest_current_test_ != NULL) - acutest_fini_(acutest_current_test_->name); - abort(); - } -} - -static void -acutest_list_names_(void) -{ - const struct acutest_test_* test; - - printf("Unit tests:\n"); - for(test = ´st_list_[0]; test->func != NULL; test++) - printf(" %s\n", test->name); -} - -static void -acutest_remember_(int i) -{ - if(acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_) - return; - - acutest_test_data_[i].flags |= ACUTEST_FLAG_RUN_; - acutest_count_++; -} - -static void -acutest_set_success_(int i, int success) -{ - acutest_test_data_[i].flags |= success ? ACUTEST_FLAG_SUCCESS_ : ACUTEST_FLAG_FAILURE_; -} - -static void -acutest_set_duration_(int i, double duration) -{ - acutest_test_data_[i].duration = duration; -} - -static int -acutest_name_contains_word_(const char* name, const char* pattern) -{ - static const char word_delim[] = " \t-_/.,:;"; - const char* substr; - size_t pattern_len; - - pattern_len = strlen(pattern); - - substr = strstr(name, pattern); - while(substr != NULL) { - int starts_on_word_boundary = (substr == name || strchr(word_delim, substr[-1]) != NULL); - int ends_on_word_boundary = (substr[pattern_len] == '\0' || strchr(word_delim, substr[pattern_len]) != NULL); - - if(starts_on_word_boundary && ends_on_word_boundary) - return 1; - - substr = strstr(substr+1, pattern); - } - - return 0; -} - -static int -acutest_lookup_(const char* pattern) -{ - int i; - int n = 0; - - /* Try exact match. */ - for(i = 0; i < (int) acutest_list_size_; i++) { - if(strcmp(acutest_list_[i].name, pattern) == 0) { - acutest_remember_(i); - n++; - break; - } - } - if(n > 0) - return n; - - /* Try word match. */ - for(i = 0; i < (int) acutest_list_size_; i++) { - if(acutest_name_contains_word_(acutest_list_[i].name, pattern)) { - acutest_remember_(i); - n++; - } - } - if(n > 0) - return n; - - /* Try relaxed match. */ - for(i = 0; i < (int) acutest_list_size_; i++) { - if(strstr(acutest_list_[i].name, pattern) != NULL) { - acutest_remember_(i); - n++; - } - } - - return n; -} - - -/* Called if anything goes bad in Acutest, or if the unit test ends in other - * way then by normal returning from its function (e.g. exception or some - * abnormal child process termination). */ -static void ACUTEST_ATTRIBUTE_(format (printf, 1, 2)) -acutest_error_(const char* fmt, ...) -{ - if(acutest_verbose_level_ == 0) - return; - - if(acutest_verbose_level_ >= 2) { - va_list args; - - acutest_line_indent_(1); - if(acutest_verbose_level_ >= 3) - acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "ERROR: "); - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - printf("\n"); - } - - if(acutest_verbose_level_ >= 3) { - printf("\n"); - } -} - -/* Call directly the given test unit function. */ -static int -acutest_do_run_(const struct acutest_test_* test, int index) -{ - int status = -1; - - acutest_was_aborted_ = 0; - acutest_current_test_ = test; - acutest_current_index_ = index; - acutest_test_failures_ = 0; - acutest_test_already_logged_ = 0; - acutest_cond_failed_ = 0; - -#ifdef __cplusplus - try { -#endif - acutest_init_(test->name); - acutest_begin_test_line_(test); - - /* This is good to do in case the test unit crashes. */ - fflush(stdout); - fflush(stderr); - - if(!acutest_worker_) { - acutest_abort_has_jmp_buf_ = 1; - if(setjmp(acutest_abort_jmp_buf_) != 0) { - acutest_was_aborted_ = 1; - goto aborted; - } - } - - acutest_timer_get_time_(´st_timer_start_); - test->func(); -aborted: - acutest_abort_has_jmp_buf_ = 0; - acutest_timer_get_time_(´st_timer_end_); - - if(acutest_verbose_level_ >= 3) { - acutest_line_indent_(1); - if(acutest_test_failures_ == 0) { - acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS: "); - printf("All conditions have passed.\n"); - - if(acutest_timer_) { - acutest_line_indent_(1); - printf("Duration: "); - acutest_timer_print_diff_(); - printf("\n"); - } - } else { - acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); - if(!acutest_was_aborted_) { - printf("%d condition%s %s failed.\n", - acutest_test_failures_, - (acutest_test_failures_ == 1) ? "" : "s", - (acutest_test_failures_ == 1) ? "has" : "have"); - } else { - printf("Aborted.\n"); - } - } - printf("\n"); - } else if(acutest_verbose_level_ >= 1 && acutest_test_failures_ == 0) { - acutest_finish_test_line_(0); - } - - status = (acutest_test_failures_ == 0) ? 0 : -1; - -#ifdef __cplusplus - } catch(std::exception& e) { - const char* what = e.what(); - acutest_check_(0, NULL, 0, "Threw std::exception"); - if(what != NULL) - acutest_message_("std::exception::what(): %s", what); - - if(acutest_verbose_level_ >= 3) { - acutest_line_indent_(1); - acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); - printf("C++ exception.\n\n"); - } - } catch(...) { - acutest_check_(0, NULL, 0, "Threw an exception"); - - if(acutest_verbose_level_ >= 3) { - acutest_line_indent_(1); - acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED: "); - printf("C++ exception.\n\n"); - } - } -#endif - - acutest_fini_(test->name); - acutest_case_(NULL); - acutest_current_test_ = NULL; - - return status; -} - -/* Trigger the unit test. If possible (and not suppressed) it starts a child - * process who calls acutest_do_run_(), otherwise it calls acutest_do_run_() - * directly. */ -static void -acutest_run_(const struct acutest_test_* test, int index, int master_index) -{ - int failed = 1; - acutest_timer_type_ start, end; - - acutest_current_test_ = test; - acutest_test_already_logged_ = 0; - acutest_timer_get_time_(&start); - - if(!acutest_no_exec_) { - -#if defined(ACUTEST_UNIX_) - - pid_t pid; - int exit_code; - - /* Make sure the child starts with empty I/O buffers. */ - fflush(stdout); - fflush(stderr); - - pid = fork(); - if(pid == (pid_t)-1) { - acutest_error_("Cannot fork. %s [%d]", strerror(errno), errno); - failed = 1; - } else if(pid == 0) { - /* Child: Do the test. */ - acutest_worker_ = 1; - failed = (acutest_do_run_(test, index) != 0); - acutest_exit_(failed ? 1 : 0); - } else { - /* Parent: Wait until child terminates and analyze its exit code. */ - waitpid(pid, &exit_code, 0); - if(WIFEXITED(exit_code)) { - switch(WEXITSTATUS(exit_code)) { - case 0: failed = 0; break; /* test has passed. */ - case 1: /* noop */ break; /* "normal" failure. */ - default: acutest_error_("Unexpected exit code [%d]", WEXITSTATUS(exit_code)); - } - } else if(WIFSIGNALED(exit_code)) { - char tmp[32]; - const char* signame; - switch(WTERMSIG(exit_code)) { - case SIGINT: signame = "SIGINT"; break; - case SIGHUP: signame = "SIGHUP"; break; - case SIGQUIT: signame = "SIGQUIT"; break; - case SIGABRT: signame = "SIGABRT"; break; - case SIGKILL: signame = "SIGKILL"; break; - case SIGSEGV: signame = "SIGSEGV"; break; - case SIGILL: signame = "SIGILL"; break; - case SIGTERM: signame = "SIGTERM"; break; - default: sprintf(tmp, "signal %d", WTERMSIG(exit_code)); signame = tmp; break; - } - acutest_error_("Test interrupted by %s.", signame); - } else { - acutest_error_("Test ended in an unexpected way [%d].", exit_code); - } - } - -#elif defined(ACUTEST_WIN_) - - char buffer[512] = {0}; - STARTUPINFOA startupInfo; - PROCESS_INFORMATION processInfo; - DWORD exitCode; - - /* Windows has no fork(). So we propagate all info into the child - * through a command line arguments. */ - _snprintf(buffer, sizeof(buffer)-1, - "%s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s -- \"%s\"", - acutest_argv0_, index, acutest_timer_ ? "--time" : "", - acutest_tap_ ? "--tap" : "", acutest_verbose_level_, - acutest_colorize_ ? "always" : "never", - test->name); - memset(&startupInfo, 0, sizeof(startupInfo)); - startupInfo.cb = sizeof(STARTUPINFO); - if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) { - WaitForSingleObject(processInfo.hProcess, INFINITE); - GetExitCodeProcess(processInfo.hProcess, &exitCode); - CloseHandle(processInfo.hThread); - CloseHandle(processInfo.hProcess); - failed = (exitCode != 0); - if(exitCode > 1) { - switch(exitCode) { - case 3: acutest_error_("Aborted."); break; - case 0xC0000005: acutest_error_("Access violation."); break; - default: acutest_error_("Test ended in an unexpected way [%lu].", exitCode); break; - } - } - } else { - acutest_error_("Cannot create unit test subprocess [%ld].", GetLastError()); - failed = 1; - } - -#else - - /* A platform where we don't know how to run child process. */ - failed = (acutest_do_run_(test, index) != 0); - -#endif - - } else { - /* Child processes suppressed through --no-exec. */ - failed = (acutest_do_run_(test, index) != 0); - } - acutest_timer_get_time_(&end); - - acutest_current_test_ = NULL; - - acutest_stat_run_units_++; - if(failed) - acutest_stat_failed_units_++; - - acutest_set_success_(master_index, !failed); - acutest_set_duration_(master_index, acutest_timer_diff_(start, end)); -} - -#if defined(ACUTEST_WIN_) -/* Callback for SEH events. */ -static LONG CALLBACK -acutest_seh_exception_filter_(EXCEPTION_POINTERS *ptrs) -{ - acutest_check_(0, NULL, 0, "Unhandled SEH exception"); - acutest_message_("Exception code: 0x%08lx", ptrs->ExceptionRecord->ExceptionCode); - acutest_message_("Exception address: 0x%p", ptrs->ExceptionRecord->ExceptionAddress); - - fflush(stdout); - fflush(stderr); - - return EXCEPTION_EXECUTE_HANDLER; -} -#endif - - -#define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ 0x0001 -#define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ 0x0002 - -#define ACUTEST_CMDLINE_OPTID_NONE_ 0 -#define ACUTEST_CMDLINE_OPTID_UNKNOWN_ (-0x7fffffff + 0) -#define ACUTEST_CMDLINE_OPTID_MISSINGARG_ (-0x7fffffff + 1) -#define ACUTEST_CMDLINE_OPTID_BOGUSARG_ (-0x7fffffff + 2) - -typedef struct acutest_test_CMDLINE_OPTION_ { - char shortname; - const char* longname; - int id; - unsigned flags; -} ACUTEST_CMDLINE_OPTION_; - -static int -acutest_cmdline_handle_short_opt_group_(const ACUTEST_CMDLINE_OPTION_* options, - const char* arggroup, - int (*callback)(int /*optval*/, const char* /*arg*/)) -{ - const ACUTEST_CMDLINE_OPTION_* opt; - int i; - int ret = 0; - - for(i = 0; arggroup[i] != '\0'; i++) { - for(opt = options; opt->id != 0; opt++) { - if(arggroup[i] == opt->shortname) - break; - } - - if(opt->id != 0 && !(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { - ret = callback(opt->id, NULL); - } else { - /* Unknown option. */ - char badoptname[3]; - badoptname[0] = '-'; - badoptname[1] = arggroup[i]; - badoptname[2] = '\0'; - ret = callback((opt->id != 0 ? ACUTEST_CMDLINE_OPTID_MISSINGARG_ : ACUTEST_CMDLINE_OPTID_UNKNOWN_), - badoptname); - } - - if(ret != 0) - break; - } - - return ret; -} - -#define ACUTEST_CMDLINE_AUXBUF_SIZE_ 32 - -static int -acutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_* options, int argc, char** argv, - int (*callback)(int /*optval*/, const char* /*arg*/)) -{ - - const ACUTEST_CMDLINE_OPTION_* opt; - char auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_+1]; - int after_doubledash = 0; - int i = 1; - int ret = 0; - - auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_] = '\0'; - - while(i < argc) { - if(after_doubledash || strcmp(argv[i], "-") == 0) { - /* Non-option argument. */ - ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); - } else if(strcmp(argv[i], "--") == 0) { - /* End of options. All the remaining members are non-option arguments. */ - after_doubledash = 1; - } else if(argv[i][0] != '-') { - /* Non-option argument. */ - ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); - } else { - for(opt = options; opt->id != 0; opt++) { - if(opt->longname != NULL && strncmp(argv[i], "--", 2) == 0) { - size_t len = strlen(opt->longname); - if(strncmp(argv[i]+2, opt->longname, len) == 0) { - /* Regular long option. */ - if(argv[i][2+len] == '\0') { - /* with no argument provided. */ - if(!(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) - ret = callback(opt->id, NULL); - else - ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); - break; - } else if(argv[i][2+len] == '=') { - /* with an argument provided. */ - if(opt->flags & (ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ | ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) { - ret = callback(opt->id, argv[i]+2+len+1); - } else { - sprintf(auxbuf, "--%s", opt->longname); - ret = callback(ACUTEST_CMDLINE_OPTID_BOGUSARG_, auxbuf); - } - break; - } else { - continue; - } - } - } else if(opt->shortname != '\0' && argv[i][0] == '-') { - if(argv[i][1] == opt->shortname) { - /* Regular short option. */ - if(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_) { - if(argv[i][2] != '\0') - ret = callback(opt->id, argv[i]+2); - else if(i+1 < argc) - ret = callback(opt->id, argv[++i]); - else - ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]); - break; - } else { - ret = callback(opt->id, NULL); - - /* There might be more (argument-less) short options - * grouped together. */ - if(ret == 0 && argv[i][2] != '\0') - ret = acutest_cmdline_handle_short_opt_group_(options, argv[i]+2, callback); - break; - } - } - } - } - - if(opt->id == 0) { /* still not handled? */ - if(argv[i][0] != '-') { - /* Non-option argument. */ - ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]); - } else { - /* Unknown option. */ - char* badoptname = argv[i]; - - if(strncmp(badoptname, "--", 2) == 0) { - /* Strip any argument from the long option. */ - char* assignment = strchr(badoptname, '='); - if(assignment != NULL) { - size_t len = assignment - badoptname; - if(len > ACUTEST_CMDLINE_AUXBUF_SIZE_) - len = ACUTEST_CMDLINE_AUXBUF_SIZE_; - strncpy(auxbuf, badoptname, len); - auxbuf[len] = '\0'; - badoptname = auxbuf; - } - } - - ret = callback(ACUTEST_CMDLINE_OPTID_UNKNOWN_, badoptname); - } - } - } - - if(ret != 0) - return ret; - i++; - } - - return ret; -} - -static void -acutest_help_(void) -{ - printf("Usage: %s [options] [test...]\n", acutest_argv0_); - printf("\n"); - printf("Run the specified unit tests; or if the option '--skip' is used, run all\n"); - printf("tests in the suite but those listed. By default, if no tests are specified\n"); - printf("on the command line, all unit tests in the suite are run.\n"); - printf("\n"); - printf("Options:\n"); - printf(" -s, --skip Execute all unit tests but the listed ones\n"); - printf(" --exec[=WHEN] If supported, execute unit tests as child processes\n"); - printf(" (WHEN is one of 'auto', 'always', 'never')\n"); - printf(" -E, --no-exec Same as --exec=never\n"); -#if defined ACUTEST_WIN_ - printf(" -t, --time Measure test duration\n"); -#elif defined ACUTEST_HAS_POSIX_TIMER_ - printf(" -t, --time Measure test duration (real time)\n"); - printf(" --time=TIMER Measure test duration, using given timer\n"); - printf(" (TIMER is one of 'real', 'cpu')\n"); -#endif - printf(" --no-summary Suppress printing of test results summary\n"); - printf(" --tap Produce TAP-compliant output\n"); - printf(" (See https://testanything.org/)\n"); - printf(" -x, --xml-output=FILE Enable XUnit output to the given file\n"); - printf(" -l, --list List unit tests in the suite and exit\n"); - printf(" -v, --verbose Make output more verbose\n"); - printf(" --verbose=LEVEL Set verbose level to LEVEL:\n"); - printf(" 0 ... Be silent\n"); - printf(" 1 ... Output one line per test (and summary)\n"); - printf(" 2 ... As 1 and failed conditions (this is default)\n"); - printf(" 3 ... As 1 and all conditions (and extended summary)\n"); - printf(" -q, --quiet Same as --verbose=0\n"); - printf(" --color[=WHEN] Enable colorized output\n"); - printf(" (WHEN is one of 'auto', 'always', 'never')\n"); - printf(" --no-color Same as --color=never\n"); - printf(" -h, --help Display this help and exit\n"); - - if(acutest_list_size_ < 16) { - printf("\n"); - acutest_list_names_(); - } -} - -static const ACUTEST_CMDLINE_OPTION_ acutest_cmdline_options_[] = { - { 's', "skip", 's', 0 }, - { 0, "exec", 'e', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, - { 'E', "no-exec", 'E', 0 }, -#if defined ACUTEST_WIN_ - { 't', "time", 't', 0 }, - { 0, "timer", 't', 0 }, /* kept for compatibility */ -#elif defined ACUTEST_HAS_POSIX_TIMER_ - { 't', "time", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, - { 0, "timer", 't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, /* kept for compatibility */ -#endif - { 0, "no-summary", 'S', 0 }, - { 0, "tap", 'T', 0 }, - { 'l', "list", 'l', 0 }, - { 'v', "verbose", 'v', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, - { 'q', "quiet", 'q', 0 }, - { 0, "color", 'c', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ }, - { 0, "no-color", 'C', 0 }, - { 'h', "help", 'h', 0 }, - { 0, "worker", 'w', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, /* internal */ - { 'x', "xml-output", 'x', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ }, - { 0, NULL, 0, 0 } -}; - -static int -acutest_cmdline_callback_(int id, const char* arg) -{ - switch(id) { - case 's': - acutest_skip_mode_ = 1; - break; - - case 'e': - if(arg == NULL || strcmp(arg, "always") == 0) { - acutest_no_exec_ = 0; - } else if(strcmp(arg, "never") == 0) { - acutest_no_exec_ = 1; - } else if(strcmp(arg, "auto") == 0) { - /*noop*/ - } else { - fprintf(stderr, "%s: Unrecognized argument '%s' for option --exec.\n", acutest_argv0_, arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - } - break; - - case 'E': - acutest_no_exec_ = 1; - break; - - case 't': -#if defined ACUTEST_WIN_ || defined ACUTEST_HAS_POSIX_TIMER_ - if(arg == NULL || strcmp(arg, "real") == 0) { - acutest_timer_ = 1; - #ifndef ACUTEST_WIN_ - } else if(strcmp(arg, "cpu") == 0) { - acutest_timer_ = 2; - #endif - } else { - fprintf(stderr, "%s: Unrecognized argument '%s' for option --time.\n", acutest_argv0_, arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - } -#endif - break; - - case 'S': - acutest_no_summary_ = 1; - break; - - case 'T': - acutest_tap_ = 1; - break; - - case 'l': - acutest_list_names_(); - acutest_exit_(0); - break; - - case 'v': - acutest_verbose_level_ = (arg != NULL ? atoi(arg) : acutest_verbose_level_+1); - break; - - case 'q': - acutest_verbose_level_ = 0; - break; - - case 'c': - if(arg == NULL || strcmp(arg, "always") == 0) { - acutest_colorize_ = 1; - } else if(strcmp(arg, "never") == 0) { - acutest_colorize_ = 0; - } else if(strcmp(arg, "auto") == 0) { - /*noop*/ - } else { - fprintf(stderr, "%s: Unrecognized argument '%s' for option --color.\n", acutest_argv0_, arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - } - break; - - case 'C': - acutest_colorize_ = 0; - break; - - case 'h': - acutest_help_(); - acutest_exit_(0); - break; - - case 'w': - acutest_worker_ = 1; - acutest_worker_index_ = atoi(arg); - break; - case 'x': - acutest_xml_output_ = fopen(arg, "w"); - if (!acutest_xml_output_) { - fprintf(stderr, "Unable to open '%s': %s\n", arg, strerror(errno)); - acutest_exit_(2); - } - break; - - case 0: - if(acutest_lookup_(arg) == 0) { - fprintf(stderr, "%s: Unrecognized unit test '%s'\n", acutest_argv0_, arg); - fprintf(stderr, "Try '%s --list' for list of unit tests.\n", acutest_argv0_); - acutest_exit_(2); - } - break; - - case ACUTEST_CMDLINE_OPTID_UNKNOWN_: - fprintf(stderr, "Unrecognized command line option '%s'.\n", arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - break; - - case ACUTEST_CMDLINE_OPTID_MISSINGARG_: - fprintf(stderr, "The command line option '%s' requires an argument.\n", arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - break; - - case ACUTEST_CMDLINE_OPTID_BOGUSARG_: - fprintf(stderr, "The command line option '%s' does not expect an argument.\n", arg); - fprintf(stderr, "Try '%s --help' for more information.\n", acutest_argv0_); - acutest_exit_(2); - break; - } - - return 0; -} - - -#ifdef ACUTEST_LINUX_ -static int -acutest_is_tracer_present_(void) -{ - /* Must be large enough so the line 'TracerPid: ${PID}' can fit in. */ - static const int OVERLAP = 32; - - char buf[256+OVERLAP+1]; - int tracer_present = 0; - int fd; - size_t n_read = 0; - - fd = open("/proc/self/status", O_RDONLY); - if(fd == -1) - return 0; - - while(1) { - static const char pattern[] = "TracerPid:"; - const char* field; - - while(n_read < sizeof(buf) - 1) { - ssize_t n; - - n = read(fd, buf + n_read, sizeof(buf) - 1 - n_read); - if(n <= 0) - break; - n_read += n; - } - buf[n_read] = '\0'; - - field = strstr(buf, pattern); - if(field != NULL && field < buf + sizeof(buf) - OVERLAP) { - pid_t tracer_pid = (pid_t) atoi(field + sizeof(pattern) - 1); - tracer_present = (tracer_pid != 0); - break; - } - - if(n_read == sizeof(buf)-1) { - memmove(buf, buf + sizeof(buf)-1 - OVERLAP, OVERLAP); - n_read = OVERLAP; - } else { - break; - } - } - - close(fd); - return tracer_present; -} -#endif - -int -main(int argc, char** argv) -{ - int i; - - acutest_argv0_ = argv[0]; - -#if defined ACUTEST_UNIX_ - acutest_colorize_ = isatty(STDOUT_FILENO); -#elif defined ACUTEST_WIN_ - #if defined _BORLANDC_ - acutest_colorize_ = isatty(_fileno(stdout)); - #else - acutest_colorize_ = _isatty(_fileno(stdout)); - #endif -#else - acutest_colorize_ = 0; -#endif - - /* Count all test units */ - acutest_list_size_ = 0; - for(i = 0; acutest_list_[i].func != NULL; i++) - acutest_list_size_++; - - acutest_test_data_ = (struct acutest_test_data_*)calloc(acutest_list_size_, sizeof(struct acutest_test_data_)); - if(acutest_test_data_ == NULL) { - fprintf(stderr, "Out of memory.\n"); - acutest_exit_(2); - } - - /* Parse options */ - acutest_cmdline_read_(acutest_cmdline_options_, argc, argv, acutest_cmdline_callback_); - - /* Initialize the proper timer. */ - acutest_timer_init_(); - -#if defined(ACUTEST_WIN_) - SetUnhandledExceptionFilter(acutest_seh_exception_filter_); -#ifdef _MSC_VER - _set_abort_behavior(0, _WRITE_ABORT_MSG); -#endif -#endif - - /* By default, we want to run all tests. */ - if(acutest_count_ == 0) { - for(i = 0; acutest_list_[i].func != NULL; i++) - acutest_remember_(i); - } - - /* Guess whether we want to run unit tests as child processes. */ - if(acutest_no_exec_ < 0) { - acutest_no_exec_ = 0; - - if(acutest_count_ <= 1) { - acutest_no_exec_ = 1; - } else { -#ifdef ACUTEST_WIN_ - if(IsDebuggerPresent()) - acutest_no_exec_ = 1; -#endif -#ifdef ACUTEST_LINUX_ - if(acutest_is_tracer_present_()) - acutest_no_exec_ = 1; -#endif -#ifdef RUNNING_ON_VALGRIND - /* RUNNING_ON_VALGRIND is provided by optionally included */ - if(RUNNING_ON_VALGRIND) - acutest_no_exec_ = 1; -#endif - } - } - - if(acutest_tap_) { - /* TAP requires we know test result ("ok", "not ok") before we output - * anything about the test, and this gets problematic for larger verbose - * levels. */ - if(acutest_verbose_level_ > 2) - acutest_verbose_level_ = 2; - - /* TAP harness should provide some summary. */ - acutest_no_summary_ = 1; - - if(!acutest_worker_) - printf("1..%d\n", (int) acutest_count_); - } - - int index = acutest_worker_index_; - for(i = 0; acutest_list_[i].func != NULL; i++) { - int run = (acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_); - if (acutest_skip_mode_) /* Run all tests except those listed. */ - run = !run; - if(run) - acutest_run_(´st_list_[i], index++, i); - } - - /* Write a summary */ - if(!acutest_no_summary_ && acutest_verbose_level_ >= 1) { - if(acutest_verbose_level_ >= 3) { - acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, "Summary:\n"); - - printf(" Count of all unit tests: %4d\n", (int) acutest_list_size_); - printf(" Count of run unit tests: %4d\n", acutest_stat_run_units_); - printf(" Count of failed unit tests: %4d\n", acutest_stat_failed_units_); - printf(" Count of skipped unit tests: %4d\n", (int) acutest_list_size_ - acutest_stat_run_units_); - } - - if(acutest_stat_failed_units_ == 0) { - acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, "SUCCESS:"); - printf(" All unit tests have passed.\n"); - } else { - acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, "FAILED:"); - printf(" %d of %d unit tests %s failed.\n", - acutest_stat_failed_units_, acutest_stat_run_units_, - (acutest_stat_failed_units_ == 1) ? "has" : "have"); - } - - if(acutest_verbose_level_ >= 3) - printf("\n"); - } - - if (acutest_xml_output_) { -#if defined ACUTEST_UNIX_ - char *suite_name = basename(argv[0]); -#elif defined ACUTEST_WIN_ - char suite_name[_MAX_FNAME]; - _splitpath(argv[0], NULL, NULL, suite_name, NULL); -#else - const char *suite_name = argv[0]; -#endif - fprintf(acutest_xml_output_, "\n"); - fprintf(acutest_xml_output_, "\n", - suite_name, (int)acutest_list_size_, acutest_stat_failed_units_, acutest_stat_failed_units_, - (int)acutest_list_size_ - acutest_stat_run_units_); - for(i = 0; acutest_list_[i].func != NULL; i++) { - struct acutest_test_data_ *details = ´st_test_data_[i]; - fprintf(acutest_xml_output_, " \n", acutest_list_[i].name, details->duration); - if (details->flags & ACUTEST_FLAG_FAILURE_) - fprintf(acutest_xml_output_, " \n"); - if (!(details->flags & ACUTEST_FLAG_FAILURE_) && !(details->flags & ACUTEST_FLAG_SUCCESS_)) - fprintf(acutest_xml_output_, " \n"); - fprintf(acutest_xml_output_, " \n"); - } - fprintf(acutest_xml_output_, "\n"); - fclose(acutest_xml_output_); - } - - acutest_cleanup_(); - - return (acutest_stat_failed_units_ == 0) ? 0 : 1; -} - - -#endif /* #ifndef TEST_NO_MAIN */ - -#ifdef _MSC_VER - #pragma warning(pop) -#endif - -#ifdef __cplusplus - } /* extern "C" */ -#endif - -#endif /* #ifndef ACUTEST_H */ diff --git a/graalpython/hpy/c_test/test_debug_handles.c b/graalpython/hpy/c_test/test_debug_handles.c deleted file mode 100644 index a5584fdb39..0000000000 --- a/graalpython/hpy/c_test/test_debug_handles.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include "acutest.h" // https://github.com/mity/acutest -#include "hpy/debug/src/debug_internal.h" - -static void check_DHQueue(DHQueue *q, HPy_ssize_t size, ...) -{ - va_list argp; - va_start(argp, size); - DHQueue_sanity_check(q); - TEST_CHECK(q->size == size); - DHQueueNode *h = q->head; - while(h != NULL) { - DHQueueNode *expected = va_arg(argp, DHQueueNode*); - TEST_CHECK(h == expected); - h = h->next; - } - va_end(argp); -} - -void test_DHQueue_init(void) -{ - DHQueue q; - DHQueue_init(&q); - TEST_CHECK(q.head == NULL); - TEST_CHECK(q.tail == NULL); - TEST_CHECK(q.size == 0); - DHQueue_sanity_check(&q); -} - -void test_DHQueue_append(void) -{ - DHQueue q; - DHQueueNode h1; - DHQueueNode h2; - DHQueueNode h3; - DHQueue_init(&q); - DHQueue_append(&q, &h1); - DHQueue_append(&q, &h2); - DHQueue_append(&q, &h3); - check_DHQueue(&q, 3, &h1, &h2, &h3); -} - -void test_DHQueue_popfront(void) -{ - DHQueue q; - DHQueueNode h1; - DHQueueNode h2; - DHQueueNode h3; - DHQueue_init(&q); - DHQueue_append(&q, &h1); - DHQueue_append(&q, &h2); - DHQueue_append(&q, &h3); - - TEST_CHECK(DHQueue_popfront(&q) == &h1); - check_DHQueue(&q, 2, &h2, &h3); - - TEST_CHECK(DHQueue_popfront(&q) == &h2); - check_DHQueue(&q, 1, &h3); - - TEST_CHECK(DHQueue_popfront(&q) == &h3); - check_DHQueue(&q, 0); -} - - -void test_DHQueue_remove(void) -{ - DHQueue q; - DHQueueNode h1; - DHQueueNode h2; - DHQueueNode h3; - DHQueueNode h4; - DHQueue_init(&q); - DHQueue_append(&q, &h1); - DHQueue_append(&q, &h2); - DHQueue_append(&q, &h3); - DHQueue_append(&q, &h4); - - DHQueue_remove(&q, &h3); // try to remove something in the middle - check_DHQueue(&q, 3, &h1, &h2, &h4); - - DHQueue_remove(&q, &h1); // try to remove the head - check_DHQueue(&q, 2, &h2, &h4); - - DHQueue_remove(&q, &h4); // try to remove the tail - check_DHQueue(&q, 1, &h2); - - DHQueue_remove(&q, &h2); // try to remove the only element - check_DHQueue(&q, 0); -} - -#define MYTEST(X) { #X, X } - -TEST_LIST = { - MYTEST(test_DHQueue_init), - MYTEST(test_DHQueue_append), - MYTEST(test_DHQueue_popfront), - MYTEST(test_DHQueue_remove), - { NULL, NULL } -}; diff --git a/graalpython/hpy/c_test/test_stacktrace.c b/graalpython/hpy/c_test/test_stacktrace.c deleted file mode 100644 index 5d02eced84..0000000000 --- a/graalpython/hpy/c_test/test_stacktrace.c +++ /dev/null @@ -1,22 +0,0 @@ -// Smoke test for the create_stacktrace function - -#include -#include "acutest.h" // https://github.com/mity/acutest -#include "hpy/debug/src/debug_internal.h" - -void test_create_stacktrace(void) -{ - char *trace; - create_stacktrace(&trace, 16); - if (trace != NULL) { - printf("\n\nTRACE:\n%s\n\n", trace); - free(trace); - } -} - -#define MYTEST(X) { #X, X } - -TEST_LIST = { - MYTEST(test_create_stacktrace), - { NULL, NULL } -}; \ No newline at end of file diff --git a/graalpython/hpy/docs/Makefile b/graalpython/hpy/docs/Makefile deleted file mode 100644 index 7164c8d0e5..0000000000 --- a/graalpython/hpy/docs/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -livehtml: - @sphinx-autobuild \ - "$(SOURCEDIR)" \ - -b html \ - --ignore "*~" \ - --ignore ".#*" \ - $(SPHINXOPTS) $(BUILDDIR)/html diff --git a/graalpython/hpy/docs/_static/README.txt b/graalpython/hpy/docs/_static/README.txt deleted file mode 100644 index 4d871f5a5a..0000000000 --- a/graalpython/hpy/docs/_static/README.txt +++ /dev/null @@ -1 +0,0 @@ -Static files for the Sphinx documentation. diff --git a/graalpython/hpy/docs/_templates/README.txt b/graalpython/hpy/docs/_templates/README.txt deleted file mode 100644 index 2dc51448da..0000000000 --- a/graalpython/hpy/docs/_templates/README.txt +++ /dev/null @@ -1 +0,0 @@ -Template files for the Sphinx documentation. diff --git a/graalpython/hpy/docs/api-reference/argument-parsing.rst b/graalpython/hpy/docs/api-reference/argument-parsing.rst deleted file mode 100644 index ff22665254..0000000000 --- a/graalpython/hpy/docs/api-reference/argument-parsing.rst +++ /dev/null @@ -1,5 +0,0 @@ -Argument Parsing -================ - -.. autocmodule:: runtime/argparse.c - :members: diff --git a/graalpython/hpy/docs/api-reference/build-value.rst b/graalpython/hpy/docs/api-reference/build-value.rst deleted file mode 100644 index a8cafb6bfe..0000000000 --- a/graalpython/hpy/docs/api-reference/build-value.rst +++ /dev/null @@ -1,5 +0,0 @@ -Building Complex Python Objects -=============================== - -.. autocmodule:: runtime/buildvalue.c - :members: diff --git a/graalpython/hpy/docs/api-reference/formatting.rst b/graalpython/hpy/docs/api-reference/formatting.rst deleted file mode 100644 index f4ea6f26f4..0000000000 --- a/graalpython/hpy/docs/api-reference/formatting.rst +++ /dev/null @@ -1,5 +0,0 @@ -String Formatting Helpers -========================= - -.. autocmodule:: runtime/format.c - :no-members: diff --git a/graalpython/hpy/docs/api-reference/function-index.rst b/graalpython/hpy/docs/api-reference/function-index.rst deleted file mode 100644 index 5e2cbcb59b..0000000000 --- a/graalpython/hpy/docs/api-reference/function-index.rst +++ /dev/null @@ -1,187 +0,0 @@ - -.. note: DO NOT EDIT THIS FILE! - This file is automatically generated by hpy.tools.autogen.doc.autogen_function_index - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -HPy Core API Function Index -########################### - -* :c:func:`HPyBool_FromBool` -* :c:func:`HPyBytes_AS_STRING` -* :c:func:`HPyBytes_AsString` -* :c:func:`HPyBytes_Check` -* :c:func:`HPyBytes_FromString` -* :c:func:`HPyBytes_FromStringAndSize` -* :c:func:`HPyBytes_GET_SIZE` -* :c:func:`HPyBytes_Size` -* :c:func:`HPyCallable_Check` -* :c:func:`HPyCapsule_Get` -* :c:func:`HPyCapsule_IsValid` -* :c:func:`HPyCapsule_New` -* :c:func:`HPyCapsule_Set` -* :c:func:`HPyContextVar_Get` -* :c:func:`HPyContextVar_New` -* :c:func:`HPyContextVar_Set` -* :c:func:`HPyDict_Check` -* :c:func:`HPyDict_Copy` -* :c:func:`HPyDict_Keys` -* :c:func:`HPyDict_New` -* :c:func:`HPyErr_Clear` -* :c:func:`HPyErr_ExceptionMatches` -* :c:func:`HPyErr_NewException` -* :c:func:`HPyErr_NewExceptionWithDoc` -* :c:func:`HPyErr_NoMemory` -* :c:func:`HPyErr_Occurred` -* :c:func:`HPyErr_SetFromErrnoWithFilename` -* :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` -* :c:func:`HPyErr_SetObject` -* :c:func:`HPyErr_SetString` -* :c:func:`HPyErr_WarnEx` -* :c:func:`HPyErr_WriteUnraisable` -* :c:func:`HPyField_Load` -* :c:func:`HPyField_Store` -* :c:func:`HPyFloat_AsDouble` -* :c:func:`HPyFloat_FromDouble` -* :c:func:`HPyGlobal_Load` -* :c:func:`HPyGlobal_Store` -* :c:func:`HPyImport_ImportModule` -* :c:func:`HPyIter_Check` -* :c:func:`HPyIter_Next` -* :c:func:`HPyListBuilder_Build` -* :c:func:`HPyListBuilder_Cancel` -* :c:func:`HPyListBuilder_New` -* :c:func:`HPyListBuilder_Set` -* :c:func:`HPyList_Append` -* :c:func:`HPyList_Check` -* :c:func:`HPyList_Insert` -* :c:func:`HPyList_New` -* :c:func:`HPyLong_AsDouble` -* :c:func:`HPyLong_AsInt32_t` -* :c:func:`HPyLong_AsInt64_t` -* :c:func:`HPyLong_AsSize_t` -* :c:func:`HPyLong_AsSsize_t` -* :c:func:`HPyLong_AsUInt32_t` -* :c:func:`HPyLong_AsUInt32_tMask` -* :c:func:`HPyLong_AsUInt64_t` -* :c:func:`HPyLong_AsUInt64_tMask` -* :c:func:`HPyLong_AsVoidPtr` -* :c:func:`HPyLong_FromInt32_t` -* :c:func:`HPyLong_FromInt64_t` -* :c:func:`HPyLong_FromSize_t` -* :c:func:`HPyLong_FromSsize_t` -* :c:func:`HPyLong_FromUInt32_t` -* :c:func:`HPyLong_FromUInt64_t` -* :c:func:`HPyNumber_Check` -* :c:func:`HPySlice_New` -* :c:func:`HPySlice_Unpack` -* :c:func:`HPyTracker_Add` -* :c:func:`HPyTracker_Close` -* :c:func:`HPyTracker_ForgetAll` -* :c:func:`HPyTracker_New` -* :c:func:`HPyTupleBuilder_Build` -* :c:func:`HPyTupleBuilder_Cancel` -* :c:func:`HPyTupleBuilder_New` -* :c:func:`HPyTupleBuilder_Set` -* :c:func:`HPyTuple_Check` -* :c:func:`HPyTuple_FromArray` -* :c:func:`HPyType_FromSpec` -* :c:func:`HPyType_GenericNew` -* :c:func:`HPyType_GetName` -* :c:func:`HPyType_IsSubtype` -* :c:func:`HPyUnicode_AsASCIIString` -* :c:func:`HPyUnicode_AsLatin1String` -* :c:func:`HPyUnicode_AsUTF8AndSize` -* :c:func:`HPyUnicode_AsUTF8String` -* :c:func:`HPyUnicode_Check` -* :c:func:`HPyUnicode_DecodeASCII` -* :c:func:`HPyUnicode_DecodeFSDefault` -* :c:func:`HPyUnicode_DecodeFSDefaultAndSize` -* :c:func:`HPyUnicode_DecodeLatin1` -* :c:func:`HPyUnicode_EncodeFSDefault` -* :c:func:`HPyUnicode_FromEncodedObject` -* :c:func:`HPyUnicode_FromString` -* :c:func:`HPyUnicode_FromWideChar` -* :c:func:`HPyUnicode_ReadChar` -* :c:func:`HPyUnicode_Substring` -* :c:func:`HPy_ASCII` -* :c:func:`HPy_Absolute` -* :c:func:`HPy_Add` -* :c:func:`HPy_And` -* :c:func:`HPy_AsPyObject` -* :c:func:`HPy_Bytes` -* :c:func:`HPy_Call` -* :c:func:`HPy_CallMethod` -* :c:func:`HPy_CallTupleDict` -* :c:func:`HPy_Close` -* :c:func:`HPy_Compile_s` -* :c:func:`HPy_Contains` -* :c:func:`HPy_DelItem` -* :c:func:`HPy_DelItem_i` -* :c:func:`HPy_DelItem_s` -* :c:func:`HPy_DelSlice` -* :c:func:`HPy_Divmod` -* :c:func:`HPy_Dup` -* :c:func:`HPy_EvalCode` -* :c:func:`HPy_FatalError` -* :c:func:`HPy_Float` -* :c:func:`HPy_FloorDivide` -* :c:func:`HPy_FromPyObject` -* :c:func:`HPy_GetAttr` -* :c:func:`HPy_GetAttr_s` -* :c:func:`HPy_GetItem` -* :c:func:`HPy_GetItem_i` -* :c:func:`HPy_GetItem_s` -* :c:func:`HPy_GetIter` -* :c:func:`HPy_GetSlice` -* :c:func:`HPy_HasAttr` -* :c:func:`HPy_HasAttr_s` -* :c:func:`HPy_Hash` -* :c:func:`HPy_InPlaceAdd` -* :c:func:`HPy_InPlaceAnd` -* :c:func:`HPy_InPlaceFloorDivide` -* :c:func:`HPy_InPlaceLshift` -* :c:func:`HPy_InPlaceMatrixMultiply` -* :c:func:`HPy_InPlaceMultiply` -* :c:func:`HPy_InPlaceOr` -* :c:func:`HPy_InPlacePower` -* :c:func:`HPy_InPlaceRemainder` -* :c:func:`HPy_InPlaceRshift` -* :c:func:`HPy_InPlaceSubtract` -* :c:func:`HPy_InPlaceTrueDivide` -* :c:func:`HPy_InPlaceXor` -* :c:func:`HPy_Index` -* :c:func:`HPy_Invert` -* :c:func:`HPy_Is` -* :c:func:`HPy_IsTrue` -* :c:func:`HPy_LeavePythonExecution` -* :c:func:`HPy_Length` -* :c:func:`HPy_Long` -* :c:func:`HPy_Lshift` -* :c:func:`HPy_MatrixMultiply` -* :c:func:`HPy_Multiply` -* :c:func:`HPy_Negative` -* :c:func:`HPy_Or` -* :c:func:`HPy_Positive` -* :c:func:`HPy_Power` -* :c:func:`HPy_ReenterPythonExecution` -* :c:func:`HPy_Remainder` -* :c:func:`HPy_Repr` -* :c:func:`HPy_RichCompare` -* :c:func:`HPy_RichCompareBool` -* :c:func:`HPy_Rshift` -* :c:func:`HPy_SetAttr` -* :c:func:`HPy_SetAttr_s` -* :c:func:`HPy_SetCallFunction` -* :c:func:`HPy_SetItem` -* :c:func:`HPy_SetItem_i` -* :c:func:`HPy_SetItem_s` -* :c:func:`HPy_SetSlice` -* :c:func:`HPy_Str` -* :c:func:`HPy_Subtract` -* :c:func:`HPy_TrueDivide` -* :c:func:`HPy_Type` -* :c:func:`HPy_TypeCheck` -* :c:func:`HPy_Xor` diff --git a/graalpython/hpy/docs/api-reference/helpers.rst b/graalpython/hpy/docs/api-reference/helpers.rst deleted file mode 100644 index df7725f8d4..0000000000 --- a/graalpython/hpy/docs/api-reference/helpers.rst +++ /dev/null @@ -1,5 +0,0 @@ -Misc Helpers -============ - -.. autocmodule:: runtime/helpers.c - :members: diff --git a/graalpython/hpy/docs/api-reference/hpy-call.rst b/graalpython/hpy/docs/api-reference/hpy-call.rst deleted file mode 100644 index d685898f1e..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-call.rst +++ /dev/null @@ -1,5 +0,0 @@ -HPy Call API -============ - -.. autocmodule:: autogen/public_api.h - :members: HPy_Call,HPy_CallMethod,HPy_CallTupleDict diff --git a/graalpython/hpy/docs/api-reference/hpy-ctx.rst b/graalpython/hpy/docs/api-reference/hpy-ctx.rst deleted file mode 100644 index 040903f005..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-ctx.rst +++ /dev/null @@ -1,9 +0,0 @@ -HPy Context -=========== - -The ``HPyContext`` structure is also part of the API since it provides handles -for built-in objects. For a high-level description of the context, please also -read :ref:`api:hpycontext`. - -.. autocstruct:: hpy/cpython/autogen_ctx.h::_HPyContext_s - :members: diff --git a/graalpython/hpy/docs/api-reference/hpy-dict.rst b/graalpython/hpy/docs/api-reference/hpy-dict.rst deleted file mode 100644 index fb9400f4c1..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-dict.rst +++ /dev/null @@ -1,5 +0,0 @@ -HPy Dict -======== - -.. autocmodule:: autogen/public_api.h - :members: HPyDict_Check, HPyDict_New, HPyDict_Keys, HPyDict_Copy diff --git a/graalpython/hpy/docs/api-reference/hpy-err.rst b/graalpython/hpy/docs/api-reference/hpy-err.rst deleted file mode 100644 index aeba618295..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-err.rst +++ /dev/null @@ -1,5 +0,0 @@ -Exception Handling -================== - -.. autocmodule:: autogen/public_api.h - :members: HPyErr_SetFromErrnoWithFilename, HPyErr_SetFromErrnoWithFilenameObjects, HPy_FatalError, HPyErr_SetString, HPyErr_SetObject, HPyErr_Occurred, HPyErr_ExceptionMatches, HPyErr_NoMemory, HPyErr_Clear, HPyErr_NewException, HPyErr_NewExceptionWithDoc, HPyErr_WarnEx, HPyErr_WriteUnraisable diff --git a/graalpython/hpy/docs/api-reference/hpy-eval.rst b/graalpython/hpy/docs/api-reference/hpy-eval.rst deleted file mode 100644 index 4e73e6d6fe..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-eval.rst +++ /dev/null @@ -1,8 +0,0 @@ -HPy Eval -======== - -.. autocmodule:: hpy.h - :members: HPy_SourceKind - -.. autocmodule:: autogen/public_api.h - :members: HPy_Compile_s,HPy_EvalCode diff --git a/graalpython/hpy/docs/api-reference/hpy-field.rst b/graalpython/hpy/docs/api-reference/hpy-field.rst deleted file mode 100644 index 2973af4c5e..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-field.rst +++ /dev/null @@ -1,5 +0,0 @@ -HPyField -======== - -.. autocmodule:: autogen/public_api.h - :members: HPyField_Load,HPyField_Store diff --git a/graalpython/hpy/docs/api-reference/hpy-gil.rst b/graalpython/hpy/docs/api-reference/hpy-gil.rst deleted file mode 100644 index b64f96042d..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-gil.rst +++ /dev/null @@ -1,5 +0,0 @@ -Leave/enter Python execution (GIL) -================================== - -.. autocmodule:: autogen/public_api.h - :members: HPy_LeavePythonExecution,HPy_ReenterPythonExecution diff --git a/graalpython/hpy/docs/api-reference/hpy-global.rst b/graalpython/hpy/docs/api-reference/hpy-global.rst deleted file mode 100644 index 9cbaa539e4..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-global.rst +++ /dev/null @@ -1,5 +0,0 @@ -HPyGlobal -========= - -.. autocmodule:: autogen/public_api.h - :members: HPyGlobal_Store,HPyGlobal_Load diff --git a/graalpython/hpy/docs/api-reference/hpy-object.rst b/graalpython/hpy/docs/api-reference/hpy-object.rst deleted file mode 100644 index eeb5a6544b..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-object.rst +++ /dev/null @@ -1,5 +0,0 @@ -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_GetSlice,HPy_SetItem,HPy_SetItem_s,HPy_SetItem_i,HPy_SetSlice,HPy_DelItem,HPy_DelItem_s,HPy_DelItem_i,HPy_DelSlice,HPy_Type,HPy_TypeCheck,HPy_Is,HPy_Repr,HPy_Str,HPy_ASCII,HPy_Bytes,HPy_RichCompare,HPy_RichCompareBool,HPy_Hash,HPy_SetCallFunction diff --git a/graalpython/hpy/docs/api-reference/hpy-sequence.rst b/graalpython/hpy/docs/api-reference/hpy-sequence.rst deleted file mode 100644 index 21b7756e03..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-sequence.rst +++ /dev/null @@ -1,23 +0,0 @@ -HPy Lists and Tuples -==================== - -Building Tuples and Lists -------------------------- - -.. autocmodule:: autogen/public_api.h - :members: HPyTupleBuilder_New,HPyTupleBuilder_Set,HPyTupleBuilder_Build,HPyTupleBuilder_Cancel - -.. autocmodule:: autogen/public_api.h - :members: HPyListBuilder_New,HPyListBuilder_Set,HPyListBuilder_Build,HPyListBuilder_Cancel - -Tuples ------- - -.. autocmodule:: autogen/public_api.h - :members: HPyTuple_Check,HPyTuple_FromArray - -Lists ------ - -.. autocmodule:: autogen/public_api.h - :members: HPyList_Check,HPyList_New,HPyList_Append,HPyList_Insert diff --git a/graalpython/hpy/docs/api-reference/hpy-type.rst b/graalpython/hpy/docs/api-reference/hpy-type.rst deleted file mode 100644 index 9fccdfa37a..0000000000 --- a/graalpython/hpy/docs/api-reference/hpy-type.rst +++ /dev/null @@ -1,50 +0,0 @@ -HPy Types and Modules -===================== - -Types, modules and their attributes (i.e. methods, members, slots, get-set -descriptors) are defined in a similar way. Section `HPy Type`_ documents the -type-specific and `HPy Module`_ documents the module-specific part. Section -`HPy Definition`_ documents how to define attributes for both, types and -modules. - - -HPy Type --------- - -Definition -~~~~~~~~~~ - -.. autocmodule:: hpy/hpytype.h - :members: HPyType_Spec,HPyType_BuiltinShape,HPyType_SpecParam,HPyType_SpecParam_Kind,HPyType_HELPERS,HPyType_LEGACY_HELPERS,HPy_TPFLAGS_DEFAULT,HPy_TPFLAGS_BASETYPE,HPy_TPFLAGS_HAVE_GC - -Construction and More -~~~~~~~~~~~~~~~~~~~~~ - -.. autocmodule:: autogen/public_api.h - :members: HPyType_FromSpec, HPyType_GetName, HPyType_IsSubtype - -HPy Module ----------- - -.. c:macro:: HPY_EMBEDDED_MODULES - - If ``HPY_EMBEDDED_MODULES`` is defined, this means that there will be - several embedded HPy modules (and so, several ``HPy_MODINIT`` usages) in the - same binary. In this case, some restrictions apply: - - 1. all of the module's methods/member/slots/... must be defined in the same - file - 2. the embedder **MUST** declare the module to be *embeddable* by using macro - :c:macro:`HPY_MOD_EMBEDDABLE`. - -.. autocmodule:: hpy/hpymodule.h - :members: HPY_MOD_EMBEDDABLE,HPyModuleDef,HPy_MODINIT - -HPy Definition --------------- - -Defining slots, methods, members, and get-set descriptors for types and modules -is done with HPy definition (represented by C struct :c:struct:`HPyDef`). - -.. autocmodule:: hpy/hpydef.h - :members: HPyDef,HPyDef_Kind,HPySlot,HPyMeth,HPyMember_FieldType,HPyMember,HPyGetSet,HPyDef_SLOT,HPyDef_METH,HPyDef_MEMBER,HPyDef_GET,HPyDef_SET,HPyDef_GETSET,HPyDef_CALL_FUNCTION diff --git a/graalpython/hpy/docs/api-reference/index.rst b/graalpython/hpy/docs/api-reference/index.rst deleted file mode 100644 index 89380d6377..0000000000 --- a/graalpython/hpy/docs/api-reference/index.rst +++ /dev/null @@ -1,69 +0,0 @@ -API Reference -============= - -HPy's public API consists of three parts: - -1. The **Core API** as defined in the :doc:`public-api` -2. **HPy Helper** functions -3. **Inline Helper** functions - -Core API --------- - -The **Core API** consists of inline functions that call into the Python -interpreter. Those functions will be implemented by each Python interpreter. In -:term:`CPython ABI` mode, many of these inline functions will just delegate to -a C API functions. In :term:`HPy Universal ABI` mode, they will call a function -pointer from the HPy context. This is the source of the performance change -between the modes. - -.. toctree:: - :maxdepth: 2 - - function-index - hpy-ctx - hpy-object - hpy-type - hpy-call - hpy-field - hpy-global - hpy-dict - hpy-sequence - hpy-gil - hpy-err - hpy-eval - public-api - - -HPy Helper Functions --------------------- - -**HPy Helper** functions are functions (written in C) that will be compiled -together with the HPy extension's sources. The appropriate source files are -automatically added to the extension sources. The helper functions will, of -course, use the core API to interact with the interpreter. The main reason for -having the helper functions in the HPy extension is to avoid compatibility -problems due to different compilers. - -.. toctree:: - :maxdepth: 2 - - argument-parsing - build-value - formatting - structseq - helpers - - -Inline Helper Functions ------------------------ - -**Inline Helper** functions are ``static inline`` functions (written in C). -Those functions are usually small convenience functions that everyone could -write but in order to avoid duplicated effort, they are defined by HPy. - -.. toctree:: - :maxdepth: 2 - - inline-helpers - diff --git a/graalpython/hpy/docs/api-reference/inline-helpers.rst b/graalpython/hpy/docs/api-reference/inline-helpers.rst deleted file mode 100644 index 2e719caf77..0000000000 --- a/graalpython/hpy/docs/api-reference/inline-helpers.rst +++ /dev/null @@ -1,14 +0,0 @@ -Inline Helpers -============== - -**Inline Helper** functions are ``static inline`` functions (written in C). -Those functions are usually small convenience functions that everyone could -write but in order to avoid duplicated effort, they are defined by HPy. - -One category of inline helpers are functions that convert the commonly used -but not fixed width C types, such as ``int``, or ``long long``, to HPy API. -The HPy API always uses well-defined fixed width types like ``int32`` or -``unsigned int8``. - -.. autocmodule:: hpy/inline_helpers.h - :members: diff --git a/graalpython/hpy/docs/api-reference/public-api.rst b/graalpython/hpy/docs/api-reference/public-api.rst deleted file mode 100644 index 992df114f8..0000000000 --- a/graalpython/hpy/docs/api-reference/public-api.rst +++ /dev/null @@ -1,9 +0,0 @@ -Public API Header -================= - -The core API is defined in `public_api.h -`_: - -.. literalinclude:: ../../hpy/tools/autogen/public_api.h - :language: c - :linenos: diff --git a/graalpython/hpy/docs/api-reference/structseq.rst b/graalpython/hpy/docs/api-reference/structseq.rst deleted file mode 100644 index 2772b3edfe..0000000000 --- a/graalpython/hpy/docs/api-reference/structseq.rst +++ /dev/null @@ -1,15 +0,0 @@ -Struct Sequences -================ - -Struct sequences are subclasses of tuple. Similar to the API for creating -tuples, HPy provides an API to create struct sequences. This is a builder API -such that the struct sequence is guaranteed not to be written after it is -created. - -.. note:: - - There is no specific getter function for struct sequences. Just use one of - :c:func:`HPy_GetItem`, :c:func:`HPy_GetItem_i`, or :c:func:`HPy_GetItem_s`. - -.. autocmodule:: hpy/runtime/structseq.h - :members: HPyStructSequence_Field,HPyStructSequence_Desc,HPyStructSequence_UnnamedField,HPyStructSequence_NewType,HPyStructSequence_New diff --git a/graalpython/hpy/docs/api.rst b/graalpython/hpy/docs/api.rst deleted file mode 100644 index 7146e024e2..0000000000 --- a/graalpython/hpy/docs/api.rst +++ /dev/null @@ -1,581 +0,0 @@ -HPy API Introduction -==================== - -Handles -------- - -The "H" in HPy stands for **handle**, which is a central concept: handles are -used to hold a C reference to Python objects, and they are represented by the -C ``HPy`` type. They play the same role as ``PyObject *`` in the ``Python.h`` -API, albeit with some important differences which are detailed below. - -When they are no longer needed, handles must be closed by calling -``HPy_Close``, which plays more or less the same role as ``Py_DECREF``. -Similarly, if you need a new handle for an existing object, you can duplicate -it by calling ``HPy_Dup``, which plays more or less the same role as -``Py_INCREF``. - -The HPy API strictly follows these rules: - -- ``HPy`` handles returned by a function are **never borrowed**, i.e., - the caller must either close or return it. -- ``HPy`` handles passed as function arguments are **never stolen**; - if you receive a ``HPy`` handle argument from your caller, you should never close it. - -These rules makes the code simpler to reason about. Moreover, no reference -borrowing enables the Python implementations to use whatever internal -representation they wish. For example, the object returned by ``HPy_GetItem_i`` -may be created on demand from some compact internal representation, which does -not need to convert itself to full blown representation in order to hold onto -the borrowed object. - -We strongly encourage the users of HPy to also internally follow these rules -for their own internal APIs and helper functions. For the sake of simplicity -and easier local reasoning and also because in the future, code adhering -to those rules may be suitable target for some scalable and precise static -analysis tool. - -The concept of handles is certainly not unique to HPy. Other examples include -Unix file descriptors, where you have ``dup()`` and ``close()``, and Windows' -``HANDLE``, where you have ``DuplicateHandle()`` and ``CloseHandle()``. - - -Handles vs ``PyObject *`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -In order to fully understand the way HPy handles work, it is useful to discuss -the ``Pyobject *`` pointer in ``Python.h``. These pointers always -point to the same object, and a python object's identity is completely given -by its address in memory, and two pointers with the same address can -be passed to ``Python.h`` API functions interchangeably. As a result, ``Py_INCREF`` -and ``Py_DECREF`` can be called with any reference to an object as long as the -total number of calls of ``incref`` is equal to the number of calls of ``decref`` -at the end of the object lifetime. - -Whereas using HPy API, each handle must be closed independently. - -Thus, the following perfectly valid piece of code using ``Python.h``:: - - void foo(void) - { - PyObject *x = PyLong_FromLong(42); // implicit INCREF on x - PyObject *y = x; - Py_INCREF(y); // INCREF on y - /* ... */ - Py_DECREF(x); - Py_DECREF(x); // two DECREF on x - } - -Becomes using HPy API: - -.. literalinclude:: examples/snippets/snippets.c - :start-after: // BEGIN: foo - :end-before: // END: foo - -Calling any HPy function on a closed handle is an error. Calling -``HPy_Close()`` on the same handle twice is an error. Forgetting to call -``HPy_Close()`` on a handle results in a memory leak. When running in -:ref:`debug-mode:debug mode`, HPy actively checks that you don't -close a handle twice and that you don't forget to close any. - - -.. note:: - Debug mode is a good example of how powerful it is to decouple the - identity and therefore the lifetime of handles and those of objects. - If you find a memory leak on CPython, you know that you are missing a - ``Py_DECREF`` somewhere but the only way to find the corresponding - ``Py_INCREF`` is to manually and carefully study the source code. - On the other hand, if you forget to call ``HPy_Close()``, debug mode - is able to identify the precise code location which created the unclosed - handle. Similarly, if you try to operate on a closed handle, it will - identify the precise code locations which created and closed it. This is - possible because handles are associated with a single call to a C/API - function. As a result, given a handle that is leaked or used after freeing, - it is possible to identify exactly the C/API function that produced it. - - -Remember that ``Python.h`` guarantees that multiple references to the same -object results in the very same ``PyObject *`` pointer. Thus, it is -possible to compare the pointer addresses to check whether they refer -to the same object:: - - int is_same_object(PyObject *x, PyObject *y) - { - return x == y; - } - -On the other hand, in HPy, each handle is independent and it is common to have -two different handles which point to the same underlying object, so comparing -two handles directly is ill-defined. To prevent this kind of common error -(especially when porting existing code to HPy), the ``HPy`` C type is opaque -and the C compiler actively forbids comparisons between them. To check for -identity, you can use ``HPy_Is()``: - -.. literalinclude:: examples/snippets/snippets.c - :start-after: // BEGIN: is_same_object - :end-before: // END: is_same_object - -.. note:: - The main benefit of opaque handle semantics is that implementations are - allowed to use very different models of memory management. On CPython, - implementing handles is trivial because ``HPy`` is basically ``PyObject *`` - in disguise, and ``HPy_Dup()`` and ``HPy_Close()`` are just aliases for - ``Py_INCREF`` and ``Py_DECREF``. - - Unlike CPython, PyPy does not use reference counting to manage memory: - instead, it uses a *moving GC*, which means that the address of an object - might change during its lifetime, and this makes it hard to implement - semantics like ``PyObject *``'s where the address *identifies* the object, - and this is directly exposed to the user. HPy solves this problem: on - PyPy, handles are integers which represent indices into a list, which - is itself managed by the GC. When an address changes, the GC edits the - list, without having to touch all the handles which have been passed to C. - - -HPyContext ------------ - -All HPy function calls take an ``HPyContext`` as a first argument, which -represents the Python interpreter all the handles belong to. Strictly -speaking, it would be possible to design the HPy API without using -``HPyContext``: after all, all HPy function calls are ultimately mapped to -``Python.h`` function call, where there is no notion of context. - -One of the reasons to include ``HPyContext`` from the day one is to be -future-proof: it is conceivable to use it to hold the interpreter or the -thread state in the future, in particular when there will be support for -sub-interpreters. Another possible usage could be to embed different versions -or implementations of Python inside the same process. In addition, the -``HPyContext`` may also be extended by adding new functions to the end without -breaking any extensions built against the current ``HPyContext``. - -Moreover, ``HPyContext`` is used by the :term:`HPy Universal ABI` to contain a -sort of virtual function table which is used by the C extensions to call back -into the Python interpreter. - -.. _simple example: - -A simple example ------------------ - -In this section, we will see how to write a simple C extension using HPy. It -is assumed that you are already familiar with the existing ``Python.h`` API, so we -will underline the similarities and the differences with it. - -We want to create a function named ``myabs`` and ``double`` which takes a -single argument and computes its absolute value: - -.. literalinclude:: examples/simple-example/simple.c - :start-after: // BEGIN: myabs - :end-before: // END: myabs - -There are a couple of points which are worth noting: - - * We use the macro ``HPyDef_METH`` to declare we are going to define a HPy - function called ``myabs``. - - * The function will be available under the name ``"myabs"`` in our Python - module. - - * The actual C function which implements ``myabs`` is called ``myabs_impl`` - and is inferred by the macro. The macro takes the name and adds ``_impl`` - to the end of it. - - * It uses the ``HPyFunc_O`` calling convention. Like ``METH_O`` in ``Python.h``, - ``HPyFunc_O`` means that the function receives a single argument on top of - ``self``. - - * ``myabs_impl`` takes two arguments of type ``HPy``: handles for ``self`` - and the argument, which are guaranteed to be valid. They are automatically - closed by the caller, so there is no need to call ``HPy_Close`` on them. - - * ``myabs_impl`` returns a handle, which has to be closed by the caller. - - * ``HPy_Absolute`` is the equivalent of ``PyNumber_Absolute`` and - computes the absolute value of the given argument. - - * We also do not call ``HPy_Close`` on the result returned to the caller. - We must return a valid handle. - -.. note:: - Among other things, - the ``HPyDef_METH`` macro is needed to maintain compatibility with CPython. - In CPython, C functions and methods have a C signature that is different to - the one used by HPy: they don't receive an ``HPyContext`` and their arguments - have the type ``PyObject *`` instead of ``HPy``. The macro automatically - generates a trampoline function whose signature is appropriate for CPython and - which calls the ``myabs_impl``. This trampoline is then used from both the - CPython ABI and the CPython implementation of the universal ABI, but other - implementations of the universal ABI will usually call directly the HPy - function itself. - -The second function definition is a bit different: - -.. literalinclude:: examples/simple-example/simple.c - :start-after: // BEGIN: double - :end-before: // END: double - -This shows off the other way of creating functions. - - * This example is much the same but the difference is that we use - ``HPyDef_METH_IMPL`` to define a function named ``double``. - - * The difference between ``HPyDef_METH_IMPL`` and ``HPyDef_METH`` is that - the former needs to be given a name for a the functions as the third - argument. - -Now, we can define our module: - -.. literalinclude:: examples/simple-example/simple.c - :start-after: // BEGIN: methodsdef - :end-before: // END: methodsdef - -This part is very similar to the one you would write with ``Python.h``. Note that -we specify ``myabs`` (and **not** ``myabs_impl``) in the method table. There -is also the ``.legacy_methods`` field, which allows to add methods that use the -``Python.h`` API, i.e., the value should be an array of ``PyMethodDef``. This -feature enables support for hybrid extensions in which some of the methods -are still written using the ``Python.h`` API. - -Note that the HPy module does not specify its name. HPy does not support the legacy -single phase module initialization and the only module initialization approach is -the multi-phase initialization (`PEP 489 `_). -With multi-phase module initialization, -the name of the module is always taken from the ``ModuleSpec`` (`PEP 451 `_) -, i.e., most likely from the name used in the ``import {{name}}`` statement that -imported your module. - -This is the only difference stemming from multi-phase module initialization in this -simple example. -As long as there is no need for any further initialization, we can just "register" -our module using the ``HPy_MODINIT`` convenience macro. The first argument is the -name of the extension file and is needed for HPy, among other things, to be able -to generate the entry point for CPython called ``PyInit_{{name}}``. The second argument -is the ``HPyModuleDef`` we just defined. - -.. literalinclude:: examples/simple-example/simple.c - :start-after: // BEGIN: moduledef - :end-before: // END: moduledef - -Building the module -~~~~~~~~~~~~~~~~~~~~ - -Let's write a ``setup.py`` to build our extension: - -.. literalinclude:: examples/simple-example/setup.py - :language: python - -We can now build the extension by running ``python setup.py build_ext -i``. On -CPython, it will target the :term:`CPython ABI` by default, so you will end up with -a file named e.g. ``simple.cpython-37m-x86_64-linux-gnu.so`` which can be -imported directly on CPython with no dependency on HPy. - -To target the :term:`HPy Universal ABI` instead, it is possible to pass the -option ``--hpy-abi=universal`` to ``setup.py``. The following command will -produce a file called ``simple.hpy.so`` (note that you need to specify -``--hpy-abi`` **before** ``build_ext``, since it is a global option):: - - python setup.py --hpy-abi=universal build_ext -i - -.. note:: - This command will also produce a Python file named ``simple.py``, which - loads the HPy module using the ``universal.load`` function from - the ``hpy`` Python package. - -VARARGS calling convention -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If we want to receive more than a single arguments, we need the -``HPy_METH_VARARGS`` calling convention. Let's add a function ``add_ints`` -which adds two integers: - -.. literalinclude:: examples/snippets/hpyvarargs.c - :start-after: // BEGIN: add_ints - :end-before: // END: add_ints - -There are a few things to note: - - * The C signature is different than the corresponding ``Python.h`` - ``METH_VARARGS``: in particular, instead of taking a tuple ``PyObject *args``, - we take an array of ``HPy`` and its size. This allows the call to happen - more efficiently, because you don't need to create a tuple just to pass the - arguments. - - * We call ``HPyArg_Parse`` to parse the arguments. Contrarily to almost all - the other HPy functions, this is **not** a thin wrapper around - ``PyArg_ParseTuple`` because as stated above we don't have a tuple to pass - to it, although the idea is to mimic its behavior as closely as - possible. The parsing logic is implemented from scratch inside HPy, and as - such there might be missing functionality during the early stages of HPy - development. - - * If an error occurs, we return ``HPy_NULL``: we cannot simply ``return NULL`` - because ``HPy`` is not a pointer type. - -Once we have written our function, we can add it to the ``SimpleMethods[]`` -table, which now becomes: - -.. literalinclude:: examples/snippets/hpyvarargs.c - :start-after: // BEGIN: methodsdef - :end-before: // END: methodsdef - -Creating types in HPy ---------------------- - -Creating Python types in an HPy extension is again very similar to the C API -with the difference that HPy only supports creating types from a specification. -This is necessary because there is no such C-level type as ``PyTypeObject`` -since that would expose the internal implementation. - - -Creating a simple type in HPy -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section assumes that the user wants to define a type that stores some data -in a C-level structure. As an example, we will create a simple C structure -``PointObject`` that represents a two-dimensional point. - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: PointObject - :end-before: // END: PointObject - -The macro call ``HPyType_HELPERS(PointObject)`` generates useful helper -facilities for working with the type. It generates a C enum -``PointObject_SHAPE`` and a helper function ``PointObject_AsStruct``. The enum -is used in the type specification. The helper function is used to efficiently -retrieving the pointer ``PointObject *`` from an HPy handle to be able to access -the C structure. We will use this helper function to implement the methods, -get-set descriptors, and slots. - -It makes sense to expose fields ``PointObject.x`` and ``PointObject.y`` as -Python-level members. To do so, we need to define members by specifying their -name, type, and location using HPy's convenience macro ``HPyDef_MEMBER``: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: members - :end-before: // END: members - -The first argument of the macro is the name for the C glabal variable that will -store the necessary information. We will need that later for registration of -the type. The second, third, and fourth arguments are the Python-level name, the -C type of the member, and the offset in the C structure, respectively. - -Similarly, methods and get-set descriptors can be defined. For example, method -``foo`` is an instance method that takes no arguments (the self argument is, of -course, implicit), does some computation with fields ``x`` and ``y`` and -returns a Python ``int``: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: methods - :end-before: // END: methods - -Get-set descriptors are also defined in a very similar way as methods. The -following example defines a get-set descriptor for attribute ``z`` which is -calculated from the ``x`` and ``y`` fields of the struct. - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: getset - :end-before: // END: getset - -It is also possible to define a get-descriptor or a set-descriptor by using -HPy's macros ``HPyDef_GET`` and ``HPyDef_SET`` in the same way. - -HPy also supports type slots. In this example, we will define slot -``HPy_tp_new`` (which corresponds to magic method ``__new__``) to initialize -fields ``x`` and ``y`` when constructing the object: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: slots - :end-before: // END: slots - -After everything was defined, we need to create a list of all defines such that -we are able to eventually register them to the type: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: defines - :end-before: // END: defines - -Please note that it is required to terminate the list with ``NULL``. -We can now create the actual type specification by appropriately filling an -``HPyType_Spec`` structure: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: spec - :end-before: // END: spec - -First, we need to define the name of the type by setting a C string to member -``name``. Since this type has a C structure, we need to define the ``basicsize`` -and best practice is to set it to ``sizeof(PointObject)``. Also best practice is -to set ``builtin_shape`` to ``PointObject_SHAPE`` where ``PointObject_SHAPE`` is -generated by the previous usage of macro ``HPyType_HELPERS(PointObject)``. Last -but not least, we need to register the defines by setting field ``defines`` to -the previously defined array ``Point_defines``. - -The type specification for the simple type ``simple_type.Point`` represented in -C by structure ``PointObject`` is now complete. All that remains is to create -the type object and add it to the module. - -We will define a module execute slot, which is executed by the runtime right -after the module is created. The purpose of the execute slot is to initialize -the newly created module object. We can then add the type by using -:c:func:`HPyHelpers_AddType`: - -.. literalinclude:: examples/hpytype-example/simple_type.c - :start-after: // BEGIN: add_type - :end-before: // END: add_type - -Also look at the full example at: :doc:`examples/hpytype-example/simple_type`. - - -Legacy types -~~~~~~~~~~~~ - -A type whose struct starts with ``PyObject_HEAD`` (either directly by -embedding it in the type struct or indirectly by embedding another struct like -``PyLongObject``) is a *legacy type*. A legacy type must set -``.builtin_shape = HPyType_BuiltinShape_Legacy`` -in its ``HPyType_Spec``. The counterpart (i.e. a non-legacy type) is called HPy -pure type. - -Legacy types are available to allow gradual porting of existing CPython -extensions. It is possible to reuse existing ``PyType_Slot`` entities (i.e. -slots, methods, members, and get/set descriptors). The idea is that you can then -migrate one after each other while still running the tests. - -The major restriction when using legacy types is that you cannot build a -universal binary of your HPy extension (i.e. you cannot use :term:`HPy Universal -ABI`). The resulting binary will be specific to the Python interpreter used for -building. Therefore, the goal should always be to fully migrate to HPy pure -types. - -A type with ``.legacy_slots != NULL`` is required to have -``HPyType_BuiltinShape_Legacy`` and to include ``PyObject_HEAD`` at the start of -its struct. It would be easy to relax this requirement on CPython (where the -``PyObject_HEAD`` fields are always present) but a large burden on other -implementations (e.g. PyPy, GraalPy) where a struct starting with -``PyObject_HEAD`` might not exist. - -Types created via the old Python C API are automatically legacy types. - -This section does not provide a dedicated example for how to create and use -legacy types because the :doc:`porting-example/index` already shows how that -is useful during incremental migration to HPy. - -Inherit from a built-in type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -HPy also supports inheriting from following built-in types: - - * ``type`` - - * ``int`` - - * ``float`` - - * ``unicode`` - - * ``tuple`` - - * ``list`` - -Inheriting from built-in types is straight forward if you don't have a C -structure that represents your type. In other words, you can simply inherit -from, e.g., ``str`` if the ``basicsize`` in your type specification is ``0``. -For example: - -.. literalinclude:: examples/hpytype-example/builtin_type.c - :start-after: // BEGIN: spec_Dummy - :end-before: // END: spec_Dummy - -.. literalinclude:: examples/hpytype-example/builtin_type.c - :start-after: // BEGIN: add_Dummy - :end-before: // END: add_Dummy - -This case is simple because there is no ``Dummy_AsStruct`` since there is no -associated C-level structure. - -It is, however, more involved if your type also defines its own C structure -(i.e. ``basicsize > 0`` in the type specification). In this case, it is strictly -necessary to use the right *built-in shape*. - -**What is the right built-in shape?** - -This question is easy to answer: Each built-in shape (except of -:c:enumerator:`HPyType_BuiltinShape_Legacy`) represents a built-in type. You -need to use the built-in shape that fits to the specified base class. The -mapping is described in :c:enum:`HPyType_BuiltinShape`. - -Let's do an example. Assume we want to define a type that stores the natural -language of a unicode string to the unicode object but the object should still -just behave like a Python unicode object. So, we define struct -``LanguageObject``: - -.. literalinclude:: examples/hpytype-example/builtin_type.c - :start-after: // BEGIN: LanguageObject - :end-before: // END: LanguageObject - -As you can see, we already specify the built-in shape here using -``HPyType_HELPERS(LanguageObject, HPyType_BuiltinShape_Unicode)``. Then, in the -type specification, we do: - -.. literalinclude:: examples/hpytype-example/builtin_type.c - :start-after: // BEGIN: spec_Language - :end-before: // END: spec_Language - -In the last step, when actually creating the type from the specification, we -need to define that its base class is ``str`` (aka. ``UnicodeType``): - -.. literalinclude:: examples/hpytype-example/builtin_type.c - :start-after: // BEGIN: add_Language - :end-before: // END: add_Language - -Function ``LanguageObject_AsStruct`` (which is generated by ``HPyType_HELPERS``) -will then return a pointer to ``LanguageObject``. - -To summarize this: Specifying a type that inherits from a built-in type needs to -be considered in three places: - -1. Pass the appropriate built-in shape to :c:macro:`HPyType_HELPERS`. -2. Assign ``SHAPE(TYPE)`` to :c:member:`HPyType_Spec.builtin_shape`. -3. Specify the desired base class in the type specification parameters. - -For more information about the built-in shape and for a technical explanation -for why it is required, see :c:member:`HPyType_Spec.builtin_shape` and -:c:enum:`HPyType_BuiltinShape`. - -More Examples -------------- - -The :doc:`porting-example/index` shows another complete example -of HPy extension ported from Python/C API. - -The `HPy project space `_ on GitHub -contains forks of some popular Python extensions ported to HPy as -a proof of concept/feasibility studies, such as the -`Kiwi solver `_. -Note that those forks may not be up to date with their upstream projects -or with the upstream HPy changes. - -HPy unit tests -~~~~~~~~~~~~~~ - -HPy usually has tests for each API function. This means that there is lots of -examples available by looking at the tests. However, the test source uses -many macros and is hard to read. To overcome this we supply a utility to -export clean C sources for the tests. Since the HPy tests are not shipped by -default, you need to clone the HPy repository from GitHub: - -.. code-block:: console - - > git clone https://github.com/hpyproject/hpy.git - -After that, install all test requirements and dump the sources: - -.. code-block:: console - - > cd hpy - > python3 -m pip install pytest filelock - > python3 -m pytest --dump-dir=test_sources test/ - -This will dump the generated test sources into folder ``test_sources``. Note, -that the tests won't be executed but skipped with an appropriate message. diff --git a/graalpython/hpy/docs/changelog.rst b/graalpython/hpy/docs/changelog.rst deleted file mode 100644 index e2915b98d3..0000000000 --- a/graalpython/hpy/docs/changelog.rst +++ /dev/null @@ -1,235 +0,0 @@ -Changelog -========= - -Version 0.9 (April 25th, 2023) ------------------------------- - -This release adds numerous major features and indicates the end of HPy's *alhpa* -phase. We've migrated several key packages to HPy (for a list, see our website -https://hpyproject.org) and we are now confident that HPy is mature enough for -being used as serious extension API. We also plan that the next major release -will be ``1.0``. - -Major new features -~~~~~~~~~~~~~~~~~~ - -Support subclasses of built-in types - It is now possible to create pure HPy types that inherit from built-in types - like ``type`` or ``float``. This was already possible before but in a very - limited way, i.e., by setting :c:member:`HPyType_Spec.basicsize` to ``0``. In - this case, the type implicitly inherited the basic size of the supertype but - that also means that you cannot have a custom C struct. It is now possible - inherit from a built-in type **AND** have a custom C struct. For further - reference, see :c:member:`HPyType_Spec.builtin_shape` and - :c:enum:`HPyType_BuiltinShape`. - -Support for metaclasses - HPy now supports creating types with metaclasses. This can be done by passing - type specification parameter with kind - :c:enumerator:`HPyType_SpecParam_Metaclass` when calling - :c:func:`HPyType_FromSpec`. - -:term:`HPy Hybrid ABI` - In addition to :term:`CPython ABI` and :term:`HPy Universal ABI`, we now - introduced the Hybrid ABI. The major difference is that whenever you use a - legacy API like :c:func:`HPy_AsPyObject` or :c:func:`HPy_FromPyObject`, the - prdouced binary will then be specific to one interpreter. This was necessary - to ensure that universal binaries are really portable and can be used on any - HPy-capable interpreter. - -:doc:`trace-mode` - Similar to the :doc:`debug-mode`, HPy now provides the Trace Mode that can be - enabled at runtime and helps analyzing API usage and identifying performance - issues. - -:ref:`porting-guide:multi-phase module initialization` - HPy now support multi-phase module initialization which is an important - feature in particular needed for two important use cases: (1) module state - support (which is planned to be introduced in the next major release), and (2) - subinterpreters. We decided to drop support for single-phase module - initialization since this makes the API cleaner and easier to use. - -HPy :ref:`porting-guide:calling protocol` - This was a big missing piece and is now eventually available. It enables slot - ``HPy_tp_call``, which can now be used in the HPy type specification. We - decided to use a calling convention similar to CPython's vectorcall calling - convention. This is: the arguments are passed in a C array and the keyword - argument names are provided as a Python tuple. Before this release, the only - way to create a callable type was to set the special method ``__call__``. - However, this has several disadvantages. In particlar, poor performance on - CPython (and maybe other implementations) and it was not possible to have - specialized call function implementations per object (see - :c:func:`HPy_SetCallFunction`) - -Added APIs -~~~~~~~~~~ - -Deleting attributes and items - :c:func:`HPy_DelAttr`, :c:func:`HPy_DelAttr_s`, :c:func:`HPy_DelItem`, :c:func:`HPy_DelItem_i`, :c:func:`HPy_DelItem_s` - -Capsule API - :c:func:`HPyCapsule_New`, :c:func:`HPyCapsule_IsValid`, :c:func:`HPyCapsule_Get`, :c:func:`HPyCapsule_Set` - -Eval API - :c:func:`HPy_Compile_s` and :c:func:`HPy_EvalCode` - -Formatting helpers - :c:func:`HPyUnicode_FromFormat` and :c:func:`HPyErr_Format` - -Contextvar API - :c:func:`HPyContextVar_New`, :c:func:`HPyContextVar_Get`, :c:func:`HPyContextVar_Set` - -Unicode API - :c:func:`HPyUnicode_FromEncodedObject` and :c:func:`HPyUnicode_Substring` - -Dict API - :c:func:`HPyDict_Keys` and :c:func:`HPyDict_Copy` - -Type API - :c:func:`HPyType_GetName` and :c:func:`HPyType_IsSubtype` - -Slice API - :c:func:`HPySlice_Unpack` and :c:func:`HPySlice_AdjustIndices` - -Structseq API - :c:func:`HPyStructSequence_NewType`, :c:func:`HPyStructSequence_New` - -Call API - :c:func:`HPy_Call`, :c:func:`HPy_CallMethod`, :c:func:`HPy_CallMethodTupleDict`, :c:func:`HPy_CallMethodTupleDict_s` - -HPy call protocol - :c:func:`HPy_SetCallFunction` - -Debug mode -~~~~~~~~~~ - -* Detect closing and returning (without dup) of context handles -* Detect invalid usage of stored ``HPyContext *`` pointer -* Detect invalid usage of tuple and list builders -* Added Windows support for checking invalid use of raw data pointers (e.g - ``HPyUnicode_AsUTF8AndSize``) after handle was closed. -* Added support for backtrace on MacOS - -Documentation -~~~~~~~~~~~~~ - -* Added incremental :doc:`porting-example/index` -* Added :doc:`quickstart` guide -* Extended :doc:`api-reference/index` -* Added :doc:`api-reference/function-index` -* Added possiblity to generate examples from tests with argument ``--dump-dir`` - (see :ref:`api:hpy unit tests`) -* Added initial :doc:`contributing/index` docs - -Incompatible changes to version 0.0.4 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* Simplified ``HPyDef_*`` macros -* Changed macro :c:macro:`HPy_MODINIT` because of multi-phase module init - support. -* Replace environment variable ``HPY_DEBUG`` by ``HPY`` (see :doc:`debug-mode` - or :doc:`trace-mode`). -* Changed signature of ``HPyFunc_VARARGS`` and ``HPyFunc_ KEYWORDS`` to align - with HPy's call protocol calling convention. - -Supported Python versions -~~~~~~~~~~~~~~~~~~~~~~~~~ - -* Added Python 3.11 support -* Preliminary Python 3.12 support -* Dropped Python 3.6 support (since EOL) -* Dropped Python 3.7 support (since EOL by June 2023) - -Misc -~~~~ - -* Ensure deterministic auto-generation -* Ensure ABI backwards compatibility - - * Explicitly define slot within HPyContext of function pointers and handles - * Compile HPy ABI version into binary and verify at load time -* Added proper support for object members ``HPyMember_OBJECT`` -* Changed :c:func:`HPyBytes_AsString` and :c:func:`HPyBytes_AS_STRING` to return ``const char *`` -* Use fixed-width integers in context functions - - - -Version 0.0.4 (May 25th, 2022) ------------------------------- - -New Features/API: - - - HPy headers are C++ compliant - - Python 3.10 support - - `HPyField `_: - References to Python objects that can be stored in raw native memory owned by Python objects. - - - New API functions: ``HPyField_Load``, ``HPyField_Store`` - - `HPyGlobal `_: - References to Python objects that can be stored into a C global variable. - - - New API functions: ``HPyGlobal_Load``, ``HPyGlobal_Store`` - - Note: ``HPyGlobal`` does not allow to share Python objects between (sub)interpreters - - - `GIL support `_ - - New API functions: ``HPy_ReenterPythonExecution``, ``HPy_LeavePythonExecution`` - - - `Value building support `_ (``HPy_BuildValue``) - - - New type slots - - - ``HPy_mp_ass_subscript``, ``HPy_mp_length``, ``HPy_mp_subscript`` - - ``HPy_tp_finalize`` - - - Other new API functions - - - ``HPyErr_SetFromErrnoWithFilename``, ``HPyErr_SetFromErrnoWithFilenameObjects`` - - ``HPyErr_ExceptionMatches`` - - ``HPyErr_WarnEx`` - - ``HPyErr_WriteUnraisable`` - - ``HPy_Contains`` - - ``HPyLong_AsVoidPtr`` - - ``HPyLong_AsDouble`` - - ``HPyUnicode_AsASCIIString``, ``HPyUnicode_DecodeASCII`` - - ``HPyUnicode_AsLatin1String``, ``HPyUnicode_DecodeLatin1`` - - ``HPyUnicode_DecodeFSDefault``, ``HPyUnicode_DecodeFSDefaultAndSize`` - - ``HPyUnicode_ReadChar`` - -Debug mode: - - - Support activation of debug mode via environment variable ``HPY_DEBUG`` - - Support capturing stack traces of handle allocations - - Check for invalid use of raw data pointers (e.g ``HPyUnicode_AsUTF8AndSize``) after handle was closed. - - Detect invalid handles returned from extension functions - - Detect incorrect closing of handles passed as arguments - -Misc Changes: - - - Removed unnecessary prefix ``"m_"`` from fields of ``HPyModuleDef`` (incompatible change) - - For HPy implementors: new pytest mark for HPy tests assuming synchronous GC - -Version 0.0.3 (September 22nd, 2021) ------------------------------------- - -This release adds various new API functions (see below) and extends the debug -mode with the ability to track closed handles. -The default ABI mode now is 'universal' for non-CPython implementations. -Also, the type definition of ``HPyContext`` was changed and it's no longer a -pointer type. -The name of the HPy dev package was changed to 'hpy' (formerly: 'hpy.devel'). -Macro HPy_CAST was replaced by HPy_AsStruct. - -New features: - - - Added helper HPyHelpers_AddType for creating new types - - Support format specifier 's' in HPyArg_Parse - - Added API functions: HPy_Is, HPy_AsStructLegacy (for legacy types), - HPyBytes_FromStringAndSize, HPyErr_NewException, HPyErr_NewExceptionWithDoc, - HPyUnicode_AsUTF8AndSize, HPyUnicode_DecodeFSDefault, HPyImport_ImportModule - - Debug mode: Implemented tracking of closed handles - - Debug mode: Add hook for invalid handle access - -Bug fixes: - - - Distinguish between pure and legacy types - - Fix Sphinx doc errors diff --git a/graalpython/hpy/docs/conf.py b/graalpython/hpy/docs/conf.py deleted file mode 100644 index 45a9077616..0000000000 --- a/graalpython/hpy/docs/conf.py +++ /dev/null @@ -1,134 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -import sys -import os -import re -import datetime - -# -- Project information ----------------------------------------------------- - -project = "HPy" -copyright = "2019-{}, HPy Collective".format(datetime.date.today().year) -author = "HPy Collective" - -# The full version, including alpha/beta/rc tags -release = "0.9" - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.autosectionlabel", - "sphinx_c_autodoc", - "sphinx_c_autodoc.viewcode", - "sphinx_rtd_theme", -] - -autosectionlabel_prefix_document = True - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - -# -- autodoc ----------------------------------------------------------------- - -autodoc_member_order = "bysource" - -# -- sphinx_c_autodoc -------------------------------------------------------- - -c_autodoc_roots = [ - "../hpy/devel/include", - "../hpy/devel/src", - "../hpy/tools", -] - - -def pre_process(app, filename, contents, *args): - # FIXME: the missing typedef for 'HPy' causes the file formatting to fail - if filename.endswith('public_api.h'): - contents[0] = '#include "../../devel/include/hpy.h"\n' + contents[0] - if filename.endswith('autogen_ctx.h'): - contents[0] = 'typedef int HPy;' + contents[0] - - # remove HPyAPI_HELPER so that the sphinx-c-autodoc and clang - # find and render the API functions - contents[:] = [ - re.sub(r"^(HPyAPI_HELPER|HPyAPI_INLINE_HELPER|HPy_ID\(\d+\))", r"", part, flags=re.MULTILINE) - for part in contents - ] - - -def setup(app): - app.connect("c-autodoc-pre-process", pre_process) - - -def setup_clang(): - """ - Make sure clang is set up correctly for the sphinx_c_autodoc extension. - - The Python clang package requires a matching libclang*.so. Our - ``doc/requirements.txt`` file specifies ``clang==10.0.1``, so we need - ``libclang-10``. - - On Ubuntu 20.04 (and possibly later), this can be installed with - ``apt install libclang-10-dev`` and the Python clang package finds the - appropriate .so automatically. - - However, ReadTheDocs has an older Ubuntu that only packages libclang-6.0. - The Python ``clang==10.0.1`` packages supports this older .so, but - needs to be explicitly told where to find it. - - If you encounter issues with a local build, please start by checking that - the ``libclang-10-dev`` system package or equivalent is installed. - """ - from clang import cindex - if 'READTHEDOCS' in os.environ: - # TODO: Hopefully we can remove this setting of the libclang path once - # readthedocs updates its docker image to Ubuntu 20.04 which - # supports clang-10 and clang-11. - cindex.Config.set_library_file( - "/usr/lib/x86_64-linux-gnu/libclang-6.0.so.1" - ) - elif sys.platform == "darwin": - cindex.Config.set_library_file( - "/Library/Developer/CommandLineTools/usr/lib/libclang.dylib" - ) - - -setup_clang() - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - -# most the the code examples will be in C, let's make it the default -highlight_language = 'C' diff --git a/graalpython/hpy/docs/contributing/index.rst b/graalpython/hpy/docs/contributing/index.rst deleted file mode 100644 index 1dba877a90..0000000000 --- a/graalpython/hpy/docs/contributing/index.rst +++ /dev/null @@ -1,33 +0,0 @@ -Contributing -============ - -Getting Started ---------------- - -TBD - - -Adding New API --------------- - -1. Add the function to ``hpy/tools/autogen/public_api.h``. If the CPython - equivalent function name is not the same (after removing the leading ``H``, - add an appropriate CPython function mapping in ``hpy/tools/autogen/conf.py``. - If the signature is complicated or there is no clear equivalent function, - the mapping should be ``None``, and follow the directions in the next step. - Otherwise all the needed functions will be autogenerated. - -2. If the function cannot be autogenerated (i.e. the mapping does not exist), - you must write the wrapper by hand. Add the function to ``NO_WRAPPER`` in - ``hpy/tools/autogen/debug.py``, and add a ``ctx_fname`` function to - ``hyp/devel/src/runtime/*.c`` (possibly adding the new file to ``setup.py``), - add a debug wrapper to ``hpy/debug/src/debug_ctx.c``, add a implementation - that uses the ``ctx`` variant to ``hpy/devel/include/hpy/cpython/misc.h`` and - add the declaration to ``hpy/devel/include/hpy/runtime/ctx_funcs.h``. - -3. Run ``make autogen`` which will turn the mapping into autogenerated functions - -4. Add a test for the functionality - -5. Build with ``python setup.py build_ext``. After that works, build with - ``python -m pip install -e .``, then run the test with ``python -m pytest ...``. diff --git a/graalpython/hpy/docs/debug-mode.rst b/graalpython/hpy/docs/debug-mode.rst deleted file mode 100644 index 0f59bc9486..0000000000 --- a/graalpython/hpy/docs/debug-mode.rst +++ /dev/null @@ -1,169 +0,0 @@ -Debug Mode -========== - -HPy includes a debug mode which does useful run-time checks to ensure that C -extensions use the API correctly. Its features include: - - 1. No special compilation flags are required: it is enough to compile the - extension with the Universal ABI. - - 2. Debug mode can be activated at *import time*, and it can be activated - per-extension. - - 3. You pay the overhead of debug mode only if you use it. Extensions loaded - without the debug mode run at full speed. - -This is possible because the whole of the HPy API is provided as part of the HPy -context, so debug mode can pass in a special debugging context without affecting -the performance of the regular context at all. - -.. note:: The debug mode is only available if the module (you want to use it - for) was built for :term:`HPy Universal ABI`. - -The debugging context can already check for: - -* Leaked handles. -* Handles used after they are closed. -* Tuple and list builder used after they were *closed* (i.e. cancelled or the - tuple/list was built). -* Reading from a memory which is no longer guaranteed to be still valid, - for example, the buffer returned by :c:func:`HPyUnicode_AsUTF8AndSize`, - :c:func:`HPyBytes_AsString`, and :c:func:`HPyBytes_AS_STRING`, after the - corresponding ``HPy`` handle was closed. -* Writing to memory which should be read-only, for example the buffer - returned by :c:func:`HPyUnicode_AsUTF8AndSize`, :c:func:`HPyBytes_AsString`, - and :c:func:`HPyBytes_AS_STRING` - - -Activating Debug Mode ---------------------- - -Debug mode works *only* for extensions built with HPy universal ABI. - -To enable debug mode, use environment variable ``HPY``. If ``HPY=debug``, then -all HPy modules are loaded with the trace context. Alternatively, it is also -possible to specify the mode per module like this: -``HPY=modA:debug,modB:debug``. - -In order to verify that your extension is being loaded in debug mode, use -environment variable ``HPY_LOG``. If this variable is set, then all HPy -extensions built in universal ABI mode print a message when loaded, such as: - -.. code-block:: console - - > import snippets - Loading 'snippets' in HPy universal mode with a debug context - -.. Note: the output above is tested in test_leak_detector_with_traces_output - -If the extension is built in CPython ABI mode, then the ``HPY_LOG`` environment -variable has no effect. - -An HPy extension module may be also explicitly loaded in debug mode using: - -.. code-block:: python - - from hpy.universal import load, MODE_DEBUG - mod = load(module_name, so_filename, mode=MODE_DEBUG) - -When loading HPy extensions explicitly, environment variables ``HPY_LOG`` -and ``HPY`` have no effect for that extension. - - -Using Debug Mode ----------------- - -By default, when debug mode detects an error it will either abort the process -(using :c:func:`HPy_FatalError`) or raise a fatal exception. This may sound very -strict but in general, it is not safe to continue the execution. - -When testing, aborting the process is unwanted. Module ``hpy.debug`` exposes the -``LeakDetector`` class to detect leaked ``HPy`` handles. For example: - -.. literalinclude:: examples/tests.py - :language: python - :start-at: def test_leak_detector - :end-before: # END: test_leak_detector - -Additionally, the debug module also provides a pytest fixture, ``hpy_debug``, -that for the time being, enables the ``LeakDetector``. In the future, it -may also enable other useful debugging facilities. - -.. literalinclude:: examples/tests.py - :language: python - :start-at: from hpy.debug.pytest import hpy_debug - :end-at: # Run some HPy extension code - -.. warning:: The usage of ``LeakDetector`` or ``hpy_debug`` by itself does not - enable HPy debug mode! If debug mode is not enabled for any extension, then - those features have no effect. - -When dealing with handle leaks, it is useful to get a stack trace of the -allocation of the leaked handle. This feature has large memory requirements -and is therefore opt-in. It can be activated by: - -.. literalinclude:: examples/tests.py - :language: python - :start-at: hpy.debug.set_handle_stack_trace_limit - :end-at: hpy.debug.set_handle_stack_trace_limit - -and disabled by: - -.. literalinclude:: examples/tests.py - :language: python - :start-at: hpy.debug.disable_handle_stack_traces - :end-at: hpy.debug.disable_handle_stack_traces - - -Example -------- - -.. note: The following output is tested in test_leak_detector_with_traces_output - -Following HPy function leaks a handle: - -.. literalinclude:: examples/snippets/snippets.c - :start-after: // BEGIN: test_leak_stacktrace - :end-before: // END: test_leak_stacktrace - -When this script is executed in debug mode: - -.. literalinclude:: examples/debug-example.py - :language: python - :end-before: print("SUCCESS") - -The output is:: - - Traceback (most recent call last): - File "/path/to/hpy/docs/examples/debug-example.py", line 7, in - snippets.test_leak_stacktrace() - File "/path/to/hpy/debug/leakdetector.py", line 43, in __exit__ - self.stop() - File "/path/to/hpy/debug/leakdetector.py", line 36, in stop - raise HPyLeakError(leaks) - hpy.debug.leakdetector.HPyLeakError: 1 unclosed handle: - - Allocation stacktrace: - /path/to/site-packages/hpy-0.0.4.dev227+gd7eeec6.d20220510-py3.8-linux-x86_64.egg/hpy/universal.cpython-38d-x86_64-linux-gnu.so(debug_ctx_Long_FromLong+0x45) [0x7f1d928c48c4] - /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x122c) [0x7f1d921a622c] - /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x14b1) [0x7f1d921a64b1] - /path/to/site-packages/hpy-0.0.4.dev227+gd7eeec6.d20220510-py3.8-linux-x86_64.egg/hpy/universal.cpython-38d-x86_64-linux-gnu.so(debug_ctx_CallRealFunctionFromTrampoline+0xca) [0x7f1d928bde1e] - /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x129b) [0x7f1d921a629b] - /path/to/site-packages/hpy_snippets-0.0.0-py3.8-linux-x86_64.egg/snippets.hpy.so(+0x1472) [0x7f1d921a6472] - /path/to/libpython3.8d.so.1.0(+0x10a022) [0x7f1d93807022] - /path/to/libpython3.8d.so.1.0(+0x1e986b) [0x7f1d938e686b] - /path/to/libpython3.8d.so.1.0(+0x2015e9) [0x7f1d938fe5e9] - /path/to/libpython3.8d.so.1.0(_PyEval_EvalFrameDefault+0x1008c) [0x7f1d938f875a] - /path/to/libpython3.8d.so.1.0(PyEval_EvalFrameEx+0x64) [0x7f1d938e86b8] - /path/to/libpython3.8d.so.1.0(_PyEval_EvalCodeWithName+0xfaa) [0x7f1d938fc8af] - /path/to/libpython3.8d.so.1.0(PyEval_EvalCodeEx+0x86) [0x7f1d938fca25] - /path/to/libpython3.8d.so.1.0(PyEval_EvalCode+0x4b) [0x7f1d938e862b] - -For the time being, HPy uses the glibc ``backtrace`` and ``backtrace_symbols`` -`functions `_. -Therefore all their caveats and limitations apply. Usual recommendations to get -more symbols in the traces and not only addresses, such as ``snippets.hpy.so(+0x122c)``, are: - -* link your native code with ``-rdynamic`` flag (``LDFLAGS="-rdynamic"``) -* build your code without optimizations and with debug symbols (``CFLAGS="-O0 -g"``) -* use ``addr2line`` command line utility, e.g.: ``addr2line -e /path/to/snippets.hpy.so -C -f +0x122c`` diff --git a/graalpython/hpy/docs/examples/debug-example.py b/graalpython/hpy/docs/examples/debug-example.py deleted file mode 100644 index 0cd16cae36..0000000000 --- a/graalpython/hpy/docs/examples/debug-example.py +++ /dev/null @@ -1,10 +0,0 @@ -# Run with HPY=debug -import hpy.debug -import snippets - -hpy.debug.set_handle_stack_trace_limit(16) -from hpy.debug.pytest import LeakDetector -with LeakDetector() as ld: - snippets.test_leak_stacktrace() - -print("SUCCESS") # Should not be actually printed diff --git a/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c b/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c deleted file mode 100644 index 5ec749b690..0000000000 --- a/graalpython/hpy/docs/examples/hpytype-example/builtin_type.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -// BEGIN: spec_Dummy -static HPyType_Spec Dummy_spec = { - .name = "builtin_type.Dummy", - .basicsize = 0 -}; - -// END: spec_Dummy -static void make_Dummy(HPyContext *ctx, HPy module) -{ -// BEGIN: add_Dummy - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Base, ctx->h_UnicodeType }, - { (HPyType_SpecParam_Kind)0 } - }; - if (!HPyHelpers_AddType(ctx, module, "Dummy", &Dummy_spec, param)) - return; -// END: add_Dummy -} - -// BEGIN: LanguageObject -typedef struct { - char *language; -} LanguageObject; -HPyType_HELPERS(LanguageObject, HPyType_BuiltinShape_Unicode) -// END: LanguageObject - -HPyDef_GETSET(Language_lang, "lang") -static HPy Language_lang_get(HPyContext *ctx, HPy self, void *closure) -{ - LanguageObject *data = LanguageObject_AsStruct(ctx, self); - return HPyUnicode_FromString(ctx, data->language); -} -static int Language_lang_set(HPyContext *ctx, HPy self, HPy value, void *closure) -{ - LanguageObject *data = LanguageObject_AsStruct(ctx, self); - HPy_ssize_t size; - const char *s = HPyUnicode_AsUTF8AndSize(ctx, value, &size); - if (s == NULL) - return -1; - data->language = (char *)calloc(size+1, sizeof(char)); - strncpy(data->language, s, size); - return 0; -} - -HPyDef_SLOT(Language_destroy, HPy_tp_destroy) -static void Language_destroy_impl(void *data) -{ - LanguageObject *ldata = (LanguageObject *)data; - if (ldata->language) - free(ldata->language); -} - -HPyDef *Language_defines[] = { - &Language_lang, - &Language_destroy, - NULL -}; - - -// BEGIN: spec_Language -static HPyType_Spec Language_spec = { - .name = "builtin_type.Language", - .basicsize = sizeof(LanguageObject), - .builtin_shape = SHAPE(LanguageObject), - .defines = Language_defines -}; -// END: spec_Language - -static void make_Language(HPyContext *ctx, HPy module) -{ -// BEGIN: add_Language - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Base, ctx->h_UnicodeType }, - { (HPyType_SpecParam_Kind)0 } - }; - if (!HPyHelpers_AddType(ctx, module, "Language", &Language_spec, param)) - return; -// END: add_Language -} - -HPyDef_SLOT(simple_exec, HPy_mod_exec) -static int simple_exec_impl(HPyContext *ctx, HPy m) { - make_Dummy(ctx, m); - if (HPyErr_Occurred(ctx)) - return -1; - - make_Language(ctx, m); - if (HPyErr_Occurred(ctx)) - return -1; - - return 0; // success -} - -static HPyDef *mod_defines[] = { - &simple_exec, // 'simple_exec' is generated by the HPyDef_SLOT macro - NULL, -}; - -static HPyModuleDef moduledef = { - .defines = mod_defines -}; - -HPy_MODINIT(builtin_type, moduledef) diff --git a/graalpython/hpy/docs/examples/hpytype-example/setup.py b/graalpython/hpy/docs/examples/hpytype-example/setup.py deleted file mode 100644 index f740a424e1..0000000000 --- a/graalpython/hpy/docs/examples/hpytype-example/setup.py +++ /dev/null @@ -1,11 +0,0 @@ -from setuptools import setup, Extension -from os import path - -setup( - name="hpy-type-example", - hpy_ext_modules=[ - Extension('simple_type', sources=['simple_type.c']), - Extension('builtin_type', sources=['builtin_type.c']), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/examples/hpytype-example/simple_type.c b/graalpython/hpy/docs/examples/hpytype-example/simple_type.c deleted file mode 100644 index 40b1fba715..0000000000 --- a/graalpython/hpy/docs/examples/hpytype-example/simple_type.c +++ /dev/null @@ -1,102 +0,0 @@ -#include - -// BEGIN: PointObject -typedef struct { - long x; - long y; -} PointObject; -HPyType_HELPERS(PointObject) -// END: PointObject - -// BEGIN: members -HPyDef_MEMBER(Point_x, "x", HPyMember_LONG, offsetof(PointObject, x)) -HPyDef_MEMBER(Point_y, "y", HPyMember_LONG, offsetof(PointObject, y)) -// END: members - -// BEGIN: methods -HPyDef_METH(Point_foo, "foo", HPyFunc_NOARGS) -static HPy Point_foo_impl(HPyContext *ctx, HPy self) -{ - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x * 10 + point->y); -} -// END: methods - -// BEGIN: getset -HPyDef_GETSET(Point_z, "z", .closure=(void *)1000) -static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) -{ - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y + (long)(HPy_ssize_t)closure); -} - -static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) -{ - PointObject *point = PointObject_AsStruct(ctx, self); - long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - long target = HPyLong_AsLong(ctx, value); // assume no exception - point->y += target - current; - return 0; -} -// END: getset - -// BEGIN: slots -HPyDef_SLOT(Point_new, HPy_tp_new) -static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) -{ - long x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) - return HPy_NULL; - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = x; - point->y = y; - return h_point; -} -// END: slots - -// BEGIN: defines -static HPyDef *Point_defines[] = { - &Point_x, - &Point_y, - &Point_z, - &Point_new, - &Point_foo, - NULL -}; -// END: defines - -// BEGIN: spec -static HPyType_Spec Point_spec = { - .name = "simple_type.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = PointObject_SHAPE, - .defines = Point_defines -}; -// END: spec - -// BEGIN: add_type -HPyDef_SLOT(simple_exec, HPy_mod_exec) -static int simple_exec_impl(HPyContext *ctx, HPy m) { - if (!HPyHelpers_AddType(ctx, m, "Point", &Point_spec, NULL)) { - return -1; - } - return 0; // success -} - -static HPyDef *mod_defines[] = { - &simple_exec, // 'simple_exec' is generated by the HPyDef_SLOT macro - NULL, -}; - -static HPyModuleDef moduledef = { - .defines = mod_defines, - // ... -// END: add_type - .doc = "A simple HPy type", -}; - -HPy_MODINIT(simple_type, moduledef) \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst b/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst deleted file mode 100644 index d611e5113c..0000000000 --- a/graalpython/hpy/docs/examples/hpytype-example/simple_type.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -simple_type.c -============= - -.. literalinclude:: ./simple_type.c - :language: c - :linenos: diff --git a/graalpython/hpy/docs/examples/mixed-example/mixed.c b/graalpython/hpy/docs/examples/mixed-example/mixed.c deleted file mode 100644 index d041f3f41c..0000000000 --- a/graalpython/hpy/docs/examples/mixed-example/mixed.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Simple C module that shows how to mix CPython API and HPY. - * At the moment, this code is not referenced from the documentation, but it is - * tested nonetheless. - */ - -#include "hpy.h" - -/* a HPy style function */ -HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) -static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} - - -/* Add an old-style function */ -static PyObject * -add_ints2(PyObject *self, PyObject *args) -{ - - long a, b, ret; - if (!PyArg_ParseTuple(args, "ll", &a, &b)) - return NULL; - ret = a + b; - return PyLong_FromLong(ret); -} - -static HPyDef *hpy_defines[] = { - &add_ints, - NULL -}; - -static PyMethodDef py_defines[] = { - {"add_ints_legacy", add_ints2, METH_VARARGS, "add two ints"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static HPyModuleDef moduledef = { - .doc = "HPy Example of mixing CPython API and HPy API", - .size = 0, - .defines = hpy_defines, - .legacy_methods = py_defines -}; - - -HPy_MODINIT(mixed, moduledef) diff --git a/graalpython/hpy/docs/examples/mixed-example/setup.py b/graalpython/hpy/docs/examples/mixed-example/setup.py deleted file mode 100644 index 75af734583..0000000000 --- a/graalpython/hpy/docs/examples/mixed-example/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, Extension -from os import path - -setup( - name="hpy-mixed-example", - hpy_ext_modules=[ - Extension('mixed', sources=[path.join(path.dirname(__file__), 'mixed.c')]), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/examples/quickstart/quickstart.c b/graalpython/hpy/docs/examples/quickstart/quickstart.c deleted file mode 100644 index ce9542046a..0000000000 --- a/graalpython/hpy/docs/examples/quickstart/quickstart.c +++ /dev/null @@ -1,39 +0,0 @@ -// quickstart.c - -// This header file is the entrypoint to the HPy API: -#include "hpy.h" - -// HPy method: the HPyDef_METH macro generates some boilerplate code, -// the same code can be also written manually if desired -HPyDef_METH(say_hello, "say_hello", HPyFunc_NOARGS) -static HPy say_hello_impl(HPyContext *ctx, HPy self) -{ - // Methods take HPyContext, which must be passed as the first argument to - // all HPy API functions. Other than that HPyUnicode_FromString does the - // same thing as PyUnicode_FromString. - // - // HPy type represents a "handle" to a Python object, but may not be - // a pointer to the object itself. It should be fully "opaque" to the - // users. Try uncommenting the following two lines to see the difference - // from PyObject*: - // - // if (self == self) - // HPyUnicode_FromString(ctx, "Surprise? Try HPy_Is(ctx, self, self)"); - - return HPyUnicode_FromString(ctx, "Hello world"); -} - -static HPyDef *QuickstartMethods[] = { - &say_hello, // 'say_hello' generated for us by the HPyDef_METH macro - NULL, -}; - -static HPyModuleDef quickstart_def = { - .doc = "HPy Quickstart Example", - .defines = QuickstartMethods, -}; - -// The Python interpreter will create the module for us from the -// HPyModuleDef specification. Additional initialization can be -// done in the HPy_mod_exec slot -HPy_MODINIT(quickstart, quickstart_def) diff --git a/graalpython/hpy/docs/examples/quickstart/setup.py b/graalpython/hpy/docs/examples/quickstart/setup.py deleted file mode 100644 index 0d56aefec4..0000000000 --- a/graalpython/hpy/docs/examples/quickstart/setup.py +++ /dev/null @@ -1,13 +0,0 @@ -# setup.py - -from setuptools import setup, Extension -from os import path - -DIR = path.dirname(__file__) -setup( - name="hpy-quickstart", - hpy_ext_modules=[ - Extension('quickstart', sources=[path.join(DIR, 'quickstart.c')]), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/examples/simple-example/setup.py b/graalpython/hpy/docs/examples/simple-example/setup.py deleted file mode 100644 index af81861942..0000000000 --- a/graalpython/hpy/docs/examples/simple-example/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, Extension -from os import path - -setup( - name="hpy-simple-example", - hpy_ext_modules=[ - Extension('simple', sources=[path.join(path.dirname(__file__), 'simple.c')]), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/examples/simple-example/simple.c b/graalpython/hpy/docs/examples/simple-example/simple.c deleted file mode 100644 index 49883a950a..0000000000 --- a/graalpython/hpy/docs/examples/simple-example/simple.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Simple C module that defines single simple function "myabs". - * We need to have a separate standalone package for those snippets, because we - * want to show the source code in its entirety, including the HPyDef array - * initialization, the module definition, and the setup.py script, so there is - * no room left for mixing these code snippets with other code snippets. - */ - -// BEGIN: myabs -#include "hpy.h" - -HPyDef_METH(myabs, "myabs", HPyFunc_O) -static HPy myabs_impl(HPyContext *ctx, HPy self, HPy arg) -{ - return HPy_Absolute(ctx, arg); -} -// END: myabs - -// BEGIN: double -HPyDef_METH_IMPL(double_num, "double", double_impl, HPyFunc_O) -static HPy double_impl(HPyContext *ctx, HPy self, HPy arg) -{ - return HPy_Add(ctx, arg, arg); -} -// END: double - -// BEGIN: methodsdef -static HPyDef *SimpleMethods[] = { - &myabs, - &double_num, - NULL, -}; - -static HPyModuleDef simple = { - .doc = "HPy Example", - .size = 0, - .defines = SimpleMethods, - .legacy_methods = NULL -}; -// END: methodsdef - -// BEGIN: moduledef -HPy_MODINIT(simple, simple) -// END: moduledef \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/hpycall.c b/graalpython/hpy/docs/examples/snippets/hpycall.c deleted file mode 100644 index 9fc51e1f3e..0000000000 --- a/graalpython/hpy/docs/examples/snippets/hpycall.c +++ /dev/null @@ -1,196 +0,0 @@ -#include - -// BEGIN EuclideanVectorObject -typedef struct { - long x; - long y; -} EuclideanVectorObject; -HPyType_HELPERS(EuclideanVectorObject) -// END EuclideanVectorObject - -// BEGIN HPy_tp_call -HPyDef_SLOT(call, HPy_tp_call) -static HPy -call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, - HPy kwnames) -{ - static const char *keywords[] = { "x1", "y1", NULL }; - long x1, y1; - HPyTracker ht; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "ll", keywords, - &x1, &y1)) { - return HPy_NULL; - } - EuclideanVectorObject *data = EuclideanVectorObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, data->x * x1 + data->y * y1); -} -// END HPy_tp_call - -// BEGIN HPy_SetCallFunction -HPyDef_CALL_FUNCTION(special_call) -static HPy -special_call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, - HPy kwnames) -{ - HPy tmp = call_impl(ctx, self, args, nargs, kwnames); - HPy res = HPy_Negative(ctx, tmp); - HPy_Close(ctx, tmp); - return res; -} - -HPyDef_SLOT(new, HPy_tp_new) -static HPy -new_impl(HPyContext *ctx, HPy cls, const HPy *args, HPy_ssize_t nargs, HPy kw) -{ - static const char *keywords[] = { "x", "y", "use_special_call", NULL }; - HPyTracker ht; - long x, y; - HPy use_special_call = ctx->h_False; - if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "ll|O", keywords, - &x, &y, &use_special_call)) { - return HPy_NULL; - } - EuclideanVectorObject *vector; - HPy h_point = HPy_New(ctx, cls, &vector); - if (HPy_IsNull(h_point)) { - HPyTracker_Close(ctx, ht); - return HPy_NULL; - } - if (HPy_IsTrue(ctx, use_special_call) && - HPy_SetCallFunction(ctx, h_point, &special_call) < 0) { - HPyTracker_Close(ctx, ht); - HPy_Close(ctx, h_point); - return HPy_NULL; - } - HPyTracker_Close(ctx, ht); - vector->x = x; - vector->y = y; - return h_point; -} -// END HPy_SetCallFunction - -// BEGIN FooObject -typedef struct { - void *a; - HPyCallFunction call_func; - void *b; -} FooObject; -HPyType_HELPERS(FooObject) -// END FooObject - -// BEGIN vectorcalloffset -HPyDef_MEMBER(Foo_call_func_offset, "__vectorcalloffset__", HPyMember_HPYSSIZET, - offsetof(FooObject, call_func), .readonly=1) - -HPyDef_CALL_FUNCTION(Foo_call_func) -static HPy -Foo_call_func_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, - HPy kwnames) -{ - return HPyUnicode_FromString(ctx, - "hello manually initialized call function"); -} - -HPyDef_SLOT(Foo_new, HPy_tp_new) -static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) -{ - FooObject *data; - HPy h_obj = HPy_New(ctx, cls, &data); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - data->call_func = Foo_call_func; - return h_obj; -} -// END vectorcalloffset - -// BEGIN pack_args -// function using legacy 'tp_call' calling convention -static HPy -Pack_call_legacy(HPyContext *ctx, HPy self, HPy args, HPy kwd) -{ - // use 'args' and 'kwd' - return HPy_Dup(ctx, ctx->h_None); -} - -// function using HPy calling convention -HPyDef_SLOT(Pack_call, HPy_tp_call) -static HPy -Pack_call_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, - HPy kwnames) -{ - HPy args_tuple, kwd; - HPy result; - if (!HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, kwnames, - &args_tuple, &kwd)) { - return HPy_NULL; - } - result = Pack_call_legacy(ctx, self, args_tuple, kwd); - HPy_Close(ctx, args_tuple); - HPy_Close(ctx, kwd); - return result; -} -// END pack_args - -static HPyDef *Point_defines[] = { - &call, - &new, - NULL -}; -static HPyType_Spec EuclideanVector_spec = { - .name = "hpycall.EuclideanVector", - .basicsize = sizeof(EuclideanVectorObject), - .builtin_shape = SHAPE(EuclideanVectorObject), - .defines = Point_defines -}; - -static HPyDef *Foo_defines[] = { - &Foo_call_func_offset, - &Foo_new, - NULL -}; -static HPyType_Spec Foo_spec = { - .name = "hpycall.Foo", - .basicsize = sizeof(FooObject), - .builtin_shape = SHAPE(FooObject), - .defines = Foo_defines -}; - -static HPyDef *Pack_defines[] = { - &Pack_call, - NULL -}; -static HPyType_Spec Pack_spec = { - .name = "hpycall.Pack", - .defines = Pack_defines -}; - -HPyDef_SLOT(init, HPy_mod_exec) -static int init_impl(HPyContext *ctx, HPy m) -{ - if (!HPyHelpers_AddType(ctx, m, "EuclideanVector", &EuclideanVector_spec, NULL)) { - return -1; - } - if (!HPyHelpers_AddType(ctx, m, "Foo", &Foo_spec, NULL)) { - return -1; - } - if (!HPyHelpers_AddType(ctx, m, "Pack", &Pack_spec, NULL)) { - return -1; - } - return 0; -} - -static HPyDef *moduledefs[] = { - &init, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "HPy call protocol usage example", - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - -}; - -HPy_MODINIT(hpycall, moduledef) diff --git a/graalpython/hpy/docs/examples/snippets/hpyinit.c b/graalpython/hpy/docs/examples/snippets/hpyinit.c deleted file mode 100644 index f23bba29eb..0000000000 --- a/graalpython/hpy/docs/examples/snippets/hpyinit.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "hpy.h" - -// BEGIN -HPyDef_SLOT(my_exec, HPy_mod_exec) -int my_exec_impl(HPyContext *ctx, HPy mod) { - - // Some initialization: add types, constants, ... - - return 0; // success -} - -static HPyDef *Methods[] = { - &my_exec, // HPyDef_SLOT macro generated `my_exec` for us - NULL, -}; - -static HPyModuleDef mod_def = { - .defines = Methods -}; - -HPy_MODINIT(hpyinit, mod_def) -// END \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/hpyvarargs.c b/graalpython/hpy/docs/examples/snippets/hpyvarargs.c deleted file mode 100644 index a95617d542..0000000000 --- a/graalpython/hpy/docs/examples/snippets/hpyvarargs.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Simple C module that defines simple functions "myabs" and "add_ints". - * - * This module represents an incremental change over the "simple" package - * and shows how to add a method with VARARGS calling convention. - * - * We need to have a separate standalone C module for those snippets, because we - * want to show the source code including the HPyDef array initialization, so - * there is no room left for adding other entry points for other code snippets. - */ - -#include "hpy.h" - -// This is here to make the module look like an incremental change to simple-example -HPyDef_METH(myabs, "myabs", HPyFunc_O) -static HPy myabs_impl(HPyContext *ctx, HPy self, HPy arg) -{ - return HPy_Absolute(ctx, arg); -} - -// BEGIN: add_ints -HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) -static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} -// END: add_ints - -// BEGIN: methodsdef -static HPyDef *SimpleMethods[] = { - &myabs, - &add_ints, - NULL, -}; -// END: methodsdef - -static HPyModuleDef def = { - .doc = "HPy Example of varargs calling convention", - .size = 0, - .defines = SimpleMethods -}; - -HPy_MODINIT(hpyvarargs, def) diff --git a/graalpython/hpy/docs/examples/snippets/legacyinit.c b/graalpython/hpy/docs/examples/snippets/legacyinit.c deleted file mode 100644 index f10381b617..0000000000 --- a/graalpython/hpy/docs/examples/snippets/legacyinit.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -// BEGIN -static struct PyModuleDef mod_def = { - PyModuleDef_HEAD_INIT, - .m_name = "legacyinit", - .m_size = -1 -}; - -PyMODINIT_FUNC -PyInit_legacyinit(void) -{ - PyObject *mod = PyModule_Create(&mod_def); - if (mod == NULL) return NULL; - - // Some initialization: add types, constants, ... - - return mod; -} -// END \ No newline at end of file diff --git a/graalpython/hpy/docs/examples/snippets/setup.py b/graalpython/hpy/docs/examples/snippets/setup.py deleted file mode 100644 index 6c097b0385..0000000000 --- a/graalpython/hpy/docs/examples/snippets/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -from setuptools import setup, Extension -from os import path - -setup( - name="hpy-snippets", - hpy_ext_modules=[ - Extension('hpyvarargs', sources=[path.join(path.dirname(__file__), 'hpyvarargs.c')]), - Extension('snippets', sources=[path.join(path.dirname(__file__), 'snippets.c')]), - Extension('hpyinit', sources=[path.join(path.dirname(__file__), 'hpyinit.c')]), - Extension('hpycall', sources=[path.join(path.dirname(__file__), 'hpycall.c')]), - ], - ext_modules=[ - Extension('legacyinit', sources=[path.join(path.dirname(__file__), 'legacyinit.c')]), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/examples/snippets/snippets.c b/graalpython/hpy/docs/examples/snippets/snippets.c deleted file mode 100644 index 7e60a52cab..0000000000 --- a/graalpython/hpy/docs/examples/snippets/snippets.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Module with various code snippets used in the docs. - * All code snippets should be put into this file if possible. Notable - * exception are code snippets showing definition of the module or the - * HPyDef array initialization. Remember to also add tests to ../tests.py - */ -#include "hpy.h" - -// ------------------------------------ -// Snippets used in api.rst - -// BEGIN: foo -void foo(HPyContext *ctx) -{ - HPy x = HPyLong_FromLong(ctx, 42); - HPy y = HPy_Dup(ctx, x); - /* ... */ - // we need to close x and y independently - HPy_Close(ctx, x); - HPy_Close(ctx, y); -} -// END: foo - -// BEGIN: is_same_object -int is_same_object(HPyContext *ctx, HPy x, HPy y) -{ - // return x == y; // compilation error! - return HPy_Is(ctx, x, y); -} -// END: is_same_object - -// dummy entry point so that we can test the snippets: -HPyDef_METH(test_foo_and_is_same_object, "test_foo_and_is_same_object", HPyFunc_VARARGS) -static HPy test_foo_and_is_same_object_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) -{ - foo(ctx); // not much we can test here - return HPyLong_FromLong(ctx, is_same_object(ctx, args[0], args[1])); -} - -// BEGIN: test_leak_stacktrace -HPyDef_METH(test_leak_stacktrace, "test_leak_stacktrace", HPyFunc_NOARGS) -static HPy test_leak_stacktrace_impl(HPyContext *ctx, HPy self) -{ - HPy num = HPyLong_FromLong(ctx, 42); - if (HPy_IsNull(num)) { - return HPy_NULL; - } - // No HPy_Close(ctx, num); - return HPy_Dup(ctx, ctx->h_None); -} -// END: test_leak_stacktrace - -// BEGIN: add -HPyDef_METH(add, "add", HPyFunc_VARARGS) -static HPy add_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly two args"); - return HPy_NULL; - } - return HPy_Add(ctx, args[0], args[1]); -} -// END: add - -// ------------------------------------ -// Dummy module definition, so that we can test the snippets - -static HPyDef *Methods[] = { - &test_foo_and_is_same_object, - &test_leak_stacktrace, - &add, - NULL, -}; - -static HPyModuleDef snippets = { - .doc = "Various HPy code snippets for the docs", - .size = 0, - .defines = Methods -}; - -HPy_MODINIT(snippets, snippets) diff --git a/graalpython/hpy/docs/examples/tests.py b/graalpython/hpy/docs/examples/tests.py deleted file mode 100644 index 8a8ee5f5df..0000000000 --- a/graalpython/hpy/docs/examples/tests.py +++ /dev/null @@ -1,124 +0,0 @@ -import os -import os.path -import re -import subprocess -import sys - -import simple -import mixed -import hpyvarargs -import snippets -import simple_type -import builtin_type -import hpycall - - -def test_simple_abs(): - assert simple.myabs(-42) == 42 - assert simple.myabs(42) == 42 - - -def test_hpyvarargs(): - assert hpyvarargs.add_ints(40, 2) == 42 - - -def test_mixed_add_ints(): - assert mixed.add_ints_legacy(40, 2) == 42 - assert mixed.add_ints(40, 2) == 42 - - -def test_snippets(): - x = 2 - assert snippets.test_foo_and_is_same_object(x, x) == 1 - assert snippets.test_foo_and_is_same_object(x, 42) == 0 - - -def test_simple_type(): - p = simple_type.Point(4, 5) - assert p.x == 4 - assert p.y == 5 - assert p.foo() == 45 - assert p.z == 1045 - p.z = 2000 - assert p.y == 960 - assert p.z == 2000 - - -def test_quickstart(): - import quickstart - assert quickstart.say_hello() == "Hello world" -# END: test_quickstart - - -def test_builtin_type(): - obj = builtin_type.Dummy("hello") - assert obj == "hello" - - obj = builtin_type.Language("hello") - obj.lang = "en" - assert obj == "hello" - assert obj.lang == "en" - - -def test_leak_detector(): - from hpy.debug.pytest import LeakDetector - with LeakDetector() as ld: - # add_ints is an HPy C function. If it forgets to close a handle, - # LeakDetector will complain - assert mixed.add_ints(40, 2) == 42 -# END: test_leak_detector - -from hpy.debug.pytest import hpy_debug -def test_that_uses_leak_detector_fixture(hpy_debug): - # Run some HPy extension code - assert mixed.add_ints(40, 2) == 42 - - -def test_leak_detector_with_traces(): - import hpy.debug - hpy.debug.set_handle_stack_trace_limit(16) - assert mixed.add_ints(40, 2) == 42 - hpy.debug.disable_handle_stack_traces() - - -def test_leak_detector_with_traces_output(): - # Update the debug documentation if anything here changes! - env = os.environ.copy() - env['HPY'] = 'debug' - env['HPY_LOG'] = '1' - script = os.path.join(os.path.dirname(__file__), 'debug-example.py') - result = subprocess.run([sys.executable, script], env=env, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - # Rudimentary check that the output contains what we have in the documentation - out = result.stdout.decode('latin-1') - assert out == "Loading 'snippets' in HPy universal mode with a debug context" + os.linesep - err = result.stderr.decode('latin-1') - assert 'hpy.debug.leakdetector.HPyLeakError: 1 unclosed handle:' in err - assert re.search('', err) - assert 'Allocation stacktrace:' in err - if sys.platform.startswith(("linux", "darwin")): - assert 'snippets.hpy0.so' in err # Should be somewhere in the stack trace - else: - assert 'At the moment this is only supported on Linux with glibc' in err - -def test_trace_mode_output(): - # Update the trace mode documentation if anything here changes! - env = os.environ.copy() - env['HPY'] = 'trace' - env['HPY_LOG'] = '1' - script = os.path.join(os.path.dirname(__file__), 'trace-example.py') - result = subprocess.run([sys.executable, script], env=env, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - # Rudimentary check that the output contains what we have in the documentation - out = result.stdout.decode('latin-1') - assert 'get_call_counts()["ctx_Add"] == 1' in out - -def test_call_dot_product(): - vec = hpycall.EuclideanVector(4, 5) - assert vec(6, 7) == 4 * 6 + 5 * 7 - vec = hpycall.EuclideanVector(4, 5, use_special_call=True) - assert vec(6, 7) == -(4 * 6 + 5 * 7) - foo = hpycall.Foo() - assert foo() == 'hello manually initialized call function' - pack = hpycall.Pack() - assert pack() is None diff --git a/graalpython/hpy/docs/examples/trace-example.py b/graalpython/hpy/docs/examples/trace-example.py deleted file mode 100644 index 2a4d92838e..0000000000 --- a/graalpython/hpy/docs/examples/trace-example.py +++ /dev/null @@ -1,9 +0,0 @@ -# Run with HPY=trace -from hpy.trace import get_call_counts -import snippets - -add_count_0 = get_call_counts()["ctx_Add"] -snippets.add(1, 2) == 3 -add_count_1 = get_call_counts()["ctx_Add"] - -print('get_call_counts()["ctx_Add"] == %d' % (add_count_1 - add_count_0)) diff --git a/graalpython/hpy/docs/index.rst b/graalpython/hpy/docs/index.rst deleted file mode 100644 index 9ca101b753..0000000000 --- a/graalpython/hpy/docs/index.rst +++ /dev/null @@ -1,80 +0,0 @@ -.. HPy documentation master file, created by - sphinx-quickstart on Thu Apr 2 23:01:08 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -HPy: a better API for Python -=============================== - -HPy provides a new API for extending Python in C. - -There are several advantages to writing C extensions in HPy: - - - **Speed**: it runs much faster on PyPy, GraalPy, and at native speed on CPython - - - **Deployment**: it is possible to compile a single binary which runs unmodified on all - supported Python implementations and versions -- think "stable ABI" on steroids - - - **Simplicity**: it is simpler and more manageable than the ``Python.h`` API, both for - the users and the Pythons implementing it - - - **Debugging**: it provides an improved debugging experience. Debug mode can be turned - on at runtime without the need to recompile the extension or the Python running it. - HPy design is more suitable for automated checks. - -The official `Python/C API `_, -also informally known as ``#include ``, is -specific to the current implementation of CPython: it exposes a lot of -internal details which makes it hard to: - - - implement it for other Python implementations (e.g. PyPy, GraalPy, - Jython, ...) - - - experiment with new approaches inside CPython itself, for example: - - - use a tracing garbage collection instead of reference counting - - remove the global interpreter lock (GIL) to take full advantage of multicore architectures - - use tagged pointers to reduce memory footprint - -Where to go next: ------------------ - - - Show me the code: - - - :doc:`Quickstart` - - :ref:`Simple documented HPy extension example` - - :doc:`Tutorial: porting Python/C API extension to HPy` - - - Details: - - - :doc:`HPy overview: motivation, goals, current status` - - :doc:`HPy API concepts introduction` - - :doc:`Python/C API to HPy Porting guide` - - :doc:`HPy API reference` - - -Full table of contents: ------------------------ - -.. toctree:: - :maxdepth: 2 - - quickstart - overview - api - porting-guide - porting-example/index - debug-mode - trace-mode - api-reference/index - contributing/index - misc/index - changelog - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/graalpython/hpy/docs/leysin-2020-design-decisions.md b/graalpython/hpy/docs/leysin-2020-design-decisions.md deleted file mode 100644 index b50bb081c5..0000000000 --- a/graalpython/hpy/docs/leysin-2020-design-decisions.md +++ /dev/null @@ -1,295 +0,0 @@ -Leysin Sprint 2020 Design Decisions -=================================== - -Closing and duping HPy_NULL ---------------------------- - -Question: Should `HPy_Close` silently ignore attempts to close `HPy_NULL`? - -Decisions: - -* `HPy_Close` should function like `Py_XDECREF` and silently not close `HPy_NULL`. -* `HPy_Dup` should silently not dup `HPy_NULL` for symmetry with `HPy_Close`, - i.e. `HPy_Dup(ctx, HPy_NULL)` should return `HPy_NULL`. -* Both the API and ABI versions should have this behaviour. -* We should add tests for this behaviour. - - -Attribute and item access -------------------------- - -Question: Should we have separate HPySequence_GetItem and HPyMapping_GetItem -or just one HPy_GetItem? Should we explore the idea of protocols for such -access. - -Decisions: - -* We should start with `HPy_GetItem` and `HPy_SetItem` and `HPy_GetItem_i` and - `HPy_SetItem_i` for item access and `HPy_GetAttr`, `HPy_SetAttr`, - `HPy_GetAttr_s` and `HPy_SetAttr_s` for attribute access.. -* We could add an `hpy/compat.h` that supports accessing the old Python mapping - and sequence get item slots. For example, `HPyDict_GetItem_NotBorrowed`. - `PyDict_GetItem` returns a borrower reference. `HPyDict_GetItem_NotBorrowed` - should return a new handle that has to be closed. -* HPy API functions MUST NOT return a borrowed reference and we should add this - to our official documentation. -* We should add an `HPyBuffer` protocol later (with the design still to be - decided). - -Proposed function signatures: - -```C -HPy HPy_GetItem(HPyContext ctx, HPy obj, HPy idx); -HPy HPy_GetItem_i(HPyContext ctx, HPy obj, HPy_ssize_t idx); -HPy HPy_GetItem_s(HPyContext ctx, HPy obj, const char * idx); // UTF8 bytes - -int HPy_SetItem(HPyContext ctx, HPy obj, HPy idx, HPy value); -int HPy_SetItem_i(HPyContext ctx, HPy obj, HPy_ssize_t idx, HPy value); -int HPy_SetItem_s(HPyContext ctx, HPy obj, const char * idx, HPy value); // UTF8 bytes - -HPy HPy_GetAttr(HPyContext ctx, HPy obj, HPy idx); -HPy HPy_GetAttr_s(HPyContext ctx, HPy obj, const char * idx); // UTF8 bytes - -int HPy_SetAttr(HPyContext ctx, HPy obj, HPy idx, HPy value); -int HPy_SetAttr_s(HPyContext ctx, HPy obj, const char * idx, HPy value); // UTF8 bytes -``` - -Macro for returning None ------------------------- - -Question: Should we have an HPy_RETURN_NONE macro? - -Decisions: - -* Yes we should, but it should be `HPy_RETURN_NONE(ctx)`. -* We should also change `HPy_IsNull(x)` to `HPy_IsNull(ctx, x)`. - -Proposed macros: - -```C -#define HPy_RETURN_NONE(ctx) return HPy_Dup(ctx, ctx->h_None); -#define HPy_IsNull(ctx, x) ...; -``` - -Passing handles as void pointers --------------------------------- - -Question: Should we add `HPy_AsVoidP` and `HPy_FromVoidP` to the API? Should they -be on the ctx or not? - -Decisions: - -* Yes, they should be part of the API. -* They should take the ctx as an argument in case a future implementation needs - it (much like `HPy_IsNull`). - -Proposed functions: - -```C -// universal -static inline HPy HPy_FromVoidP(HPyContext ctx, void *p) { return (HPy){(HPy_ssize_t)p}; } -static inline void* HPy_AsVoidP(HPyContext ctx, HPy h) { return (void*)h._i; } - -// cpython (the -/+4 is to avoid people casting it to PyObject) -static inline HPy HPy_FromVoidP(HPyContext ctx, void *p) { return (HPy){(HPy_ssize_t)p - 4}; } -static inline void* HPy_AsVoidP(HPyContext ctx, HPy h) { return (void*)h._o + 4; } -``` - -/* - * Should we implement HPy_Dump? - * - * Question: What should it print and where should it print it? - * - * Decision: It's useful for debugging if all macros are also available as functions - * definitions. - * - * Decision: It should dump to stderr just like PyObject_Dump. - */ - -/* - * How do we silence warnings from using HPy_METH_KEYWORDS? - * - * Decision: Write a cast to HPyMeth. - */ - -{"add_ints_kw", (HPyMeth) add_ints_kw, HPy_METH_KEYWORDS, ""} - -/* - * How should HPyErr_Format be implemented? Should we avoid va_args? - * - * Decision: - */ - -HPyErr_Format(ctx, const char *fmt, ...) { - const char *msg = HPyStr_Format(ctx, fmt, ...); - HPyErr_SetString(msg); -} - -ctx->ctx_HPyErr_Format(???) - -/* - * Should make specifying values for optional arguments & dup / closing them - * less messy? - * - * Decision: Right now, No. In the future, someone should invent - * ARGUMENT_CLINIC for HPy. - */ - -/* - * Should we rename "struct _object*" to "PyObject*" and "_HPy_PyCFunction" - * to "PyCFunction" in universal/hpy.h? - * - * Decision: No. This would generate a warning if one imports Python.h. - * - * Decision: Comment in the code that this _object* is PyObject* and why we - * cannot call it that. - * - * Decision: In user documentation, just call ing PyObject *. - */ - -/* - * How should the API pass around exceptions? - * - * Decision: Follow CPython for each API call. - * - */ - -// E.g. API call returns HPy: - -HPy h = HPyLong_FromLong(ctx, 5); -if (HPy_IsNull(ctx, h)) { - // handle error - // python error has been set by the API call -} - -// or - -HPy h = HPyLong_FromLong(ctx, 5); -if (HPyErr_Occurred(ctx)) { - // handle error - // python error has been set by the API call -} - -// E.g. API call returns a value that is not an HPy: - -long l = HPyLong_AsLong(ctx, h); -if (l == -1 && HPyErr_Occurred(ctx)) { - // handle error - // python error has been set by the API call -} - -// E.g. API call returns a success or error flag: - -// int error = HPyArg_Parse(...); -if (!HPyArg_Parse(...)) { - // handle error - // python error has been set by the API call -} - -/* - * How should support for creating custom Python types look? - * - * Decisions: - * - * - */ - -// When using C-API: - -typedef struct { - PyObject_HEAD - /* Type-specific fields go here. */ - PyObject *x; - PyObject *y; - double *data; - int size; -} PointObject; - -// When using HPy: - -typedef struct { - HPyObject_HEAD - double x; - double y; -} HPy_Point; - -typedef struct { - HPyObject_HEAD - HPyField a; - HPyField b; -} HPy_Rectangle; - -/* Possible HPy code */ - -typedef struct { - ??? ob_type; -} _HPy_ObjectHeader; - -#define HPyObject_HEAD _HPy_ObjectHeader head; - -#define HPy_STORE(ctx, obj, field, value) ((ctx)->ctx_HPy_StoreInto((_HPy_ObjectHeader *) obj, &((obj)->field), value)) -#define HPy_STORE_INTO(ctx, obj, pointer, value) ((ctx)->ctx_HPy_StoreInto((_HPy_ObjectHeader *) obj, pointer, value)) - -// Using the debug mode ctx, this should check that obj->ob_type->tp_traverse is not NULL. -void HPy_StoreInto(HPyContext ctx, _HPy_ObjectHeader *obj, HPyField *pointer, HPy value) - -// HPy_New: -// -// * Should return a handle. -// * It should be possible to go from the handle to struct, but not -// from struct to handle. E.g. HPy_CAST(ctx, HPyRectangle, h) -> HPyRectangle, -// but no inverse. -// * We should not have an HPy_Init at the moment -- HPy_New both allocates -// the object and initializes it. We will add separate allocation and init -// later if we encounter a need for it. -// * HPyTypeSpec should follow the CPython type spec. - -#define HPy_CAST(ctx, return_type, h) (return_type *) ctx->ctx_HPy_Cast(h) - -void* HPy_Cast(ctx, HPy h); - -HPy HPy_TypeFromSpec(ctx, HPyTypeSpec type_spec); -HPy HPy_New(ctx, HPy h_type); - -/* end of possible HPy code */ - -HPy new_rect(HPy p1, HPy p2) { - // HPy_New always initialize the whole object to 0. We can also have - // HPy_NewUninitialized if we don't want to pay the penalty - HPy_Rectangle *rect; - HPy rect_handle = HPy_New(ctx, HPy_Rectangle, h_rectangle_type, &rect); - - // HPy_Store does a write barrier on PyPy, and DECREF the old rect->a on - // CPython if needed - HPy_Store(ctx, rect, a, p1); - HPy_Store(ctx, rect, b, p2); - return rect_handle; -} - -double calc_diagonal(HPy rect_handle) { - // rect is valid until rect_handle is closed. on PyPy we pin the object, and - // we unpin it when we close the handle - HPy_Rectangle *rect = HPy_Cast(HPy_Rectangle, rect_handle); - - // HPy_Load reads a field and turn it into a handle - HPy p1_handle = HPy_Load(rect->a); // p1 is a handle which must be closed - HPy_Point *p1 = HPy_Cast(HPy_Point, p1_handle); - - // for C99 compilers, we can also provide a macro which declares p2 and - // p2_handle automatically and does the equivalent of the two lines above - HPY_LOAD(HPy_Point, p2, rect->b); - - double diag = sqrt(p1->x - p2->x /* etc. etc. */); - - // close all the handles - HPy_Close(p1_handle); - HPy_Close(p2_handle); - - return diag; -} - -/* - * Should HPy support Python without the GIL? - * - * Problem left as an exercise for the reader. - */ diff --git a/graalpython/hpy/docs/misc/embedding.rst b/graalpython/hpy/docs/misc/embedding.rst deleted file mode 100644 index cb85d2bc10..0000000000 --- a/graalpython/hpy/docs/misc/embedding.rst +++ /dev/null @@ -1,46 +0,0 @@ -Embedding HPy modules -===================== - -There might be cases where it is beneficial or even necessary to embed multiple -HPy modules into one library. HPy itself already makes use of that. The debug -and the trace module do not have individual libraries but are embedded into the -universal module. - -To achieve that, the embedder will use the macro :c:macro:`HPy_MODINIT` several times. -Unfortunately, this macro defines global state and cannot repeatedly be used by -default. In order to correctly embed several HPy modules into one library, the -embedder needs to consider following: - -* The modules must be compiled with preprocessor macro - :c:macro:`HPY_EMBEDDED_MODULES` defined to enable this feature. - -* There is one major restriction: All HPy-specific module pieces must be - in the same compilation unit. *HPy-specific pieces* are things like the - module's init function (``HPy_MODINIT``) and all slots, members, methods of - the module or any type of it (``HPyDef_*``). The implementation functions - (usually the ``*_impl`` functions) of the slots, members, methods, etc. and - any helper functions may still be in different compilation units. The reason - for this is that the global state induced by ``HPy_MODINIT`` is, of course, - made local (e.g. using C modifier ``static``). - -* It is also necessary to use macro :c:macro:`HPY_MOD_EMBEDDABLE` before the - first usage of any ``HPyDef_*`` macro. - -Also refer to the API reference :ref:`api-reference/hpy-type:hpy module`. - - -**Example** - -.. code-block:: c - - // compile with -DHPY_EMBEDDED_MODULES - - HPY_MOD_EMBEDDABLE(hpymodA) - - HPyDef_METH(foo, /* ... */) - static HPy foo_impl(/* ... */) - { - // ... - } - - HPy_MODINIT(extension_name, hpymodA) diff --git a/graalpython/hpy/docs/misc/index.rst b/graalpython/hpy/docs/misc/index.rst deleted file mode 100644 index f305c8ed01..0000000000 --- a/graalpython/hpy/docs/misc/index.rst +++ /dev/null @@ -1,7 +0,0 @@ -Misc Notes -========== - -.. toctree:: - :maxdepth: 1 - - embedding diff --git a/graalpython/hpy/docs/module-state.txt b/graalpython/hpy/docs/module-state.txt deleted file mode 100644 index 3682a8820e..0000000000 --- a/graalpython/hpy/docs/module-state.txt +++ /dev/null @@ -1,44 +0,0 @@ -How to replace global variables -------------------------------- - -In a given .c source, write: - - -typedef struct { - long x; - HPy y; -} my_globals_t; - -static void my_globals_traverse(traversefunc traverse, my_globals_t *g) -{ - traverse(g->y); -} - -HPyGlobalSpec my_globals = { - .m_size = sizeof(my_globals_t), - .m_traverse = my_globals_traverse -}; - - -There can be several HPyGlobalSpec structures around; in CPython it's done as -part of the PyModuleDef type, but there is no real reason for why it should -be tightly tied to a module. - - -To use: - - my_globals_t *g = HPy_GetState(ctx, &my_globals); - g->x++; - HPy_DoRandomStuffWithHandle(ctx, g->y); - - -Implementation: the type HPyGlobalSpec contains extra internal fields -which should give us a very fast cache: _last_ctx and _last_result, -and HPy_GetState() can be: - - if (ctx == globspec->_last_ctx) - return globspec->_last_result; - else - look up globspec in a dictionary attached to ctx, or vice-versa, - or maybe initialize globspec->_index with a unique incrementing - index and use that to index an array attached to ctx diff --git a/graalpython/hpy/docs/overview.rst b/graalpython/hpy/docs/overview.rst deleted file mode 100644 index e4c9e30b86..0000000000 --- a/graalpython/hpy/docs/overview.rst +++ /dev/null @@ -1,444 +0,0 @@ -HPy Overview -============ - -Motivation and goals ---------------------- - -The superpower of the Python ecosystem is its libraries, which are developed by -users. Over time, these libraries have grown in number, quality, and -applicability. While it is possible to write python libraries entirely in -python, many of them, especially in the scientific community, are written in C -and exposed to Python using the `Python.h API -`_. The existence of these C -extensions using the ``Python.h`` API leads to some issues: - - 1. Usually, alternative implementation of the Python programming language - want to support C extensions. To do so, they must implement the same - ``Python.h`` API or provide a compatibility layer. - - 2. CPython developers cannot experiment with new designs or refactoring - without breaking compatibility with existing extensions. - -Over the years, it has become evident that emulating ``Python.h`` in an -efficient way is `challenging, if not impossible -`_. -To summarize, it is mainly due to leaking of implementation details of CPython -into the C/API - which makes it difficult to make different design choices than -those made by CPython. As such - the main goal of HPy is to provide a **C API -which makes as few assumptions as possible about the design decisions of any -implementation of Python, allowing diverse implementations to support it -efficiently and without compromise**. In particular, **reference counting is not -part of the API**: we want a more generic way of managing resources that is -possible to implement with different strategies, including the existing -reference counting and/or with a moving *Garbage Collector* (like the ones used -by PyPy, GraalPy or Java, for example). Moreover, each implementation can -experiment with new memory layout of objects, add optimizations, etc. The -following is a list of sub-goals. - - -Performance on CPython - HPy is usable on CPython from day 1 with no performance impact compared to - the existing ``Python.h`` API. - - -Incremental adoption - It is possible to port existing C extensions piece by piece and to use - the old and the new API side-by-side during the transition. - - -Easy migration - It should be easy to migrate existing C extensions to HPy. Thanks to an - appropriate and regular naming convention it should be obvious what the - HPy equivalent of any existing ``Python.h`` API is. When a perfect replacement - does not exist, the documentation explains what the alternative options are. - - -Better debugging - In debug mode, you get early and precise errors and warnings when you make - some specific kind of mistakes and/or violate the API rules and - assumptions. For example, you get an error if you try to use a handle - (see :ref:`api:handles`) which has already been closed. It is possible to - turn on the debug mode at startup time, *without needing to recompile*. - -Simplicity - The HPy API aims to be smaller and easier to study/use/manage than the - existing ``Python.h`` API. Sometimes there is a trade-off between this goal and - the others above, in particular *Performance on CPython* and *Easy migration*. - The general approach is to have an API which is "as simple as possible" while - not violating the other goals. - - -Universal binaries - It is possible to compile extensions to a single binary which is - ABI-compatible across multiple Python versions and/or multiple - implementation. See :ref:`hpy-target-abis`. - - -Opt-in low level data structures - Internal details might still be available, but in a opt-in way: for example, - if Cython wants to iterate over a list of integers, it can ask if the - implementation provides a direct low-level access to the content (e.g. in - the form of a ``int64_t[]`` array) and use that. But at the same time, be - ready to handle the generic fallback case. - - -API vs ABI ------------ - -HPy defines *both* an API and an ABI. Before digging further into details, -let's distinguish them: - - - The **API** works at the level of source code: it is the set of functions, - macros, types and structs which developers can use to write their own - extension modules. For C programs, the API is generally made available - through one or more header files (``*.h``). - - - The **ABI** works at the level of compiled code: it is the interface between - the host interpreter and the compiled DLL. Given a target CPU and - operating system it defines things like the set of exported symbols, the - precise memory layout of objects, the size of types, etc. - -In general it is possible to compile the same source into multiple compiled -libraries, each one targeting a different ABI. :pep:`3149` states that the -filename of the compiled extension should contain the *ABI tag* to specify -what the target ABI is. For example, if you compile an extension called -``simple.c`` on CPython 3.8, you get a DLL called -``simple.cpython-38-x86_64-linux-gnu.so``: - - - ``cpython-38`` is the ABI tag, in this case CPython 3.8 - - - ``x86_64`` is the CPU architecture - - - ``linux-gnu`` is the operating system - -The same source code compiled on PyPy3.6 7.2.0 results in a file called -``simple.pypy38-pp73-x86_64-linux-gnu.so``: - - - ``pypy38-pp73`` is the ABI tag, in this case "PyPy3.8", version "7.3.x" - -The HPy C API is exposed to the user by including ``hpy.h`` and it is -explained in its own section of the documentation. - - -Legacy and compatibility features ---------------------------------- - -To allow an incremental transition to HPy, it is possible to use both -``hpy.h`` and ``Python.h`` API calls in the same extension. Using *HPy legacy -features* you can: - - - mix ``Python.h`` and HPy method defs in the same HPy module - - - mix ``Python.h`` and HPy method defs and slots in the same HPy type - - - convert ``HPy`` handles to and from ``PyObject *`` using - ``HPy_AsPyObject()`` and ``HPy_FromPyObject()`` - - -Thanks to this, you can port your code to HPy one method and one type at a -time, while keeping the extension fully functional during the transition -period. See the :ref:`porting-guide:Porting guide` for a concrete example. - -Legacy features are available only if you target the CPython or HPy Hybrid -ABIs, as explained in the next section. - - -.. _hpy-target-abis: - -Target ABIs ------------ - -Depending on the compilation options, an HPy extension can target three -different ABIs: - -.. glossary:: - - CPython ABI - In this mode, HPy is implemented as a set of C macros and ``static inline`` - functions which translate the HPy API into the CPython API at compile - time. The result is a compiled extension which is indistinguishable from a - "normal" one and can be distributed using all the standard tools and will - run at the very same speed. - - *Legacy features* are available. - - The output filename is e.g. ``simple.cpython-38-x86_64-linux-gnu.so``. - - - HPy Universal ABI - As the name suggests, the HPy Universal ABI is designed to be loaded and - executed by a variety of different Python implementations. Compiled - extensions can be loaded unmodified on all the interpreters which support - it. PyPy and GraalPy support it natively. CPython supports it by using the - ``hpy.universal`` package, and there is a small speed penalty [#f1]_ compared to - the CPython ABI. - - *Legacy features* are **not** available and it is forbidden to ``#include ``. - - The resulting filename is e.g. ``simple.hpy0.so``. - - HPy Hybrid ABI - - The HPy Hybrid ABI is essentially the same as the Universal ABI, with - the big difference that it allows to ``#include ``, to use the - legacy features and thus to allow incremental porting. - - At the ABI level the resulting binary depends on *both* HPy and the - specific Python implementation which was used to compile the extension. - As the name suggests, this means that the binary is not "universal", - thus negating some of the benefits of HPy. The main benefit of using - the HPy Hybrid ABI instead of the CPython ABI is being able to use the - :ref:`debug-mode:Debug mode` on the HPy parts, and faster speed on - alternative implementations. - - *Legacy features* are available. - - The resulting filename is e.g. ``simple.hpy0-cp38.so``. - - -Moreover, each alternative Python implementation could decide to implement its -own non-universal ABI if it makes sense for them. For example, a hypothetical -project *DummyPython* could decide to ship its own ``hpy.h`` which implements -the HPy API but generates a DLL which targets the DummyPython ABI. - -This means that to compile an extension for CPython, you can choose whether to -target the CPython ABI or the Universal ABI. The advantage of the former is -that it runs at native speed, while the advantage of the latter is that you -can distribute a single binary, although with a small speed penalty on -CPython. Obviously, nothing stops you compiling and distributing both -versions: this is very similar to what most projects are already doing, since -they automatically compile and distribute extensions for many different -CPython versions. - -From the user point of view, extensions compiled for the CPython ABI can be -distributed and installed as usual, while those compiled for the HPy Universal -or HPy Hybrid ABIs require installing the ``hpy.universal`` package on -CPython and have no further requirements on Pythons that support HPy natively. - - -Benefits for the Python ecosystem ---------------------------------- - -The HPy project offers some benefits to the python ecosystem, both to Python -users and to library developers. - - - C extensions can achieve much better speed on alternative implementions, - including PyPy and GraalPy: according to early :ref:`benchmarks`, an - extension written in HPy can be ~3x faster than the equivalent extension - written using ``Python.h``. - - Improved debugging: when you load extensions in :ref:`debug-mode:debug mode`, - many common mistakes are checked and reported automatically. - - Universal binaries: libraries can choose to distribute only Universal ABI - binaries. By doing so, they can support all Python implementations and - version of CPython (like PyPy, GraalPy, CPython 3.10, CPython 3.11, etc) - for which an HPy loader exists, including those that do not yet exist! This - currently comes with a small speed penalty on CPython, but for - non-performance critical libraries it might still be a good tradeoff. - - Python environments: With general availability of universal ABI binaries for - popular packages, users can create equivalent python environments that - target different Python implementations. Thus, Python users can try their - workload against different implementations and pick the one best suited for - their usage. - - In a situation where most or all popular Python extensions target the - universal ABI, it will be more feasible for CPython to make breaking changes - to its C/API for performance or maintainability reasons. - - -Cython extensions ------------------ - -If you use Cython, you can't use HPy directly. There is a -`work in progress `_ to -add Cython backend which emits HPy code instead of using ``Python.h`` code: once this is -done, you will get the benefits of HPy automatically. - - -Extensions in other languages ------------------------------ - -On the API side, HPy is designed with C in mind, so it is not directly useful -if you want to write an extension in a language other than C. - -However, Python bindings for other languages could decide to target the -:term:`HPy Universal ABI` instead of the :term:`CPython ABI`, and generate -extensions which can be loaded seamlessly on all Python implementations which -supports it. This is the route taken, for example, by `Rust -`_. - - -Benefits for alternative Python implementations ------------------------------------------------ - -If you are writing an alternative Python implementation, there is a good -chance that you already know how painful it is to support the ``Python.h`` API. -HPy is designed to be both faster and easier to implement! - -You have two choices: - - - support the Universal ABI: in this case, you just need to export the - needed functions and to add a hook to ``dlopen()`` the desired libraries - - - use a custom ABI: in this case, you have to write your own replacement for - ``hpy.h`` and recompile the C extensions with it. - - -Current status and roadmap --------------------------- - -HPy left the early stages of development and already provides a noticeable set -of features. As on April 2023, the following milestones have been reached: - - - some prominent real-world Python packages have been ported to HPy API. There - is a list of HPy-compatible packages we know about on the HPy website - `hpyproject.org `_. - - - one can write extensions which expose module-level functions, with all - the various kinds of calling conventions. - - - there is support for argument parsing (i.e., the equivalents of - ``PyArg_ParseTuple`` and ``PyArg_ParseTupleAndKeywords``), and a - convenient complex value building (i.e., the equivalent ``Py_BuildValue``). - - - one can implement custom types, whose struct may contain references to other - Python objects using ``HPyField``. - - - there is a support for globally accessible Python object handles: ``HPyGlobal``, - which can still provide isolation for subinterpreters if needed. - - - there is support for raising and catching exceptions. - - - debug mode has been implemented and can be activated at run-time without - recompiling. It can detect leaked handles or handles used after - being closed. - - - trace mode has been implemented and can be activated just like the debug - mode. It helps analyzing the API usage (in particular wrt. performance). - - - wheels can be built for HPy extensions with ``python setup.py bdist_wheel`` - and can be installed with ``pip install``. - - - it is possible to choose between the :term:`CPython ABI` and the - :term:`HPy Universal ABI` when compiling an extension module. - - - extensions compiled with the CPython ABI work out of the box on - CPython. - - - it is possible to load HPy Universal extensions on CPython, thanks to the - ``hpy.universal`` package. - - - it is possible to load HPy Universal extensions on - PyPy (using the PyPy `hpy branch `_). - - - it is possible to load HPy Universal extensions on `GraalPy - `_. - - - there is support for multi-phase module initialization. - - - support for metaclasses has been added. - - -However, there is still a long road before HPy is usable for the general -public. In particular, the following features are on our roadmap but have not -been implemented yet: - - - many of the original ``Python.h`` functions have not been ported to - HPy yet. Porting most of them is straightforward, so for now the priority - is to test HPy with real-world Python packages and primarily resolve the - "hard" features to prove that the HPy approach works. - - - add C-level module state to complement the ``HPyGlobal`` approach. While ``HPyGlobal`` - is easier to use, it will make the migration simpler for existing extensions that - use CPython module state. - - - the integration with Cython is work in progress - - - it is not clear yet how to approach pybind11 and similar C++ bindings. They serve two use-cases: - - - As C++ wrappers for CPython API. HPy is fundamentally different in some ways, so fully compatible - pybind11 port of this API to HPy does not make sense. There can be a similar or even partially pybind11 - compatible C++ wrapper for HPy adhering to the HPy semantics and conventions (e.g., passing the - HPyContext pointer argument around, no reference stealing, etc.). - - - Way to expose (or "bind") mostly pure C++ functions as Python functions where the C++ templating - machinery takes care of the conversion between the Python world, i.e., ``PyObject*``, and the C++ - types. Porting this abstraction to HPy is possible and desired in the future. To determine the priority - or such effort, we need to get more knowledge about existing pybind11 use-cases. - - -.. _benchmarks: - -Early benchmarks ------------------ - -To validate our approach, we ported a simple yet performance critical module -to HPy. We chose `ultrajson `_ -because it is simple enough to require porting only a handful of API -functions, but at the same time it is performance critical and performs many -API calls during the parsing of a JSON file. - -This `blog post `_ -explains the results in more detail, but they can be summarized as follows: - - - ``ujson-hpy`` compiled with the CPython ABI is as fast as the original - ``ujson``. - - - A bit surprisingly, ``ujson-hpy`` compiled with the HPy Universal ABI is - only 10% slower on CPython. We need more evidence than a single benchmark - of course, but if the overhead of the HPy Universal ABI is only 10% on - CPython, many projects may find it small enough that the benefits - of distributing extensions using only the HPy Universal ABI out weight - the performance costs. - - - On PyPy, ``ujson-hpy`` runs 3x faster than the original ``ujson``. Note - the HPy implementation on PyPy is not fully optimized yet, so we expect - even bigger speedups eventually. - - -Projects involved ------------------ - -HPy was born during EuroPython 2019, were a small group of people started to -discuss the problems of the ``Python.h`` API and how it would be nice to -have a way to fix them. Since then, it has gathered the attention and interest -of people who are involved in many projects within the Python ecosystem. The -following is a (probably incomplete) list of projects whose core developers -are involved in HPy, in one way or the other. The mere presence in this list -does not mean that the project as a whole endorse or recognize HPy in any way, -just that some of the people involved contributed to the -code/design/discussions of HPy: - - - PyPy - - - CPython - - - Cython - - - GraalPy - - - RustPython - - - rust-hpy (fork of the `cpython crate `_) - - -Related work -------------- - -A partial list of alternative implementations which offer a ``Python.h`` -compatibility layer include: - - - `PyPy `_ - - - `Jython `_ - - - `IronPython `_ - - - `GraalPy `_ - -.. rubric:: Footnotes - -.. [#f1] The reason for this minor performance penalty is a layer of pointer - indirection. For instance, ``ctx->HPyLong_FromLong`` is called from the - CPython extension, which in universal mode simply forwards the call to - ``PyLong_FromLong``. It is technically possible to implement a CPython - universal module loader which edits the program's executable code at runtime - to replace that call. Note that this is not at all trivial. diff --git a/graalpython/hpy/docs/porting-example/index.rst b/graalpython/hpy/docs/porting-example/index.rst deleted file mode 100644 index e5a6dcd7b8..0000000000 --- a/graalpython/hpy/docs/porting-example/index.rst +++ /dev/null @@ -1,356 +0,0 @@ -Porting Example -=============== - -HPy supports *incrementally* porting an existing C extension from the -original Python C API to the HPy API and to have the extension compile and -run at each step along the way. - -Here we walk through porting a small C extension that implements a Point type -with some simple methods (a norm and a dot product). The Point type is minimal, -but does contain additional C attributes (the x and y values of the point) -and an attribute (obj) that contains a Python object (that we will need to -convert from a ``PyObject *`` to an ``HPyField``). - -There is a separate C file illustrating each step of the incremental port: - -* :doc:`steps/step_00_c_api`: The original C API version that we are going to - port. - -* :doc:`steps/step_01_hpy_legacy`: A possible first step where all methods still - receive ``PyObject *`` arguments and may still cast them to ``PyPointObject *`` - if they are instances of Point. - -* :doc:`steps/step_02_hpy_legacy`: Shows how to transition some methods to HPy - methods that receive ``HPy`` handles as arguments while still supporting legacy - methods that receive ``PyObject *`` arguments. - -* :doc:`steps/step_03_hpy_final`: The completed port to HPy where all methods - receive ``HPy`` handles and ``PyObject_HEAD`` has been removed. - -Take a moment to read through :doc:`steps/step_00_c_api`. Then, once you're -ready, keep reading. - -Each section below corresponds to one of the three porting steps above: - -.. contents:: - :local: - :depth: 2 - -.. note:: - The steps used here are one approach to porting a module. The specific - steps are not required. They're just an example approach. - - -Step 01: Converting the module to a (legacy) HPy module -------------------------------------------------------- - -First for the easy bit -- let's include ``hpy.h``: - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: #include - :end-at: #include - -We'd like to differentiate between references to ``PyPointObject`` that have -been ported to HPy and those that haven't, so let's rename it to ``PointObject`` -and alias ``PyPointObject`` to ``PointObject``. We'll keep ``PyPointObject`` for -the instances that haven't been ported yet (the legacy ones) and use -``PointObject`` where we have ported the references: - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: typedef struct { - :end-at: } PointObject; - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: typedef PointObject PyPointObject; - :end-at: typedef PointObject PyPointObject; - -For this step, all references will be to ``PyPointObject`` -- we'll only start -porting references in the next step. - -Let's also call ``HPyType_LEGACY_HELPERS`` to define some helper functions -for use with the ``PointObject`` struct: - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: HPyType_LEGACY_HELPERS(PointObject) - :end-at: HPyType_LEGACY_HELPERS(PointObject) - -Again, we won't use these helpers in this step -- we're just setting things -up for later. - -Now for the big steps. - -We need to replace ``PyType_Spec`` for the ``Point`` type with the equivalent -``HPyType_Spec``: - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: // HPy type methods and slots (no methods or slots have been ported yet) - :end-before: // Legacy module methods (the "dot" method is still a PyCFunction) - -Initially the list of ported methods in ``point_defines`` is empty and all of -the methods are still in ``Point_slots`` which we have renamed to -``Point_legacy_slots`` for clarity. - -``SHAPE(PointObject)`` is a macro that retrieves the shape of ``PointObject`` as it -was defined by the ``HPyType_LEGACY_HELPERS`` macro and will be set to -``HPyType_BuiltinShape_Legacy`` until we replace the legacy macro with the -``HPyType_HELPERS`` one. Any type with ``legacy_slots`` or that still includes -``PyObject_HEAD`` in its struct should have ``.builtin_shape`` set to -``HPyType_BuiltinShape_Legacy``. - -Similarly we replace ``PyModuleDef`` with ``HPyModuleDef``: - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: // Legacy module methods (the "dot" method is still a PyCFunction) - :end-before: // END-OF: HPyModuleDef - -Like the type, the list of ported methods in ``module_defines`` is initially -almost empty: all the regular methods are still in ``PointModuleMethods`` which has -been renamed to ``PointModuleLegacyMethods``. However, because HPy supports only -multiphase module initialization, we must convert our module initialization code -to an "exec" slot on the module and add that slot to ``module_defines``. - -Now all that is left is to replace the module initialization function with -one that uses ``HPy_MODINIT``. The first argument is the name of the extension, -i.e., what was ``XXX`` in ``PyInit_XXX``, and the second argument -is the ``HPyModuleDef``. - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: HPy_MODINIT(step_01_hpy_legacy, moduledef) - -And we're done! - -Instead of the ``PyInit_XXX``, we now have an "exec" slot on the module. -We implement it with a C function that that takes an ``HPyContext *ctx`` and ``HPy mod`` -as arguments. The ``ctx`` must be forwarded as the first argument to calls to -HPy API methods. The ``mod`` argument is a handle for the module object. The runtime -creates the module for us from the provided ``HPyModuleDef``. There is no need to -call API like ``PyModule_Create`` explicitly. - -Next step is to replace ``PyType_FromSpec`` by ``HPyType_FromSpec``. - -``HPy_SetAttr_s`` is used to add the ``Point`` class to the module. HPy requires no -special ``PyModule_AddObject`` method. - -.. literalinclude:: steps/step_01_hpy_legacy.c - :lineno-match: - :start-at: HPyDef_SLOT(module_exec, HPy_mod_exec) - :end-at: } - - -Step 02: Transition some methods to HPy ---------------------------------------- - -In the previous step we put in place the type and module definitions required -to create an HPy extension module. In this step we will port some individual -methods. - -Let us start by migrating ``Point_traverse``. First we need to change -``PyObject *obj`` in the ``PointObject`` struct to ``HPyField obj``: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: typedef struct { - :end-at: } PointObject; - -``HPy`` handles can only be short-lived -- i.e. local variables, arguments to -functions or return values. ``HPyField`` is the way to store long-lived -references to Python objects. For more information, please refer to the -documentation of :ref:`api-reference/hpy-field:HPyField`. - -Now we can update ``Point_traverse``: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: HPyDef_SLOT(Point_traverse, HPy_tp_traverse) - :end-before: // this is a method for creating a Point - -In the first line we used the ``HPyDef_SLOT`` macro to define a small structure -that describes the slot being implemented. The first argument, ``Point_traverse``, -is the name to assign the structure to. By convention, the ``HPyDef_SLOT`` macro -expects a function called ``Point_traverse_impl`` implementing the slot. The -second argument, ``HPy_tp_traverse``, specifies the kind of slot. - -This is a change from how slots are defined in the old C API. In the old API, -the kind of slot is only specified much lower down in ``Point_legacy_slots``. In -HPy the implementation and kind are defined in one place using a syntax -reminiscent of Python decorators. - -The implementation of traverse is now a bit simpler than in the old C API. -We no longer need to visit ``Py_TYPE(self)`` and need only ``HPy_VISIT`` -``self->obj``. HPy ensures that interpreter knows that the type of the instance -is still referenced. - -Only struct members of type ``HPyField`` can be visited with ``HPy_VISIT``, which -is why we needed to convert ``obj`` to an ``HPyField`` before we implemented the -HPy traverse. - -Next we must update ``Point_init`` to store the value of ``obj`` as an ``HPyField``: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: HPyDef_SLOT(Point_init, HPy_tp_init) - :end-before: // this is the getter for the associated object - -There are a few new HPy constructs used here: - -- The kind of the slot passed to ``HPyDef_SLOT`` is ``HPy_tp_init``. - -- ``PointObject_AsStruct`` is defined by ``HPyType_LEGACY_HELPERS`` and returns - an instance of the ``PointObject`` struct. Because we still include - ``PyObject_HEAD`` at the start of the struct this is still a valid ``PyObject *`` - but once we finish the port the struct will no longer contain ``PyObject_HEAD`` - and this will just be an ordinary C struct with no memory overhead! - -- We use ``HPyTracker`` when parsing the arguments with ``HPyArg_ParseKeywords``. - The ``HPyTracker`` keeps track of open handles so that they can be closed - easily at the end with ``HPyTracker_Close``. - -- ``HPyArg_ParseKeywords`` is the equivalent of ``PyArg_ParseTupleAndKeywords``. - Note that the HPy version does not steal a reference like the Python - version. - -- ``HPyField_Store`` is used to store a reference to ``obj`` in the struct. The - arguments are the context (``ctx``), a handle to the object that owns the - reference (``self``), the address of the ``HPyField`` (``&p->obj``), and the - handle to the object (``obj``). - -.. note:: - - An ``HPyTracker`` is not strictly needed for ``HPyArg_ParseKeywords`` - in ``Point_init``. The arguments ``x`` and ``y`` are C floats (so there are no - handles to close) and the handle stored in ``obj`` was passed in to the - ``Point_init`` as an argument and so should not be closed. - - We showed the tracker here to demonstrate its use. You can read more - about argument parsing in the - :doc:`API docs `. - - If a tracker is needed and one is not provided, ``HPyArg_ParseKeywords`` - will return an error. - - -The last update we need to make for the change to ``HPyField`` is to migrate -``Point_obj_get`` which retrieves ``obj`` from the stored ``HPyField``: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: HPyDef_GET(Point_obj, "obj", .doc="Associated object.") - :end-before: // an HPy method of Point - -Above we have used ``PointObject_AsStruct`` again, and then ``HPyField_Load`` to -retrieve the value of ``obj`` from the ``HPyField``. - -We've now finished all of the changes needed by introducing ``HPyField``. We -could stop here, but let's migrate one ordinary method, ``Point_norm``, to end -off this stage of the port: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") - :end-before: // this is an LEGACY function which casts a PyObject* into a PyPointObject* - -To define a method we use ``HPyDef_METH`` instead of ``HPyDef_SLOT``. ``HPyDef_METH`` -creates a small structure defining the method. The first argument is the name -to assign to the structure (``Point_norm``). The second is the Python name of -the method (``norm``). The third specifies the method signature (``HPyFunc_NOARGS`` --- i.e. no additional arguments in this case). The last provides the docstring. -The macro then expects a function named ``Point_norm_impl`` implementing the -method. - -The rest of the implementation remains similar, except that we use -``HPyFloat_FromDouble`` to create a handle to a Python float containing the -result (i.e. the distance of the point from the origin). - -Now we are done and just have to remove the old implementations from -``Point_legacy_slots`` and add them to ``point_defines``: - -.. literalinclude:: steps/step_02_hpy_legacy.c - :lineno-match: - :start-at: static HPyDef *point_defines[] = { - :end-before: static HPyType_Spec Point_Type_spec = { - - -Step 03: Complete the port to HPy ---------------------------------- - -In this step we'll complete the port. We'll no longer include Python, remove -``PyObject_HEAD`` from the ``PointObject`` struct, and port the remaining methods. - -First, let's remove the import of ``Python.h``: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: // #include // disallow use of the old C API - :end-at: // #include // disallow use of the old C API - -And ``PyObject_HEAD`` from the struct: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: typedef struct { - :end-at: } PointObject; - -And the typedef of ``PointObject`` to ``PyPointObject``: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: // typedef PointObject PyPointObject; - :end-at: // typedef PointObject PyPointObject; - -Now any code that has not been ported should result in a compilation error. - -We must also change the type helpers from ``HPyType_LEGACY_HELPERS`` to -``HPyType_HELPERS`` so that ``PointObject_AsStruct`` knows that ``PyObject_HEAD`` -has been removed: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: HPyType_HELPERS(PointObject) - :end-at: HPyType_HELPERS(PointObject) - -There is one more method to port, the ``dot`` method which is a module method -that implements the dot product between two points: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: HPyDef_METH(dot, "dot", HPyFunc_VARARGS, .doc="Dot product.") - :end-before: // Method, type and module definitions. In this porting step all - -The changes are similar to those used in porting the ``norm`` method, except: - -- We use ``HPyArg_Parse`` instead of ``HPyArg_ParseKeywordsDict``. - -- We opted not to use an ``HPyTracker`` by passing ``NULL`` as the pointer to the - tracker when calling ``HPyArg_Parse``. There is no reason not to use a - tracker here, but the handles to the two points are passed in as arguments - to ``dot_impl`` and thus there is no need to close them (and they should not - be closed). - -We use ``PointObject_AsStruct`` and ``HPyFloat_FromDouble`` as before. - -Now that we have ported everything we can remove ``PointMethods``, -``Point_legacy_slots`` and ``PointModuleLegacyMethods``. The resulting -type definition is much cleaner: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: static HPyDef *point_defines[] = { - :end-before: // HPy module methods - -and the module definition is simpler too: - -.. literalinclude:: steps/step_03_hpy_final.c - :lineno-match: - :start-at: static HPyDef *module_defines[] = { - :end-before: HPy_MODINIT(step_03_hpy_final, moduledef) - -Now that the port is complete, when we compile our extension in HPy -universal mode, we obtain a built extension that depends only on the HPy ABI -and not on the CPython ABI at all! diff --git a/graalpython/hpy/docs/porting-example/steps/.gitignore b/graalpython/hpy/docs/porting-example/steps/.gitignore deleted file mode 100644 index 36733d4937..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/.gitignore +++ /dev/null @@ -1 +0,0 @@ -step_03_hpy_final.py diff --git a/graalpython/hpy/docs/porting-example/steps/conftest.py b/graalpython/hpy/docs/porting-example/steps/conftest.py deleted file mode 100644 index 06b7c319ee..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/conftest.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- - -""" Pytest configuration for the porting example tests. """ - -import glob -import os -import sys - -import pytest - - -sys.path.insert(0, os.path.join(os.path.dirname(__file__))) - - -class PortingStep: - def __init__(self, src): - self.name = os.path.splitext(os.path.basename(src))[0] - self.src = src - - def import_step(self): - return __import__(self.name) - - -PORTING_STEPS = [ - PortingStep(src) for src in sorted( - glob.glob(os.path.join(os.path.dirname(__file__), "step_*.c"))) -] - - -@pytest.fixture( - params=PORTING_STEPS, - ids=[step.name for step in PORTING_STEPS], -) -def step(request): - return request.param diff --git a/graalpython/hpy/docs/porting-example/steps/setup00.py b/graalpython/hpy/docs/porting-example/steps/setup00.py deleted file mode 100644 index b3ea47b7aa..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/setup00.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- - -from setuptools import setup, Extension - - -setup( - name="hpy-porting-example", - ext_modules=[ - Extension("step_00_c_api", sources=["step_00_c_api.c"]) - ], - py_modules=["step_00_c_api"], -) diff --git a/graalpython/hpy/docs/porting-example/steps/setup01.py b/graalpython/hpy/docs/porting-example/steps/setup01.py deleted file mode 100644 index 33803453a7..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/setup01.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- - -from setuptools import setup, Extension - - -setup( - name="hpy-porting-example", - hpy_ext_modules=[ - Extension("step_01_hpy_legacy", sources=["step_01_hpy_legacy.c"]) - ], - py_modules=["step_01_hpy_legacy"], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/porting-example/steps/setup02.py b/graalpython/hpy/docs/porting-example/steps/setup02.py deleted file mode 100644 index 6ab9b95e73..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/setup02.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- - -from setuptools import setup, Extension - - -setup( - name="hpy-porting-example", - hpy_ext_modules=[ - Extension("step_02_hpy_legacy", sources=["step_02_hpy_legacy.c"]) - ], - py_modules=["step_02_hpy_legacy"], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/porting-example/steps/setup03.py b/graalpython/hpy/docs/porting-example/steps/setup03.py deleted file mode 100644 index c12ec40020..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/setup03.py +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- - -from setuptools import setup, Extension - -# now we can add --hpy-abi=universal to the invocation of setup.py to build a -# universal binary -setup( - name="hpy-porting-example", - hpy_ext_modules=[ - Extension("step_03_hpy_final", sources=["step_03_hpy_final.c"]) - ], - py_modules=["step_03_hpy_final"], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c deleted file mode 100644 index 0b2742fd4d..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include - -// Porting to HPy, Step 0: Original Python C API version -// -// An example of porting a C extension that implements a Point type -// with a couple of simple methods (a norm and a dot product). It -// illustrates the steps needed to port types that contain additional -// C attributes (in this case, x and y). -// -// This file contains the original C API version that needs to be ported. -// -// HPy supports porting C extensions piece by piece. -// -// point_hpy_legacy_1.c illustrates a possible first step where all -// methods still receive PyObject arguments and may still cast them to -// PyPointObject if they are instances of Point. -// -// point_hpy_legacy_2.c shows how to transition some methods to HPy methods -// that receive HPy handles as arguments while still supporting legacy -// methods that receive PyObject arguments. -// -// point_hpy_final.c shows the completed port to HPy where all methods receive -// HPy handles and PyObject_HEAD has been removed. - -typedef struct { - PyObject_HEAD - double x; - double y; - PyObject *obj; -} PyPointObject; - -int Point_traverse(PyObject *self, visitproc visit, void *arg) -{ - Py_VISIT(((PyPointObject*)self)->obj); - Py_VISIT(Py_TYPE(self)); - return 0; -} - -void Point_dealloc(PyObject *self) -{ - Py_CLEAR(((PyPointObject*)self)->obj); - PyTypeObject *tp = Py_TYPE(self); - tp->tp_free(self); - Py_DECREF(tp); -} - -// this is a method for creating a Point -int Point_init(PyObject *self, PyObject *args, PyObject *kw) -{ - static char *kwlist[] = {"x", "y", "obj", NULL}; - PyPointObject *p = (PyPointObject *)self; - p->x = 0.0; - p->y = 0.0; - p->obj = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|ddO", kwlist, - &p->x, &p->y, &p->obj)) - return -1; - if (p->obj == NULL) - p->obj = Py_None; - Py_INCREF(p->obj); - return 0; -} - -// this is a method of Point -PyObject* Point_norm(PyObject *self) -{ - PyPointObject *p = (PyPointObject *)self; - double norm; - PyObject *result; - norm = sqrt(p->x * p->x + p->y * p->y); - result = PyFloat_FromDouble(norm); - return result; -} - -// this is the getter for the associated object -PyObject* Point_obj_get(PyObject *self, void *context) -{ - PyPointObject *p = (PyPointObject *)self; - Py_INCREF(p->obj); - return p->obj; -} - -// this is an unrelated function which happens to cast a PyObject* into a -// PyPointObject* -PyObject* dot(PyObject *self, PyObject *args) -{ - PyObject *point1, *point2; - if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) - return NULL; - - PyPointObject *p1 = (PyPointObject *)point1; - PyPointObject *p2 = (PyPointObject *)point2; - - double dp; - PyObject *result; - dp = p1->x * p2->x + p1->y * p2->y; - result = PyFloat_FromDouble(dp); - return result; -} - - -// Method, type and module definitions. These will be updated to add HPy -// module support in point_hpy_legacy_1.c. - -static PyMethodDef PointMethods[] = { - {"norm", (PyCFunction)Point_norm, METH_NOARGS, "Distance from origin."}, - {NULL, NULL, 0, NULL} -}; - -static PyGetSetDef PointGetSets[] = { - {"obj", (getter)Point_obj_get, NULL, "Associated object.", NULL}, - {NULL, NULL, 0, NULL} -}; - -static PyType_Slot Point_slots[] = { - {Py_tp_doc, "Point (Step 0; C API implementation)"}, - {Py_tp_init, Point_init}, - {Py_tp_methods, PointMethods}, - {Py_tp_getset, PointGetSets}, - {Py_tp_traverse, Point_traverse}, - {Py_tp_dealloc, Point_dealloc}, - {0, 0} -}; - -static PyType_Spec Point_Type_spec = { - .name = "point_capi.Point", - .basicsize = sizeof(PyPointObject), - .itemsize = 0, - .flags = Py_TPFLAGS_DEFAULT, - .slots = Point_slots -}; - -static PyMethodDef PointModuleMethods[] = { - {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "step_00_c_api", - "Point module (Step 0; C API implementation)", - -1, - PointModuleMethods, - NULL, - NULL, - NULL, - NULL, -}; - -PyMODINIT_FUNC -PyInit_step_00_c_api(void) -{ - PyObject* m; - m = PyModule_Create(&moduledef); - if (m == NULL) - return NULL; - - PyObject *point_type = PyType_FromSpec(&Point_Type_spec); - if (point_type == NULL) - return NULL; - PyModule_AddObject(m, "Point", point_type); - - return m; -} diff --git a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst b/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst deleted file mode 100644 index c9e9b76c18..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_00_c_api.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -step_00_c_api.c -=============== - -.. literalinclude:: ./step_00_c_api.c - :language: c - :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c deleted file mode 100644 index 48137cc589..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.c +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include - -// Porting to HPy, Step 1: All legacy methods -// -// An example of porting a C extension that implements a Point type -// with a couple of simple methods (a norm and a dot product). It -// illustrates the steps needed to port types that contain additional -// C attributes (in this case, x and y). -// -// This file contains an example first step of the port in which all methods -// still receive PyObject arguments and may still cast them to -// PyPointObject if they are instances of Point. - -typedef struct { - // PyObject_HEAD is required while legacy_slots are still used - // but can (and should) be removed once the port to HPy is completed. - PyObject_HEAD - double x; - double y; - PyObject *obj; -} PointObject; - -// This defines PyPointObject as an alias of PointObject so that existing -// code that still uses PyPointObject and expects PyObject_HEAD continues to -// compile and run. Once PyObject_HEAD has been removed, this alias should be -// removed so that code that still expects PyObject_HEAD will fail to compile. -typedef PointObject PyPointObject; - -// The legacy type helper macro defines an PointObject_AsStruct function allows -// non-legacy methods to convert HPy handles to PointObject structs. It is not -// used in this file, but is provided so that methods can start to be ported -// (see point_hpy_legacy_2.c). The legacy type helper macro is used because -// PyObject_HEAD is still present in PointObject. Once PyObject_HEAD has been -// removed (see point_hpy_final.c) we will use HPy_TYPE_HELPERS instead. -HPyType_LEGACY_HELPERS(PointObject) - -int Point_traverse(PyObject *self, visitproc visit, void *arg) -{ - Py_VISIT(((PyPointObject*)self)->obj); - Py_VISIT(Py_TYPE(self)); - return 0; -} - -void Point_dealloc(PyObject *self) -{ - Py_CLEAR(((PyPointObject*)self)->obj); - PyTypeObject *tp = Py_TYPE(self); - tp->tp_free(self); - Py_DECREF(tp); -} - -// this is a method for creating a Point -int Point_init(PyObject *self, PyObject *args, PyObject *kw) -{ - static char *kwlist[] = {"x", "y", "obj", NULL}; - PyPointObject *p = (PyPointObject *)self; - p->x = 0.0; - p->y = 0.0; - p->obj = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|ddO", kwlist, - &p->x, &p->y, &p->obj)) - return -1; - if (p->obj == NULL) - p->obj = Py_None; - Py_INCREF(p->obj); - return 0; -} - -// this is a LEGACY method of Point -PyObject* Point_norm(PyObject *self) -{ - PyPointObject *p = (PyPointObject *)self; - double norm; - norm = sqrt(p->x * p->x + p->y * p->y); - return PyFloat_FromDouble(norm); -} - -// this is the getter for the associated object -PyObject* Point_obj_get(PyObject *self, void *context) -{ - PyPointObject *p = (PyPointObject *)self; - Py_INCREF(p->obj); - return p->obj; -} - -// this is an LEGACY function which casts a PyObject* into a PyPointObject* -PyObject* dot(PyObject *self, PyObject *args) -{ - PyObject *point1, *point2; - if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) - return NULL; - - PyPointObject *p1 = (PyPointObject *)point1; - PyPointObject *p2 = (PyPointObject *)point2; - - double dp; - dp = p1->x * p2->x + p1->y * p2->y; - return PyFloat_FromDouble(dp); -} - - -// Method, type and module definitions. In this porting step, the module and -// type definitions have been ported to HPy, but the methods themselves -// remaining legacy methods. - -// Legacy methods (all methods are still legacy methods) -static PyMethodDef PointMethods[] = { - {"norm", (PyCFunction)Point_norm, METH_NOARGS, "Distance from origin."}, - {NULL, NULL, 0, NULL} -}; - -// Legacy getsets -static PyGetSetDef PointGetSets[] = { - {"obj", (getter)Point_obj_get, NULL, "Associated object.", NULL}, - {NULL, NULL, 0, NULL} -}; - -// Legacy slots (all slots are still legacy slots) -static PyType_Slot Point_legacy_slots[] = { - {Py_tp_doc, "Point (Step 1; All legacy methods)"}, - {Py_tp_init, Point_init}, - {Py_tp_methods, PointMethods}, - {Py_tp_getset, PointGetSets}, - {Py_tp_traverse, Point_traverse}, - {Py_tp_dealloc, Point_dealloc}, - {0, 0} -}; - -// HPy type methods and slots (no methods or slots have been ported yet) -static HPyDef *point_defines[] = { - NULL -}; - -static HPyType_Spec Point_Type_spec = { - .name = "point_hpy_legacy_1.Point", - .basicsize = sizeof(PointObject), - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT, - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_legacy_slots, - .defines = point_defines, -}; - -// HPy supports only multiphase module initialization, so we must migrate the -// single phase initialization by extracting the code that populates the module -// object with attributes into a separate 'exec' slot. The module is not -// created manually by calling API like PyModule_Create, but the runtime creates -// the module for us from the specification in HPyModuleDef, and we can provide -// additional slots to populate the module before its initialization is finalized -HPyDef_SLOT(module_exec, HPy_mod_exec) -static int module_exec_impl(HPyContext *ctx, HPy mod) -{ - HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); - if (HPy_IsNull(point_type)) - return -1; - HPy_SetAttr_s(ctx, mod, "Point", point_type); - return 0; -} - -// Legacy module methods (the "dot" method is still a PyCFunction) -static PyMethodDef PointModuleLegacyMethods[] = { - {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, - {NULL, NULL, 0, NULL} -}; - -// HPy module methods: no regular methods have been ported yet, -// but we add the module execute slot -static HPyDef *module_defines[] = { - &module_exec, - NULL -}; - -static HPyModuleDef moduledef = { - // .name = "step_01_hpy_legacy", - // ^-- .name is not needed for multiphase module initialization, - // it is always taken from the ModuleSpec - .doc = "Point module (Step 1; All legacy methods)", - .size = 0, - .legacy_methods = PointModuleLegacyMethods, - .defines = module_defines, -}; -// END-OF: HPyModuleDef - -// HPy_MODINIT takes the extension name, i.e., what would be XXX in PyInit_XXX, -// and the module definition. The module will be created by the runtime and -// passed to the HPy_mod_exec slots if any are defined -HPy_MODINIT(step_01_hpy_legacy, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst b/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst deleted file mode 100644 index 7ba453ac10..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_01_hpy_legacy.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -step_01_hpy_legacy.c -==================== - -.. literalinclude:: ./step_01_hpy_legacy.c - :language: c - :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c deleted file mode 100644 index 0d4ff7b04b..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.c +++ /dev/null @@ -1,169 +0,0 @@ -#include -#include -#include - -// Porting to HPy, Step 2: Porting some methods -// -// An example of porting a C extension that implements a Point type -// with a couple of simple methods (a norm and a dot product). It -// illustrates the steps needed to port types that contain additional -// C attributes (in this case, x and y). -// -// This file contains an example second step of the port in which some methods -// have been converted to HPy methods that receive handles as arguments, but -// other methods are still legacy methods that receive PyObject arguments. - -typedef struct { - // PyObject_HEAD is required while legacy methods still access - // PointObject and should be removed once the port to HPy is completed. - PyObject_HEAD - double x; - double y; - // HPy handles are shortlived to support all GC strategies - // For that reason, PyObject* in C structs are replaced by HPyField - HPyField obj; -} PointObject; - -// This defines PyPointObject as an alias of PointObject so that existing -// code that still uses PyPointObject and expects PyObject_HEAD continues to -// compile and run. Once PyObject_HEAD has been removed, this alias should be -// removed so that code that still expects PyObject_HEAD will fail to compile. -typedef PointObject PyPointObject; - -// The legacy type helper macro defines an PointObject_AsStruct function allows -// non-legacy methods to convert HPy handles to PointObject structs. The legacy -// type helper macro is used because PyObject_HEAD is still present in -// PointObject. Once PyObject_HEAD has been removed (see point_hpy_final.c) we -// will use HPy_TYPE_HELPERS instead. -HPyType_LEGACY_HELPERS(PointObject) - -HPyDef_SLOT(Point_traverse, HPy_tp_traverse) -int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) -{ - HPy_VISIT(&((PointObject*)self)->obj); - return 0; -} - -// this is a method for creating a Point -HPyDef_SLOT(Point_init, HPy_tp_init) -int Point_init_impl(HPyContext *ctx, HPy self, const HPy *args, - HPy_ssize_t nargs, HPy kw) -{ - static const char *kwlist[] = {"x", "y", "obj", NULL}; - PointObject *p = PointObject_AsStruct(ctx, self); - p->x = 0.0; - p->y = 0.0; - HPy obj = HPy_NULL; - HPyTracker ht; - if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "|ddO", kwlist, - &p->x, &p->y, &obj)) - return -1; - if (HPy_IsNull(obj)) - obj = ctx->h_None; - /* INCREF not needed because HPyArg_ParseKeywordsDict does not steal a - reference */ - HPyField_Store(ctx, self, &p->obj, obj); - HPyTracker_Close(ctx, ht); - return 0; -} - -// this is the getter for the associated object -HPyDef_GET(Point_obj, "obj", .doc="Associated object.") -HPy Point_obj_get(HPyContext *ctx, HPy self, void* closure) -{ - PointObject *p = PointObject_AsStruct(ctx, self); - return HPyField_Load(ctx, self, p->obj); -} - -// an HPy method of Point -HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") -HPy Point_norm_impl(HPyContext *ctx, HPy self) -{ - PointObject *p = PointObject_AsStruct(ctx, self); - double norm; - norm = sqrt(p->x * p->x + p->y * p->y); - return HPyFloat_FromDouble(ctx, norm); -} - -// this is an LEGACY function which casts a PyObject* into a PyPointObject* -PyObject* dot(PyObject *self, PyObject *args) -{ - PyObject *point1, *point2; - if (!PyArg_ParseTuple(args, "OO", &point1, &point2)) - return NULL; - - PyPointObject *p1 = (PyPointObject *)point1; - PyPointObject *p2 = (PyPointObject *)point2; - - double dp; - dp = p1->x * p2->x + p1->y * p2->y; - return PyFloat_FromDouble(dp); -} - -// Method, type and module definitions. In this porting step .norm() -// is ported to HPy, but dot(...) remains a legacy methods. -// Point.__init__ and Point.__doc__ are ported from legacy slots to -// HPy type defines. - -// Legacy methods (there are no legacy methods left now) -static PyMethodDef PointMethods[] = { - {NULL, NULL, 0, NULL} -}; - -// Legacy slots (all slots are still legacy slots) -static PyType_Slot Point_legacy_slots[] = { - {Py_tp_doc, "Point (Step 2; Porting some methods)"}, - {Py_tp_methods, PointMethods}, - {0, 0} -}; - -// HPy type methods and slots -static HPyDef *point_defines[] = { - &Point_init, - &Point_norm, - &Point_obj, - &Point_traverse, - NULL -}; - -static HPyType_Spec Point_Type_spec = { - .name = "point_hpy_legacy_2.Point", - .basicsize = sizeof(PointObject), - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT, - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_legacy_slots, - .defines = point_defines -}; - -// Legacy module methods (the "dot" method is still a PyCFunction) -static PyMethodDef PointModuleLegacyMethods[] = { - {"dot", (PyCFunction)dot, METH_VARARGS, "Dot product."}, - {NULL, NULL, 0, NULL} -}; - -HPyDef_SLOT(module_exec, HPy_mod_exec) -static int module_exec_impl(HPyContext *ctx, HPy mod) -{ - HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); - if (HPy_IsNull(point_type)) - return -1; - HPy_SetAttr_s(ctx, mod, "Point", point_type); - return 0; -} - -// HPy module methods: no regular methods have been ported yet, -// but we add the module execute slot -static HPyDef *module_defines[] = { - &module_exec, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "Point module (Step 2; Porting some methods)", - .size = 0, - .legacy_methods = PointModuleLegacyMethods, - .defines = module_defines, -}; - -HPy_MODINIT(step_02_hpy_legacy, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst b/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst deleted file mode 100644 index 5523681465..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_02_hpy_legacy.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -step_02_hpy_legacy.c -==================== - -.. literalinclude:: ./step_02_hpy_legacy.c - :language: c - :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c deleted file mode 100644 index 8f49ecf857..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -// #include // disallow use of the old C API -#include - -// Porting to HPy, Step 3: All methods ported -// -// An example of porting a C extension that implements a Point type -// with a couple of simple methods (a norm and a dot product). It -// illustrates the steps needed to port types that contain additional -// C attributes (in this case, x and y). -// -// This file contains an example final step of the port in which all methods -// have been converted to HPy methods and PyObject_HEAD has been removed. - -typedef struct { - // PyObject_HEAD is no longer available in PointObject. In CPython, - // of course, it still exists but is inaccessible from HPy_AsStruct. In - // other Python implementations (e.g. PyPy) it might no longer exist at - // all. - double x; - double y; - HPyField obj; -} PointObject; - -// Code using PyPointObject relied on PyObject_HEAD and is no longer valid -// (PyObject_HEAD has been removed from the PointObject struct above). The -// typedef below has been deleted to ensure that such code is now generates -// an error during compilation. -// typedef PointObject PyPointObject; - -// The type helper macro defines an PointObject_AsStruct function allows -// converting HPy handles to PointObject structs. We no longer need to use -// the legacy type helper macro because PyObject_HEAD has been removed from -// PointObject. -HPyType_HELPERS(PointObject) - -HPyDef_SLOT(Point_traverse, HPy_tp_traverse) -int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) -{ - HPy_VISIT(&((PointObject*)self)->obj); - return 0; -} - -// this is a method for creating a Point -HPyDef_SLOT(Point_init, HPy_tp_init) -int Point_init_impl(HPyContext *ctx, HPy self, const HPy *args, - HPy_ssize_t nargs, HPy kw) -{ - static const char *kwlist[] = {"x", "y", "obj", NULL}; - PointObject *p = PointObject_AsStruct(ctx, self); - p->x = 0.0; - p->y = 0.0; - HPy obj = HPy_NULL; - HPyTracker ht; - if (!HPyArg_ParseKeywordsDict(ctx, &ht, args, nargs, kw, "|ddO", kwlist, - &p->x, &p->y, &obj)) - return -1; - if (HPy_IsNull(obj)) - obj = ctx->h_None; - /* INCREF not needed because HPyArg_ParseKeywordsDict does not steal a - reference */ - HPyField_Store(ctx, self, &p->obj, obj); - HPyTracker_Close(ctx, ht); - return 0; -} - -// this is the getter for the associated object -HPyDef_GET(Point_obj, "obj", .doc="Associated object.") -HPy Point_obj_get(HPyContext *ctx, HPy self, void* closure) -{ - PointObject *p = PointObject_AsStruct(ctx, self); - return HPyField_Load(ctx, self, p->obj); -} - -// an HPy method of Point -HPyDef_METH(Point_norm, "norm", HPyFunc_NOARGS, .doc="Distance from origin.") -HPy Point_norm_impl(HPyContext *ctx, HPy self) -{ - PointObject *p = PointObject_AsStruct(ctx, self); - double norm; - norm = sqrt(p->x * p->x + p->y * p->y); - return HPyFloat_FromDouble(ctx, norm); -} - -// this is an HPy function that uses Point -HPyDef_METH(dot, "dot", HPyFunc_VARARGS, .doc="Dot product.") -HPy dot_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - HPy point1, point2; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &point1, &point2)) - return HPy_NULL; - PointObject *p1 = PointObject_AsStruct(ctx, point1); - PointObject *p2 = PointObject_AsStruct(ctx, point2); - double dp; - dp = p1->x * p2->x + p1->y * p2->y; - return HPyFloat_FromDouble(ctx, dp); -} - -// Method, type and module definitions. In this porting step all -// methods and slots have been ported to HPy and all legacy support -// has been removed. - -// Support for legacy methods and slots has been removed. It used to be: -/// -// static PyMethodDef PointMethods[] = { ... } -// static PyType_Slot Point_legacy_slots[] = { ... } -// static PyMethodDef PointModuleLegacyMethods[] = { ... } -// -// and .legacy_slots and .legacy_defines have been removed from HPyType_Spec -// HPyModuleDef respectively. - -// HPy type methods and slots -static HPyDef *point_defines[] = { - &Point_init, - &Point_norm, - &Point_obj, - &Point_traverse, - NULL -}; - -static HPyType_Spec Point_Type_spec = { - .name = "point_hpy_final.Point", - .doc = "Point (Step 03)", - .basicsize = sizeof(PointObject), - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT, - .defines = point_defines -}; - -HPyDef_SLOT(module_exec, HPy_mod_exec) -static int module_exec_impl(HPyContext *ctx, HPy mod) -{ - HPy point_type = HPyType_FromSpec(ctx, &Point_Type_spec, NULL); - if (HPy_IsNull(point_type)) - return -1; - HPy_SetAttr_s(ctx, mod, "Point", point_type); - return 0; -} - -// HPy module methods -static HPyDef *module_defines[] = { - &module_exec, - &dot, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "Point module (Step 3; Porting complete)", - .size = 0, - .defines = module_defines, -}; - -HPy_MODINIT(step_03_hpy_final, moduledef) diff --git a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst b/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst deleted file mode 100644 index 3b8f561fc7..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/step_03_hpy_final.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -step_03_hpy_final.c -=================== - -.. literalinclude:: ./step_03_hpy_final.c - :language: c - :linenos: diff --git a/graalpython/hpy/docs/porting-example/steps/test_porting_example.py b/graalpython/hpy/docs/porting-example/steps/test_porting_example.py deleted file mode 100644 index 013b010c03..0000000000 --- a/graalpython/hpy/docs/porting-example/steps/test_porting_example.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -""" Porting example tests. """ - -import pytest -import math -import types - - -class TestPorting: - def test_load_module(self, step): - mod = step.import_step() - assert isinstance(mod, types.ModuleType) - assert mod.__name__ == step.name - assert mod.__doc__.startswith("Point module (Step ") - assert type(mod.Point) == type - assert mod.Point.__doc__.startswith("Point (Step ") - assert isinstance(mod.dot, types.BuiltinFunctionType) - assert mod.dot.__doc__ == "Dot product." - - def test_create_point(self, step): - mod = step.import_step() - p = mod.Point(1, 2) - assert type(p) == mod.Point - - def test_norm(self, step): - mod = step.import_step() - assert mod.Point(1, 2).norm() == math.sqrt(5.0) - assert mod.Point(1.5).norm() == 1.5 - - def test_dot(self, step): - mod = step.import_step() - p1 = mod.Point(1, 2) - p2 = mod.Point(3, 2) - assert mod.dot(p1, p2) == 7.0 - - def test_object(self, step): - mod = step.import_step() - p1 = mod.Point(23, 42, ...) - assert p1.obj is ... - p2 = mod.Point(23, 42) - assert p2.obj is None - - def test_leak_checker(self, step): - if "hpy_final" not in step.name: - pytest.skip("Can only check for leaks in universal mode") - mod = step.import_step() - import hpy.debug - hpy.debug.set_handle_stack_trace_limit(10) - with hpy.debug.LeakDetector(): - p1 = mod.Point(1, 2, ...) - p2 = mod.Point(3, 2) - - assert p1.obj is ... - assert p2.obj is None - assert p1.norm() == math.sqrt(5.0) - assert mod.dot(p1, p2) == 7.0 - - del p1 - del p2 diff --git a/graalpython/hpy/docs/porting-guide.rst b/graalpython/hpy/docs/porting-guide.rst deleted file mode 100644 index c21961366d..0000000000 --- a/graalpython/hpy/docs/porting-guide.rst +++ /dev/null @@ -1,569 +0,0 @@ -Porting Guide -============= - -Porting ``PyObject *`` to HPy API constructs --------------------------------------------- - -While in CPython one always uses ``PyObject *`` to reference to Python objects, -in HPy there are several types of handles that should be used depending on the -life-time of the handle: ``HPy``, ``HPyField``, and ``HPyGlobal``. - -- ``HPy`` represents short lived handles that live no longer than the duration of - one call from Python to HPy extension function. Rule of thumb: use for local - variables, arguments, and return values. - -- ``HPyField`` represents handles that are Python object struct fields, i.e., - live in native memory attached to some Python object. - -- ``HPyGlobal`` represents handles stored in C global variables. ``HPyGlobal`` - can provide isolation between subinterpreters. - -.. warning:: Never use a local variable of type ``HPyField``, for any reason! If - the GC kicks in, it might become invalid and become a dangling pointer. - -.. warning:: Never store `HPy` handles to a long-lived memory, for example: C - global variables or Python object structs. - -The ``HPy``/``HPyField`` dichotomy might seem arbitrary at first, but it is -needed to allow Python implementations to use a moving GC, such as PyPy. It is -easier to explain and understand the rules by thinking about how a moving GC -interacts with the C code inside an HPy extension. - -It is worth remembering that during the collection phase, a moving GC might -move an existing object to another memory location, and in that case it needs -to update all the places which store a pointer to it. In order to do so, it -needs to *know* where the pointers are. If there is a local C variable which is -unknown to the GC but contains a pointer to a GC-managed object, the variable -will point to invalid memory as soon as the object is moved. - -Back to ``HPy`` vs ``HPyField`` vs ``HPyGlobal``: - - * ``HPy`` handles must be used for all C local variables, function arguments - and function return values. They are supposed to be short-lived and closed - as soon as they are no longer needed. The debug mode will report a - long-lived ``HPy`` as a potential memory leak. - - * In PyPy and GraalPy, ``HPy`` handles are implemented using an - indirection: they are indexes inside a big list of GC-managed objects: this - big list is tracked by the GC, so when an object moves its pointer is - correctly updated. - - * ``HPyField`` is for long-lived references, and the GC must be aware of - their location in memory. In PyPy, an ``HPyField`` is implemented as a - direct pointer to the object, and thus we need a way to inform the GC - where it is in memory, so that it can update its value upon moving: this - job is done by ``tp_traverse``, as explained in the next section. - - * ``HPyGlobal`` is for long-lived references that are supposed to be closed - implicitly when the module is unloaded (once module unloading is actually - implemented). ``HPyGlobal`` provides indirection to isolate subinterpreters. - Implementation wise, ``HPyGlobal`` will usually contain an index to a table - with Python objects stored in the interpreter state. - - * On CPython without subinterpreters support, ``HPy``, ``HPyGlobal``, - and ``HPyField`` are implemented as ``PyObject *``. - - * On CPython with subinterpreters support, ``HPyGlobal`` will be implemented - by an indirection through the interpreter state. Note that thanks to the HPy - design, switching between this and the more efficient implementation without - subinterpreter support will not require rebuilding of the extension (in HPy - universal mode), nor rebuilding of CPython. - -.. note:: If you write a custom type using ``HPyField``, you **MUST** also write - a ``tp_traverse`` slot. Note that this is different than the old ``Python.h`` - API, where you need ``tp_traverse`` only under certain conditions. See the - next section for more details. - -.. note:: The contract of ``tp_traverse`` is that it must visit all members of - type ``HPyField`` contained within given struct, or more precisely *owned* by - given Python object (in the sense of the *owner* argument to - ``HPyField_Store``), and nothing more, nothing less. Some Python - implementations may choose to not call the provided ``tp_traverse`` if they - know how to visit all members of type ``HPyField`` by other means (for - example, when they track them internally already). The debug mode will check - this contract. - -``tp_traverse``, ``tp_clear``, ``Py_TPFLAGS_HAVE_GC`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Let's quote the ``Python.h`` documentation about `GC support -`_ - - Python's support for detecting and collecting garbage which involves - circular references requires support from object types which are - “containers” for other objects which may also be containers. Types which do - not store references to other objects, or which only store references to - atomic types (such as numbers or strings), do not need to provide any - explicit support for garbage collection. - -A good rule of thumb is that if your type contains ``PyObject *`` fields, you -need to: - - 1. provide a ``tp_traverse`` slot; - - 2. provide a ``tp_clear`` slot; - - 3. add the ``Py_TPFLAGS_GC`` to the ``tp_flags``. - - -However, if you know that your ``PyObject *`` fields will contain only -"atomic" types, you can avoid these steps. - -In HPy the rules are slightly different: - - 1. if you have a field of type ``HPyField``, you always **MUST** provide a - ``tp_traverse``. This is needed so that a moving GC can track the - relevant areas of memory. However, you **MUST NOT** rely on - ``tp_traverse`` to be called; - - 2. ``tp_clear`` does not exist. On CPython, ``HPy`` automatically generates - one for you, by using ``tp_traverse`` to know which are the fields to - clear. Other implementations are free to ignore it, if it's not needed; - - 3. ``HPy_TPFLAGS_GC`` is still needed, especially on CPython. If you don't - specify it, your type will not be tracked by CPython's GC and thus it - might cause memory leaks if it's part of a reference cycle. However, - other implementations are free to ignore the flag and track the objects - anyway, if their GC implementation allows it. - -``tp_dealloc`` and ``Py_DECREF`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Generally speaking, if you have one or more ``PyObject *`` fields in the old -``Python.h``, you must provide a ``tp_dealloc`` slot where you ``Py_DECREF`` all -of them. In HPy this is not needed and will be handled automatically by the -system. - -In particular, when running on top of CPython, HPy will automatically provide -a ``tp_dealloc`` which decrefs all the fields listed by ``tp_traverse``. - -See also, :ref:`dealloc`. - - -Direct C API to HPy mappings ----------------------------- - -In many cases, migrating to HPy is as easy as just replacing a certain C API -function by the appropriate HPy API function. Table :ref:`table-mapping` gives a -mapping between C API and HPy API functions. This mapping is generated together -with the code for the :term:`CPython ABI` mode, so it is guaranteed to be correct. - - -.. mark: BEGIN API MAPPING -.. _table-mapping: -.. table:: Safe API function mapping - :widths: auto - - ================================================================================================================================== ================================================ - C API function HPY API function - ================================================================================================================================== ================================================ - `PyBool_FromLong `_ :c:func:`HPyBool_FromLong` - `PyBytes_AS_STRING `_ :c:func:`HPyBytes_AS_STRING` - `PyBytes_AsString `_ :c:func:`HPyBytes_AsString` - `PyBytes_Check `_ :c:func:`HPyBytes_Check` - `PyBytes_FromString `_ :c:func:`HPyBytes_FromString` - `PyBytes_GET_SIZE `_ :c:func:`HPyBytes_GET_SIZE` - `PyBytes_Size `_ :c:func:`HPyBytes_Size` - `PyCallable_Check `_ :c:func:`HPyCallable_Check` - `PyCapsule_IsValid `_ :c:func:`HPyCapsule_IsValid` - `PyContextVar_Get `_ :c:func:`HPyContextVar_Get` - `PyContextVar_New `_ :c:func:`HPyContextVar_New` - `PyContextVar_Set `_ :c:func:`HPyContextVar_Set` - `PyDict_Check `_ :c:func:`HPyDict_Check` - `PyDict_Copy `_ :c:func:`HPyDict_Copy` - `PyDict_Keys `_ :c:func:`HPyDict_Keys` - `PyDict_New `_ :c:func:`HPyDict_New` - `PyErr_Clear `_ :c:func:`HPyErr_Clear` - `PyErr_ExceptionMatches `_ :c:func:`HPyErr_ExceptionMatches` - `PyErr_NewException `_ :c:func:`HPyErr_NewException` - `PyErr_NewExceptionWithDoc `_ :c:func:`HPyErr_NewExceptionWithDoc` - `PyErr_NoMemory `_ :c:func:`HPyErr_NoMemory` - `PyErr_SetFromErrnoWithFilename `_ :c:func:`HPyErr_SetFromErrnoWithFilename` - `PyErr_SetFromErrnoWithFilenameObjects `_ :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` - `PyErr_SetObject `_ :c:func:`HPyErr_SetObject` - `PyErr_SetString `_ :c:func:`HPyErr_SetString` - `PyErr_WarnEx `_ :c:func:`HPyErr_WarnEx` - `PyErr_WriteUnraisable `_ :c:func:`HPyErr_WriteUnraisable` - `PyEval_EvalCode `_ :c:func:`HPy_EvalCode` - `PyEval_RestoreThread `_ :c:func:`HPy_ReenterPythonExecution` - `PyEval_SaveThread `_ :c:func:`HPy_LeavePythonExecution` - `PyFloat_AsDouble `_ :c:func:`HPyFloat_AsDouble` - `PyFloat_FromDouble `_ :c:func:`HPyFloat_FromDouble` - `PyImport_ImportModule `_ :c:func:`HPyImport_ImportModule` - `PyIter_Check `_ :c:func:`HPyIter_Check` - `PyIter_Next `_ :c:func:`HPyIter_Next` - `PyList_Append `_ :c:func:`HPyList_Append` - `PyList_Check `_ :c:func:`HPyList_Check` - `PyList_Insert `_ :c:func:`HPyList_Insert` - `PyList_New `_ :c:func:`HPyList_New` - `PyLong_AsDouble `_ :c:func:`HPyLong_AsDouble` - `PyLong_AsLong `_ :c:func:`HPyLong_AsLong` - `PyLong_AsLongLong `_ :c:func:`HPyLong_AsLongLong` - `PyLong_AsSize_t `_ :c:func:`HPyLong_AsSize_t` - `PyLong_AsSsize_t `_ :c:func:`HPyLong_AsSsize_t` - `PyLong_AsUnsignedLong `_ :c:func:`HPyLong_AsUnsignedLong` - `PyLong_AsUnsignedLongLong `_ :c:func:`HPyLong_AsUnsignedLongLong` - `PyLong_AsUnsignedLongLongMask `_ :c:func:`HPyLong_AsUnsignedLongLongMask` - `PyLong_AsUnsignedLongMask `_ :c:func:`HPyLong_AsUnsignedLongMask` - `PyLong_AsVoidPtr `_ :c:func:`HPyLong_AsVoidPtr` - `PyLong_FromLong `_ :c:func:`HPyLong_FromLong` - `PyLong_FromLongLong `_ :c:func:`HPyLong_FromLongLong` - `PyLong_FromSize_t `_ :c:func:`HPyLong_FromSize_t` - `PyLong_FromSsize_t `_ :c:func:`HPyLong_FromSsize_t` - `PyLong_FromUnsignedLong `_ :c:func:`HPyLong_FromUnsignedLong` - `PyLong_FromUnsignedLongLong `_ :c:func:`HPyLong_FromUnsignedLongLong` - `PyNumber_Absolute `_ :c:func:`HPy_Absolute` - `PyNumber_Add `_ :c:func:`HPy_Add` - `PyNumber_And `_ :c:func:`HPy_And` - `PyNumber_Check `_ :c:func:`HPyNumber_Check` - `PyNumber_Divmod `_ :c:func:`HPy_Divmod` - `PyNumber_Float `_ :c:func:`HPy_Float` - `PyNumber_FloorDivide `_ :c:func:`HPy_FloorDivide` - `PyNumber_InPlaceAdd `_ :c:func:`HPy_InPlaceAdd` - `PyNumber_InPlaceAnd `_ :c:func:`HPy_InPlaceAnd` - `PyNumber_InPlaceFloorDivide `_ :c:func:`HPy_InPlaceFloorDivide` - `PyNumber_InPlaceLshift `_ :c:func:`HPy_InPlaceLshift` - `PyNumber_InPlaceMatrixMultiply `_ :c:func:`HPy_InPlaceMatrixMultiply` - `PyNumber_InPlaceMultiply `_ :c:func:`HPy_InPlaceMultiply` - `PyNumber_InPlaceOr `_ :c:func:`HPy_InPlaceOr` - `PyNumber_InPlacePower `_ :c:func:`HPy_InPlacePower` - `PyNumber_InPlaceRemainder `_ :c:func:`HPy_InPlaceRemainder` - `PyNumber_InPlaceRshift `_ :c:func:`HPy_InPlaceRshift` - `PyNumber_InPlaceSubtract `_ :c:func:`HPy_InPlaceSubtract` - `PyNumber_InPlaceTrueDivide `_ :c:func:`HPy_InPlaceTrueDivide` - `PyNumber_InPlaceXor `_ :c:func:`HPy_InPlaceXor` - `PyNumber_Index `_ :c:func:`HPy_Index` - `PyNumber_Invert `_ :c:func:`HPy_Invert` - `PyNumber_Long `_ :c:func:`HPy_Long` - `PyNumber_Lshift `_ :c:func:`HPy_Lshift` - `PyNumber_MatrixMultiply `_ :c:func:`HPy_MatrixMultiply` - `PyNumber_Multiply `_ :c:func:`HPy_Multiply` - `PyNumber_Negative `_ :c:func:`HPy_Negative` - `PyNumber_Or `_ :c:func:`HPy_Or` - `PyNumber_Positive `_ :c:func:`HPy_Positive` - `PyNumber_Power `_ :c:func:`HPy_Power` - `PyNumber_Remainder `_ :c:func:`HPy_Remainder` - `PyNumber_Rshift `_ :c:func:`HPy_Rshift` - `PyNumber_Subtract `_ :c:func:`HPy_Subtract` - `PyNumber_TrueDivide `_ :c:func:`HPy_TrueDivide` - `PyNumber_Xor `_ :c:func:`HPy_Xor` - `PyObject_ASCII `_ :c:func:`HPy_ASCII` - `PyObject_Bytes `_ :c:func:`HPy_Bytes` - `PyObject_Call `_ :c:func:`HPy_CallTupleDict` - `PyObject_DelItem `_ :c:func:`HPy_DelItem` - `PyObject_GetAttr `_ :c:func:`HPy_GetAttr` - `PyObject_GetAttrString `_ :c:func:`HPy_GetAttr_s` - `PyObject_GetItem `_ :c:func:`HPy_GetItem` - `PyObject_GetIter `_ :c:func:`HPy_GetIter` - `PyObject_HasAttr `_ :c:func:`HPy_HasAttr` - `PyObject_HasAttrString `_ :c:func:`HPy_HasAttr_s` - `PyObject_Hash `_ :c:func:`HPy_Hash` - `PyObject_IsTrue `_ :c:func:`HPy_IsTrue` - `PyObject_Length `_ :c:func:`HPy_Length` - `PyObject_Repr `_ :c:func:`HPy_Repr` - `PyObject_RichCompare `_ :c:func:`HPy_RichCompare` - `PyObject_RichCompareBool `_ :c:func:`HPy_RichCompareBool` - `PyObject_SetAttr `_ :c:func:`HPy_SetAttr` - `PyObject_SetAttrString `_ :c:func:`HPy_SetAttr_s` - `PyObject_SetItem `_ :c:func:`HPy_SetItem` - `PyObject_Str `_ :c:func:`HPy_Str` - `PyObject_Type `_ :c:func:`HPy_Type` - `PyObject_TypeCheck `_ :c:func:`HPy_TypeCheck` - `PyObject_Vectorcall `_ :c:func:`HPy_Call` - `PyObject_VectorcallMethod `_ :c:func:`HPy_CallMethod` - `PySequence_Contains `_ :c:func:`HPy_Contains` - `PySequence_DelSlice `_ :c:func:`HPy_DelSlice` - `PySequence_GetSlice `_ :c:func:`HPy_GetSlice` - `PySequence_SetSlice `_ :c:func:`HPy_SetSlice` - `PySlice_AdjustIndices `_ :c:func:`HPySlice_AdjustIndices` - `PySlice_New `_ :c:func:`HPySlice_New` - `PySlice_Unpack `_ :c:func:`HPySlice_Unpack` - `PyTuple_Check `_ :c:func:`HPyTuple_Check` - `PyType_IsSubtype `_ :c:func:`HPyType_IsSubtype` - `PyUnicode_AsASCIIString `_ :c:func:`HPyUnicode_AsASCIIString` - `PyUnicode_AsLatin1String `_ :c:func:`HPyUnicode_AsLatin1String` - `PyUnicode_AsUTF8AndSize `_ :c:func:`HPyUnicode_AsUTF8AndSize` - `PyUnicode_AsUTF8String `_ :c:func:`HPyUnicode_AsUTF8String` - `PyUnicode_Check `_ :c:func:`HPyUnicode_Check` - `PyUnicode_DecodeASCII `_ :c:func:`HPyUnicode_DecodeASCII` - `PyUnicode_DecodeFSDefault `_ :c:func:`HPyUnicode_DecodeFSDefault` - `PyUnicode_DecodeFSDefaultAndSize `_ :c:func:`HPyUnicode_DecodeFSDefaultAndSize` - `PyUnicode_DecodeLatin1 `_ :c:func:`HPyUnicode_DecodeLatin1` - `PyUnicode_EncodeFSDefault `_ :c:func:`HPyUnicode_EncodeFSDefault` - `PyUnicode_FromEncodedObject `_ :c:func:`HPyUnicode_FromEncodedObject` - `PyUnicode_FromString `_ :c:func:`HPyUnicode_FromString` - `PyUnicode_FromWideChar `_ :c:func:`HPyUnicode_FromWideChar` - `PyUnicode_ReadChar `_ :c:func:`HPyUnicode_ReadChar` - `PyUnicode_Substring `_ :c:func:`HPyUnicode_Substring` - `Py_FatalError `_ :c:func:`HPy_FatalError` - ================================================================================================================================== ================================================ -.. mark: END API MAPPING - - -.. note: There are, of course, also cases where it is not possible to map directly and safely from a C API function (or concept) to an HPy API function (or concept). - -Reference Counting ``Py_INCREF`` and ``Py_DECREF`` --------------------------------------------------- - -The equivalents of ``Py_INCREF`` and ``Py_DECREF`` are essentially -:c:func:`HPy_Dup` and :c:func:`HPy_Close`, respectively. The main difference is -that :c:func:`HPy_Dup` gives you a *new handle* to the same object which means -that the two handles may be different if comparing them with ``memcmp`` but -still reference the same object. As a consequence, you may close a handle only -once, i.e., you cannot call :c:func:`HPy_Close` twice on the same ``HPy`` -handle, even if returned from ``HPy_Dup``. For examples, see also sections -:ref:`api:handles` and :ref:`api:handles vs ``pyobject *``` - -Calling functions ``PyObject_Call`` and ``PyObject_CallObject`` ---------------------------------------------------------------- - -Both ``PyObject_Call`` and ``PyObject_CallObject`` are replaced by -``HPy_CallTupleDict(callable, args, kwargs)`` in which either or both of -``args`` and ``kwargs`` may be null handles. - -``PyObject_Call(callable, args, kwargs)`` becomes:: - - HPy result = HPy_CallTupleDict(ctx, callable, args, kwargs); - -``PyObject_CallObject(callable, args)`` becomes:: - - HPy result = HPy_CallTupleDict(ctx, callable, args, HPy_NULL); - -If ``args`` is not a handle to a tuple or ``kwargs`` is not a handle to a -dictionary, ``HPy_CallTupleDict`` will return ``HPy_NULL`` and raise a -``TypeError``. This is different to ``PyObject_Call`` and -``PyObject_CallObject`` which may segfault instead. - -Calling Protocol ----------------- - -Both the *tp_call* and *vectorcall* calling protocols are replaced by HPy's -calling protocol. This is done by defining slot ``HPy_tp_call``. HPy uses only -one calling convention which is similar to the vectorcall calling convention. -In the following example, we implement a call function for a simple Euclidean -vector type. The function computes the dot product of two vectors. - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN EuclideanVectorObject - :end-before: // END EuclideanVectorObject - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN HPy_tp_call - :end-before: // END HPy_tp_call - -Positional and keyword arguments are passed as C array ``args``. Argument -``nargs`` specifies the number of positional arguments. Argument ``kwnames`` is -a tuple containing the names of the keyword arguments. The keyword argument -values are appended to positional arguments and start at ``args[nargs]`` (if -there are any). - -In the above example, function ``call_impl`` will be used by default to call all -instances of the corresponding type. It is also possible to install (maybe -specialized) call function implementations per instances by using function -:c:func:`HPy_SetCallFunction`. This needs to be done in the constructor of an -object. For example: - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN HPy_SetCallFunction - :end-before: // END HPy_SetCallFunction - -Limitations -~~~~~~~~~~~ - - 1. It is not possible to use slot ``HPy_tp_call`` for a *var object* (i.e. if - :c:member:`HPyType_Spec.itemsize` is greater ``0``). Reason: HPy installs - a hidden field in the object's data to store the call function pointer - which is appended to everything else. In case of ``EuclideanVectorObject``, - a field is implicitly appended after member ``y``. This is not possible for - var objects because the variable part will also start after the fixed - members. - - 2. It is also not possible to use slot ``HPy_tp_call`` with a legacy type that - inherits the basicsize (i.e. if :c:member:`HPyType_Spec.basicsize` is - ``0``) for the same reason as above. - -To overcome these limitations, it is still possible to manually embed a field -for the call function pointer in a type's C struct and tell HPy where this field -is. In this case, it is always necessary to set the call function pointer using -:c:func:`HPy_SetCallFunction` in the object's constructor. This procedure is -less convenient than just using slot ``HPy_tp_cal`` but still not hard to use. -Consider following example. We define a struct ``FooObject`` and declare field -``HPyCallFunction call_func`` which will be used to store the call function's -pointer. We need to register the offset of that field with member -``__vectorcalloffset__`` and in the constructor ``Foo_new``, we assign the call -function ``Foo_call_func``. - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN FooObject - :end-before: // END FooObject - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN vectorcalloffset - :end-before: // END vectorcalloffset - -.. note:: - - In contrast to CPython's vectorcall protocol, ``nargs`` will never have flag - ``PY_VECTORCALL_ARGUMENTS_OFFSET`` set. It will **only** be the positional - argument count. - -.. _call-migration: - -Incremental Migration to HPy's Calling Protocol -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In order to support incremental migration, HPy provides helper function -:c:func:`HPyHelpers_PackArgsAndKeywords` that converts from HPy's calling -convention to CPython's *tp_call* calling convention. Consider following -example: - -.. literalinclude:: examples/snippets/hpycall.c - :start-after: // BEGIN pack_args - :end-before: // END pack_args - -In this example, ``args``, ``nargs``, and ``kwnames`` are used to create a tuple -of positional arguments ``args_tuple`` and a keyword arguments dictionary -``kwd``. - -PyModule_AddObject ------------------- - -``PyModule_AddObject`` is replaced with a regular :c:func:`HPy_SetAttr_s`. There -is no ``HPyModule_AddObject`` function because it has an unusual refcount -behavior (stealing a reference but only when it returns ``0``). - - -.. _dealloc: - -Deallocator slot ``Py_tp_dealloc`` ----------------------------------- - -``Py_tp_dealloc`` essentially becomes ``HPy_tp_destroy``. The name intentionally -differs because there are major differences: while the slot function of -``Py_tp_dealloc`` receives the full object (which makes it possible to resurrect -it) and while there are no restrictions on what you may call in the C API -deallocator, you must not do that in HPy's deallocator. - -The two major restrictions apply to the slot function of ``HPy_tp_destroy``: - -1. The function must be **thread-safe**. -2. The function **must not** call into the interpreter. - -The idea is, that ``HPy_tp_destroy`` just releases native resources (e.g. by -using C lib's ``free`` function). Therefore, it only receives a pointer to the -object's native data (and not a handle to the object) and it does not receive an -``HPyContext`` pointer argument. - -For the time being, HPy will support the ``HPy_tp_finalize`` slot where those -tight restrictions do not apply at the (significant) cost of performance. - -Special slots ``Py_tp_methods``, ``Py_tp_members``, and ``Py_tp_getset`` ------------------------------------------------------------------------- - -There is no direct replacement for C API slots ``Py_tp_methods``, -``Py_tp_members``, and ``Py_tp_getset`` because they are no longer needed. -Methods, members, and get/set descriptors are specified *flatly* together with -the other slots, using the standard mechanisms of :c:macro:`HPyDef_METH`, -:c:macro:`HPyDef_MEMBER`, and :c:macro:`HPyDef_GETSET`. The resulting ``HPyDef`` -structures are then accumulated in :c:member:`HPyType_Spec.defines`. - -Creating lists and tuples -------------------------- - -The C API way of creating lists and tuples is to create an empty list or tuple -object using ``PyList_New(n)`` or ``PyTuple_New(n)``, respectively, and then to -fill the empty object using ``PyList_SetItem / PyList_SET_ITEM`` or -``PyTuple_SetItem / PyTuple_SET_ITEM``, respectively. - -This is in particular problematic for tuples because they are actually -immutable. HPy goes a different way and provides a dedicated *builder* API to -avoid the (temporary) inconsistent state during object initialization. - -Long story short, doing the same in HPy with builders is still very simple and -straight forward. Following an example for creating a list: - -.. code-block:: c - - PyObject *list = PyList_New(5); - if (list == NULL) - return NULL; /* error */ - PyList_SET_ITEM(list, 0, item0); - PyList_SET_ITEM(list, 1, item0); - ... - PyList_SET_ITEM(list, 4, item0); - /* now 'list' is ready to use */ - -becomes - -.. code-block:: c - - HPyListBuilder builder = HPyListBuilder_New(ctx, 5); - HPyListBuilder_Set(ctx, builder, 0, h_item0); - HPyListBuilder_Set(ctx, builder, 1, h_item1); - ... - HPyListBuilder_Set(ctx, builder, 4, h_item4); - HPy h_list = HPyListBuilder_Build(ctx, builder); - if (HPy_IsNull(h_list)) - return HPy_NULL; /* error */ - -.. note:: In contrast to ``PyList_SetItem``, ``PyList_SET_ITEM``, - ``PyTuple_SetItem``, and ``PyTuple_SET_ITEM``, the builder functions - :c:func:`HPyListBuilder_Set` and :c:func:`HPyTupleBuilder_Set` are **NOT** - stealing references. It is necessary to close the passed item handles (e.g. - ``h_item0`` in the above example) if they are no longer needed. - -If an error occurs during building the list or tuple, it is necessary to call -:c:func:`HPyListBuilder_Cancel` or :c:func:`HPyTupleBuilder_Cancel`, -respectively, to avoid memory leaks. - -For details, see the API reference documentation -:doc:`api-reference/hpy-sequence`. - -Buffers -------- - -The buffer API in HPy is implemented using the ``HPy_buffer`` struct, which looks -very similar to ``Py_buffer`` (refer to the `CPython documentation -`_ for the -meaning of the fields):: - - typedef struct { - void *buf; - HPy obj; - HPy_ssize_t len; - HPy_ssize_t itemsize; - int readonly; - int ndim; - char *format; - HPy_ssize_t *shape; - HPy_ssize_t *strides; - HPy_ssize_t *suboffsets; - void *internal; - } HPy_buffer; - -Buffer slots for HPy types are specified using slots ``HPy_bf_getbuffer`` and -``HPy_bf_releasebuffer`` on all supported Python versions, even though the -matching PyType_Spec slots, ``Py_bf_getbuffer`` and ``Py_bf_releasebuffer``, are -only available starting from CPython 3.9. - -Multi-phase Module Initialization ---------------------------------- - -HPy supports only multi-phase module initialization (PEP 451). This means that -the module object is typically created by interpreter from the ``HPyModuleDef`` -specification and there is no "init" function. However, the module can define -one or more ``HPy_mod_exec`` slots, which will be executed just after the module -object is created. Inside the code of those slots, one can usually perform the same -initialization as before. - -Example of legacy single phase module initialization that uses Python/C API: - -.. literalinclude:: examples/snippets/legacyinit.c - :start-after: // BEGIN - :end-before: // END - -The same code structure ported to HPy and multi-phase module initialization: - -.. literalinclude:: examples/snippets/hpyinit.c - :start-after: // BEGIN - :end-before: // END diff --git a/graalpython/hpy/docs/quickstart.rst b/graalpython/hpy/docs/quickstart.rst deleted file mode 100644 index f57063cfa8..0000000000 --- a/graalpython/hpy/docs/quickstart.rst +++ /dev/null @@ -1,55 +0,0 @@ -HPy Quickstart -============== - -This section shows how to quickly get started with HPy by creating -a simple HPy extension from scratch. - -Install latest HPy release: - -.. code-block:: console - - python3 -m pip install hpy - -Alternatively, you can also install HPy from the development repository: - -.. code-block:: console - - python3 -m pip install git+https://github.com/hpyproject/hpy.git#egg=hpy - -Create a new directory for the new HPy extension. Location and name of the directory -do not matter. Add the following two files: - -.. literalinclude:: examples/quickstart/quickstart.c - -.. literalinclude:: examples/quickstart/setup.py - :language: python - -Build the extension: - -.. code-block:: console - - python3 setup.py --hpy-abi=universal develop - -Try it out -- start Python console in the same directory and type: - -.. literalinclude:: examples/tests.py - :start-after: test_quickstart - :end-before: # END: test_quickstart - -Notice the shared library that was created by running ``setup.py``: - -.. code-block:: console - - > ls *.so - quickstart.hpy0.so - -It does not have Python version encoded in it. If you happen to have -GraalPy or PyPy installation that supports given HPy version, you can -try running the same extension on it. For example, start -``$GRAALVM_HOME/bin/graalpy`` in the same directory and type the same -Python code: the extension should load and work just fine. - -Where to go next? - - - :ref:`Simple documented HPy extension example` - - :doc:`Tutorial: porting Python/C API extension to HPy` diff --git a/graalpython/hpy/docs/requirements.txt b/graalpython/hpy/docs/requirements.txt deleted file mode 100644 index 4d5b85f2fa..0000000000 --- a/graalpython/hpy/docs/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Requirements for building the documentation -Jinja2==3.1.6 -sphinx==5.0.2 -sphinx-rtd-theme==2.0.0 -sphinx-autobuild==2021.3.14 -sphinx-c-autodoc==1.3.0 -clang==17.0.6 -docutils==0.18.1 # Latest release supported by Sphinx 5.0.2 diff --git a/graalpython/hpy/docs/trace-mode.rst b/graalpython/hpy/docs/trace-mode.rst deleted file mode 100644 index b8763b4220..0000000000 --- a/graalpython/hpy/docs/trace-mode.rst +++ /dev/null @@ -1,64 +0,0 @@ -Trace Mode -========== - -HPy's trace mode allows you to analyze the usage of the HPy API. The two -fundamental metrics are ``call count`` and ``duration``. As the name already -suggests, ``call count`` tells you how often a certain HPy API function was called -and ``duration`` uses a monotonic clock to measure how much (accumulated) time was -spent in a certain HPy API function. It is further possible to register custom -*on-enter* and *on-exit* Python functions. - -As with the debug mode, the trace mode can be activated at *import time*, so no -recompilation is required. - - -Activating Trace Mode ---------------------- - -Similar to how the -:ref:`debug mode is activated `, use -environment variable ``HPY``. If ``HPY=trace``, then all HPy modules are loaded -with the trace context. Alternatively, it is also possible to specify the mode -per module like this: ``HPY=modA:trace,modB:trace``. -Environment variable ``HPY_LOG`` also works. - - -Using Trace Mode ----------------- - -The trace mode can be accessed via the shipped module ``hpy.trace``. It provides -following functions: - -* ``get_call_counts()`` returns a dict. The HPy API function names are used as - keys and the corresponding call count is the value. -* ``get_durations()`` also returns a dict similar to ``get_call_counts`` but - the value is the accumulated time spent in the corresponding HPy API - function (in nanoseconds). Note, the used clock does not necessarily have a - nanosecond resolution which means that the least significant digits may not be - accurate. -* ``set_trace_functions(on_enter=None, on_exit=None)`` allows the user to - register custom trace functions. The function provided for ``on_enter`` and - ``on_exit`` functions will be executed before and after and HPy API function - is and was executed, respectively. Passing ``None`` to any of the two - arguments or omitting one will clear the corresponding function. -* ``get_frequency()`` returns the resolution of the used clock to measure the - time in Hertz. For example, a value of ``10000000`` corresponds to - ``10 MHz``. In that case, the two least significant digits of the durations - are inaccurate. - - -Example -------- - -Following HPy function uses ``HPy_Add``: - -.. literalinclude:: examples/snippets/snippets.c - :start-after: // BEGIN: add - :end-before: // END: add - -When this script is executed in trace mode: - -.. literalinclude:: examples/trace-example.py - :language: python - -The output is ``get_call_counts()["ctx_Add"] == 1``. diff --git a/graalpython/hpy/docs/xxx-unsorted-notes.txt b/graalpython/hpy/docs/xxx-unsorted-notes.txt deleted file mode 100644 index 159b6e315c..0000000000 --- a/graalpython/hpy/docs/xxx-unsorted-notes.txt +++ /dev/null @@ -1,91 +0,0 @@ -Goal: better C API for CPython and 1st-class citizen on PyPy - -- everything should be opaque by default - - - should we have an API to "query" if an object supports a certain low-level layout? E.g list-of-integer - - - should we have an API to e.g. ask "give me the nth C-level long in the - list? And then rely on the compiler to turn this into an efficient loop: - long PyObject_GetLongItem(PyHandle h, long index) ? - - -- we need PyObject_GetItem(handle) and PyObject_GetItem(int_index) - -- PyHandle PyObject_GetMappingProtocol(PyHandle o): ask a python object if it - has the "mapping" interface; then you can close it when you are done with it - and e.g. PyPy can release when it's no longer needed - -- should we write a tool to convert from the old API to the new API? - -- how we do deploy it? Should we have a single PyHandle.h file which is enough - to include? Or do like numpy.get_include_dirs()? - - - we need to do what cffi does (and ship our version on PyPy) - - - cython might need/want to ship its own vendored version of PyHandle - -- we need a versioning system which is possible to query at runtime? (to check - that it was compiled with the "correct/expected" PyHandle version - -- what to do with existing code which actively check whether the refcount is 1? E.g. PyString_Resize? - -- fast c-to-c calls: should we use argument clinic or something similar? - - - -Protocol sketch ----------------- - -HPySequence_long x = HPy_AsSequence_long(obj); /* it is possible to fail and you should be ready to handle the fallback */ -int len = HPy_Sequence_Len_long(x, obj); -for(int i=0; i sequence index access -* comparisons (<, <=, ==, !=, >=, >) - * rich comparisons - * boolean comparisons (0/1) -* call (call/vectorcall/method/special-method) - * e.g. PyCall_SpecialMethodOneArg(obj, __add__, arg) -> call specific macro - * … -* context manager (enter/exit) - * -> call special method -* async (await/aiter/anext) - * -> call special method diff --git a/graalpython/hpy/gdb-py.test b/graalpython/hpy/gdb-py.test deleted file mode 100755 index 7412a06214..0000000000 --- a/graalpython/hpy/gdb-py.test +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -gdb --eval-command run --args python3 -m pytest -s "$@" diff --git a/graalpython/hpy/hpy/debug/__init__.py b/graalpython/hpy/hpy/debug/__init__.py deleted file mode 100644 index 71ece53923..0000000000 --- a/graalpython/hpy/hpy/debug/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from .leakdetector import HPyDebugError, HPyLeakError, LeakDetector - - -def set_handle_stack_trace_limit(limit): - from hpy.universal import _debug - _debug.set_handle_stack_trace_limit(limit) - - -def disable_handle_stack_traces(): - from hpy.universal import _debug - _debug.set_handle_stack_trace_limit(None) diff --git a/graalpython/hpy/hpy/debug/leakdetector.py b/graalpython/hpy/hpy/debug/leakdetector.py deleted file mode 100644 index 56a68d344c..0000000000 --- a/graalpython/hpy/hpy/debug/leakdetector.py +++ /dev/null @@ -1,43 +0,0 @@ -from hpy.universal import _debug - -class HPyDebugError(Exception): - pass - -class HPyLeakError(HPyDebugError): - def __init__(self, leaks): - super().__init__() - self.leaks = leaks - - def __str__(self): - lines = [] - n = len(self.leaks) - s = 's' if n != 1 else '' - lines.append(f'{n} unclosed handle{s}:') - for dh in self.leaks: - lines.append(' %r' % dh) - return '\n'.join(lines) - - -class LeakDetector: - - def __init__(self): - self.generation = None - - def start(self): - if self.generation is not None: - raise ValueError('LeakDetector already started') - self.generation = _debug.new_generation() - - def stop(self): - if self.generation is None: - raise ValueError('LeakDetector not started yet') - leaks = _debug.get_open_handles(self.generation) - if leaks: - raise HPyLeakError(leaks) - - def __enter__(self): - self.start() - return self - - def __exit__(self, etype, evalue, tb): - self.stop() diff --git a/graalpython/hpy/hpy/debug/pytest.py b/graalpython/hpy/hpy/debug/pytest.py deleted file mode 100644 index 9a33c51343..0000000000 --- a/graalpython/hpy/hpy/debug/pytest.py +++ /dev/null @@ -1,31 +0,0 @@ -# hpy.debug / pytest integration - -import pytest -from .leakdetector import LeakDetector - -# For now "hpy_debug" just does leak detection, but in the future it might -# grows extra features: that's why it's called generically "hpy_debug" instead -# of "detect_leaks". - -# NOTE: the fixture itself is currently untested :(. It turns out that testing -# that the fixture raises during the teardown is complicated and probably -# requires to write a full-fledged plugin. We might want to turn this into a -# real plugin in the future, but for now I think this is enough. - -# pypy still uses a very ancient version of pytest, 2.9.2: pytest<3.x needs to -# use @yield_fixture, which is deprecated in newer version of pytest (where -# you can just use @fixture) -if pytest.__version__ < '3': - fixture = pytest.yield_fixture -else: - fixture = pytest.fixture - -@fixture -def hpy_debug(request): - """ - pytest fixture which makes it possible to control hpy.debug from within a test. - - In particular, it automatically check that the test doesn't leak. - """ - with LeakDetector() as ld: - yield ld diff --git a/graalpython/hpy/hpy/debug/src/_debugmod.c b/graalpython/hpy/hpy/debug/src/_debugmod.c deleted file mode 100644 index 2bd71f3262..0000000000 --- a/graalpython/hpy/hpy/debug/src/_debugmod.c +++ /dev/null @@ -1,432 +0,0 @@ -// Python-level interface for the _debug module. Written in HPy itself, the -// idea is that it should be reusable by other implementations - -// NOTE: hpy.debug._debug is loaded using the UNIVERSAL ctx. To make it -// clearer, we will use "uctx" and "dctx" to distinguish them. - -#include "hpy.h" -#include "debug_internal.h" - -static UHPy new_DebugHandleObj(HPyContext *uctx, UHPy u_DebugHandleType, - DebugHandle *handle); - -HPY_MOD_EMBEDDABLE(_debug) - -HPyDef_METH(new_generation, "new_generation", HPyFunc_NOARGS) -static UHPy new_generation_impl(HPyContext *uctx, UHPy self) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - info->current_generation++; - return HPyLong_FromLong(uctx, info->current_generation); -} - -static UHPy build_list_of_handles(HPyContext *uctx, UHPy u_self, DHQueue *q, - long gen) -{ - UHPy u_DebugHandleType = HPy_NULL; - UHPy u_result = HPy_NULL; - UHPy u_item = HPy_NULL; - - u_DebugHandleType = HPy_GetAttr_s(uctx, u_self, "DebugHandle"); - if (HPy_IsNull(u_DebugHandleType)) - goto error; - - u_result = HPyList_New(uctx, 0); - if (HPy_IsNull(u_result)) - goto error; - - DHQueueNode *node = q->head; - while(node != NULL) { - DebugHandle *dh = (DebugHandle *)node; - if (dh->generation >= gen) { - UHPy u_item = new_DebugHandleObj(uctx, u_DebugHandleType, dh); - if (HPy_IsNull(u_item)) - goto error; - if (HPyList_Append(uctx, u_result, u_item) == -1) - goto error; - HPy_Close(uctx, u_item); - } - node = node->next; - } - - HPy_Close(uctx, u_DebugHandleType); - return u_result; - - error: - HPy_Close(uctx, u_DebugHandleType); - HPy_Close(uctx, u_result); - HPy_Close(uctx, u_item); - return HPy_NULL; -} - - -HPyDef_METH(get_open_handles, "get_open_handles", HPyFunc_O, .doc= - "Return a list containing all the open handles whose generation is >= " - "of the given arg") -static UHPy get_open_handles_impl(HPyContext *uctx, UHPy u_self, UHPy u_gen) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - - long gen = HPyLong_AsLong(uctx, u_gen); - if (HPyErr_Occurred(uctx)) - return HPy_NULL; - - return build_list_of_handles(uctx, u_self, &info->open_handles, gen); -} - -HPyDef_METH(get_closed_handles, "get_closed_handles", HPyFunc_VARARGS, - .doc="Return a list of all the closed handle in the cache") -static UHPy get_closed_handles_impl(HPyContext *uctx, UHPy u_self, const HPy *args, size_t nargs) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - long gen = 0; - if (nargs > 0) { - if (nargs != 1) { - HPyErr_SetString(uctx, uctx->h_TypeError, - "get_closed_handles expects no arguments or exactly one argument"); - return HPy_NULL; - } - gen = HPyLong_AsLong(uctx, args[0]); - if (HPyErr_Occurred(uctx)) - return HPy_NULL; - } - return build_list_of_handles(uctx, u_self, &info->closed_handles, gen); -} - -HPyDef_METH(get_closed_handles_queue_max_size, "get_closed_handles_queue_max_size", HPyFunc_NOARGS, - .doc="Return the maximum size of the closed handles queue") -static UHPy get_closed_handles_queue_max_size_impl(HPyContext *uctx, UHPy u_self) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - return HPyLong_FromSsize_t(uctx, info->closed_handles_queue_max_size); -} - -HPyDef_METH(set_closed_handles_queue_max_size, "set_closed_handles_queue_max_size", HPyFunc_O, - .doc="Set the maximum size of the closed handles queue") -static UHPy set_closed_handles_queue_max_size_impl(HPyContext *uctx, UHPy u_self, UHPy u_size) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - HPy_ssize_t size = HPyLong_AsSize_t(uctx, u_size); - if (HPyErr_Occurred(uctx)) - return HPy_NULL; - info->closed_handles_queue_max_size = size; - return HPy_Dup(uctx, uctx->h_None); -} - -HPyDef_METH(get_protected_raw_data_max_size, "get_protected_raw_data_max_size", HPyFunc_NOARGS, - .doc="Return the maximum size of the retained raw memory associated with closed handles") -static UHPy get_protected_raw_data_max_size_impl(HPyContext *uctx, UHPy u_self) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - return HPyLong_FromSsize_t(uctx, info->protected_raw_data_max_size); -} - -HPyDef_METH(set_protected_raw_data_max_size, "set_protected_raw_data_max_size", HPyFunc_O, - .doc="Set the maximum size of the retained raw memory associated with closed handles") -static UHPy set_protected_raw_data_max_size_impl(HPyContext *uctx, UHPy u_self, UHPy u_size) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - HPy_ssize_t size = HPyLong_AsSize_t(uctx, u_size); - if (HPyErr_Occurred(uctx)) - return HPy_NULL; - info->protected_raw_data_max_size = size; - return HPy_Dup(uctx, uctx->h_None); -} - -HPyDef_METH(set_on_invalid_handle, "set_on_invalid_handle", HPyFunc_O, - .doc="Set the function to call when we detect the usage of an invalid handle") -static UHPy set_on_invalid_handle_impl(HPyContext *uctx, UHPy u_self, UHPy u_arg) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - if (HPy_Is(uctx, u_arg, uctx->h_None)) { - info->uh_on_invalid_handle = HPy_NULL; - } else if (!HPyCallable_Check(uctx, u_arg)) { - HPyErr_SetString(uctx, uctx->h_TypeError, "Expected a callable object"); - return HPy_NULL; - } else { - info->uh_on_invalid_handle = HPy_Dup(uctx, u_arg); - } - return HPy_Dup(uctx, uctx->h_None); -} - -HPyDef_METH(set_on_invalid_builder_handle, "set_on_invalid_builder_handle", HPyFunc_O, - .doc="Set the function to call when we detect the usage of an invalid builder handle") -static UHPy set_on_invalid_builder_handle_impl(HPyContext *uctx, UHPy u_self, UHPy u_arg) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - if (HPy_Is(uctx, u_arg, uctx->h_None)) { - info->uh_on_invalid_builder_handle = HPy_NULL; - } else if (!HPyCallable_Check(uctx, u_arg)) { - HPyErr_SetString(uctx, uctx->h_TypeError, "Expected a callable object"); - return HPy_NULL; - } else { - info->uh_on_invalid_builder_handle = HPy_Dup(uctx, u_arg); - } - return HPy_Dup(uctx, uctx->h_None); -} - -HPyDef_METH(set_handle_stack_trace_limit, "set_handle_stack_trace_limit", HPyFunc_O, - .doc="Set the limit to captured HPy handles allocations stack traces. " - "None means do not capture the stack traces.") -static UHPy set_handle_stack_trace_limit_impl(HPyContext *uctx, UHPy u_self, UHPy u_arg) -{ - HPyContext *dctx = hpy_debug_get_ctx(uctx); - HPyDebugInfo *info = get_info(dctx); - if (HPy_Is(uctx, u_arg, uctx->h_None)) { - info->handle_alloc_stacktrace_limit = 0; - } else { - assert(!HPyErr_Occurred(uctx)); - HPy_ssize_t newlimit = HPyLong_AsSsize_t(uctx, u_arg); - if (newlimit == -1 && HPyErr_Occurred(uctx)) { - return HPy_NULL; - } - info->handle_alloc_stacktrace_limit = newlimit; - } - return HPy_Dup(uctx, uctx->h_None); -} - - -/* ~~~~~~ DebugHandleType and DebugHandleObject ~~~~~~~~ - - This is the applevel view of a DebugHandle/DHPy. - - Note that there are two different ways to expose DebugHandle to applevel: - - 1. make DebugHandle itself a Python object: this is simple but means that - you have to pay the PyObject_HEAD overhead (16 bytes) for all of them - - 2. make DebugHandle a plain C struct, and expose them through a - Python-level wrapper. - - We choose to implement solution 2 because we expect to have many - DebugHandle around, but to expose only few of them to applevel, when you - call get_open_handles. This way, we save 16 bytes per DebugHandle. - - This means that you can have different DebugHandleObjects wrapping the same - DebugHandle. To make it easier to compare them, they expose the .id - attribute, which is the address of the wrapped DebugHandle. Also, - DebugHandleObjects compare equal if their .id is equal. -*/ - -typedef struct { - DebugHandle *handle; -} DebugHandleObject; - -HPyType_HELPERS(DebugHandleObject) - -HPyDef_GET(DebugHandle_obj, "obj", .doc="The object which the handle points to") -static UHPy DebugHandle_obj_get(HPyContext *uctx, UHPy self, void *closure) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - return HPy_Dup(uctx, dh->handle->uh); -} - -HPyDef_GET(DebugHandle_id, "id", - .doc="A numeric identifier representing the underlying universal handle") -static UHPy DebugHandle_id_get(HPyContext *uctx, UHPy self, void *closure) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - return HPyLong_FromSsize_t(uctx, (HPy_ssize_t)dh->handle); -} - -HPyDef_GET(DebugHandle_is_closed, "is_closed", - .doc="Self-explanatory") -static UHPy DebugHandle_is_closed_get(HPyContext *uctx, UHPy self, void *closure) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - return HPyBool_FromBool(uctx, dh->handle->is_closed); -} - -HPyDef_GET(DebugHandle_raw_data_size, "raw_data_size", -.doc="Size of retained raw memory. FOR TESTS ONLY.") -static UHPy DebugHandle_raw_data_size_get(HPyContext *uctx, UHPy self, void *closure) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - if (dh->handle->associated_data) { - return HPyLong_FromSsize_t(uctx, dh->handle->associated_data_size); - } else { - return HPyLong_FromLong(uctx, -1); - } -} - -HPyDef_SLOT(DebugHandle_cmp, HPy_tp_richcompare) -static UHPy DebugHandle_cmp_impl(HPyContext *uctx, UHPy self, UHPy o, HPy_RichCmpOp op) -{ - UHPy T = HPy_Type(uctx, self); - if (!HPy_TypeCheck(uctx, o, T)) - return HPy_Dup(uctx, uctx->h_NotImplemented); - DebugHandleObject *dh_self = DebugHandleObject_AsStruct(uctx, self); - DebugHandleObject *dh_o = DebugHandleObject_AsStruct(uctx, o); - - switch(op) { - case HPy_EQ: - return HPyBool_FromBool(uctx, dh_self->handle == dh_o->handle); - case HPy_NE: - return HPyBool_FromBool(uctx, dh_self->handle != dh_o->handle); - default: - return HPy_Dup(uctx, uctx->h_NotImplemented); - } -} - -HPyDef_SLOT(DebugHandle_repr, HPy_tp_repr) -static UHPy DebugHandle_repr_impl(HPyContext *uctx, UHPy self) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - UHPy uh_fmt = HPy_NULL; - UHPy uh_id = HPy_NULL; - UHPy uh_args = HPy_NULL; - UHPy uh_result = HPy_NULL; - UHPy h_trace_header = HPy_NULL; - UHPy h_trace = HPy_NULL; - - const char *fmt = NULL; - if (dh->handle->is_closed) - fmt = "\n%s%s"; - else - fmt = "\n%s%s"; - - // XXX: switch to HPyUnicode_FromFormat when we have it - uh_fmt = HPyUnicode_FromString(uctx, fmt); - if (HPy_IsNull(uh_fmt)) - goto exit; - - uh_id = HPyLong_FromSsize_t(uctx, (HPy_ssize_t)dh->handle); - if (HPy_IsNull(uh_id)) - goto exit; - - const char *trace_header; - const char *trace; - if (dh->handle->allocation_stacktrace) { - trace_header = "Allocation stacktrace:\n"; - trace = dh->handle->allocation_stacktrace; - } else { - trace_header = "To get the stack trace of where it was allocated use:\nhpy.debug."; - trace = set_handle_stack_trace_limit.meth.name; - } - h_trace_header = HPyUnicode_FromString(uctx, trace_header); - h_trace = HPyUnicode_FromString(uctx, trace); - - if (dh->handle->is_closed) - uh_args = HPyTuple_FromArray(uctx, (UHPy[]){uh_id, - h_trace_header, h_trace}, 3); - else - uh_args = HPyTuple_FromArray(uctx, (UHPy[]){uh_id, dh->handle->uh, - h_trace_header, h_trace}, 4); - if (HPy_IsNull(uh_args)) - goto exit; - - uh_result = HPy_Remainder(uctx, uh_fmt, uh_args); - - exit: - HPy_Close(uctx, uh_fmt); - HPy_Close(uctx, uh_id); - HPy_Close(uctx, uh_args); - HPy_Close(uctx, h_trace); - HPy_Close(uctx, h_trace_header); - return uh_result; -} - - -HPyDef_METH(DebugHandle__force_close, "_force_close", - HPyFunc_NOARGS, .doc="Close the underlying handle. FOR TESTS ONLY.") -static UHPy DebugHandle__force_close_impl(HPyContext *uctx, UHPy self) -{ - DebugHandleObject *dh = DebugHandleObject_AsStruct(uctx, self); - HPyContext *dctx = hpy_debug_get_ctx(uctx); - if (dctx == NULL) - return HPy_NULL; - HPy_Close(dctx, as_DHPy(dh->handle)); - return HPy_Dup(uctx, uctx->h_None); -} - -static HPyDef *DebugHandleType_defs[] = { - &DebugHandle_obj, - &DebugHandle_id, - &DebugHandle_is_closed, - &DebugHandle_raw_data_size, - &DebugHandle_cmp, - &DebugHandle_repr, - &DebugHandle__force_close, - NULL -}; - -static HPyType_Spec DebugHandleType_spec = { - .name = "hpy.debug._debug.DebugHandle", - .basicsize = sizeof(DebugHandleObject), - .flags = HPy_TPFLAGS_DEFAULT, - .defines = DebugHandleType_defs, -}; - - -static UHPy new_DebugHandleObj(HPyContext *uctx, UHPy u_DebugHandleType, - DebugHandle *handle) -{ - DebugHandleObject *dhobj; - UHPy u_result = HPy_New(uctx, u_DebugHandleType, &dhobj); - dhobj->handle = handle; - return u_result; -} - - -/* ~~~~~~ definition of the module hpy.debug._debug ~~~~~~~ */ - -HPyDef_SLOT(module_exec, HPy_mod_exec) -static int module_exec_impl(HPyContext *uctx, HPy m) -{ - UHPy h_DebugHandleType = HPyType_FromSpec(uctx, &DebugHandleType_spec, NULL); - if (HPy_IsNull(h_DebugHandleType)) - return -1; - HPy_SetAttr_s(uctx, m, "DebugHandle", h_DebugHandleType); - HPy_Close(uctx, h_DebugHandleType); - return 0; -} - -static HPyDef *module_defines[] = { - &new_generation, - &get_open_handles, - &get_closed_handles, - &get_closed_handles_queue_max_size, - &set_closed_handles_queue_max_size, - &get_protected_raw_data_max_size, - &set_protected_raw_data_max_size, - &set_on_invalid_handle, - &set_on_invalid_builder_handle, - &set_handle_stack_trace_limit, - &module_exec, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "HPy debug mode", - .size = 0, - .defines = module_defines -}; - -HPy_MODINIT(_debug, moduledef) diff --git a/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i deleted file mode 100644 index 0cd23a98aa..0000000000 --- a/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_call.i +++ /dev/null @@ -1,468 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.debug.autogen_debug_ctx_call_i - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - - case HPyFunc_NOARGS: { - HPyFunc_noargs f = (HPyFunc_noargs)func; - _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; - DHPy dh_self = _py2dh(dctx, a->self); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_self); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_self); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_O: { - HPyFunc_o f = (HPyFunc_o)func; - _HPyFunc_args_O *a = (_HPyFunc_args_O*)args; - DHPy dh_self = _py2dh(dctx, a->self); - DHPy dh_arg = _py2dh(dctx, a->arg); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_self, dh_arg); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_self); - DHPy_close_and_check(dctx, dh_arg); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_UNARYFUNC: { - HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; - _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0); - _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); - return; - } - case HPyFunc_BINARYFUNC: { - HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); - _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); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_TERNARYFUNC: { - HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)func; - _HPyFunc_args_TERNARYFUNC *a = (_HPyFunc_args_TERNARYFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - _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); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_INQUIRY: { - HPyFunc_inquiry f = (HPyFunc_inquiry)func; - _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - return; - } - case HPyFunc_LENFUNC: { - HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; - _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - return; - } - case HPyFunc_SSIZEARGFUNC: { - HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; - _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - _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); - return; - } - case HPyFunc_SSIZESSIZEARGFUNC: { - HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; - _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, a->arg1, a->arg2); - _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); - return; - } - case HPyFunc_SSIZEOBJARGPROC: { - HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg2); - return; - } - case HPyFunc_SSIZESSIZEOBJARGPROC: { - HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, a->arg1, a->arg2, dh_arg3); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg3); - return; - } - case HPyFunc_OBJOBJARGPROC: { - HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)func; - _HPyFunc_args_OBJOBJARGPROC *a = (_HPyFunc_args_OBJOBJARGPROC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - _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); - return; - } - case HPyFunc_FREEFUNC: { - HPyFunc_freefunc f = (HPyFunc_freefunc)func; - _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - return; - } - f(next_dctx, a->arg0); - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - _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); - return; - } - case HPyFunc_GETATTROFUNC: { - HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1); - _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); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_SETATTRFUNC: { - HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, a->arg1, dh_arg2); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg2); - return; - } - case HPyFunc_SETATTROFUNC: { - HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)func; - _HPyFunc_args_SETATTROFUNC *a = (_HPyFunc_args_SETATTROFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - _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); - return; - } - case HPyFunc_REPRFUNC: { - HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; - _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0); - _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); - return; - } - case HPyFunc_HASHFUNC: { - HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; - _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - return; - } - case HPyFunc_RICHCMPFUNC: { - HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); - _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); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_GETITERFUNC: { - HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; - _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0); - _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); - return; - } - case HPyFunc_ITERNEXTFUNC: { - HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; - _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0); - _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); - return; - } - case HPyFunc_DESCRGETFUNC: { - HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)func; - _HPyFunc_args_DESCRGETFUNC *a = (_HPyFunc_args_DESCRGETFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - _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); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_DESCRSETFUNC: { - HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)func; - _HPyFunc_args_DESCRSETFUNC *a = (_HPyFunc_args_DESCRSETFUNC*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - DHPy dh_arg1 = _py2dh(dctx, a->arg1); - DHPy dh_arg2 = _py2dh(dctx, a->arg2); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, dh_arg1, dh_arg2); - _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); - return; - } - case HPyFunc_GETTER: { - HPyFunc_getter f = (HPyFunc_getter)func; - _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - DHPy dh_result = f(next_dctx, dh_arg0, a->arg1); - _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); - return; - } - case HPyFunc_SETTER: { - HPyFunc_setter f = (HPyFunc_setter)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, dh_arg1, a->arg2); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return; - } - case HPyFunc_OBJOBJPROC: { - HPyFunc_objobjproc f = (HPyFunc_objobjproc)func; - _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 = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - a->result = f(next_dctx, dh_arg0, dh_arg1); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - DHPy_close_and_check(dctx, dh_arg1); - return; - } - case HPyFunc_DESTRUCTOR: { - HPyFunc_destructor f = (HPyFunc_destructor)func; - _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; - DHPy dh_arg0 = _py2dh(dctx, a->arg0); - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - return; - } - f(next_dctx, dh_arg0); - _switch_back_to_original_dctx(dctx, next_dctx); - DHPy_close_and_check(dctx, dh_arg0); - return; - } diff --git a/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h b/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h deleted file mode 100644 index c394c362ce..0000000000 --- a/graalpython/hpy/hpy/debug/src/autogen_debug_ctx_init.h +++ /dev/null @@ -1,478 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.debug.autogen_debug_ctx_init_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -DHPy debug_ctx_Dup(HPyContext *dctx, DHPy h); -void debug_ctx_Close(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Long_FromInt32_t(HPyContext *dctx, int32_t value); -DHPy debug_ctx_Long_FromUInt32_t(HPyContext *dctx, uint32_t value); -DHPy debug_ctx_Long_FromInt64_t(HPyContext *dctx, int64_t v); -DHPy debug_ctx_Long_FromUInt64_t(HPyContext *dctx, uint64_t v); -DHPy debug_ctx_Long_FromSize_t(HPyContext *dctx, size_t value); -DHPy debug_ctx_Long_FromSsize_t(HPyContext *dctx, HPy_ssize_t value); -int32_t debug_ctx_Long_AsInt32_t(HPyContext *dctx, DHPy h); -uint32_t debug_ctx_Long_AsUInt32_t(HPyContext *dctx, DHPy h); -uint32_t debug_ctx_Long_AsUInt32_tMask(HPyContext *dctx, DHPy h); -int64_t debug_ctx_Long_AsInt64_t(HPyContext *dctx, DHPy h); -uint64_t debug_ctx_Long_AsUInt64_t(HPyContext *dctx, DHPy h); -uint64_t debug_ctx_Long_AsUInt64_tMask(HPyContext *dctx, DHPy h); -size_t debug_ctx_Long_AsSize_t(HPyContext *dctx, DHPy h); -HPy_ssize_t debug_ctx_Long_AsSsize_t(HPyContext *dctx, DHPy h); -void *debug_ctx_Long_AsVoidPtr(HPyContext *dctx, DHPy h); -double debug_ctx_Long_AsDouble(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Float_FromDouble(HPyContext *dctx, double v); -double debug_ctx_Float_AsDouble(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Bool_FromBool(HPyContext *dctx, bool v); -HPy_ssize_t debug_ctx_Length(HPyContext *dctx, DHPy h); -int debug_ctx_Number_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Add(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Subtract(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Multiply(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_MatrixMultiply(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_FloorDivide(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_TrueDivide(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Remainder(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Divmod(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Power(HPyContext *dctx, DHPy h1, DHPy h2, DHPy h3); -DHPy debug_ctx_Negative(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Positive(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Absolute(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Invert(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Lshift(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Rshift(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_And(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Xor(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Or(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_Index(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Long(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_Float(HPyContext *dctx, DHPy h1); -DHPy debug_ctx_InPlaceAdd(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceSubtract(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceMultiply(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceMatrixMultiply(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceFloorDivide(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceTrueDivide(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceRemainder(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlacePower(HPyContext *dctx, DHPy h1, DHPy h2, DHPy h3); -DHPy debug_ctx_InPlaceLshift(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceRshift(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceAnd(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceXor(HPyContext *dctx, DHPy h1, DHPy h2); -DHPy debug_ctx_InPlaceOr(HPyContext *dctx, DHPy h1, DHPy h2); -int debug_ctx_Callable_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_CallTupleDict(HPyContext *dctx, DHPy callable, DHPy args, DHPy kw); -DHPy debug_ctx_Call(HPyContext *dctx, DHPy callable, const DHPy *args, size_t nargs, DHPy kwnames); -DHPy debug_ctx_CallMethod(HPyContext *dctx, DHPy name, const DHPy *args, size_t nargs, DHPy kwnames); -DHPy debug_ctx_GetIter(HPyContext *dctx, DHPy obj); -DHPy debug_ctx_Iter_Next(HPyContext *dctx, DHPy obj); -int debug_ctx_Iter_Check(HPyContext *dctx, DHPy obj); -void debug_ctx_FatalError(HPyContext *dctx, const char *message); -void debug_ctx_Err_SetString(HPyContext *dctx, DHPy h_type, const char *utf8_message); -void debug_ctx_Err_SetObject(HPyContext *dctx, DHPy h_type, DHPy h_value); -DHPy debug_ctx_Err_SetFromErrnoWithFilename(HPyContext *dctx, DHPy h_type, const char *filename_fsencoded); -void debug_ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *dctx, DHPy h_type, DHPy filename1, DHPy filename2); -int debug_ctx_Err_Occurred(HPyContext *dctx); -int debug_ctx_Err_ExceptionMatches(HPyContext *dctx, DHPy exc); -void debug_ctx_Err_NoMemory(HPyContext *dctx); -void debug_ctx_Err_Clear(HPyContext *dctx); -DHPy debug_ctx_Err_NewException(HPyContext *dctx, const char *utf8_name, DHPy base, DHPy dict); -DHPy debug_ctx_Err_NewExceptionWithDoc(HPyContext *dctx, const char *utf8_name, const char *utf8_doc, DHPy base, DHPy dict); -int debug_ctx_Err_WarnEx(HPyContext *dctx, DHPy category, const char *utf8_message, HPy_ssize_t stack_level); -void debug_ctx_Err_WriteUnraisable(HPyContext *dctx, DHPy obj); -int debug_ctx_IsTrue(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Type_FromSpec(HPyContext *dctx, HPyType_Spec *spec, HPyType_SpecParam *params); -DHPy debug_ctx_Type_GenericNew(HPyContext *dctx, DHPy type, const DHPy *args, HPy_ssize_t nargs, DHPy kw); -DHPy debug_ctx_GetAttr(HPyContext *dctx, DHPy obj, DHPy name); -DHPy debug_ctx_GetAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name); -int debug_ctx_HasAttr(HPyContext *dctx, DHPy obj, DHPy name); -int debug_ctx_HasAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name); -int debug_ctx_SetAttr(HPyContext *dctx, DHPy obj, DHPy name, DHPy value); -int debug_ctx_SetAttr_s(HPyContext *dctx, DHPy obj, const char *utf8_name, DHPy value); -DHPy debug_ctx_GetItem(HPyContext *dctx, DHPy obj, DHPy key); -DHPy debug_ctx_GetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx); -DHPy debug_ctx_GetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key); -DHPy debug_ctx_GetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end); -int debug_ctx_Contains(HPyContext *dctx, DHPy container, DHPy key); -int debug_ctx_SetItem(HPyContext *dctx, DHPy obj, DHPy key, DHPy value); -int debug_ctx_SetItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx, DHPy value); -int debug_ctx_SetItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key, DHPy value); -int debug_ctx_SetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end, DHPy value); -int debug_ctx_DelItem(HPyContext *dctx, DHPy obj, DHPy key); -int debug_ctx_DelItem_i(HPyContext *dctx, DHPy obj, HPy_ssize_t idx); -int debug_ctx_DelItem_s(HPyContext *dctx, DHPy obj, const char *utf8_key); -int debug_ctx_DelSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end); -DHPy debug_ctx_Type(HPyContext *dctx, DHPy obj); -int debug_ctx_TypeCheck(HPyContext *dctx, DHPy obj, DHPy type); -const char *debug_ctx_Type_GetName(HPyContext *dctx, DHPy type); -int debug_ctx_Type_IsSubtype(HPyContext *dctx, DHPy sub, DHPy type); -int debug_ctx_Is(HPyContext *dctx, DHPy obj, DHPy other); -void *debug_ctx_AsStruct_Object(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Legacy(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Type(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Long(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Float(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Unicode(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Tuple(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_List(HPyContext *dctx, DHPy h); -void *debug_ctx_AsStruct_Dict(HPyContext *dctx, DHPy h); -HPyType_BuiltinShape debug_ctx_Type_GetBuiltinShape(HPyContext *dctx, DHPy h_type); -DHPy debug_ctx_New(HPyContext *dctx, DHPy h_type, void **data); -DHPy debug_ctx_Repr(HPyContext *dctx, DHPy obj); -DHPy debug_ctx_Str(HPyContext *dctx, DHPy obj); -DHPy debug_ctx_ASCII(HPyContext *dctx, DHPy obj); -DHPy debug_ctx_Bytes(HPyContext *dctx, DHPy obj); -DHPy debug_ctx_RichCompare(HPyContext *dctx, DHPy v, DHPy w, int op); -int debug_ctx_RichCompareBool(HPyContext *dctx, DHPy v, DHPy w, int op); -HPy_hash_t debug_ctx_Hash(HPyContext *dctx, DHPy obj); -int debug_ctx_Bytes_Check(HPyContext *dctx, DHPy h); -HPy_ssize_t debug_ctx_Bytes_Size(HPyContext *dctx, DHPy h); -HPy_ssize_t debug_ctx_Bytes_GET_SIZE(HPyContext *dctx, DHPy h); -const char *debug_ctx_Bytes_AsString(HPyContext *dctx, DHPy h); -const char *debug_ctx_Bytes_AS_STRING(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Bytes_FromString(HPyContext *dctx, const char *bytes); -DHPy debug_ctx_Bytes_FromStringAndSize(HPyContext *dctx, const char *bytes, HPy_ssize_t len); -DHPy debug_ctx_Unicode_FromString(HPyContext *dctx, const char *utf8); -int debug_ctx_Unicode_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Unicode_AsASCIIString(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Unicode_AsLatin1String(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Unicode_AsUTF8String(HPyContext *dctx, DHPy h); -const char *debug_ctx_Unicode_AsUTF8AndSize(HPyContext *dctx, DHPy h, HPy_ssize_t *size); -DHPy debug_ctx_Unicode_FromWideChar(HPyContext *dctx, const wchar_t *w, HPy_ssize_t size); -DHPy debug_ctx_Unicode_DecodeFSDefault(HPyContext *dctx, const char *v); -DHPy debug_ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *dctx, const char *v, HPy_ssize_t size); -DHPy debug_ctx_Unicode_EncodeFSDefault(HPyContext *dctx, DHPy h); -HPy_UCS4 debug_ctx_Unicode_ReadChar(HPyContext *dctx, DHPy h, HPy_ssize_t index); -DHPy debug_ctx_Unicode_DecodeASCII(HPyContext *dctx, const char *ascii, HPy_ssize_t size, const char *errors); -DHPy debug_ctx_Unicode_DecodeLatin1(HPyContext *dctx, const char *latin1, HPy_ssize_t size, const char *errors); -DHPy debug_ctx_Unicode_FromEncodedObject(HPyContext *dctx, DHPy obj, const char *encoding, const char *errors); -DHPy debug_ctx_Unicode_Substring(HPyContext *dctx, DHPy str, HPy_ssize_t start, HPy_ssize_t end); -int debug_ctx_List_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_List_New(HPyContext *dctx, HPy_ssize_t len); -int debug_ctx_List_Append(HPyContext *dctx, DHPy h_list, DHPy h_item); -int debug_ctx_List_Insert(HPyContext *dctx, DHPy h_list, HPy_ssize_t index, DHPy h_item); -int debug_ctx_Dict_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Dict_New(HPyContext *dctx); -DHPy debug_ctx_Dict_Keys(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Dict_Copy(HPyContext *dctx, DHPy h); -int debug_ctx_Tuple_Check(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, const DHPy items[], HPy_ssize_t n); -DHPy debug_ctx_Slice_New(HPyContext *dctx, DHPy start, DHPy stop, DHPy step); -int debug_ctx_Slice_Unpack(HPyContext *dctx, DHPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); -DHPy debug_ctx_Import_ImportModule(HPyContext *dctx, const char *utf8_name); -DHPy debug_ctx_Capsule_New(HPyContext *dctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); -void *debug_ctx_Capsule_Get(HPyContext *dctx, DHPy capsule, _HPyCapsule_key key, const char *utf8_name); -int debug_ctx_Capsule_IsValid(HPyContext *dctx, DHPy capsule, const char *utf8_name); -int debug_ctx_Capsule_Set(HPyContext *dctx, DHPy capsule, _HPyCapsule_key key, void *value); -DHPy debug_ctx_FromPyObject(HPyContext *dctx, cpy_PyObject *obj); -cpy_PyObject *debug_ctx_AsPyObject(HPyContext *dctx, DHPy h); -void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, HPyFunc_Signature sig, HPyCFunction func, void *args); -HPyListBuilder debug_ctx_ListBuilder_New(HPyContext *dctx, HPy_ssize_t size); -void debug_ctx_ListBuilder_Set(HPyContext *dctx, HPyListBuilder builder, HPy_ssize_t index, DHPy h_item); -DHPy debug_ctx_ListBuilder_Build(HPyContext *dctx, HPyListBuilder builder); -void debug_ctx_ListBuilder_Cancel(HPyContext *dctx, HPyListBuilder builder); -HPyTupleBuilder debug_ctx_TupleBuilder_New(HPyContext *dctx, HPy_ssize_t size); -void debug_ctx_TupleBuilder_Set(HPyContext *dctx, HPyTupleBuilder builder, HPy_ssize_t index, DHPy h_item); -DHPy debug_ctx_TupleBuilder_Build(HPyContext *dctx, HPyTupleBuilder builder); -void debug_ctx_TupleBuilder_Cancel(HPyContext *dctx, HPyTupleBuilder builder); -HPyTracker debug_ctx_Tracker_New(HPyContext *dctx, HPy_ssize_t size); -int debug_ctx_Tracker_Add(HPyContext *dctx, HPyTracker ht, DHPy h); -void debug_ctx_Tracker_ForgetAll(HPyContext *dctx, HPyTracker ht); -void debug_ctx_Tracker_Close(HPyContext *dctx, HPyTracker ht); -void debug_ctx_Field_Store(HPyContext *dctx, DHPy target_object, HPyField *target_field, DHPy h); -DHPy debug_ctx_Field_Load(HPyContext *dctx, DHPy source_object, HPyField source_field); -void debug_ctx_ReenterPythonExecution(HPyContext *dctx, HPyThreadState state); -HPyThreadState debug_ctx_LeavePythonExecution(HPyContext *dctx); -void debug_ctx_Global_Store(HPyContext *dctx, HPyGlobal *global, DHPy h); -DHPy debug_ctx_Global_Load(HPyContext *dctx, HPyGlobal global); -void debug_ctx_Dump(HPyContext *dctx, DHPy h); -DHPy debug_ctx_Compile_s(HPyContext *dctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); -DHPy debug_ctx_EvalCode(HPyContext *dctx, DHPy code, DHPy globals, DHPy locals); -DHPy debug_ctx_ContextVar_New(HPyContext *dctx, const char *name, DHPy default_value); -int32_t debug_ctx_ContextVar_Get(HPyContext *dctx, DHPy context_var, DHPy default_value, DHPy *result); -DHPy debug_ctx_ContextVar_Set(HPyContext *dctx, DHPy context_var, DHPy value); -int debug_ctx_SetCallFunction(HPyContext *dctx, DHPy h, HPyCallFunction *func); - -static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx) -{ - dctx->h_None = DHPy_open_immortal(dctx, uctx->h_None); - dctx->h_True = DHPy_open_immortal(dctx, uctx->h_True); - dctx->h_False = DHPy_open_immortal(dctx, uctx->h_False); - dctx->h_NotImplemented = DHPy_open_immortal(dctx, uctx->h_NotImplemented); - dctx->h_Ellipsis = DHPy_open_immortal(dctx, uctx->h_Ellipsis); - dctx->h_BaseException = DHPy_open_immortal(dctx, uctx->h_BaseException); - dctx->h_Exception = DHPy_open_immortal(dctx, uctx->h_Exception); - dctx->h_StopAsyncIteration = DHPy_open_immortal(dctx, uctx->h_StopAsyncIteration); - dctx->h_StopIteration = DHPy_open_immortal(dctx, uctx->h_StopIteration); - dctx->h_GeneratorExit = DHPy_open_immortal(dctx, uctx->h_GeneratorExit); - dctx->h_ArithmeticError = DHPy_open_immortal(dctx, uctx->h_ArithmeticError); - dctx->h_LookupError = DHPy_open_immortal(dctx, uctx->h_LookupError); - dctx->h_AssertionError = DHPy_open_immortal(dctx, uctx->h_AssertionError); - dctx->h_AttributeError = DHPy_open_immortal(dctx, uctx->h_AttributeError); - dctx->h_BufferError = DHPy_open_immortal(dctx, uctx->h_BufferError); - dctx->h_EOFError = DHPy_open_immortal(dctx, uctx->h_EOFError); - dctx->h_FloatingPointError = DHPy_open_immortal(dctx, uctx->h_FloatingPointError); - dctx->h_OSError = DHPy_open_immortal(dctx, uctx->h_OSError); - dctx->h_ImportError = DHPy_open_immortal(dctx, uctx->h_ImportError); - dctx->h_ModuleNotFoundError = DHPy_open_immortal(dctx, uctx->h_ModuleNotFoundError); - dctx->h_IndexError = DHPy_open_immortal(dctx, uctx->h_IndexError); - dctx->h_KeyError = DHPy_open_immortal(dctx, uctx->h_KeyError); - dctx->h_KeyboardInterrupt = DHPy_open_immortal(dctx, uctx->h_KeyboardInterrupt); - dctx->h_MemoryError = DHPy_open_immortal(dctx, uctx->h_MemoryError); - dctx->h_NameError = DHPy_open_immortal(dctx, uctx->h_NameError); - dctx->h_OverflowError = DHPy_open_immortal(dctx, uctx->h_OverflowError); - dctx->h_RuntimeError = DHPy_open_immortal(dctx, uctx->h_RuntimeError); - dctx->h_RecursionError = DHPy_open_immortal(dctx, uctx->h_RecursionError); - dctx->h_NotImplementedError = DHPy_open_immortal(dctx, uctx->h_NotImplementedError); - dctx->h_SyntaxError = DHPy_open_immortal(dctx, uctx->h_SyntaxError); - dctx->h_IndentationError = DHPy_open_immortal(dctx, uctx->h_IndentationError); - dctx->h_TabError = DHPy_open_immortal(dctx, uctx->h_TabError); - dctx->h_ReferenceError = DHPy_open_immortal(dctx, uctx->h_ReferenceError); - dctx->h_SystemError = DHPy_open_immortal(dctx, uctx->h_SystemError); - dctx->h_SystemExit = DHPy_open_immortal(dctx, uctx->h_SystemExit); - dctx->h_TypeError = DHPy_open_immortal(dctx, uctx->h_TypeError); - dctx->h_UnboundLocalError = DHPy_open_immortal(dctx, uctx->h_UnboundLocalError); - dctx->h_UnicodeError = DHPy_open_immortal(dctx, uctx->h_UnicodeError); - dctx->h_UnicodeEncodeError = DHPy_open_immortal(dctx, uctx->h_UnicodeEncodeError); - dctx->h_UnicodeDecodeError = DHPy_open_immortal(dctx, uctx->h_UnicodeDecodeError); - dctx->h_UnicodeTranslateError = DHPy_open_immortal(dctx, uctx->h_UnicodeTranslateError); - dctx->h_ValueError = DHPy_open_immortal(dctx, uctx->h_ValueError); - dctx->h_ZeroDivisionError = DHPy_open_immortal(dctx, uctx->h_ZeroDivisionError); - dctx->h_BlockingIOError = DHPy_open_immortal(dctx, uctx->h_BlockingIOError); - dctx->h_BrokenPipeError = DHPy_open_immortal(dctx, uctx->h_BrokenPipeError); - dctx->h_ChildProcessError = DHPy_open_immortal(dctx, uctx->h_ChildProcessError); - dctx->h_ConnectionError = DHPy_open_immortal(dctx, uctx->h_ConnectionError); - dctx->h_ConnectionAbortedError = DHPy_open_immortal(dctx, uctx->h_ConnectionAbortedError); - dctx->h_ConnectionRefusedError = DHPy_open_immortal(dctx, uctx->h_ConnectionRefusedError); - dctx->h_ConnectionResetError = DHPy_open_immortal(dctx, uctx->h_ConnectionResetError); - dctx->h_FileExistsError = DHPy_open_immortal(dctx, uctx->h_FileExistsError); - dctx->h_FileNotFoundError = DHPy_open_immortal(dctx, uctx->h_FileNotFoundError); - dctx->h_InterruptedError = DHPy_open_immortal(dctx, uctx->h_InterruptedError); - dctx->h_IsADirectoryError = DHPy_open_immortal(dctx, uctx->h_IsADirectoryError); - dctx->h_NotADirectoryError = DHPy_open_immortal(dctx, uctx->h_NotADirectoryError); - dctx->h_PermissionError = DHPy_open_immortal(dctx, uctx->h_PermissionError); - dctx->h_ProcessLookupError = DHPy_open_immortal(dctx, uctx->h_ProcessLookupError); - dctx->h_TimeoutError = DHPy_open_immortal(dctx, uctx->h_TimeoutError); - dctx->h_Warning = DHPy_open_immortal(dctx, uctx->h_Warning); - dctx->h_UserWarning = DHPy_open_immortal(dctx, uctx->h_UserWarning); - dctx->h_DeprecationWarning = DHPy_open_immortal(dctx, uctx->h_DeprecationWarning); - dctx->h_PendingDeprecationWarning = DHPy_open_immortal(dctx, uctx->h_PendingDeprecationWarning); - dctx->h_SyntaxWarning = DHPy_open_immortal(dctx, uctx->h_SyntaxWarning); - dctx->h_RuntimeWarning = DHPy_open_immortal(dctx, uctx->h_RuntimeWarning); - dctx->h_FutureWarning = DHPy_open_immortal(dctx, uctx->h_FutureWarning); - dctx->h_ImportWarning = DHPy_open_immortal(dctx, uctx->h_ImportWarning); - dctx->h_UnicodeWarning = DHPy_open_immortal(dctx, uctx->h_UnicodeWarning); - dctx->h_BytesWarning = DHPy_open_immortal(dctx, uctx->h_BytesWarning); - dctx->h_ResourceWarning = DHPy_open_immortal(dctx, uctx->h_ResourceWarning); - dctx->h_BaseObjectType = DHPy_open_immortal(dctx, uctx->h_BaseObjectType); - dctx->h_TypeType = DHPy_open_immortal(dctx, uctx->h_TypeType); - dctx->h_BoolType = DHPy_open_immortal(dctx, uctx->h_BoolType); - dctx->h_LongType = DHPy_open_immortal(dctx, uctx->h_LongType); - dctx->h_FloatType = DHPy_open_immortal(dctx, uctx->h_FloatType); - dctx->h_UnicodeType = DHPy_open_immortal(dctx, uctx->h_UnicodeType); - dctx->h_TupleType = DHPy_open_immortal(dctx, uctx->h_TupleType); - dctx->h_ListType = DHPy_open_immortal(dctx, uctx->h_ListType); - dctx->h_ComplexType = DHPy_open_immortal(dctx, uctx->h_ComplexType); - dctx->h_BytesType = DHPy_open_immortal(dctx, uctx->h_BytesType); - dctx->h_MemoryViewType = DHPy_open_immortal(dctx, uctx->h_MemoryViewType); - dctx->h_CapsuleType = DHPy_open_immortal(dctx, uctx->h_CapsuleType); - dctx->h_SliceType = DHPy_open_immortal(dctx, uctx->h_SliceType); - dctx->h_DictType = DHPy_open_immortal(dctx, uctx->h_DictType); - dctx->h_Builtins = DHPy_open_immortal(dctx, uctx->h_Builtins); - dctx->ctx_Dup = &debug_ctx_Dup; - dctx->ctx_Close = &debug_ctx_Close; - dctx->ctx_Long_FromInt32_t = &debug_ctx_Long_FromInt32_t; - dctx->ctx_Long_FromUInt32_t = &debug_ctx_Long_FromUInt32_t; - dctx->ctx_Long_FromInt64_t = &debug_ctx_Long_FromInt64_t; - dctx->ctx_Long_FromUInt64_t = &debug_ctx_Long_FromUInt64_t; - dctx->ctx_Long_FromSize_t = &debug_ctx_Long_FromSize_t; - dctx->ctx_Long_FromSsize_t = &debug_ctx_Long_FromSsize_t; - dctx->ctx_Long_AsInt32_t = &debug_ctx_Long_AsInt32_t; - dctx->ctx_Long_AsUInt32_t = &debug_ctx_Long_AsUInt32_t; - dctx->ctx_Long_AsUInt32_tMask = &debug_ctx_Long_AsUInt32_tMask; - dctx->ctx_Long_AsInt64_t = &debug_ctx_Long_AsInt64_t; - dctx->ctx_Long_AsUInt64_t = &debug_ctx_Long_AsUInt64_t; - dctx->ctx_Long_AsUInt64_tMask = &debug_ctx_Long_AsUInt64_tMask; - dctx->ctx_Long_AsSize_t = &debug_ctx_Long_AsSize_t; - dctx->ctx_Long_AsSsize_t = &debug_ctx_Long_AsSsize_t; - dctx->ctx_Long_AsVoidPtr = &debug_ctx_Long_AsVoidPtr; - dctx->ctx_Long_AsDouble = &debug_ctx_Long_AsDouble; - dctx->ctx_Float_FromDouble = &debug_ctx_Float_FromDouble; - dctx->ctx_Float_AsDouble = &debug_ctx_Float_AsDouble; - dctx->ctx_Bool_FromBool = &debug_ctx_Bool_FromBool; - dctx->ctx_Length = &debug_ctx_Length; - dctx->ctx_Number_Check = &debug_ctx_Number_Check; - dctx->ctx_Add = &debug_ctx_Add; - dctx->ctx_Subtract = &debug_ctx_Subtract; - dctx->ctx_Multiply = &debug_ctx_Multiply; - dctx->ctx_MatrixMultiply = &debug_ctx_MatrixMultiply; - dctx->ctx_FloorDivide = &debug_ctx_FloorDivide; - dctx->ctx_TrueDivide = &debug_ctx_TrueDivide; - dctx->ctx_Remainder = &debug_ctx_Remainder; - dctx->ctx_Divmod = &debug_ctx_Divmod; - dctx->ctx_Power = &debug_ctx_Power; - dctx->ctx_Negative = &debug_ctx_Negative; - dctx->ctx_Positive = &debug_ctx_Positive; - dctx->ctx_Absolute = &debug_ctx_Absolute; - dctx->ctx_Invert = &debug_ctx_Invert; - dctx->ctx_Lshift = &debug_ctx_Lshift; - dctx->ctx_Rshift = &debug_ctx_Rshift; - dctx->ctx_And = &debug_ctx_And; - dctx->ctx_Xor = &debug_ctx_Xor; - dctx->ctx_Or = &debug_ctx_Or; - dctx->ctx_Index = &debug_ctx_Index; - dctx->ctx_Long = &debug_ctx_Long; - dctx->ctx_Float = &debug_ctx_Float; - dctx->ctx_InPlaceAdd = &debug_ctx_InPlaceAdd; - dctx->ctx_InPlaceSubtract = &debug_ctx_InPlaceSubtract; - dctx->ctx_InPlaceMultiply = &debug_ctx_InPlaceMultiply; - dctx->ctx_InPlaceMatrixMultiply = &debug_ctx_InPlaceMatrixMultiply; - dctx->ctx_InPlaceFloorDivide = &debug_ctx_InPlaceFloorDivide; - dctx->ctx_InPlaceTrueDivide = &debug_ctx_InPlaceTrueDivide; - dctx->ctx_InPlaceRemainder = &debug_ctx_InPlaceRemainder; - dctx->ctx_InPlacePower = &debug_ctx_InPlacePower; - dctx->ctx_InPlaceLshift = &debug_ctx_InPlaceLshift; - dctx->ctx_InPlaceRshift = &debug_ctx_InPlaceRshift; - dctx->ctx_InPlaceAnd = &debug_ctx_InPlaceAnd; - dctx->ctx_InPlaceXor = &debug_ctx_InPlaceXor; - dctx->ctx_InPlaceOr = &debug_ctx_InPlaceOr; - dctx->ctx_Callable_Check = &debug_ctx_Callable_Check; - dctx->ctx_CallTupleDict = &debug_ctx_CallTupleDict; - dctx->ctx_Call = &debug_ctx_Call; - dctx->ctx_CallMethod = &debug_ctx_CallMethod; - dctx->ctx_GetIter = &debug_ctx_GetIter; - dctx->ctx_Iter_Next = &debug_ctx_Iter_Next; - dctx->ctx_Iter_Check = &debug_ctx_Iter_Check; - dctx->ctx_FatalError = &debug_ctx_FatalError; - dctx->ctx_Err_SetString = &debug_ctx_Err_SetString; - dctx->ctx_Err_SetObject = &debug_ctx_Err_SetObject; - dctx->ctx_Err_SetFromErrnoWithFilename = &debug_ctx_Err_SetFromErrnoWithFilename; - dctx->ctx_Err_SetFromErrnoWithFilenameObjects = &debug_ctx_Err_SetFromErrnoWithFilenameObjects; - dctx->ctx_Err_Occurred = &debug_ctx_Err_Occurred; - dctx->ctx_Err_ExceptionMatches = &debug_ctx_Err_ExceptionMatches; - dctx->ctx_Err_NoMemory = &debug_ctx_Err_NoMemory; - dctx->ctx_Err_Clear = &debug_ctx_Err_Clear; - dctx->ctx_Err_NewException = &debug_ctx_Err_NewException; - dctx->ctx_Err_NewExceptionWithDoc = &debug_ctx_Err_NewExceptionWithDoc; - dctx->ctx_Err_WarnEx = &debug_ctx_Err_WarnEx; - dctx->ctx_Err_WriteUnraisable = &debug_ctx_Err_WriteUnraisable; - dctx->ctx_IsTrue = &debug_ctx_IsTrue; - dctx->ctx_Type_FromSpec = &debug_ctx_Type_FromSpec; - dctx->ctx_Type_GenericNew = &debug_ctx_Type_GenericNew; - dctx->ctx_GetAttr = &debug_ctx_GetAttr; - dctx->ctx_GetAttr_s = &debug_ctx_GetAttr_s; - dctx->ctx_HasAttr = &debug_ctx_HasAttr; - dctx->ctx_HasAttr_s = &debug_ctx_HasAttr_s; - dctx->ctx_SetAttr = &debug_ctx_SetAttr; - dctx->ctx_SetAttr_s = &debug_ctx_SetAttr_s; - dctx->ctx_GetItem = &debug_ctx_GetItem; - dctx->ctx_GetItem_i = &debug_ctx_GetItem_i; - dctx->ctx_GetItem_s = &debug_ctx_GetItem_s; - dctx->ctx_GetSlice = &debug_ctx_GetSlice; - dctx->ctx_Contains = &debug_ctx_Contains; - dctx->ctx_SetItem = &debug_ctx_SetItem; - dctx->ctx_SetItem_i = &debug_ctx_SetItem_i; - dctx->ctx_SetItem_s = &debug_ctx_SetItem_s; - dctx->ctx_SetSlice = &debug_ctx_SetSlice; - dctx->ctx_DelItem = &debug_ctx_DelItem; - dctx->ctx_DelItem_i = &debug_ctx_DelItem_i; - dctx->ctx_DelItem_s = &debug_ctx_DelItem_s; - dctx->ctx_DelSlice = &debug_ctx_DelSlice; - dctx->ctx_Type = &debug_ctx_Type; - dctx->ctx_TypeCheck = &debug_ctx_TypeCheck; - dctx->ctx_Type_GetName = &debug_ctx_Type_GetName; - dctx->ctx_Type_IsSubtype = &debug_ctx_Type_IsSubtype; - dctx->ctx_Is = &debug_ctx_Is; - dctx->ctx_AsStruct_Object = &debug_ctx_AsStruct_Object; - dctx->ctx_AsStruct_Legacy = &debug_ctx_AsStruct_Legacy; - dctx->ctx_AsStruct_Type = &debug_ctx_AsStruct_Type; - dctx->ctx_AsStruct_Long = &debug_ctx_AsStruct_Long; - dctx->ctx_AsStruct_Float = &debug_ctx_AsStruct_Float; - dctx->ctx_AsStruct_Unicode = &debug_ctx_AsStruct_Unicode; - dctx->ctx_AsStruct_Tuple = &debug_ctx_AsStruct_Tuple; - dctx->ctx_AsStruct_List = &debug_ctx_AsStruct_List; - dctx->ctx_AsStruct_Dict = &debug_ctx_AsStruct_Dict; - dctx->ctx_Type_GetBuiltinShape = &debug_ctx_Type_GetBuiltinShape; - dctx->ctx_New = &debug_ctx_New; - dctx->ctx_Repr = &debug_ctx_Repr; - dctx->ctx_Str = &debug_ctx_Str; - dctx->ctx_ASCII = &debug_ctx_ASCII; - dctx->ctx_Bytes = &debug_ctx_Bytes; - dctx->ctx_RichCompare = &debug_ctx_RichCompare; - dctx->ctx_RichCompareBool = &debug_ctx_RichCompareBool; - dctx->ctx_Hash = &debug_ctx_Hash; - dctx->ctx_Bytes_Check = &debug_ctx_Bytes_Check; - dctx->ctx_Bytes_Size = &debug_ctx_Bytes_Size; - dctx->ctx_Bytes_GET_SIZE = &debug_ctx_Bytes_GET_SIZE; - dctx->ctx_Bytes_AsString = &debug_ctx_Bytes_AsString; - dctx->ctx_Bytes_AS_STRING = &debug_ctx_Bytes_AS_STRING; - dctx->ctx_Bytes_FromString = &debug_ctx_Bytes_FromString; - dctx->ctx_Bytes_FromStringAndSize = &debug_ctx_Bytes_FromStringAndSize; - dctx->ctx_Unicode_FromString = &debug_ctx_Unicode_FromString; - dctx->ctx_Unicode_Check = &debug_ctx_Unicode_Check; - dctx->ctx_Unicode_AsASCIIString = &debug_ctx_Unicode_AsASCIIString; - dctx->ctx_Unicode_AsLatin1String = &debug_ctx_Unicode_AsLatin1String; - dctx->ctx_Unicode_AsUTF8String = &debug_ctx_Unicode_AsUTF8String; - dctx->ctx_Unicode_AsUTF8AndSize = &debug_ctx_Unicode_AsUTF8AndSize; - dctx->ctx_Unicode_FromWideChar = &debug_ctx_Unicode_FromWideChar; - dctx->ctx_Unicode_DecodeFSDefault = &debug_ctx_Unicode_DecodeFSDefault; - dctx->ctx_Unicode_DecodeFSDefaultAndSize = &debug_ctx_Unicode_DecodeFSDefaultAndSize; - dctx->ctx_Unicode_EncodeFSDefault = &debug_ctx_Unicode_EncodeFSDefault; - dctx->ctx_Unicode_ReadChar = &debug_ctx_Unicode_ReadChar; - dctx->ctx_Unicode_DecodeASCII = &debug_ctx_Unicode_DecodeASCII; - dctx->ctx_Unicode_DecodeLatin1 = &debug_ctx_Unicode_DecodeLatin1; - dctx->ctx_Unicode_FromEncodedObject = &debug_ctx_Unicode_FromEncodedObject; - dctx->ctx_Unicode_Substring = &debug_ctx_Unicode_Substring; - dctx->ctx_List_Check = &debug_ctx_List_Check; - dctx->ctx_List_New = &debug_ctx_List_New; - dctx->ctx_List_Append = &debug_ctx_List_Append; - dctx->ctx_List_Insert = &debug_ctx_List_Insert; - dctx->ctx_Dict_Check = &debug_ctx_Dict_Check; - dctx->ctx_Dict_New = &debug_ctx_Dict_New; - dctx->ctx_Dict_Keys = &debug_ctx_Dict_Keys; - dctx->ctx_Dict_Copy = &debug_ctx_Dict_Copy; - dctx->ctx_Tuple_Check = &debug_ctx_Tuple_Check; - dctx->ctx_Tuple_FromArray = &debug_ctx_Tuple_FromArray; - dctx->ctx_Slice_New = &debug_ctx_Slice_New; - dctx->ctx_Slice_Unpack = &debug_ctx_Slice_Unpack; - dctx->ctx_Import_ImportModule = &debug_ctx_Import_ImportModule; - dctx->ctx_Capsule_New = &debug_ctx_Capsule_New; - dctx->ctx_Capsule_Get = &debug_ctx_Capsule_Get; - dctx->ctx_Capsule_IsValid = &debug_ctx_Capsule_IsValid; - dctx->ctx_Capsule_Set = &debug_ctx_Capsule_Set; - dctx->ctx_FromPyObject = &debug_ctx_FromPyObject; - dctx->ctx_AsPyObject = &debug_ctx_AsPyObject; - dctx->ctx_CallRealFunctionFromTrampoline = &debug_ctx_CallRealFunctionFromTrampoline; - dctx->ctx_ListBuilder_New = &debug_ctx_ListBuilder_New; - dctx->ctx_ListBuilder_Set = &debug_ctx_ListBuilder_Set; - dctx->ctx_ListBuilder_Build = &debug_ctx_ListBuilder_Build; - dctx->ctx_ListBuilder_Cancel = &debug_ctx_ListBuilder_Cancel; - dctx->ctx_TupleBuilder_New = &debug_ctx_TupleBuilder_New; - dctx->ctx_TupleBuilder_Set = &debug_ctx_TupleBuilder_Set; - dctx->ctx_TupleBuilder_Build = &debug_ctx_TupleBuilder_Build; - dctx->ctx_TupleBuilder_Cancel = &debug_ctx_TupleBuilder_Cancel; - dctx->ctx_Tracker_New = &debug_ctx_Tracker_New; - dctx->ctx_Tracker_Add = &debug_ctx_Tracker_Add; - dctx->ctx_Tracker_ForgetAll = &debug_ctx_Tracker_ForgetAll; - dctx->ctx_Tracker_Close = &debug_ctx_Tracker_Close; - dctx->ctx_Field_Store = &debug_ctx_Field_Store; - dctx->ctx_Field_Load = &debug_ctx_Field_Load; - dctx->ctx_ReenterPythonExecution = &debug_ctx_ReenterPythonExecution; - dctx->ctx_LeavePythonExecution = &debug_ctx_LeavePythonExecution; - dctx->ctx_Global_Store = &debug_ctx_Global_Store; - dctx->ctx_Global_Load = &debug_ctx_Global_Load; - dctx->ctx_Dump = &debug_ctx_Dump; - dctx->ctx_Compile_s = &debug_ctx_Compile_s; - dctx->ctx_EvalCode = &debug_ctx_EvalCode; - dctx->ctx_ContextVar_New = &debug_ctx_ContextVar_New; - dctx->ctx_ContextVar_Get = &debug_ctx_ContextVar_Get; - dctx->ctx_ContextVar_Set = &debug_ctx_ContextVar_Set; - dctx->ctx_SetCallFunction = &debug_ctx_SetCallFunction; -} diff --git a/graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c b/graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c deleted file mode 100644 index e9eb6a15c3..0000000000 --- a/graalpython/hpy/hpy/debug/src/autogen_debug_wrappers.c +++ /dev/null @@ -1,1870 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.debug.autogen_debug_wrappers - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#include "debug_internal.h" - -DHPy debug_ctx_Dup(HPyContext *dctx, DHPy 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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); -} - -DHPy debug_ctx_GetIter(HPyContext *dctx, DHPy 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_GetIter(get_info(dctx)->uctx, dh_obj); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_Iter_Next(HPyContext *dctx, DHPy 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 = HPyIter_Next(get_info(dctx)->uctx, dh_obj); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_Iter_Check(HPyContext *dctx, DHPy 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; - int universal_result = HPyIter_Check(get_info(dctx)->uctx, dh_obj); - get_ctx_info(dctx)->is_valid = true; - return 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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); -} - -DHPy debug_ctx_GetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - 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_GetSlice(get_info(dctx)->uctx, dh_obj, start, end); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_Contains(HPyContext *dctx, DHPy container, DHPy 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) -{ - 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) -{ - 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) -{ - 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_SetSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end, DHPy 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_SetSlice(get_info(dctx)->uctx, dh_obj, start, end, dh_value); - get_ctx_info(dctx)->is_valid = true; - return universal_result; -} - -int debug_ctx_DelItem(HPyContext *dctx, DHPy obj, DHPy 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) -{ - 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) -{ - 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; -} - -int debug_ctx_DelSlice(HPyContext *dctx, DHPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - 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_DelSlice(get_info(dctx)->uctx, dh_obj, start, end); - get_ctx_info(dctx)->is_valid = true; - return universal_result; -} - -DHPy debug_ctx_Type(HPyContext *dctx, DHPy 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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); -} - -DHPy debug_ctx_Unicode_FromEncodedObject(HPyContext *dctx, DHPy obj, const char *encoding, const char *errors) -{ - 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 = HPyUnicode_FromEncodedObject(get_info(dctx)->uctx, dh_obj, encoding, errors); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_List_Check(HPyContext *dctx, DHPy 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) -{ - 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) -{ - 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_List_Insert(HPyContext *dctx, DHPy h_list, HPy_ssize_t index, DHPy 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_Insert(get_info(dctx)->uctx, dh_h_list, index, dh_h_item); - get_ctx_info(dctx)->is_valid = true; - return universal_result; -} - -int debug_ctx_Dict_Check(HPyContext *dctx, DHPy 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) -{ - 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); -} - -DHPy debug_ctx_Dict_Keys(HPyContext *dctx, DHPy 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 = HPyDict_Keys(get_info(dctx)->uctx, dh_h); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_Dict_Copy(HPyContext *dctx, DHPy 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 = HPyDict_Copy(get_info(dctx)->uctx, dh_h); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_Tuple_Check(HPyContext *dctx, DHPy 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_Slice_New(HPyContext *dctx, DHPy start, DHPy stop, DHPy step) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - HPy dh_start = DHPy_unwrap(dctx, start); - HPy dh_stop = DHPy_unwrap(dctx, stop); - HPy dh_step = DHPy_unwrap(dctx, step); - get_ctx_info(dctx)->is_valid = false; - HPy universal_result = HPySlice_New(get_info(dctx)->uctx, dh_start, dh_stop, dh_step); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_Slice_Unpack(HPyContext *dctx, DHPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - HPy dh_slice = DHPy_unwrap(dctx, slice); - get_ctx_info(dctx)->is_valid = false; - int universal_result = HPySlice_Unpack(get_info(dctx)->uctx, dh_slice, start, stop, step); - get_ctx_info(dctx)->is_valid = true; - return universal_result; -} - -DHPy debug_ctx_Import_ImportModule(HPyContext *dctx, const char *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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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; -} - -DHPy debug_ctx_Compile_s(HPyContext *dctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - get_ctx_info(dctx)->is_valid = false; - HPy universal_result = HPy_Compile_s(get_info(dctx)->uctx, utf8_source, utf8_filename, kind); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_EvalCode(HPyContext *dctx, DHPy code, DHPy globals, DHPy locals) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - HPy dh_code = DHPy_unwrap(dctx, code); - HPy dh_globals = DHPy_unwrap(dctx, globals); - HPy dh_locals = DHPy_unwrap(dctx, locals); - get_ctx_info(dctx)->is_valid = false; - HPy universal_result = HPy_EvalCode(get_info(dctx)->uctx, dh_code, dh_globals, dh_locals); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_ContextVar_New(HPyContext *dctx, const char *name, DHPy default_value) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - HPy dh_default_value = DHPy_unwrap(dctx, default_value); - get_ctx_info(dctx)->is_valid = false; - HPy universal_result = HPyContextVar_New(get_info(dctx)->uctx, name, dh_default_value); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_ContextVar_Set(HPyContext *dctx, DHPy context_var, DHPy value) -{ - if (!get_ctx_info(dctx)->is_valid) { - report_invalid_debug_context(); - } - HPy dh_context_var = DHPy_unwrap(dctx, context_var); - HPy dh_value = DHPy_unwrap(dctx, value); - get_ctx_info(dctx)->is_valid = false; - HPy universal_result = HPyContextVar_Set(get_info(dctx)->uctx, dh_context_var, dh_value); - get_ctx_info(dctx)->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -int debug_ctx_SetCallFunction(HPyContext *dctx, DHPy h, HPyCallFunction *func) -{ - 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_SetCallFunction(get_info(dctx)->uctx, dh_h, func); - get_ctx_info(dctx)->is_valid = true; - return universal_result; -} - diff --git a/graalpython/hpy/hpy/debug/src/debug_ctx.c b/graalpython/hpy/hpy/debug/src/debug_ctx.c deleted file mode 100644 index de661ea2c9..0000000000 --- a/graalpython/hpy/hpy/debug/src/debug_ctx.c +++ /dev/null @@ -1,687 +0,0 @@ -#include -#include -#include "debug_internal.h" -#include "autogen_debug_ctx_init.h" -#include "hpy/runtime/ctx_funcs.h" -#if defined(_MSC_VER) -# include /* for alloca() */ -#endif - -static struct _HPyContext_s g_debug_ctx = { - .name = "HPy Debug Mode ABI", - ._private = NULL, - .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 -// debug wrapper for each of them. -int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx) -{ - if (dctx->_private != NULL) { - // already initialized - assert(get_info(dctx)->uctx == uctx); // sanity check - return 0; - } - // initialize debug_info - // 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_INFO_MAGIC; - info->uctx = uctx; - info->current_generation = 0; - info->uh_on_invalid_handle = HPy_NULL; - info->closed_handles_queue_max_size = DEFAULT_CLOSED_HANDLES_QUEUE_MAX_SIZE; - info->protected_raw_data_max_size = DEFAULT_PROTECTED_RAW_DATA_MAX_SIZE; - info->handle_alloc_stacktrace_limit = 0; - info->protected_raw_data_size = 0; - DHQueue_init(&info->open_handles); - DHQueue_init(&info->closed_handles); - DHQueue_init(&info->closed_builder); - debug_ctx_init_fields(dctx, uctx); - if (init_dctx_cache(dctx, info) != 0) { - return -1; - } - return 0; -} - -HPyContext * hpy_debug_get_ctx(HPyContext *uctx) -{ - HPyContext *dctx = &g_debug_ctx; - if (uctx == dctx) { - HPy_FatalError(uctx, "hpy_debug_get_ctx: expected an universal ctx, " - "got a debug ctx"); - } - if (hpy_debug_ctx_init(dctx, uctx) < 0) { - HPyErr_SetString(uctx, uctx->h_SystemError, "Could not create debug context"); - return NULL; - } - return dctx; -} - -void hpy_debug_set_ctx(HPyContext *dctx) -{ - g_debug_ctx = *dctx; -} - -HPy hpy_debug_open_handle(HPyContext *dctx, HPy uh) -{ - return DHPy_open(dctx, uh); -} - -HPy hpy_debug_unwrap_handle(HPyContext *dctx, HPy dh) -{ - return DHPy_unwrap(dctx, dh); -} - -void hpy_debug_close_handle(HPyContext *dctx, HPy dh) -{ - DHPy_close(dctx, dh); -} - -// this function is supposed to be called from gdb: it tries to determine -// whether a handle is universal or debug by looking at the last bit -extern struct _HPyContext_s g_universal_ctx; -#ifndef _MSC_VER -__attribute__((unused)) -#endif -static void hpy_magic_dump(HPy h) -{ - int universal = h._i & 1; - if (universal) - fprintf(stderr, "\nUniversal handle\n"); - else - fprintf(stderr, "\nDebug handle\n"); - -#ifdef _MSC_VER - fprintf(stderr, "raw value: %Ix (%Id)\n", h._i, h._i); -#else - fprintf(stderr, "raw value: %lx (%ld)\n", h._i, h._i); -#endif - if (universal) - _HPy_Dump(&g_universal_ctx, h); - else { - DebugHandle *dh = as_DebugHandle(h); -#ifdef _MSC_VER - fprintf(stderr, "dh->uh: %Ix\n", dh->uh._i); -#else - fprintf(stderr, "dh->uh: %lx\n", dh->uh._i); -#endif - _HPy_Dump(&g_universal_ctx, dh->uh); - } -} - -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 * -protect_and_associate_data_ptr(DHPy h, void *ptr, HPy_ssize_t data_size) -{ - DebugHandle *handle = as_DebugHandle(h); - void *new_ptr; - if (ptr != NULL) - { - new_ptr = raw_data_copy(ptr, data_size, true); - handle->associated_data = new_ptr; - handle->associated_data_size = data_size; - return new_ptr; - } - else - { - handle->associated_data = NULL; - handle->associated_data_size = 0; - } - return NULL; -} - -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) { - data_size = size != NULL ? *size + 1 : (HPy_ssize_t) strlen(ptr) + 1; - } - return (const char *)protect_and_associate_data_ptr(h, (void *)ptr, data_size); -} - -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); - HPy_ssize_t data_size = 0; - if (ptr != NULL) { - // '+ 1' accountd for the implicit null byte termination - data_size = HPyBytes_Size(uctx, uh) + 1; - } - return (const char *)protect_and_associate_data_ptr(h, (void *)ptr, data_size); -} - -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); - HPy_ssize_t data_size = 0; - if (ptr != NULL) { - // '+ 1' accountd for the implicit null byte termination - data_size = HPyBytes_GET_SIZE(uctx, uh) + 1; - } - return (const char *)protect_and_associate_data_ptr(h, (void *)ptr, data_size); -} - -DHPy debug_ctx_Tuple_FromArray(HPyContext *dctx, const 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; iuctx, uh_items, n)); -} - -DHPy debug_ctx_Type_GenericNew(HPyContext *dctx, DHPy dh_type, const DHPy *dh_args, - HPy_ssize_t nargs, DHPy dh_kw) -{ - if (!get_ctx_info(dctx)->is_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; iis_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 - HPy_ssize_t n = 1; - for (HPyType_SpecParam *p = dparams; p->kind != 0; p++) { - n++; - } - HPyType_SpecParam *uparams = (HPyType_SpecParam *)alloca(n * sizeof(HPyType_SpecParam)); - for (HPy_ssize_t i=0; iuctx, spec, uparams)); - } - return DHPy_open(dctx, HPyType_FromSpec(get_info(dctx)->uctx, spec, NULL)); -} - -static const char *get_builtin_shape_name(HPyType_BuiltinShape shape) -{ -#define SHAPE_NAME(SHAPE) \ - case SHAPE: \ - return #SHAPE; \ - - /* Note: we use a switch here because then the compiler will warn us about - missing cases if shapes are added to enum 'HPyType_BuiltinShape' */ - switch (shape) - { - SHAPE_NAME(HPyType_BuiltinShape_Legacy) - SHAPE_NAME(HPyType_BuiltinShape_Object) - SHAPE_NAME(HPyType_BuiltinShape_Type) - SHAPE_NAME(HPyType_BuiltinShape_Long) - SHAPE_NAME(HPyType_BuiltinShape_Float) - SHAPE_NAME(HPyType_BuiltinShape_Unicode) - SHAPE_NAME(HPyType_BuiltinShape_Tuple) - SHAPE_NAME(HPyType_BuiltinShape_List) - SHAPE_NAME(HPyType_BuiltinShape_Dict) - } - return ""; -#undef SHAPE_NAME -} - -#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); \ - HPyType_BuiltinShape actual_shape = _HPyType_GetBuiltinShape(uctx, uh_type); \ - HPy_Close(uctx, uh_type); \ - if (actual_shape != HPyType_BuiltinShape_##SHAPE) { \ - const char *actual_shape_name = get_builtin_shape_name(actual_shape); \ - static const char *fmt = "Invalid usage of _HPy_AsStruct_%s" \ - ". Expected shape HPyType_BuiltinShape_%s but got %s"; \ - size_t nbuf = strlen(fmt) + 2 * strlen(#SHAPE) + strlen(actual_shape_name) + 1; \ - char *buf = (char *)alloca(nbuf); \ - snprintf(buf, nbuf, fmt, #SHAPE, #SHAPE, actual_shape_name); \ - HPy_FatalError(uctx, buf); \ - } \ - return _HPy_AsStruct_##SHAPE(uctx, uh); \ - } - -MAKE_debug_ctx_AsStruct(Legacy) - -MAKE_debug_ctx_AsStruct(Object) - -MAKE_debug_ctx_AsStruct(Type) - -MAKE_debug_ctx_AsStruct(Long) - -MAKE_debug_ctx_AsStruct(Float) - -MAKE_debug_ctx_AsStruct(Unicode) - -MAKE_debug_ctx_AsStruct(Tuple) - -MAKE_debug_ctx_AsStruct(List) - -MAKE_debug_ctx_AsStruct(Dict) - -/* ~~~ debug mode implementation of HPyTracker ~~~ - - This is a bit special and it's worth explaining what is going on. - - The HPyTracker functions need their own debug mode implementation because - the debug mode needs to be aware of when a DHPy is closed, for the same - reason for why we need debug_ctx_Close. - - So, in theory here we should have our own implementation of a - DebugHPyTracker which manages a growable list of handles, and which calls - debug_ctx_Close at the end. But, we ALREADY have the logic available, it's - implemented in ctx_tracker.c. - - So, here we simply implement debug_ctx_Tracker_* in terms of ctx_Tracker_*: - but note that it's VERY different than what the autogen wrappers do: - - - the autogen wrappers DHPy_unwrap() all the handles before calling the - "super" implementation. Here we don't, we pass the DHPys directly. - - - the autogen wrappers pass the uctx to the "super" implementation, here - we pass the dctx. - - Conceptually, it is equivalent to just have our own implementation of a - growable array, but by using this trick we can easily reuse the existing - code. - - It is better understood if you think of what happens on PyPy (or any other - universal implementation): normally, on PyPy HPyTracker_Add calls PyPy's - own implementation (see interp_tracker.py). But when in debug mode, - HPyTracker_Add will call the ctx_Tracker_Add defined in ctx_tracker.c, - completely bypassing PyPy's own tracker (which is fine). Incidentally, this - also means that if PyPy wants to bundle the debug mode, it also needs to - compile ctx_tracker.c -*/ - -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 - // the handles were closed. - ctx_Tracker_Close(dctx, ht); -} - -HPyListBuilder debug_ctx_ListBuilder_New(HPyContext *dctx, HPy_ssize_t size) -{ - return DHPyListBuilder_open(dctx, HPyListBuilder_New(get_info(dctx)->uctx, size)); -} - -void debug_ctx_ListBuilder_Set(HPyContext *dctx, HPyListBuilder builder, HPy_ssize_t index, DHPy h_item) -{ - HPyListBuilder_Set(get_info(dctx)->uctx, DHPyListBuilder_unwrap(dctx, builder), index, DHPy_unwrap(dctx, h_item)); -} - -DHPy debug_ctx_ListBuilder_Build(HPyContext *dctx, HPyListBuilder dh_builder) -{ - DebugBuilderHandle *handle = DHPyListBuilder_as_DebugBuilderHandle(dh_builder); - if (handle == NULL) - return HPy_NULL; - HPyContext *uctx = get_info(dctx)->uctx; - UHPy uh_result = HPyListBuilder_Build(uctx, DHPyListBuilder_unwrap(dctx, dh_builder)); - DHPy_builder_handle_close(dctx, handle); - return DHPy_open(dctx, uh_result); -} - -void debug_ctx_ListBuilder_Cancel(HPyContext *dctx, HPyListBuilder dh_builder) -{ - DebugBuilderHandle *handle = DHPyListBuilder_as_DebugBuilderHandle(dh_builder); - if (handle == NULL) - return; - HPyContext *uctx = get_info(dctx)->uctx; - HPyListBuilder_Cancel(uctx, DHPyListBuilder_unwrap(dctx, dh_builder)); - DHPy_builder_handle_close(dctx, handle); -} - -HPyTupleBuilder debug_ctx_TupleBuilder_New(HPyContext *dctx, HPy_ssize_t size) -{ - return DHPyTupleBuilder_open(dctx, HPyTupleBuilder_New(get_info(dctx)->uctx, size)); -} - -void debug_ctx_TupleBuilder_Set(HPyContext *dctx, HPyTupleBuilder builder, HPy_ssize_t index, DHPy h_item) -{ - HPyTupleBuilder_Set(get_info(dctx)->uctx, DHPyTupleBuilder_unwrap(dctx, builder), index, DHPy_unwrap(dctx, h_item)); -} - -DHPy debug_ctx_TupleBuilder_Build(HPyContext *dctx, HPyTupleBuilder dh_builder) -{ - DebugBuilderHandle *handle = DHPyTupleBuilder_as_DebugBuilderHandle(dh_builder); - if (handle == NULL) - return HPy_NULL; - HPyContext *uctx = get_info(dctx)->uctx; - UHPy uh_result = HPyTupleBuilder_Build(uctx, DHPyTupleBuilder_unwrap(dctx, dh_builder)); - DHPy_builder_handle_close(dctx, handle); - return DHPy_open(dctx, uh_result); -} - -void debug_ctx_TupleBuilder_Cancel(HPyContext *dctx, HPyTupleBuilder dh_builder) -{ - DebugBuilderHandle *handle = DHPyTupleBuilder_as_DebugBuilderHandle(dh_builder); - if (handle == NULL) - return; - HPyContext *uctx = get_info(dctx)->uctx; - HPyTupleBuilder_Cancel(uctx, DHPyTupleBuilder_unwrap(dctx, 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); -} - -int32_t debug_ctx_ContextVar_Get(HPyContext *dctx, DHPy context_var, DHPy default_value, DHPy *result) -{ - HPyContext *uctx = get_info(dctx)->uctx; - UHPy uh_context_var = DHPy_unwrap(dctx, context_var); - UHPy uh_default_value = DHPy_unwrap(dctx, default_value); - UHPy uh_result; - assert(!HPy_IsNull(uh_context_var)); - int32_t ret = HPyContextVar_Get(uctx, uh_context_var, uh_default_value, &uh_result); - if (ret < 0) { - *result = HPy_NULL; - return ret; - } - *result = DHPy_open(dctx, uh_result); - return ret; -} - -const char *debug_ctx_Type_GetName(HPyContext *dctx, DHPy type) -{ - HPyDebugCtxInfo *ctx_info; - HPyContext *uctx; - UHPy uh_type; - HPy_ssize_t n_name; - - ctx_info = get_ctx_info(dctx); - if (!ctx_info->is_valid) { - report_invalid_debug_context(); - } - uh_type = DHPy_unwrap(dctx, type); - uctx = ctx_info->info->uctx; - if (!HPy_TypeCheck(uctx, uh_type, uctx->h_TypeType)) { - HPy_FatalError(uctx, "HPyType_GetName arg must be a type"); - } - ctx_info->is_valid = false; - const char *name = HPyType_GetName(uctx, uh_type); - ctx_info->is_valid = true; - n_name = strlen(name) + 1; - return (const char *)protect_and_associate_data_ptr(type, (void *)name, n_name); -} - -int debug_ctx_Type_IsSubtype(HPyContext *dctx, DHPy sub, DHPy type) -{ - HPyDebugCtxInfo *ctx_info; - HPyContext *uctx; - int res; - - ctx_info = get_ctx_info(dctx); - if (!ctx_info->is_valid) { - report_invalid_debug_context(); - } - - UHPy uh_sub = DHPy_unwrap(dctx, sub); - uctx = ctx_info->info->uctx; - if (!HPy_TypeCheck(uctx, uh_sub, uctx->h_TypeType)) { - HPy_FatalError(uctx, "HPyType_IsSubtype arg 1 must be a type"); - } - UHPy uh_type = DHPy_unwrap(dctx, type); - if (!HPy_TypeCheck(uctx, uh_type, uctx->h_TypeType)) { - HPy_FatalError(uctx, "HPyType_IsSubtype arg 2 must be a type"); - } - - ctx_info->is_valid = false; - res = HPyType_IsSubtype(uctx, uh_sub, uh_type); - ctx_info->is_valid = true; - return res; -} - -DHPy debug_ctx_Unicode_Substring(HPyContext *dctx, DHPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - HPyDebugCtxInfo *ctx_info; - HPyContext *uctx; - - ctx_info = get_ctx_info(dctx); - if (!ctx_info->is_valid) { - report_invalid_debug_context(); - } - - HPy uh_str = DHPy_unwrap(dctx, str); - uctx = ctx_info->info->uctx; - if (!HPy_TypeCheck(uctx, uh_str, uctx->h_UnicodeType)) { - HPy_FatalError(uctx, "HPyUnicode_Substring arg 1 must be a Unicode object"); - } - ctx_info->is_valid = false; - HPy universal_result = HPyUnicode_Substring(uctx, uh_str, start, end); - ctx_info->is_valid = true; - return DHPy_open(dctx, universal_result); -} - -DHPy debug_ctx_Call(HPyContext *dctx, DHPy dh_callable, const DHPy *dh_args, size_t nargs, DHPy dh_kwnames) -{ - HPyDebugCtxInfo *ctx_info; - HPyContext *uctx; - - ctx_info = get_ctx_info(dctx); - if (!ctx_info->is_valid) { - report_invalid_debug_context(); - } - - UHPy uh_callable = DHPy_unwrap(dctx, dh_callable); - UHPy uh_kwnames = DHPy_unwrap(dctx, dh_kwnames); - uctx = ctx_info->info->uctx; - HPy_ssize_t nkw; - if (!HPy_IsNull(uh_kwnames)) { - if (!HPyTuple_Check(uctx, uh_kwnames)) { - HPy_FatalError(uctx, "HPy_Call arg 'kwnames' must be a tuple object or HPy_NULL"); - } - nkw = HPy_Length(uctx, uh_kwnames); - if (nkw < 0) { - return HPy_NULL; - } - } else { - nkw = 0; - } - const size_t n_all_args = nargs + nkw; - UHPy *uh_args = (UHPy *)alloca(n_all_args * sizeof(UHPy)); - for(size_t i=0; i < n_all_args; i++) { - uh_args[i] = DHPy_unwrap(dctx, dh_args[i]); - } - ctx_info->is_valid = false; - DHPy dh_result = DHPy_open(dctx, HPy_Call(uctx, uh_callable, uh_args, nargs, uh_kwnames)); - ctx_info->is_valid = true; - return dh_result; -} - -DHPy debug_ctx_CallMethod(HPyContext *dctx, DHPy dh_name, const DHPy *dh_args, size_t nargs, DHPy dh_kwnames) -{ - HPyDebugCtxInfo *ctx_info; - HPyContext *uctx; - - ctx_info = get_ctx_info(dctx); - if (!ctx_info->is_valid) { - report_invalid_debug_context(); - } - - UHPy uh_name = DHPy_unwrap(dctx, dh_name); - UHPy uh_kwnames = DHPy_unwrap(dctx, dh_kwnames); - uctx = ctx_info->info->uctx; - HPy_ssize_t nkw; - if (!HPy_IsNull(uh_kwnames)) { - if (!HPyTuple_Check(uctx, uh_kwnames)) { - HPy_FatalError(uctx, "HPy_CallMethod arg 'kwnames' must be a tuple object or HPy_NULL"); - } - nkw = HPy_Length(uctx, uh_kwnames); - if (nkw < 0) { - return HPy_NULL; - } - } else { - nkw = 0; - } - const size_t n_all_args = nargs + nkw; - UHPy *uh_args = (UHPy *)alloca(n_all_args * sizeof(UHPy)); - for(size_t i=0; i < n_all_args; i++) { - uh_args[i] = DHPy_unwrap(dctx, dh_args[i]); - } - ctx_info->is_valid = false; - DHPy dh_result = DHPy_open(dctx, HPy_CallMethod(uctx, uh_name, uh_args, nargs, uh_kwnames)); - ctx_info->is_valid = true; - return dh_result; -} diff --git a/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c b/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c deleted file mode 100644 index 01d9c64788..0000000000 --- a/graalpython/hpy/hpy/debug/src/debug_ctx_cpython.c +++ /dev/null @@ -1,299 +0,0 @@ -/* =========== CPython-ONLY =========== - In the following code, we use _py2h and _h2py and we assumed they are the - ones defined by CPython's version of hpy.universal. - - DO NOT COMPILE THIS FILE UNLESS YOU ARE BUILDING CPython's hpy.universal. - - If you want to compile the debug mode into your own non-CPython version of - hpy.universal, you should include debug_ctx_not_cpython.c. - ==================================== - - In theory, the debug mode is completely generic and can wrap a generic - uctx. However, CPython is special because it does not have native support - for HPy, so uctx contains the logic to call HPy functions from CPython, by - using _HPy_CallRealFunctionFromTrampoline. - - uctx->ctx_CallRealFunctionFromTrampoline converts PyObject* into UHPy. So - for the debug mode we need to: - - 1. convert the PyObject* args into UHPys. - 2. wrap the UHPys into DHPys. - 3. unwrap the resulting DHPy and convert to PyObject*. -*/ - -#include -#include "debug_internal.h" -#include "hpy/runtime/ctx_type.h" // for call_traverseproc_from_trampoline -#include "hpy/runtime/ctx_module.h" -#include "handles.h" // for _py2h and _h2py - -#if defined(_MSC_VER) -# include /* for alloca() */ -#endif - -static inline DHPy _py2dh(HPyContext *dctx, PyObject *obj) -{ - return DHPy_open(dctx, _py2h(obj)); -} - -static inline PyObject *_dh2py(HPyContext *dctx, DHPy dh) -{ - return _h2py(DHPy_unwrap(dctx, dh)); -} - -static void _buffer_h2py(HPyContext *dctx, const HPy_buffer *src, Py_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = HPy_AsPyObject(dctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - dest->internal = src->internal; -} - -static void _buffer_py2h(HPyContext *dctx, const Py_buffer *src, HPy_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = HPy_FromPyObject(dctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - 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) -{ - switch (sig) { - case HPyFunc_VARARGS: { - HPyFunc_varargs f = (HPyFunc_varargs)func; - _HPyFunc_args_VARARGS *a = (_HPyFunc_args_VARARGS*)args; - DHPy dh_self = _py2dh(dctx, a->self); - DHPy *dh_args = (DHPy *)alloca(a->nargs * sizeof(DHPy)); - for (HPy_ssize_t i = 0; i < a->nargs; i++) { - dh_args[i] = _py2dh(dctx, a->args[i]); - } - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - - DHPy dh_result = f(next_dctx, dh_self, dh_args, a->nargs); - - _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++) { - DHPy_close_and_check(dctx, dh_args[i]); - } - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_KEYWORDS: { - HPyFunc_keywords f = (HPyFunc_keywords)func; - _HPyFunc_args_KEYWORDS *a = (_HPyFunc_args_KEYWORDS*)args; - DHPy dh_self = _py2dh(dctx, a->self); - size_t n_kwnames = a->kwnames != NULL ? PyTuple_GET_SIZE(a->kwnames) : 0; - size_t nargs = PyVectorcall_NARGS(a->nargsf); - size_t nargs_with_kw = nargs + n_kwnames; - DHPy *dh_args = (DHPy *)alloca(nargs_with_kw * sizeof(DHPy)); - for (size_t i = 0; i < nargs_with_kw; i++) { - dh_args[i] = _py2dh(dctx, a->args[i]); - } - DHPy dh_kwnames = _py2dh(dctx, a->kwnames); - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - - DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kwnames); - - _switch_back_to_original_dctx(dctx, next_dctx); - - DHPy_close_and_check(dctx, dh_self); - for (size_t i = 0; i < nargs_with_kw; i++) { - DHPy_close_and_check(dctx, dh_args[i]); - } - DHPy_close_and_check(dctx, dh_kwnames); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_INITPROC: { - HPyFunc_initproc f = (HPyFunc_initproc)func; - _HPyFunc_args_INITPROC *a = (_HPyFunc_args_INITPROC*)args; - DHPy dh_self = _py2dh(dctx, a->self); - Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); - DHPy *dh_args = (DHPy *)alloca(nargs * sizeof(DHPy)); - for (Py_ssize_t i = 0; i < nargs; i++) { - dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); - } - DHPy dh_kw = _py2dh(dctx, a->kw); - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - - a->result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); - - _switch_back_to_original_dctx(dctx, next_dctx); - - DHPy_close_and_check(dctx, dh_self); - for (Py_ssize_t i = 0; i < nargs; i++) { - DHPy_close_and_check(dctx, dh_args[i]); - } - DHPy_close_and_check(dctx, dh_kw); - return; - } - case HPyFunc_NEWFUNC: { - HPyFunc_newfunc f = (HPyFunc_newfunc)func; - _HPyFunc_args_NEWFUNC *a = (_HPyFunc_args_NEWFUNC*)args; - DHPy dh_self = _py2dh(dctx, a->self); - Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); - DHPy *dh_args = (DHPy *)alloca(nargs * sizeof(DHPy)); - for (Py_ssize_t i = 0; i < nargs; i++) { - dh_args[i] = _py2dh(dctx, PyTuple_GET_ITEM(a->args, i)); - } - DHPy dh_kw = _py2dh(dctx, a->kw); - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = NULL; - return; - } - - DHPy dh_result = f(next_dctx, dh_self, dh_args, nargs, dh_kw); - - _switch_back_to_original_dctx(dctx, next_dctx); - - DHPy_close_and_check(dctx, dh_self); - for (Py_ssize_t i = 0; i < nargs; i++) { - DHPy_close_and_check(dctx, dh_args[i]); - } - DHPy_close_and_check(dctx, dh_kw); - a->result = _dh2py(dctx, dh_result); - DHPy_close(dctx, dh_result); - return; - } - case HPyFunc_GETBUFFERPROC: { - HPyFunc_getbufferproc f = (HPyFunc_getbufferproc)func; - _HPyFunc_args_GETBUFFERPROC *a = (_HPyFunc_args_GETBUFFERPROC*)args; - HPy_buffer hbuf; - DHPy dh_self = _py2dh(dctx, a->self); - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - - a->result = f(next_dctx, dh_self, &hbuf, a->flags); - - _switch_back_to_original_dctx(dctx, next_dctx); - - DHPy_close_and_check(dctx, dh_self); - if (a->result < 0) { - a->view->obj = NULL; - return; - } - _buffer_h2py(dctx, &hbuf, a->view); - HPy_Close(dctx, hbuf.obj); - return; - } - case HPyFunc_RELEASEBUFFERPROC: { - HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc)func; - _HPyFunc_args_RELEASEBUFFERPROC *a = (_HPyFunc_args_RELEASEBUFFERPROC*)args; - HPy_buffer hbuf; - _buffer_py2h(dctx, a->view, &hbuf); - DHPy dh_self = _py2dh(dctx, a->self); - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - return; - } - - f(next_dctx, dh_self, &hbuf); - - _switch_back_to_original_dctx(dctx, next_dctx); - - DHPy_close_and_check(dctx, dh_self); - // XXX: copy back from hbuf? - HPy_Close(dctx, hbuf.obj); - return; - } - case HPyFunc_TRAVERSEPROC: { - HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; - _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; - - HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx); - if (next_dctx == NULL) { - a->result = -1; - return; - } - - a->result = call_traverseproc_from_trampoline(f, a->self, - a->visit, a->arg); - - _switch_back_to_original_dctx(dctx, next_dctx); - return; - } - case HPyFunc_CAPSULE_DESTRUCTOR: { - HPyFunc_Capsule_Destructor f = (HPyFunc_Capsule_Destructor)func; - PyObject *capsule = (PyObject *)args; - const char *name = PyCapsule_GetName(capsule); - f(name, PyCapsule_GetPointer(capsule, name), - PyCapsule_GetContext(capsule)); - return; - } - case HPyFunc_MOD_CREATE: { - 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); - DHPy_close_and_check(dctx, dh_arg0); - a->result = _dh2py(dctx, dh_result); - _HPyModule_CheckCreateSlotResult(&a->result); - DHPy_close(dctx, dh_result); - return; - } -#include "autogen_debug_ctx_call.i" - default: - Py_FatalError("Unsupported HPyFunc_Signature in debug_ctx_cpython.c"); - } -} diff --git a/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c b/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c deleted file mode 100644 index 7df607ee76..0000000000 --- a/graalpython/hpy/hpy/debug/src/debug_ctx_not_cpython.c +++ /dev/null @@ -1,16 +0,0 @@ -// This is for non-CPython implementations! -// -// If you want to bundle the debug mode into your own version of -// hpy.universal, make sure to compile this file and NOT debug_ctx_cpython.c - -#include "debug_internal.h" - -void debug_ctx_CallRealFunctionFromTrampoline(HPyContext *dctx, - HPyFunc_Signature sig, - void *func, void *args) -{ - HPyContext *uctx = get_info(dctx)->uctx; - HPy_FatalError(uctx, - "Something is very wrong! _HPy_CallRealFunctionFromTrampoline() " - "should be used only by the CPython version of hpy.universal"); -} diff --git a/graalpython/hpy/hpy/debug/src/debug_handles.c b/graalpython/hpy/hpy/debug/src/debug_handles.c deleted file mode 100644 index fe2d32cb7d..0000000000 --- a/graalpython/hpy/hpy/debug/src/debug_handles.c +++ /dev/null @@ -1,298 +0,0 @@ -#include -#include "debug_internal.h" - -static void debug_handles_sanity_check(HPyDebugInfo *info) -{ -#ifndef NDEBUG - DHQueue_sanity_check(&info->open_handles); - DHQueue_sanity_check(&info->closed_handles); - DebugHandle *h = (DebugHandle *)info->open_handles.head; - while(h != NULL) { - assert(!h->is_closed); - h = (DebugHandle *)h->node.next; - } - h = (DebugHandle *)info->closed_handles.head; - while(h != NULL) { - assert(h->is_closed); - h = (DebugHandle *)h->node.next; - } -#endif -} - -static void DebugHandle_free_raw_data(HPyDebugInfo *info, DebugHandle *handle, bool was_counted_in_limit) { - if (handle->associated_data) { - if (was_counted_in_limit) { - info->protected_raw_data_size -= handle->associated_data_size; - } - if (raw_data_free(handle->associated_data, handle->associated_data_size)) { - HPy_FatalError(info->uctx, "HPy could not free internally allocated memory."); - } - handle->associated_data = NULL; - } -} - -static DHPy _DHPy_open(HPyContext *dctx, UHPy uh, bool is_immortal) -{ - UHPy_sanity_check(uh); - if (HPy_IsNull(uh)) - return HPy_NULL; - HPyDebugInfo *info = get_info(dctx); - - // if the closed_handles queue is full, let's reuse one of those. Else, - // malloc a new one - DebugHandle *handle = NULL; - if (info->closed_handles.size >= info->closed_handles_queue_max_size) { - handle = (DebugHandle *)DHQueue_popfront(&info->closed_handles); - DebugHandle_free_raw_data(info, handle, true); - if (handle->allocation_stacktrace) - free(handle->allocation_stacktrace); - } - else { - handle = malloc(sizeof(DebugHandle)); - if (handle == NULL) { - return HPyErr_NoMemory(info->uctx); - } - } - if (info->handle_alloc_stacktrace_limit > 0) { - create_stacktrace(&handle->allocation_stacktrace, - info->handle_alloc_stacktrace_limit); - } else { - handle->allocation_stacktrace = NULL; - } - handle->uh = uh; - handle->generation = info->current_generation; - handle->is_closed = 0; - handle->is_immortal = is_immortal; - handle->associated_data = NULL; - handle->associated_data_size = 0; - DHQueue_append(&info->open_handles, (DHQueueNode *)handle); - debug_handles_sanity_check(info); - return as_DHPy(handle); -} - -DHPy DHPy_open_immortal(HPyContext *dctx, UHPy uh) { - return _DHPy_open(dctx, uh, true); -} - -DHPy DHPy_open(HPyContext *dctx, UHPy uh) -{ - return _DHPy_open(dctx, uh, false); -} - -static void print_error(HPyContext *uctx, const char *message) -{ - // We don't have a way to propagate exceptions from within DHPy_unwrap, so - // we just print the exception to stderr and clear it - // XXX: we should use HPySys_WriteStderr when we have it - fprintf(stderr, "%s\n", message); - //HPyErr_PrintEx(0); // uncomment when we have it -} - -static inline void -debug_call_invalid_callback(HPyContext *uctx, HPy h_callback) -{ - /* Call the custom callback but do NOT abort the execution. This is useful - e.g. on CPython where "closed handles" are still actually valid (as long - as the refcount > 0): it should make it easier to port extensions to HPy, - e.g. by printing a warning inside the callback and let the execution to - continue, so that people can fix the warnings one by one. - */ - UHPy uh_res = HPy_NULL; - uh_res = HPy_CallTupleDict(uctx, h_callback, HPy_NULL, HPy_NULL); - if (HPy_IsNull(uh_res)) - print_error(uctx, - "Error when executing the on_invalid_(builder_)handle callback"); - HPy_Close(uctx, uh_res); -} - -// this is called when we try to use a closed handle -void DHPy_invalid_handle(HPyContext *dctx, DHPy dh) -{ - HPyDebugInfo *info = get_info(dctx); - HPyContext *uctx = info->uctx; - assert(as_DebugHandle(dh)->is_closed || as_DebugHandle(dh)->is_immortal); - if (HPy_IsNull(info->uh_on_invalid_handle)) { - // default behavior: print an error and abort - HPy_FatalError(uctx, "Invalid usage of already closed handle"); - } - debug_call_invalid_callback(uctx, info->uh_on_invalid_handle); -} - -// DHPy_close, unlike debug_ctx_Close does not check the validity of the handle. -// Use this in case you want to close only the debug handle like DHPy_close, -// you but still want to check its validity -void DHPy_close_and_check(HPyContext *dctx, DHPy dh) { - DHPy_unwrap(dctx, dh); - DHPy_close(dctx, dh); -} - -// Note: the difference from just HPy_Close(dctx, dh), which calls debug_ctx_Close, -// is that this only closes the debug handle. This is useful in situations -// where we know that the wrapped handle will be closed by the wrapped context. -void DHPy_close(HPyContext *dctx, DHPy dh) -{ - DHPy_sanity_check(dh); - if (HPy_IsNull(dh)) - return; - HPyDebugInfo *info = get_info(dctx); - DebugHandle *handle = as_DebugHandle(dh); - - /* This check is needed for a very specific case: calling HPy_Close twice - on the same handle is considered an error, and by default the - DHPy_unwrap inside debug_ctx_Close catches the problem and abort the - process with a HPy_FatalError. - - However, we leave the possibility to the user to install a custom hook - to be called when we detect an invalid handle. In this case, the - process does not abort and the execution tries to continue. This is - more useful than what it sounds, because on CPython "closing a handle - twice" still works in practice as long as the refcount > 0. So, we can - install a hook which emits a warning and let the user to fix the - problems one by one, without aborting the process. - */ - if (handle->is_closed) - return; - - // Closing context constants is never allowed - if (handle->is_immortal) - DHPy_invalid_handle(dctx, dh); - - // move the handle from open_handles to closed_handles - DHQueue_remove(&info->open_handles, (DHQueueNode *)handle); - DHQueue_append(&info->closed_handles, (DHQueueNode *)handle); - handle->is_closed = true; - if (handle->associated_data) { - // So far all implementations of raw_data_protect keep the physical - // memory (or at least are not guaranteed to release it), which leaks. - // Ideally the raw_data_protect implementation would at least release - // the physical memory, but in any case it would still leak the virtual - // memory. To mitigate this a bit, we free the memory once the closed - // handle is removed from the closed handles queue (because it reaches - // max size), or if the total size of the retained/leaked memory would - // overflow configured limit. - HPy_ssize_t new_size = info->protected_raw_data_size + handle->associated_data_size; - if (new_size > info->protected_raw_data_max_size) { - // free it now - DebugHandle_free_raw_data(info, handle, false); - } else { - // keep/leak it and make it protected from further reading - info->protected_raw_data_size = new_size; - raw_data_protect(handle->associated_data, handle->associated_data_size); - } - } - - if (info->closed_handles.size > info->closed_handles_queue_max_size) { - // we have too many closed handles. Let's free the oldest one - DebugHandle *oldest = (DebugHandle *)DHQueue_popfront(&info->closed_handles); - DHPy_free(dctx, as_DHPy(oldest)); - } - debug_handles_sanity_check(info); -} - -void DHPy_free(HPyContext *dctx, DHPy dh) -{ - DHPy_sanity_check(dh); - DebugHandle *handle = as_DebugHandle(dh); - HPyDebugInfo *info = get_info(dctx); - DebugHandle_free_raw_data(info, handle, true); - if (handle->allocation_stacktrace) - free(handle->allocation_stacktrace); - // this is not strictly necessary, but it increases the chances that you - // get a clear segfault if you use a freed handle - handle->uh = HPy_NULL; - free(handle); -} - -static DebugBuilderHandle *debug_builder_handle_open(HPyContext *dctx) -{ - HPyDebugInfo *info = get_info(dctx); - - /* If the closed_builder queue is full, let's reuse one of those; otherwise, - malloc a new one. */ - DebugBuilderHandle *handle = NULL; - if (info->closed_builder.size >= info->closed_handles_queue_max_size) { - handle = (DebugBuilderHandle *)DHQueue_popfront(&info->closed_builder); - } - else { - handle = malloc(sizeof(DebugBuilderHandle)); - if (handle == NULL) { - /* To be consistent with the contract of - 'HPy(Tuple|List)Builder_New', don't raise an error here and defer - to the build function. */ - return NULL; - } - } - handle->is_closed = false; - /* If we want to track open builder handles, this would be the right place - to move append the new builder handle to the list of open ones. */ - return handle; -} - -/** - * Closes a ``DebugBuilderHandle`` which means that it is appended to the list - * of closed builder handles. If the list reached its maximum, the oldest - * builder handle will be free'd. Note, that the contained builder handle - * (i.e. ``UHPyTupleBuilder`` or ``UHPyListBuilder``) won't be closed since - * that will be done by the wrapped function. - */ -void DHPy_builder_handle_close(HPyContext *dctx, DebugBuilderHandle *handle) -{ - HPyDebugInfo *info; - - /* This check is needed for a very specific case: calling - DHPy_builder_handle_close twice on the same handle is considered an - error and by default the DHPy(Tuple|List)Builder_unwrap catches the - problem and aborts the process with a HPy_FatalError. - - However, we leave the possibility to the user to install a custom hook - to be called when we detect an invalid builder handle. In this case, the - process does not abort and the execution tries to continue. This is - more useful than what it sounds. So, we can install a hook which emits a - warning and let the user to fix the problems one by one, without - aborting the process. - */ - if (handle->is_closed) - return; - - handle->is_closed = true; - info = get_info(dctx); - /* If we want to track open builder handles, this would be the right place - to move the handle from 'open_handles' to 'closed_handles'. */ - DHQueue_append(&info->closed_builder, (DHQueueNode *)handle); - if (info->closed_builder.size > info->closed_handles_queue_max_size) { - // we have too many closed builder handles. Let's free the oldest one - DebugBuilderHandle *oldest = (DebugBuilderHandle *)DHQueue_popfront(&info->closed_builder); - free(oldest); - } -} - -DHPyTupleBuilder DHPyTupleBuilder_open(HPyContext *dctx, UHPyTupleBuilder uh) -{ - if (DHPyTupleBuilder_IsNull(uh)) - return DHPyTupleBuilder_NULL; - DebugBuilderHandle *handle = debug_builder_handle_open(dctx); - if (handle != NULL) - handle->uh.tuple_builder = uh; - return as_DHPyTupleBuilder(handle); -} - -DHPyListBuilder DHPyListBuilder_open(HPyContext *dctx, UHPyListBuilder uh) -{ - if (DHPyListBuilder_IsNull(uh)) - return DHPyListBuilder_NULL; - DebugBuilderHandle *handle = debug_builder_handle_open(dctx); - if (handle != NULL) - handle->uh.list_builder = uh; - return as_DHPyListBuilder(handle); -} - -void DHPy_invalid_builder_handle(HPyContext *dctx) -{ - HPyDebugInfo *info = get_info(dctx); - HPyContext *uctx = info->uctx; - if (HPy_IsNull(info->uh_on_invalid_builder_handle)) { - // default behavior: print an error and abort - HPy_FatalError(uctx, "Invalid usage of already closed builder"); - } - debug_call_invalid_callback(uctx, info->uh_on_invalid_builder_handle); -} diff --git a/graalpython/hpy/hpy/debug/src/debug_internal.h b/graalpython/hpy/hpy/debug/src/debug_internal.h deleted file mode 100644 index af21732c7d..0000000000 --- a/graalpython/hpy/hpy/debug/src/debug_internal.h +++ /dev/null @@ -1,359 +0,0 @@ -/* Internal header for all the files in hpy/debug/src. The public API is in - include/hpy_debug.h -*/ -#ifndef HPY_DEBUG_INTERNAL_H -#define HPY_DEBUG_INTERNAL_H - -#include -#include "hpy.h" -#include "hpy_debug.h" - -#define HPY_DEBUG_INFO_MAGIC 0xDEB00FF -#define HPY_DEBUG_CTX_INFO_MAGIC 0xDDA003F - -/* === DHQueue === */ - -/** - * This struct is meant to be embedded in the actual payload struct to avoid - * a separate allocation of the queue node. - */ -typedef struct _DHQueueNode_s { - struct _DHQueueNode_s *next; - struct _DHQueueNode_s *prev; - HPy_ssize_t size; -} DHQueueNode; - -typedef struct { - DHQueueNode *head; - DHQueueNode *tail; - HPy_ssize_t size; -} DHQueue; - -void DHQueue_init(DHQueue *q); -void DHQueue_append(DHQueue *q, DHQueueNode *h); -DHQueueNode *DHQueue_popfront(DHQueue *q); -void DHQueue_remove(DHQueue *q, DHQueueNode *h); -void DHQueue_sanity_check(DHQueue *q); - -/* === DHQueue === */ - -/* The Debug context is a wrapper around an underlying context, which we will - call Universal. Inside the debug mode we manipulate handles which belongs - to both contexts, so to make things easier we create two typedefs to make - it clear what kind of handle we expect: UHPy and DHPy: - - * UHPy are opaque from our point of view. - - * DHPy are actually DebugHandle* in disguise. DebugHandles are wrappers - around a UHPy, with a bunch of extra info. - - To cast between DHPy and DebugHandle*, use as_DebugHandle and as_DHPy: - these are just no-op casts. - - Each DHPy wraps a corresponding UHPy: DHPys are created by calling - DHPy_open, and they must be eventually closed by DHPy_close. Note that if - you call DHPy_open twice on the same UHPy, you get two different DHPy. - - To unwrap a DHPy and get the underlying UHPy, call DHPy_unwrap. If you call - DHPy_unwrap multiple times on the same DHPy, you always get the same UHPy. - - WARNING: both UHPy and DHPy are alias of HPy, so we need to take care of - not mixing them, because the compiler cannot help. - - Each DebugHandle has a "generation", which is just an int to be able to get - only the handles which were created after a certain point. - - DHPys/DebugHandles are memory-managed by using a free list: - - - info->open_handles is a list of all DHPys which are currently open - - - DHPy_close() moves a DHPy from info->open_handles to info->closed_handles - - - if closed_handles is too big, the oldest DHPy is freed by DHPy_free() - - - to allocate memory for a new DHPy, DHPy_open() does the following: - - * if closed_handles is full, it reuses the memory of the oldest DHPy - in the queue - - * else, it malloc()s memory for a new DHPy - - - Each DebugHandle can have some "raw" data associated with it. It is a - generic pointer to any data. The validity, or life-time, of such pointer - is supposed to be the same as the that of the handle and the debug mode - enforces it. Additionally, the data can be also marked as write protected. - - Example is the `const char*` handed out by `HPyUnicode_AsUTF8AndSize`. It - must not be written by the user (users may discard the const modifier), and - the pointer is considered invalid once the handle is closed, so it must not - be accessed even for reading. Most Python implementations, will choose to - hand out pointer to the actual internal data, which happen to stay valid and - accessible and this may lead the users to a wrong conclusion that they can - use the pointer after the handle is closed. - - The memory protection mechanism is abstracted by several functions that - may have different implementations depending on the compile-time - configuration. Those are: - - * `raw_data_copy`: makes a copy of some data, optionally the copy can be - made read-only. - * `raw_data_protect`: protects the result of `raw_data_copy` from reading - * `raw_data_free`: if `raw_data_protect` retained any actual memory or other - resources, this indicates that those can be freed - - Any HPy context function that wishes to attach raw data to a handle should - make a copy of the actual data by using `raw_data_copy`. This copy should be - then set as the value of the associated_data field. Once the handle is - closed, the raw data pointer is passed to raw_data_protect and once the handle - is reused the raw data pointer is passed to raw_data_free. - - This means that if the implementation of `raw_data_protect` retains some - resources, we are leaking them. To mitigate this a bit, we have a limit on the - overall size of data that can be leaked and once it is reached, we use - raw_data_free immediately once the associated handle is closed. - - Note that, for example, the mmap based implementation of `raw_data_copy` - never allocates less than a page, so it actually takes more memory than - what is the size of the raw data. This is, however, mostly covered by the - limit on closed handles. For the default configuration we have: - - DEFAULT_CLOSED_HANDLES_QUEUE_MAX_SIZE = 1024 - DEFAULT_PROTECTED_RAW_DATA_MAX_SIZE = 1024 * 1024 * 10 - - the total leaked raw data size limit of 10MB is larger than if we created - and leaked 1024 handles with only a small raw data attached to them (4MB - for 1024 pages of 4KB). This ratio may be different for larger pages or for - different configuration of the limits. For the sake of keeping the - implementation reasonably simple and portable, we choose to ignore this - for the time being. -*/ - -typedef HPy UHPy; -typedef HPy DHPy; -typedef HPyTupleBuilder UHPyTupleBuilder; -typedef HPyTupleBuilder DHPyTupleBuilder; -typedef HPyListBuilder UHPyListBuilder; -typedef HPyListBuilder DHPyListBuilder; - -#define DHPyTupleBuilder_IsNull(h) ((h)._tup == 0) -#define DHPyListBuilder_IsNull(h) ((h)._lst == 0) - -#if defined(_MSC_VER) && defined(__cplusplus) // MSVC C4576 -# define UHPyListBuilder_NULL {0} -# define UHPyTupleBuilder_NULL {0} -# define DHPyListBuilder_NULL UHPyListBuilder_NULL -# define DHPyTupleBuilder_NULL UHPyTupleBuilder_NULL -#else -# define UHPyListBuilder_NULL ((UHPyListBuilder){0}) -# define UHPyTupleBuilder_NULL ((UHPyTupleBuilder){0}) -# define DHPyListBuilder_NULL ((DHPyListBuilder){0}) -# define DHPyTupleBuilder_NULL ((DHPyTupleBuilder){0}) -#endif - -/* Under CPython: - - UHPy always end with 1 (see hpy.universal's _py2h and _h2py) - - DHPy are pointers, so they always end with 0 - - DHPy_sanity_check is a minimal check to ensure that we are not treating a - UHPy as a DHPy. Note that DHPy_sanity_check works fine also on HPy_NULL. - - NOTE: UHPy_sanity_check works ONLY with CPython's hpy.universal, because - UHPys are computed in such a way that the last bit it's always 1. On other - implementations this assumption might not hold. By default, - UHPy_sanity_check does nothing, unless you #define - HPY_DEBUG_ENABLE_UHPY_SANITY_CHECK, which for CPython is done by setup.py -*/ -static inline void DHPy_sanity_check(DHPy dh) { - assert( (dh._i & 1) == 0 ); -} - -static inline void UHPy_sanity_check(UHPy uh) { -#ifdef HPY_DEBUG_ENABLE_UHPY_SANITY_CHECK - if (!HPy_IsNull(uh)) - assert( (uh._i & 1) == 1 ); -#endif -} - -// NOTE: having a "generation" field is the easiest way to know when a handle -// was created, but we waste 8 bytes per handle. Since all handles of the same -// generation are stored sequentially in the open_handles list, a possible -// alternative implementation is to put special placeholders inside the list -// to mark the creation of a new generation -typedef struct DebugHandle { - DHQueueNode node; - UHPy uh; - long generation; - bool is_closed:1; - bool is_immortal:1; - // pointer to and size of any raw data associated with - // the lifetime of the handle: - void *associated_data; - // allocation_stacktrace information if available - char *allocation_stacktrace; - HPy_ssize_t associated_data_size; -} DebugHandle; - -/** A debug handle for a tuple or list builder. */ -typedef struct DebugBuilderHandle { - DHQueueNode node; - union { - UHPyTupleBuilder tuple_builder; - UHPyListBuilder list_builder; - } uh; - - /** - * ``true`` if the builder was consumed by the build function or cancelled. - */ - bool is_closed:1; -} DebugBuilderHandle; - -static inline DebugHandle * as_DebugHandle(DHPy dh) { - DHPy_sanity_check(dh); - return (DebugHandle *)dh._i; -} - -static inline DHPy as_DHPy(DebugHandle *handle) { - return (DHPy){(HPy_ssize_t)handle}; -} - -static inline DebugBuilderHandle * DHPyTupleBuilder_as_DebugBuilderHandle(DHPyTupleBuilder dh) { - if (DHPyTupleBuilder_IsNull(dh)) - return NULL; - return (DebugBuilderHandle *)dh._tup; -} - -static inline DHPyTupleBuilder as_DHPyTupleBuilder(DebugBuilderHandle *handle) { - return (DHPyTupleBuilder){(HPy_ssize_t)handle}; -} - -static inline DebugBuilderHandle * DHPyListBuilder_as_DebugBuilderHandle(DHPyListBuilder dh) { - if (DHPyListBuilder_IsNull(dh)) - return NULL; - return (DebugBuilderHandle *)dh._lst; -} - -static inline DHPyListBuilder as_DHPyListBuilder(DebugBuilderHandle *handle) { - return (DHPyListBuilder){(HPy_ssize_t)handle}; -} - -DHPy DHPy_open(HPyContext *dctx, UHPy uh); -DHPy DHPy_open_immortal(HPyContext *dctx, UHPy uh); -void DHPy_close(HPyContext *dctx, DHPy dh); -void DHPy_close_and_check(HPyContext *dctx, DHPy dh); -void DHPy_free(HPyContext *dctx, DHPy dh); -void DHPy_invalid_handle(HPyContext *dctx, DHPy dh); -DHPyTupleBuilder DHPyTupleBuilder_open(HPyContext *dctx, UHPyTupleBuilder uh); -DHPyListBuilder DHPyListBuilder_open(HPyContext *dctx, UHPyListBuilder uh); -void DHPy_invalid_builder_handle(HPyContext *dctx); -void DHPy_builder_handle_close(HPyContext *dctx, DebugBuilderHandle *handle); - -static inline UHPy DHPy_unwrap(HPyContext *dctx, DHPy dh) -{ - if (HPy_IsNull(dh)) - return HPy_NULL; - DebugHandle *handle = as_DebugHandle(dh); - if (handle->is_closed) - DHPy_invalid_handle(dctx, dh); - return handle->uh; -} - -#define BUILDER_UNWRAP(TYPE, ACCESS) \ - static inline U##TYPE D##TYPE##_unwrap(HPyContext *dctx, D##TYPE dh) \ - { \ - DebugBuilderHandle *handle = D##TYPE##_as_DebugBuilderHandle(dh); \ - if (handle == NULL) \ - return U##TYPE##_NULL; \ - if (handle->is_closed) { \ - DHPy_invalid_builder_handle(dctx); \ - return U##TYPE##_NULL; \ - } \ - return handle->uh.ACCESS; \ - } - -BUILDER_UNWRAP(HPyTupleBuilder, tuple_builder) -BUILDER_UNWRAP(HPyListBuilder, list_builder) - -/* === HPyDebugInfo === */ - -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; - - // 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: - // 1. a generic HPy_GcMalloc() OR - // 2. HPy_{Un}TrackMemory(), so that we can add manually allocated - // memory as a GC root - // Alternative is to put it into a module state or to put it into HPyGlobal - // once those features are implemented - UHPy uh_on_invalid_handle; - UHPy uh_on_invalid_builder_handle; - HPy_ssize_t closed_handles_queue_max_size; // configurable by the user - HPy_ssize_t protected_raw_data_max_size; - HPy_ssize_t protected_raw_data_size; - // Limit for the stack traces captured for allocated handles - // Value 0 implies that stack traces should not be captured - HPy_ssize_t handle_alloc_stacktrace_limit; - DHQueue open_handles; - DHQueue closed_handles; - 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 = 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 */ -int raw_data_free(void *data, HPy_ssize_t size); - -void create_stacktrace(char **target, HPy_ssize_t max_frames_count); - -#endif /* HPY_DEBUG_INTERNAL_H */ diff --git a/graalpython/hpy/hpy/debug/src/dhqueue.c b/graalpython/hpy/hpy/debug/src/dhqueue.c deleted file mode 100644 index 86e8c17679..0000000000 --- a/graalpython/hpy/hpy/debug/src/dhqueue.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "debug_internal.h" - -// TODO: we need to make DHQueue thread-safe if we want to use the same -// context in multiple threads -void DHQueue_init(DHQueue *q) { - q->head = NULL; - q->tail = NULL; - q->size = 0; -} - -void DHQueue_append(DHQueue *q, DHQueueNode *h) { - if (q->head == NULL) { - h->prev = NULL; - h->next = NULL; - q->head = h; - q->tail = h; - } else { - h->next = NULL; - h->prev = q->tail; - q->tail->next = h; - q->tail = h; - } - q->size++; -} - -DHQueueNode *DHQueue_popfront(DHQueue *q) -{ - assert(q->size > 0); - assert(q->head != NULL); - DHQueueNode *head = q->head; - if (q->size == 1) { - q->head = NULL; - q->tail = NULL; - q->size = 0; - } - else { - q->head = head->next; - q->head->prev = NULL; - q->size--; - } - // the following is not strictly necessary, but it makes thing much easier - // to debug in case of bugs - head->next = NULL; - head->prev = NULL; - return head; -} - -void DHQueue_remove(DHQueue *q, DHQueueNode *h) -{ -#ifndef NDEBUG - // if we are debugging, let's check that h is effectively in the queue - DHQueueNode *it = q->head; - bool found = false; - while(it != NULL) { - if (it == h) { - found = true; - break; - } - it = it->next; - } - assert(found); -#endif - if (q->size == 1) { - q->head = NULL; - q->tail = NULL; - } else if (h == q->head) { - assert(h->prev == NULL); - q->head = h->next; - q->head->prev = NULL; - } else if (h == q->tail) { - assert(h->next == NULL); - q->tail = h->prev; - q->tail->next = NULL; - } - else { - h->prev->next = h->next; - h->next->prev = h->prev; - } - q->size--; - h->next = NULL; - h->prev = NULL; -} - - -#ifndef NDEBUG -static void linked_item_sanity_check(DHQueueNode *h) -{ - if (h == NULL) - return; - if (h->next != NULL) - assert(h->next->prev == h); - if (h->prev != NULL) - assert(h->prev->next == h); -} -#endif - -void DHQueue_sanity_check(DHQueue *q) -{ -#ifndef NDEBUG - if (q->head == NULL || q->tail == NULL) { - assert(q->head == NULL); - assert(q->tail == NULL); - assert(q->size == 0); - } - else { - assert(q->head->prev == NULL); - assert(q->tail->next == NULL); - assert(q->size > 0); - DHQueueNode *h = q->head; - HPy_ssize_t size = 0; - while(h != NULL) { - linked_item_sanity_check(h); - if (h->next == NULL) - assert(h == q->tail); - h = h->next; - size++; - } - assert(q->size == size); - } -#endif -} diff --git a/graalpython/hpy/hpy/debug/src/include/hpy_debug.h b/graalpython/hpy/hpy/debug/src/include/hpy_debug.h deleted file mode 100644 index f2fb9471b3..0000000000 --- a/graalpython/hpy/hpy/debug/src/include/hpy_debug.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HPY_DEBUG_H -#define HPY_DEBUG_H - -#include "hpy.h" - -/* - This is the main public API for the debug mode, and it's meant to be used - by hpy.universal implementations (including but not limited to the - CPython's version of hpy.universal which is included in this repo). - - The idea is that for every uctx there is a corresponding unique dctx which - wraps it. - - If you call hpy_debug_get_ctx twice on the same uctx, you get the same - result. - - IMPLEMENTATION NOTE: at the moment of writing, the only known user of the - debug mode is CPython's hpy.universal: in that module, the uctx is a - statically allocated singleton, so for simplicity of implementation - currently we do the same inside debug_ctx.c, with a sanity check to ensure - that we don't call hpy_debug_get_ctx with different uctxs. But this is a - limitation of the current implementation and users should not rely on it. It - is likely that we will need to change it in the future, e.g. if we want to - have per-subinterpreter uctxs. -*/ - -HPyContext * hpy_debug_get_ctx(HPyContext *uctx); -int hpy_debug_ctx_init(HPyContext *dctx, HPyContext *uctx); -void hpy_debug_set_ctx(HPyContext *dctx); - -// convert between debug and universal handles. These are basically -// the same as DHPy_open and DHPy_unwrap but with a different name -// because this is the public-facing API and DHPy/UHPy are only internal -// implementation details. -HPy hpy_debug_open_handle(HPyContext *dctx, HPy uh); -HPy hpy_debug_unwrap_handle(HPyContext *dctx, HPy dh); -void hpy_debug_close_handle(HPyContext *dctx, HPy dh); - -// this is the HPy init function created by HPy_MODINIT. In CPython's version -// of hpy.universal the code is embedded inside the extension, so we can call -// this function directly instead of dlopen it. This is similar to what -// CPython does for its own built-in modules. But we must use the same -// signature as HPy_MODINIT - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -HPyModuleDef* HPyInit__debug(); - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -void HPyInitGlobalContext__debug(HPyContext *ctx); - -#endif /* HPY_DEBUG_H */ diff --git a/graalpython/hpy/hpy/debug/src/memprotect.c b/graalpython/hpy/hpy/debug/src/memprotect.c deleted file mode 100644 index 9f2ffe69f6..0000000000 --- a/graalpython/hpy/hpy/debug/src/memprotect.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "debug_internal.h" - -// Implements OS dependent abstraction of memory protection - -#ifdef _HPY_DEBUG_MEM_PROTECT_USEMMAP - -#ifndef _WIN32 - -// On UNIX systems we use mmap and mprotect - -#include -#include - -void *raw_data_copy(const void* data, HPy_ssize_t size, bool write_protect) { - void* new_ptr; - new_ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (new_ptr == NULL) - return NULL; - memcpy(new_ptr, data, size); - if (write_protect) { - mprotect(new_ptr, size, PROT_READ); - } - return new_ptr; -} - -void raw_data_protect(void* data, HPy_ssize_t size) { - mprotect(data, size, PROT_NONE); -} - -int raw_data_free(void *data, HPy_ssize_t size) { - return munmap(data, size); -} - -#else - -// On Windows systems we use VirtualAlloc and VirtualProtect - -#include -#include - -void *raw_data_copy(const void* data, HPy_ssize_t size, bool write_protect) { - void* new_ptr; - DWORD old; - new_ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if (new_ptr == NULL) - return NULL; - memcpy(new_ptr, data, size); - if (write_protect) { - VirtualProtect(new_ptr, size, PAGE_READONLY, &old); - } - return new_ptr; -} - -void raw_data_protect(void* data, HPy_ssize_t size) { - DWORD old; - VirtualProtect(data, size, PAGE_NOACCESS, &old); -} - -int raw_data_free(void *data, HPy_ssize_t size) { - return !VirtualFree(data, 0, MEM_RELEASE); -} - -#endif /* _WIN32 */ - -#else - -// Generic fallback that should work for any OS with decent C compiler: copy -// the memory and then override it with garbage to "protect" it from reading. - -#include -#include - -void *raw_data_copy(const void* data, HPy_ssize_t size, bool write_protect) { - void *new_data = malloc(size); - memcpy(new_data, data, size); - return new_data; -} - -void raw_data_protect(void* data, HPy_ssize_t size) { - // Override the data with some garbage in hope that the program will - // eventually crash or give incorrect result if it reads the garbage - char poison[] = {0xBA, 0xD0, 0xDA, 0x7A}; - for (HPy_ssize_t dataIdx = 0, poisonIdx = 0; dataIdx < size; ++dataIdx) { - ((char*)data)[dataIdx] = poison[poisonIdx]; - poisonIdx = (poisonIdx + 1) % sizeof(poison); - } -} - -int raw_data_free(void *data, HPy_ssize_t size) { - free(data); - return 0; -} - -#endif diff --git a/graalpython/hpy/hpy/debug/src/stacktrace.c b/graalpython/hpy/hpy/debug/src/stacktrace.c deleted file mode 100644 index cc556b3bbd..0000000000 --- a/graalpython/hpy/hpy/debug/src/stacktrace.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "debug_internal.h" - -#if ((__linux__ && __GNU_LIBRARY__) || __APPLE__) - -// Basic implementation that uses backtrace from glibc - -#include -#include -#include - -static inline int max_s(size_t a, size_t b) { - return a > b ? a : b; -} - -void create_stacktrace(char **target, HPy_ssize_t max_frames_count) { - const size_t skip_frames = 2; - size_t max_stack_size = (size_t) max_frames_count; - void* stack = calloc(sizeof(void*), max_stack_size); - if (stack == NULL) { - *target = NULL; - return; - } - - size_t stack_size = backtrace(stack, max_stack_size); - if (stack_size <= skip_frames) { - *target = NULL; - free(stack); - return; - } - - char** symbols = backtrace_symbols(stack, stack_size); - if (symbols == NULL) { - *target = NULL; - free(stack); - return; - } - - size_t buffer_size = 1024; - size_t buffer_index = 0; - char *buffer = malloc(buffer_size); - if (buffer == NULL) { - *target = NULL; - free(symbols); - free(stack); - return; - } - - size_t i; - for (i = skip_frames; i < stack_size; ++i) { - size_t current_len = strlen(symbols[i]); - size_t required_buffer_size = buffer_index + current_len + 1; - if (required_buffer_size > buffer_size) { - buffer_size = max_s(buffer_size * 2, required_buffer_size); - char *new_buffer = realloc(buffer, buffer_size); - if (new_buffer == NULL) { - // allocation failed, we can still provide at least part of - // the stack trace that is currently in the buffer - break; - } - buffer = new_buffer; - } - memcpy(buffer + buffer_index, symbols[i], current_len); - buffer[buffer_index + current_len] = '\n'; - buffer_index = required_buffer_size; - } - - // override the last '\n' to '\0' - assert(stack_size - skip_frames > 0); - assert(buffer[buffer_index - 1] == '\n'); - buffer[buffer_index - 1] = '\0'; - char *shorter_buffer = realloc(buffer, buffer_index); - if (shorter_buffer != NULL) { - buffer = shorter_buffer; - } - *target = buffer; - - free(symbols); - free(stack); -} - -#else - -#include - -void create_stacktrace(char **target, HPy_ssize_t max_frames_count) { - const char msg[] = - "Current HPy build does not support getting C stack traces.\n" - "At the moment this is only supported on Linux with glibc" - " and macOS."; - *target = malloc(sizeof(msg)); - memcpy(*target, msg, sizeof(msg)); -} - -#endif \ No newline at end of file diff --git a/graalpython/hpy/hpy/devel/__init__.py b/graalpython/hpy/hpy/devel/__init__.py deleted file mode 100644 index 3b7f6e6d18..0000000000 --- a/graalpython/hpy/hpy/devel/__init__.py +++ /dev/null @@ -1,464 +0,0 @@ -# NOTE: this file is also imported by PyPy tests, so it must be compatible -# with both Python 2.7 and Python 3.x - -import sys -import os.path -import functools -import re -from pathlib import Path - -# setuptools >= 60.2 ships its own version of distutils, which monkey-patches -# the stdlib one. Here we ensure that we are using setuptool's. -# -# But this file needs to be importable also in py27 (for pypy tests), and we -# don't care about setuptools version in that case. -import setuptools -import distutils -if (sys.version_info.major > 2 and - distutils is not getattr(setuptools, '_distutils', None)): - raise Exception( - "setuptools' monkey-patching of distutils did not work. " - "Most likely this is caused by:\n" - " - a too old setuptools. Try installing setuptools>=60.2\n" - " - the env variable SETUPTOOLS_USE_DISTUTILS=stdlib. Try to unset it." - ) -from distutils import log -from distutils.errors import DistutilsError -import setuptools.command as cmd -try: - import setuptools.command.build -except ImportError: - print( - "warning: setuptools.command.build does not exist in setuptools", - setuptools.__version__, "on", sys.version - ) - setuptools.command.build = None -import setuptools.command.build_ext -import setuptools.command.bdist_egg - -from .abitag import get_hpy_ext_suffix - -DEFAULT_HPY_ABI = 'universal' -if hasattr(sys, 'implementation') and sys.implementation.name == 'cpython': - DEFAULT_HPY_ABI = 'cpython' - - -class HPyDevel: - """ Extra sources for building HPy extensions with hpy.devel. """ - - _DEFAULT_BASE_DIR = Path(__file__).parent - - def __init__(self, base_dir=_DEFAULT_BASE_DIR): - self.base_dir = Path(base_dir) - self.include_dir = self.base_dir.joinpath('include') - self.src_dir = self.base_dir.joinpath('src', 'runtime') - self._available_static_libs = None - - def get_extra_include_dirs(self): - """ Extra include directories needed by extensions in both CPython and - Universal modes. - """ - return list(map(str, [ - self.include_dir, - ])) - - def get_include_dir_forbid_python_h(self): - return self.include_dir.joinpath('hpy', 'forbid_python_h') - - def get_extra_sources(self): - """ Extra sources needed by extensions in both CPython and Universal - modes. - """ - return list(map(str, [ - self.src_dir.joinpath('argparse.c'), - self.src_dir.joinpath('buildvalue.c'), - self.src_dir.joinpath('format.c'), - self.src_dir.joinpath('helpers.c'), - self.src_dir.joinpath('structseq.c'), - ])) - - def _scan_static_lib_dir(self): - """ Scan the static library directory and build a dict for all - available static libraries. The library directory contains - subdirectories for each ABI and the ABI folders then contain - the static libraries. - """ - available_libs = {} - lib_dir = self.base_dir.joinpath('lib') - if lib_dir.exists(): - for abi_dir in lib_dir.iterdir(): - if abi_dir.is_dir(): - abi = abi_dir.name - # All files in '.../lib//' are considered to be static - # libraries. - available_libs[abi] = \ - [str(x) for x in abi_dir.iterdir() if x.is_file()] - return available_libs - - def get_static_libs(self, hpy_abi): - """ The list of necessary static libraries an HPy extension needs to - link to or 'None' (if not available). The HPy ext needs to link to - all static libraries in the list otherwise some function may stay - unresolved. For example, there is library 'hpyextra' which contains - compiled HPy helper functions like 'HPyArg_Parse' and such. - Libraries are always specific to an ABI. - """ - if not self._available_static_libs: - # lazily initialize the dict of available (=shipped) static libs - self._available_static_libs = self._scan_static_lib_dir() - return self._available_static_libs.get(hpy_abi, None) - - def get_ctx_sources(self): - """ Extra sources needed only in the CPython ABI mode. - """ - return list(map(str, self.src_dir.glob('ctx_*.c'))) - - def fix_distribution(self, dist): - """ Override build_ext to support hpy modules. - - Used from both setup.py and hpy/test. - """ - # ============= Distribution ========== - dist.hpydevel = self - - @monkeypatch(dist.__class__) - def has_ext_modules(self): - if self.ext_modules or self.hpy_ext_modules: - return True - return False - - # ============= build ========== - if cmd.build is not None: - build = dist.cmdclass.get("build", cmd.build.build) - build_hpy = make_mixin(build, build_hpy_mixin) - dist.cmdclass['build'] = build_hpy - - # ============= build_ext ========== - build_ext = dist.cmdclass.get("build_ext", cmd.build_ext.build_ext) - self.build_ext_sanity_check(build_ext) - build_ext_hpy = make_mixin(build_ext, build_ext_hpy_mixin) - dist.cmdclass['build_ext'] = build_ext_hpy - - # ============= bdist_egg ========== - @monkeypatch(setuptools.command.bdist_egg) - def write_stub(resource, pyfile): - """ - This is needed because the default bdist_egg unconditionally writes a .py - stub, thus overwriting the one which was created by - build_ext_hpy_mixin.write_stub. - """ - ext_suffix = None - if dist.hpy_abi != 'cpython': - ext_suffix = get_hpy_ext_suffix(dist.hpy_abi) - # - if ext_suffix and resource.endswith(ext_suffix): - log.info("stub file already created for %s", resource) - else: - write_stub.super(resource, pyfile) - - def build_ext_sanity_check(self, build_ext): - # check that the supplied build_ext inherits from setuptools - if isinstance(build_ext, type): - assert ('setuptools.command.build_ext', 'build_ext') in [ - (c.__module__, c.__name__) for c in build_ext.__mro__ - ], ( - "dist.cmdclass['build_ext'] does not inherit from" - " setuptools.command.build_ext.build_ext. The HPy build" - " system does not currently support any other build_ext" - " classes. If you are using distutils.commands.build_ext," - " please use setuptools.commands.build_ext instead." - ) - - -def handle_hpy_ext_modules(dist, attr, hpy_ext_modules): - """ Distuils hpy_ext_module setup(...) argument and --hpy-abi option. - - See hpy's setup.py where this function is registered as an entry - point. - """ - assert attr == 'hpy_ext_modules' - - # It can happen that this hook will be called multiple times depending on - # which command was used. So, skip patching if we already patched the - # distribution. - if getattr(dist, 'hpydevel', None): - return - - # add a global option --hpy-abi to setup.py - dist.__class__.hpy_abi = DEFAULT_HPY_ABI - dist.__class__.hpy_use_static_libs = False - dist.__class__.global_options += [ - ('hpy-abi=', None, 'Specify the HPy ABI mode (default: %s)' - % DEFAULT_HPY_ABI), - ('hpy-use-static-libs', None, 'Use static library containing context ' - 'and helper functions for building ' - 'extensions (default: False)') - ] - hpydevel = HPyDevel() - hpydevel.fix_distribution(dist) - - -_HPY_UNIVERSAL_MODULE_STUB_TEMPLATE = """ -# DO NOT EDIT THIS FILE! -# This file is automatically generated by hpy - -def __bootstrap__(): - - from sys import modules - from os import environ - from pkg_resources import resource_filename - from hpy.universal import _load_bootstrap - ext_filepath = resource_filename(__name__, {ext_file!r}) - m = _load_bootstrap({module_name!r}, __name__, __package__, ext_filepath, - __loader__, __spec__, environ) - modules[__name__] = m - -__bootstrap__() -""" - - -class HPyExtensionName(str): - """ Wrapper around str to allow HPy extension modules to be identified. - - The following build_ext command methods are passed only the *name* - of the extension and not the full extension object. The - build_ext_hpy_mixin class needs to detect when HPy are extensions - passed to these methods and override the default behaviour. - - This str sub-class allows HPy extensions to be detected, while - still allowing the extension name to be used as an ordinary string. - """ - - def split(self, *args, **kw): - result = str.split(self, *args, **kw) - return [self.__class__(s) for s in result] - - def translate(self, *args, **kw): - result = str.translate(self, *args, **kw) - return self.__class__(result) - - -def is_hpy_extension(ext_name): - """ Return True if the extension name is for an HPy extension. """ - return isinstance(ext_name, HPyExtensionName) - - -def remember_hpy_extension(f): - """ Decorator for remembering whether an extension name belongs to an - HPy extension. - """ - @functools.wraps(f) - def wrapper(self, ext_name): - if self._only_hpy_extensions: - assert is_hpy_extension(ext_name), ( - "Extension name %r is not marked as an HPyExtensionName" - " but only HPy extensions are present. This is almost" - " certainly a bug in HPy's overriding of setuptools" - " build_ext. Please report this error the HPy maintainers." - % (ext_name,) - ) - result = f(self, ext_name) - if is_hpy_extension(ext_name): - result = HPyExtensionName(result) - return result - return wrapper - - -# ================================================== -# Augmented setuptools commands and monkeypatching -# ================================================== - -def make_mixin(base, mixin): - """ - Create a new class which inherits from both mixin and base, so that the - methods of mixin effectively override the ones of base - """ - class NewClass(mixin, base, object): - _mixin_super = base - NewClass.__name__ = base.__name__ + '_hpy' - return NewClass - -def monkeypatch(target): - """ - Decorator to monkey patch a function in a module. The original function - will be available as new_function.super() - """ - def decorator(fn): - name = fn.__name__ - fn.super = getattr(target, name) - setattr(target, name, fn) - return fn - return decorator - - -class build_hpy_mixin: - """ A mixin class to override setuptools.commands.build """ - - def finalize_options(self): - self._mixin_super.finalize_options(self) - if self.distribution.hpy_abi != 'cpython': - suffix = '-hpy-%s' % self.distribution.hpy_abi - self.build_platlib += suffix - self.build_lib += suffix - self.build_temp += suffix - - -class build_ext_hpy_mixin: - """ A mixin class to override setuptools.commands.build_ext """ - - # Ideally we would have simply added the HPy extensions to .extensions - # at the end of .initialize_options() but the setuptools build_ext - # .finalize_options both iterate over and needless overwrite the - # .extensions attribute, so we hide the full extension list in - # ._extensions and expose it as a settable property that ignores attempts - # to overwrite it: - - _extensions = None - - @property - def extensions(self): - return self._extensions - - @extensions.setter - def extensions(self, value): - pass # ignore any attempts to change the list of extensions directly - - def initialize_options(self): - self._mixin_super.initialize_options(self) - self.hpydevel = self.distribution.hpydevel - - def _finalize_hpy_ext(self, ext): - if hasattr(ext, "hpy_abi"): - return - ext.name = HPyExtensionName(ext.name) - ext.hpy_abi = self.distribution.hpy_abi - ext.include_dirs += self.hpydevel.get_extra_include_dirs() - # If static libs should be used, then add all available libs (for - # the given ABI) to the extra objects. The libs will then just be added - # in the linking phase but nothing will be compiled in addition. - static_libs = self.distribution.hpy_use_static_libs - if static_libs: - static_libs = self.hpydevel.get_static_libs(ext.hpy_abi) - if static_libs is None or len(static_libs) != 1: - raise DistutilsError('Expected exactly one static library for ' - 'ABI "%s" but got: %r' % - (ext.hpy_abi, static_libs)) - - if static_libs: - ext.extra_objects += static_libs - else: - # If we should not use (pre-compiled) static libs or if they are - # not available, we just add the sources of the helpers to the - # extension. They are then compiler with the extension. - ext.sources += self.hpydevel.get_extra_sources() - ext.define_macros.append(('HPY', None)) - if ext.hpy_abi == 'cpython': - # If the user disabled using static libs, we need to add the - # context sources in this case. - if not static_libs: - ext.sources += self.hpydevel.get_ctx_sources() - ext.define_macros.append(('HPY_ABI_CPYTHON', None)) - ext._hpy_needs_stub = False - elif ext.hpy_abi == 'hybrid': - ext.define_macros.append(('HPY_ABI_HYBRID', None)) - ext._hpy_needs_stub = True - elif ext.hpy_abi == 'universal': - ext.define_macros.append(('HPY_ABI_UNIVERSAL', None)) - ext._hpy_needs_stub = True - forbid_python_h = self.hpydevel.get_include_dir_forbid_python_h() - ext.include_dirs.insert(0, forbid_python_h) - else: - raise DistutilsError('Unknown HPy ABI: %s. Valid values are: ' - 'cpython, hybrid, universal' % ext.hpy_abi) - - def finalize_options(self): - self._extensions = self.distribution.ext_modules or [] - # _only_hpy_extensions is used only as a sanity check that no - # hpy extensions are misidentified as legacy C API extensions in the - # case where only hpy extensions are present. - self._only_hpy_extensions = not bool(self._extensions) - hpy_ext_modules = self.distribution.hpy_ext_modules or [] - for ext in hpy_ext_modules: - self._finalize_hpy_ext(ext) - self._extensions.extend(hpy_ext_modules) - self._mixin_super.finalize_options(self) - for ext in hpy_ext_modules: - ext._needs_stub = ext._hpy_needs_stub - - @remember_hpy_extension - def get_ext_fullname(self, ext_name): - return self._mixin_super.get_ext_fullname(self, ext_name) - - @remember_hpy_extension - def get_ext_fullpath(self, ext_name): - return self._mixin_super.get_ext_fullpath(self, ext_name) - - @remember_hpy_extension - def get_ext_filename(self, ext_name): - hpy_abi = self.distribution.hpy_abi - if not is_hpy_extension(ext_name) or hpy_abi == 'cpython': - return self._mixin_super.get_ext_filename(self, ext_name) - else: - assert is_hpy_extension(ext_name) - assert hpy_abi in ('universal', 'hybrid') - ext_path = ext_name.split('.') - ext_suffix = get_hpy_ext_suffix(hpy_abi) - ext_filename = os.path.join(*ext_path) + ext_suffix - return ext_filename - - def write_stub(self, output_dir, ext, compile=False): - if (not hasattr(ext, "hpy_abi") or - self.distribution.hpy_abi not in ('universal', 'hybrid')): - return self._mixin_super.write_stub( - self, output_dir, ext, compile=compile) - pkgs = ext._full_name.split('.') - if compile: - # compile is true when .write_stub is called while copying - # extensions to the source folder as part of build_ext --inplace. - # In this situation, output_dir includes the folders that make up - # the packages containing the module. When compile is false, - # output_dir does not include those folders (and is just the - # build_lib folder). - pkgs = [pkgs[-1]] - stub_file = os.path.join(output_dir, *pkgs) + '.py' - log.info( - "writing hpy universal stub loader for %s to %s", - ext._full_name, stub_file) - - ext_file = os.path.basename(ext._file_name) - module_name = ext_file.split(".")[0] - if not self.dry_run: - with open(stub_file, 'w', encoding='utf-8') as f: - f.write(_HPY_UNIVERSAL_MODULE_STUB_TEMPLATE.format( - ext_file=ext_file, module_name=module_name) - ) - - def copy_extensions_to_source(self): - """Override from setuptools 64.0.0 to copy our stub instead of recreating it.""" - build_py = self.get_finalized_command('build_py') - build_lib = build_py.build_lib - for ext in self.extensions: - inplace_file, regular_file = self._get_inplace_equivalent(build_py, ext) - - # Always copy, even if source is older than destination, to ensure - # that the right extensions for the current Python/platform are - # used. - if os.path.exists(regular_file) or not ext.optional: - self.copy_file(regular_file, inplace_file, level=self.verbose) - - if ext._needs_stub: - source_stub = os.path.join(build_lib, *ext._full_name.split('.')) + '.py' - inplace_stub = self._get_equivalent_stub(ext, inplace_file) - self.copy_file(source_stub, inplace_stub, level=self.verbose) - - def get_export_symbols(self, ext): - """ Override .get_export_symbols to replace "PyInit_" - with "HPyInit_. - - Only relevant on Windows, where the .pyd file (DLL) must export the - module "HPyInit_" function. - """ - exports = self._mixin_super.get_export_symbols(self, ext) - if hasattr(ext, "hpy_abi") and ext.hpy_abi in ('universal', 'hybrid'): - exports = [re.sub(r"^PyInit_", "HPyInit_", name) for name in exports] - return exports diff --git a/graalpython/hpy/hpy/devel/abitag.py b/graalpython/hpy/hpy/devel/abitag.py deleted file mode 100644 index 2d31668d02..0000000000 --- a/graalpython/hpy/hpy/devel/abitag.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys -from distutils import sysconfig - -# NOTE: these must be kept on sync with the equivalent defines in hpy.h -HPY_ABI_VERSION = 0 -HPY_ABI_VERSION_MINOR = 0 -HPY_ABI_TAG = 'hpy%d' % HPY_ABI_VERSION - -def parse_ext_suffix(ext_suffix=None): - """ - Parse EXT_SUFFIX and return abi_tag, ext. - - - abi_tag is a string representing the CPython ABI tag: e.g. 'cp38', 'cp310d', etc. - - ext is the filename extension, e.g 'so', 'pyd' or 'dylib' - """ - if ext_suffix is None: - ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - - # ext_suffix is something like this. We want to keep the parts which are - # related to the ABI and remove the parts which are related to the - # platform: - # - linux: '.cpython-310-x86_64-linux-gnu.so' - # - mac: '.cpython-310-darwin.so' - # - win: '.cp310-win_amd64.pyd' - # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' - # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' - assert ext_suffix[0] == '.' - _, soabi, ext = ext_suffix.split('.') - - # this is very ad-hoc but couldn't find a better way to do it - parts = soabi.split('-') - if parts[0].startswith('cpython'): # cpython on linux, mac - n = 2 - elif parts[0].startswith('cp'): # cpython on windows - n = 1 - elif parts[0].startswith('pypy'): # pypy - n = 2 - elif parts[0].startswith('graalpy'): # graalpy - n = 3 - else: # none of the above, keep all parts - n = len(parts) - - abi_tag = '-'.join(parts[:n]) - # on cpython linux/mac, abi is now cpython-310: shorten it ot cp310, like - # on windows and on wheel tags - abi_tag = abi_tag.replace('cpython-', 'cp') - return abi_tag, ext - - -def get_hpy_ext_suffix(hpy_abi, ext_suffix=None): - """ - Return the proper filename extension for the given hpy_abi. - - For example with CPython 3.10 on Linux, it will return: - - - universal ==> .hpy0.so - - hybrid ==> .hpy0-cp310.so - """ - assert hpy_abi in ('cpython', 'universal', 'hybrid') - cpy_abi_tag, ext = parse_ext_suffix(ext_suffix) - if hpy_abi == 'cpython': - return sysconfig.get_config_var('EXT_SUFFIX') - elif hpy_abi == 'universal': - return '.%s.%s' % (HPY_ABI_TAG, ext) - else: - return '.%s-%s.%s' % (HPY_ABI_TAG, cpy_abi_tag, ext) diff --git a/graalpython/hpy/hpy/devel/include/hpy.h b/graalpython/hpy/hpy/devel/include/hpy.h deleted file mode 100644 index 17509d5c7e..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy.h +++ /dev/null @@ -1,292 +0,0 @@ -#ifndef HPy_H -#define HPy_H -#ifdef __cplusplus -extern "C" { -#endif - -/* ~~~~~~~~~~~~~~~~ HPy ABI version ~~~~~~~~~~~~~~~ */ -// NOTE: these must be kept on sync with the equivalent variables in hpy/devel/abitag.py -/** - * The ABI version. - * - * Minor version N+1 is binary compatible to minor version N. Major versions - * are not binary compatible (note: HPy can run several binary incompatible - * versions in one process). - */ -#define HPY_ABI_VERSION 0 -#define HPY_ABI_VERSION_MINOR 0 -#define HPY_ABI_TAG "hpy0" - - -/* ~~~~~~~~~~~~~~~~ HPy ABI macros ~~~~~~~~~~~~~~~~ */ - -/* The following macros are used to determine which kind of module we want to - compile. The build system must set one of these (e.g. by using `gcc - -D...`). This is the approach used by the setuptools support provided by - hpy.devel: - - - HPY_ABI_CPYTHON - - HPY_ABI_UNIVERSAL - - HPY_ABI_HYBRID - - In addition we also define HPY_ABI which is a string literal containing a - string representation of it. -*/ - -#if defined(HPY_ABI_CPYTHON) -# if defined(HPY_ABI_HYBRID) -# error "Conflicting macros are defined: HPY_ABI_CPYTHON and HPY_ABI_HYBRID" -# endif -# if defined(HPY_ABI_UNIVERSAL) -# error "Conflicting macros are defined: HPY_ABI_CPYTHON and HPY_ABI_UNIVERSAL" -# endif -# define HPY_ABI "cpython" - -#elif defined(HPY_ABI_HYBRID) -# if defined(HPY_ABI_UNIVERSAL) -# error "Conflicting macros are defined: HPY_ABI_HYBRID and HPY_ABI_UNIVERSAL" -# endif -# define HPY_ABI "hybrid" - -#elif defined(HPY_ABI_UNIVERSAL) -# define HPY_ABI "universal" - -#else -# error "Cannot determine the desired HPy ABI: you must set one of HPY_ABI_CPYTHON, HPY_ABI_UNIVERSAL or HPY_ABI_HYBRID" -#endif - - -#if defined(HPY_ABI_CPYTHON) || defined(HPY_ABI_HYBRID) -# define PY_SSIZE_T_CLEAN -# include -#endif - -#include -#include -#include - -/* ~~~~~~~~~~~~~~~~ useful macros ~~~~~~~~~~~~~~~~ */ - -#ifdef __GNUC__ -# define _HPy_HIDDEN __attribute__((visibility("hidden"))) -# define _HPy_UNUSED __attribute__((unused)) -#else -# define _HPy_HIDDEN -# define _HPy_UNUSED -#endif /* __GNUC__ */ -#define _HPy_UNUSED_ARG(x) (__HPy_UNUSED_TAGGED ## x) _HPy_UNUSED - -#if defined(__clang__) || \ - (defined(__GNUC__) && \ - ((__GNUC__ >= 3) || \ - (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) -# define _HPy_NO_RETURN __attribute__((__noreturn__)) -#elif defined(_MSC_VER) -# define _HPy_NO_RETURN __declspec(noreturn) -#else -# define _HPy_NO_RETURN -#endif - - -// clang and gcc supports __has_attribute, MSVC doesn't. This should be enough -// to be able to use it portably -#ifdef __has_attribute -# define _HPY_compiler_has_attribute(x) __has_attribute(x) -#else -# define _HPY_compiler_has_attribute(x) 0 -#endif - -#ifdef HPY_ABI_UNIVERSAL -# if _HPY_compiler_has_attribute(error) - // gcc, clang>=14 -# define _HPY_LEGACY __attribute__((error("Cannot use legacy functions when targeting the HPy Universal ABI"))) -# else - // we don't have any diagnostic feature, too bad -# define _HPY_LEGACY -# endif -#else - // in non-universal modes, we don't attach any attribute -# define _HPY_LEGACY -#endif - -#if defined(_MSC_VER) && defined(__cplusplus) // MSVC C4576 -# define _hconv(h) {h} -# define _hfconv(h) {h} -# define _htsconv(h) {h} -# define _hgconv(h) {h} -#else -# define _hconv(h) ((HPy){h}) -# define _hfconv(h) ((HPyField){h}) -# define _htsconv(h) ((HPyThreadState){h}) -# define _hgconv(h) ((HPyGlobal){h}) -#endif -/* ~~~~~~~~~~~~~~~~ HPyAPI declaration ~~~~~~~~~~~~~~~~ */ - -/* We have three different kind of API functions: */ - -/** - * Public API functions which are exposed to the user, e.g. - * ``HPy_Add`` or ``HPyType_FromSpec``. Generally speaking they are - * thin shims dispatching to the actual implementation: - * - * * In CPython-ABI mode they directly call the corresponding Py* or - * ``HPyAPI_IMPL`` equivalent, e.g. ``PyObject_Add`` or - * ``ctx_Type_FromSpec``. - * - * * In Universal-ABI mode, they always resolve to an indirect call - * through ``HPyContext *``, i.e. ``ctx->ctx_Add(...)``, which on CPython - * dispaches to ``ctx_Add``. - */ -#define HPyAPI_FUNC _HPy_UNUSED static inline - -/** An alias for ``HPyAPI_FUNC`` so we can handle it properly in the docs. */ -#define HPyAPI_INLINE_HELPER HPyAPI_FUNC - -/** - * CPython implementations for ``HPyAPI_FUNC`` - * functions. Generally speaking, they are put in ctx_*.c files and they are - * prefixed by ctx\_. - * - * Some of these functions are needed by the CPython ABI mode, and by - * CPython's implementation of hpy.universal: these can be found in - * hpy/devel/src/runtime/ctx_*.c, e.g. ``ctx_Type_FromSpec`` and - * ``ctx_Tuple_FromArray``. - * - * Some other are used ONLY by ``hpy.universal`` and can be found in - * hpy/universal/src/ctx_*.c. - */ -#define HPyAPI_IMPL _HPy_HIDDEN - -/** - * These functions are part of the public API but **not** of - * the ABI. They are helpers which are meant to be compiled togeher with every - * extension. E.g. ``HPyArg_Parse`` and ``HPyHelpers_AddType``. - */ -#define HPyAPI_HELPER _HPy_HIDDEN - - -/* ~~~~~~~~~~~~~~~~ Definition of the type HPy ~~~~~~~~~~~~~~~~ */ - -/* HPy handles are fully opaque: depending on the implementation, the _i can - be either an integer or a pointer. A few examples: - - * in CPython ABI mode, ._i is a PyObject* - - * in Universal ABI mode, the meaning of ._i depends on the implementation: - - - CPython (i.e., the code in hpy/universal/src/): ._i is the bitwise - invert of a PyObject* - - - PyPy: ._i is an index into a list - - - GraalPy: ._i is a tagged value, either an index into a list, - or an immediate integer or double value - - - Debug mode: _i is a pointer to a DebugHandle, which contains a - another HPy among other stuff - */ -typedef struct _HPy_s { intptr_t _i; } HPy; -typedef struct { intptr_t _i; } HPyField; -typedef struct { intptr_t _i; } HPyGlobal; -typedef struct { intptr_t _lst; } HPyListBuilder; -typedef struct { intptr_t _tup; } HPyTupleBuilder; -typedef struct { intptr_t _i; } HPyTracker; -typedef struct { intptr_t _i; } HPyThreadState; - - -/* A null handle is officially defined as a handle whose _i is 0. This is true - in all ABI modes. */ -#define HPy_NULL _hconv(0) -#define HPy_IsNull(h) ((h)._i == 0) - -#define HPyField_NULL _hfconv(0) -#define HPyField_IsNull(f) ((f)._i == 0) - -/* Convenience functions to cast between HPy and void*. We need to decide - whether these are part of the official API or not, and maybe introduce a - better naming convention. For now, they are needed for ujson. */ -static inline HPy HPy_FromVoidP(void *p) { return _hconv((intptr_t)p); } -static inline void* HPy_AsVoidP(HPy h) { return (void*)h._i; } - - -/* ~~~~~~~~~~~~~~~~ Definition of other types ~~~~~~~~~~~~~~~~ */ - -typedef struct _HPyContext_s HPyContext; - -/** An enumeration of the different kinds of source code strings. */ -typedef enum { - /** Parse isolated expressions (e.g. ``a + b``). */ - HPy_SourceKind_Expr = 0, - - /** - * Parse sequences of statements as read from a file or other source. This - * is the symbol to use when compiling arbitrarily long Python source code. - */ - HPy_SourceKind_File = 1, - - /** - * Parse a single statement. This is the mode used for the interactive - * interpreter loop. - */ - HPy_SourceKind_Single = 2, -} HPy_SourceKind; - -#ifdef HPY_ABI_CPYTHON - typedef Py_ssize_t HPy_ssize_t; - typedef Py_hash_t HPy_hash_t; - typedef Py_UCS4 HPy_UCS4; - -# define HPY_SSIZE_T_MAX PY_SSIZE_T_MAX -# define HPY_SSIZE_T_MIN PY_SSIZE_T_MIN - -#else - typedef intptr_t HPy_ssize_t; - typedef intptr_t HPy_hash_t; - typedef uint32_t HPy_UCS4; - -# define HPY_SSIZE_T_MAX INTPTR_MAX -# define HPY_SSIZE_T_MIN (-HPY_SSIZE_T_MAX-1) - - /* HPyCapsule field keys */ - typedef enum { - HPyCapsule_key_Pointer = 0, - HPyCapsule_key_Name = 1, - HPyCapsule_key_Context = 2, - HPyCapsule_key_Destructor = 3, - } _HPyCapsule_key; -#endif - - -/* ~~~~~~~~~~~~~~~~ Additional #includes ~~~~~~~~~~~~~~~~ */ - -#include "hpy/cpy_types.h" -#include "hpy/hpyexports.h" -#include "hpy/macros.h" -#include "hpy/hpyfunc.h" -#include "hpy/hpydef.h" -#include "hpy/hpytype.h" -#include "hpy/hpymodule.h" -#include "hpy/runtime/argparse.h" -#include "hpy/runtime/buildvalue.h" -#include "hpy/runtime/format.h" -#include "hpy/runtime/helpers.h" -#include "hpy/runtime/structseq.h" - -#ifdef HPY_ABI_CPYTHON -# include "hpy/cpython/autogen_ctx.h" -# include "hpy/runtime/ctx_funcs.h" -# include "hpy/runtime/ctx_type.h" -# include "hpy/cpython/misc.h" -# include "hpy/cpython/autogen_api_impl.h" -#else -# include "hpy/universal/autogen_ctx.h" -# include "hpy/universal/autogen_trampolines.h" -# include "hpy/universal/misc_trampolines.h" -#endif - -#include "hpy/inline_helpers.h" - -#ifdef __cplusplus -} -#endif -#endif /* HPy_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h deleted file mode 100644 index 334a36f8d1..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyfunc_declare.h +++ /dev/null @@ -1,87 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.hpyfunc.autogen_hpyfunc_declare_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#define _HPyFunc_DECLARE_HPyFunc_NOARGS(SYM) static HPy SYM(HPyContext *ctx, HPy self) -#define _HPyFunc_DECLARE_HPyFunc_O(SYM) static HPy SYM(HPyContext *ctx, HPy self, HPy arg) -#define _HPyFunc_DECLARE_HPyFunc_VARARGS(SYM) static HPy SYM(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -#define _HPyFunc_DECLARE_HPyFunc_KEYWORDS(SYM) static HPy SYM(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, HPy kwnames) -#define _HPyFunc_DECLARE_HPyFunc_UNARYFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_BINARYFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_TERNARYFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_INQUIRY(SYM) static int SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_LENFUNC(SYM) static HPy_ssize_t SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_SSIZEARGFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy_ssize_t) -#define _HPyFunc_DECLARE_HPyFunc_SSIZESSIZEARGFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t) -#define _HPyFunc_DECLARE_HPyFunc_SSIZEOBJARGPROC(SYM) static int SYM(HPyContext *ctx, HPy, HPy_ssize_t, HPy) -#define _HPyFunc_DECLARE_HPyFunc_SSIZESSIZEOBJARGPROC(SYM) static int SYM(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy) -#define _HPyFunc_DECLARE_HPyFunc_OBJOBJARGPROC(SYM) static int SYM(HPyContext *ctx, HPy, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_FREEFUNC(SYM) static void SYM(HPyContext *ctx, void *) -#define _HPyFunc_DECLARE_HPyFunc_GETATTRFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, char *) -#define _HPyFunc_DECLARE_HPyFunc_GETATTROFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_SETATTRFUNC(SYM) static int SYM(HPyContext *ctx, HPy, char *, HPy) -#define _HPyFunc_DECLARE_HPyFunc_SETATTROFUNC(SYM) static int SYM(HPyContext *ctx, HPy, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_REPRFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_HASHFUNC(SYM) static HPy_hash_t SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_RICHCMPFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp) -#define _HPyFunc_DECLARE_HPyFunc_GETITERFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_ITERNEXTFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_DESCRGETFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_DESCRSETFUNC(SYM) static int SYM(HPyContext *ctx, HPy, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_INITPROC(SYM) static int SYM(HPyContext *ctx, HPy self, const HPy *args, HPy_ssize_t nargs, HPy kw) -#define _HPyFunc_DECLARE_HPyFunc_NEWFUNC(SYM) static HPy SYM(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) -#define _HPyFunc_DECLARE_HPyFunc_GETTER(SYM) static HPy SYM(HPyContext *ctx, HPy, void *) -#define _HPyFunc_DECLARE_HPyFunc_SETTER(SYM) static int SYM(HPyContext *ctx, HPy, HPy, void *) -#define _HPyFunc_DECLARE_HPyFunc_OBJOBJPROC(SYM) static int SYM(HPyContext *ctx, HPy, HPy) -#define _HPyFunc_DECLARE_HPyFunc_GETBUFFERPROC(SYM) static int SYM(HPyContext *ctx, HPy, HPy_buffer *, int) -#define _HPyFunc_DECLARE_HPyFunc_RELEASEBUFFERPROC(SYM) static void SYM(HPyContext *ctx, HPy, HPy_buffer *) -#define _HPyFunc_DECLARE_HPyFunc_TRAVERSEPROC(SYM) static int SYM(void *object, HPyFunc_visitproc visit, void *arg) -#define _HPyFunc_DECLARE_HPyFunc_DESTRUCTOR(SYM) static void SYM(HPyContext *ctx, HPy) -#define _HPyFunc_DECLARE_HPyFunc_DESTROYFUNC(SYM) static void SYM(void *) -#define _HPyFunc_DECLARE_HPyFunc_MOD_CREATE(SYM) static HPy SYM(HPyContext *ctx, HPy) - -typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self); -typedef HPy (*HPyFunc_o)(HPyContext *ctx, HPy self, HPy arg); -typedef HPy (*HPyFunc_varargs)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs); -typedef HPy (*HPyFunc_keywords)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, HPy kwnames); -typedef HPy (*HPyFunc_unaryfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_binaryfunc)(HPyContext *ctx, HPy, HPy); -typedef HPy (*HPyFunc_ternaryfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_inquiry)(HPyContext *ctx, HPy); -typedef HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t); -typedef HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t); -typedef int (*HPyFunc_ssizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy); -typedef int (*HPyFunc_ssizessizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy); -typedef int (*HPyFunc_objobjargproc)(HPyContext *ctx, HPy, HPy, HPy); -typedef void (*HPyFunc_freefunc)(HPyContext *ctx, void *); -typedef HPy (*HPyFunc_getattrfunc)(HPyContext *ctx, HPy, char *); -typedef HPy (*HPyFunc_getattrofunc)(HPyContext *ctx, HPy, HPy); -typedef int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy); -typedef int (*HPyFunc_setattrofunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef HPy (*HPyFunc_reprfunc)(HPyContext *ctx, HPy); -typedef HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp); -typedef HPy (*HPyFunc_getiterfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_iternextfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_descrgetfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_descrsetfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_initproc)(HPyContext *ctx, HPy self, const HPy *args, HPy_ssize_t nargs, HPy kw); -typedef HPy (*HPyFunc_newfunc)(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); -typedef HPy (*HPyFunc_getter)(HPyContext *ctx, HPy, void *); -typedef int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *); -typedef int (*HPyFunc_objobjproc)(HPyContext *ctx, HPy, HPy); -typedef int (*HPyFunc_getbufferproc)(HPyContext *ctx, HPy, HPy_buffer *, int); -typedef void (*HPyFunc_releasebufferproc)(HPyContext *ctx, HPy, HPy_buffer *); -typedef int (*HPyFunc_traverseproc)(void *object, HPyFunc_visitproc visit, void *arg); -typedef void (*HPyFunc_destructor)(HPyContext *ctx, HPy); -typedef void (*HPyFunc_destroyfunc)(void *); -typedef HPy (*HPyFunc_mod_create)(HPyContext *ctx, HPy); diff --git a/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h b/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h deleted file mode 100644 index 117e6ccae0..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/autogen_hpyslot.h +++ /dev/null @@ -1,137 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.hpyslot.autogen_hpyslot_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -typedef enum { - HPy_bf_getbuffer = 1, - HPy_bf_releasebuffer = 2, - HPy_mp_ass_subscript = 3, - HPy_mp_length = 4, - HPy_mp_subscript = 5, - HPy_nb_absolute = 6, - HPy_nb_add = 7, - HPy_nb_and = 8, - HPy_nb_bool = 9, - HPy_nb_divmod = 10, - HPy_nb_float = 11, - HPy_nb_floor_divide = 12, - HPy_nb_index = 13, - HPy_nb_inplace_add = 14, - HPy_nb_inplace_and = 15, - HPy_nb_inplace_floor_divide = 16, - HPy_nb_inplace_lshift = 17, - HPy_nb_inplace_multiply = 18, - HPy_nb_inplace_or = 19, - HPy_nb_inplace_power = 20, - HPy_nb_inplace_remainder = 21, - HPy_nb_inplace_rshift = 22, - HPy_nb_inplace_subtract = 23, - HPy_nb_inplace_true_divide = 24, - HPy_nb_inplace_xor = 25, - HPy_nb_int = 26, - HPy_nb_invert = 27, - HPy_nb_lshift = 28, - HPy_nb_multiply = 29, - HPy_nb_negative = 30, - HPy_nb_or = 31, - HPy_nb_positive = 32, - HPy_nb_power = 33, - HPy_nb_remainder = 34, - HPy_nb_rshift = 35, - HPy_nb_subtract = 36, - HPy_nb_true_divide = 37, - HPy_nb_xor = 38, - HPy_sq_ass_item = 39, - HPy_sq_concat = 40, - HPy_sq_contains = 41, - HPy_sq_inplace_concat = 42, - HPy_sq_inplace_repeat = 43, - HPy_sq_item = 44, - HPy_sq_length = 45, - HPy_sq_repeat = 46, - HPy_tp_call = 50, - HPy_tp_descr_get = 54, - HPy_tp_hash = 59, - HPy_tp_init = 60, - HPy_tp_new = 65, - HPy_tp_repr = 66, - HPy_tp_richcompare = 67, - HPy_tp_str = 70, - HPy_tp_traverse = 71, - HPy_nb_matrix_multiply = 75, - HPy_nb_inplace_matrix_multiply = 76, - HPy_tp_finalize = 80, - HPy_tp_destroy = 1000, - HPy_mod_create = 2000, - HPy_mod_exec = 2001, -} HPySlot_Slot; - -#define _HPySlot_SIG__HPy_bf_getbuffer HPyFunc_GETBUFFERPROC -#define _HPySlot_SIG__HPy_bf_releasebuffer HPyFunc_RELEASEBUFFERPROC -#define _HPySlot_SIG__HPy_mp_ass_subscript HPyFunc_OBJOBJARGPROC -#define _HPySlot_SIG__HPy_mp_length HPyFunc_LENFUNC -#define _HPySlot_SIG__HPy_mp_subscript HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_absolute HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_add HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_and HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_bool HPyFunc_INQUIRY -#define _HPySlot_SIG__HPy_nb_divmod HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_float HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_floor_divide HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_index HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_add HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_and HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_floor_divide HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_lshift HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_multiply HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_or HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_power HPyFunc_TERNARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_remainder HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_rshift HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_subtract HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_true_divide HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_xor HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_int HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_invert HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_lshift HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_multiply HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_negative HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_or HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_positive HPyFunc_UNARYFUNC -#define _HPySlot_SIG__HPy_nb_power HPyFunc_TERNARYFUNC -#define _HPySlot_SIG__HPy_nb_remainder HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_rshift HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_subtract HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_true_divide HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_xor HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_sq_ass_item HPyFunc_SSIZEOBJARGPROC -#define _HPySlot_SIG__HPy_sq_concat HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_sq_contains HPyFunc_OBJOBJPROC -#define _HPySlot_SIG__HPy_sq_inplace_concat HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_sq_inplace_repeat HPyFunc_SSIZEARGFUNC -#define _HPySlot_SIG__HPy_sq_item HPyFunc_SSIZEARGFUNC -#define _HPySlot_SIG__HPy_sq_length HPyFunc_LENFUNC -#define _HPySlot_SIG__HPy_sq_repeat HPyFunc_SSIZEARGFUNC -#define _HPySlot_SIG__HPy_tp_call HPyFunc_KEYWORDS -#define _HPySlot_SIG__HPy_tp_descr_get HPyFunc_TERNARYFUNC -#define _HPySlot_SIG__HPy_tp_hash HPyFunc_HASHFUNC -#define _HPySlot_SIG__HPy_tp_init HPyFunc_INITPROC -#define _HPySlot_SIG__HPy_tp_new HPyFunc_NEWFUNC -#define _HPySlot_SIG__HPy_tp_repr HPyFunc_REPRFUNC -#define _HPySlot_SIG__HPy_tp_richcompare HPyFunc_RICHCMPFUNC -#define _HPySlot_SIG__HPy_tp_str HPyFunc_REPRFUNC -#define _HPySlot_SIG__HPy_tp_traverse HPyFunc_TRAVERSEPROC -#define _HPySlot_SIG__HPy_nb_matrix_multiply HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_nb_inplace_matrix_multiply HPyFunc_BINARYFUNC -#define _HPySlot_SIG__HPy_tp_finalize HPyFunc_DESTRUCTOR -#define _HPySlot_SIG__HPy_tp_destroy HPyFunc_DESTROYFUNC -#define _HPySlot_SIG__HPy_mod_create HPyFunc_MOD_CREATE -#define _HPySlot_SIG__HPy_mod_exec HPyFunc_INQUIRY diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpy_types.h b/graalpython/hpy/hpy/devel/include/hpy/cpy_types.h deleted file mode 100644 index 4c59f5e84e..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpy_types.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef HPY_UNIVERSAL_CPY_TYPES_H -#define HPY_UNIVERSAL_CPY_TYPES_H - -/* ~~~~~~~~~~~~~~~~ CPython legacy types ~~~~~~~~~~~~~~~~ */ - -/* These are the types which are needed to implement legacy features such as - .legacy_slots, .legacy_methods, HPy_FromPyObject, HPy_AsPyObject, etc. - - In cpython and hybrid ABI mode we can #include Python.h and use the "real" - types. - - In universal ABI mode, legacy features cannot be used, but we still need - the corresponding C types to use in the HPy declarations. Note that we use - only forward declarations, meaning that it will actually be impossible to - instantiate any of these struct. -*/ - -#ifdef HPY_ABI_UNIVERSAL - -typedef struct FORBIDDEN_cpy_PyObject cpy_PyObject; -typedef struct FORBIDDEN_PyMethodDef cpy_PyMethodDef; -typedef struct FORBIDDEN_PyModuleDef cpy_PyModuleDef; -typedef struct FORBIDDEN_bufferinfo cpy_Py_buffer; - -// declare the following API functions as _HPY_LEGACY, which triggers an -// #error if they are used -HPyAPI_FUNC _HPY_LEGACY cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h); -HPyAPI_FUNC _HPY_LEGACY HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj); - -#else - -// Python.h has already been included by the main hpy.h -typedef PyObject cpy_PyObject; -typedef PyMethodDef cpy_PyMethodDef; -typedef PyModuleDef cpy_PyModuleDef; -typedef Py_buffer cpy_Py_buffer; - -#endif /* HPY_ABI_UNIVERSAL */ - - -typedef cpy_PyObject *(*cpy_PyCFunction)(cpy_PyObject *, cpy_PyObject *const *, HPy_ssize_t); -typedef int (*cpy_visitproc)(cpy_PyObject *, void *); -typedef cpy_PyObject *(*cpy_getter)(cpy_PyObject *, void *); -typedef int (*cpy_setter)(cpy_PyObject *, cpy_PyObject *, void *); -typedef void (*cpy_PyCapsule_Destructor)(cpy_PyObject *); -typedef cpy_PyObject *(*cpy_vectorcallfunc)(cpy_PyObject *callable, cpy_PyObject *const *args, - size_t nargsf, cpy_PyObject *kwnames); - -#endif /* HPY_UNIVERSAL_CPY_TYPES_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h deleted file mode 100644 index 4a55fc6dc6..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_api_impl.h +++ /dev/null @@ -1,616 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trampolines.cpython_autogen_api_impl_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -HPyAPI_FUNC HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value) -{ - return _py2h(PyLong_FromSize_t(value)); -} - -HPyAPI_FUNC HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) -{ - return _py2h(PyLong_FromSsize_t(value)); -} - -HPyAPI_FUNC size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h) -{ - return PyLong_AsSize_t(_h2py(h)); -} - -HPyAPI_FUNC HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h) -{ - return PyLong_AsSsize_t(_h2py(h)); -} - -HPyAPI_FUNC void *HPyLong_AsVoidPtr(HPyContext *ctx, HPy h) -{ - return PyLong_AsVoidPtr(_h2py(h)); -} - -HPyAPI_FUNC double HPyLong_AsDouble(HPyContext *ctx, HPy h) -{ - return PyLong_AsDouble(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyFloat_FromDouble(HPyContext *ctx, double v) -{ - return _py2h(PyFloat_FromDouble(v)); -} - -HPyAPI_FUNC double HPyFloat_AsDouble(HPyContext *ctx, HPy h) -{ - return PyFloat_AsDouble(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyBool_FromBool(HPyContext *ctx, bool v) -{ - return _py2h(PyBool_FromLong(v)); -} - -HPyAPI_FUNC HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h) -{ - return PyObject_Length(_h2py(h)); -} - -HPyAPI_FUNC int HPyNumber_Check(HPyContext *ctx, HPy h) -{ - return PyNumber_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Subtract(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Multiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_MatrixMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_FloorDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_TrueDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Remainder(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Divmod(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return _py2h(PyNumber_Power(_h2py(h1), _h2py(h2), _h2py(h3))); -} - -HPyAPI_FUNC HPy HPy_Negative(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Negative(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Positive(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Positive(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Absolute(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Absolute(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Invert(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Invert(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Lshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Rshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_And(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Xor(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Or(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_Index(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Index(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Long(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Long(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_Float(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Float(_h2py(h1))); -} - -HPyAPI_FUNC HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceAdd(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceSubtract(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceMatrixMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceFloorDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceTrueDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceRemainder(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return _py2h(PyNumber_InPlacePower(_h2py(h1), _h2py(h2), _h2py(h3))); -} - -HPyAPI_FUNC HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceLshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceRshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceAnd(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceXor(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceOr(_h2py(h1), _h2py(h2))); -} - -HPyAPI_FUNC int HPyCallable_Check(HPyContext *ctx, HPy h) -{ - return PyCallable_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPy_GetIter(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_GetIter(_h2py(obj))); -} - -HPyAPI_FUNC HPy HPyIter_Next(HPyContext *ctx, HPy obj) -{ - return _py2h(PyIter_Next(_h2py(obj))); -} - -HPyAPI_FUNC int HPyIter_Check(HPyContext *ctx, HPy obj) -{ - return PyIter_Check(_h2py(obj)); -} - -HPyAPI_FUNC HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) -{ - PyErr_SetString(_h2py(h_type), utf8_message); - return HPy_NULL; -} - -HPyAPI_FUNC HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) -{ - PyErr_SetObject(_h2py(h_type), _h2py(h_value)); - return HPy_NULL; -} - -HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) -{ - return _py2h(PyErr_SetFromErrnoWithFilename(_h2py(h_type), filename_fsencoded)); -} - -HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) -{ - PyErr_SetFromErrnoWithFilenameObjects(_h2py(h_type), _h2py(filename1), _h2py(filename2)); - return HPy_NULL; -} - -HPyAPI_FUNC int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc) -{ - return PyErr_ExceptionMatches(_h2py(exc)); -} - -HPyAPI_FUNC HPy HPyErr_NoMemory(HPyContext *ctx) -{ - PyErr_NoMemory(); - return HPy_NULL; -} - -HPyAPI_FUNC void HPyErr_Clear(HPyContext *ctx) -{ - PyErr_Clear(); -} - -HPyAPI_FUNC HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) -{ - return _py2h(PyErr_NewException(utf8_name, _h2py(base), _h2py(dict))); -} - -HPyAPI_FUNC HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) -{ - return _py2h(PyErr_NewExceptionWithDoc(utf8_name, utf8_doc, _h2py(base), _h2py(dict))); -} - -HPyAPI_FUNC int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) -{ - return PyErr_WarnEx(_h2py(category), utf8_message, stack_level); -} - -HPyAPI_FUNC void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj) -{ - PyErr_WriteUnraisable(_h2py(obj)); -} - -HPyAPI_FUNC int HPy_IsTrue(HPyContext *ctx, HPy h) -{ - return PyObject_IsTrue(_h2py(h)); -} - -HPyAPI_FUNC HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return _py2h(PyObject_GetAttr(_h2py(obj), _h2py(name))); -} - -HPyAPI_FUNC HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return _py2h(PyObject_GetAttrString(_h2py(obj), utf8_name)); -} - -HPyAPI_FUNC int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return PyObject_HasAttr(_h2py(obj), _h2py(name)); -} - -HPyAPI_FUNC int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return PyObject_HasAttrString(_h2py(obj), utf8_name); -} - -HPyAPI_FUNC int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) -{ - return PyObject_SetAttr(_h2py(obj), _h2py(name), _h2py(value)); -} - -HPyAPI_FUNC int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) -{ - return PyObject_SetAttrString(_h2py(obj), utf8_name, _h2py(value)); -} - -HPyAPI_FUNC HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key) -{ - return _py2h(PyObject_GetItem(_h2py(obj), _h2py(key))); -} - -HPyAPI_FUNC HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - return _py2h(PySequence_GetSlice(_h2py(obj), start, end)); -} - -HPyAPI_FUNC int HPy_Contains(HPyContext *ctx, HPy container, HPy key) -{ - return PySequence_Contains(_h2py(container), _h2py(key)); -} - -HPyAPI_FUNC int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) -{ - return PyObject_SetItem(_h2py(obj), _h2py(key), _h2py(value)); -} - -HPyAPI_FUNC int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) -{ - return PySequence_SetSlice(_h2py(obj), start, end, _h2py(value)); -} - -HPyAPI_FUNC int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key) -{ - return PyObject_DelItem(_h2py(obj), _h2py(key)); -} - -HPyAPI_FUNC int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - return PySequence_DelSlice(_h2py(obj), start, end); -} - -HPyAPI_FUNC HPy HPy_Repr(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Repr(_h2py(obj))); -} - -HPyAPI_FUNC HPy HPy_Str(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Str(_h2py(obj))); -} - -HPyAPI_FUNC HPy HPy_ASCII(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_ASCII(_h2py(obj))); -} - -HPyAPI_FUNC HPy HPy_Bytes(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Bytes(_h2py(obj))); -} - -HPyAPI_FUNC HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) -{ - return _py2h(PyObject_RichCompare(_h2py(v), _h2py(w), op)); -} - -HPyAPI_FUNC int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) -{ - return PyObject_RichCompareBool(_h2py(v), _h2py(w), op); -} - -HPyAPI_FUNC HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj) -{ - return PyObject_Hash(_h2py(obj)); -} - -HPyAPI_FUNC int HPyBytes_Check(HPyContext *ctx, HPy h) -{ - return PyBytes_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h) -{ - return PyBytes_Size(_h2py(h)); -} - -HPyAPI_FUNC HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h) -{ - return PyBytes_GET_SIZE(_h2py(h)); -} - -HPyAPI_FUNC const char *HPyBytes_AsString(HPyContext *ctx, HPy h) -{ - return PyBytes_AsString(_h2py(h)); -} - -HPyAPI_FUNC const char *HPyBytes_AS_STRING(HPyContext *ctx, HPy h) -{ - return PyBytes_AS_STRING(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes) -{ - return _py2h(PyBytes_FromString(bytes)); -} - -HPyAPI_FUNC HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8) -{ - return _py2h(PyUnicode_FromString(utf8)); -} - -HPyAPI_FUNC int HPyUnicode_Check(HPyContext *ctx, HPy h) -{ - return PyUnicode_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsASCIIString(_h2py(h))); -} - -HPyAPI_FUNC HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsLatin1String(_h2py(h))); -} - -HPyAPI_FUNC HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsUTF8String(_h2py(h))); -} - -HPyAPI_FUNC const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) -{ - return PyUnicode_AsUTF8AndSize(_h2py(h), size); -} - -HPyAPI_FUNC HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) -{ - return _py2h(PyUnicode_FromWideChar(w, size)); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v) -{ - return _py2h(PyUnicode_DecodeFSDefault(v)); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) -{ - return _py2h(PyUnicode_DecodeFSDefaultAndSize(v, size)); -} - -HPyAPI_FUNC HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_EncodeFSDefault(_h2py(h))); -} - -HPyAPI_FUNC HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) -{ - return PyUnicode_ReadChar(_h2py(h), index); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) -{ - return _py2h(PyUnicode_DecodeASCII(ascii, size, errors)); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) -{ - return _py2h(PyUnicode_DecodeLatin1(latin1, size, errors)); -} - -HPyAPI_FUNC HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) -{ - return _py2h(PyUnicode_FromEncodedObject(_h2py(obj), encoding, errors)); -} - -HPyAPI_FUNC HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - return _py2h(PyUnicode_Substring(_h2py(str), start, end)); -} - -HPyAPI_FUNC int HPyList_Check(HPyContext *ctx, HPy h) -{ - return PyList_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len) -{ - return _py2h(PyList_New(len)); -} - -HPyAPI_FUNC int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item) -{ - return PyList_Append(_h2py(h_list), _h2py(h_item)); -} - -HPyAPI_FUNC int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) -{ - return PyList_Insert(_h2py(h_list), index, _h2py(h_item)); -} - -HPyAPI_FUNC int HPyDict_Check(HPyContext *ctx, HPy h) -{ - return PyDict_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPyDict_New(HPyContext *ctx) -{ - return _py2h(PyDict_New()); -} - -HPyAPI_FUNC HPy HPyDict_Keys(HPyContext *ctx, HPy h) -{ - return _py2h(PyDict_Keys(_h2py(h))); -} - -HPyAPI_FUNC HPy HPyDict_Copy(HPyContext *ctx, HPy h) -{ - return _py2h(PyDict_Copy(_h2py(h))); -} - -HPyAPI_FUNC int HPyTuple_Check(HPyContext *ctx, HPy h) -{ - return PyTuple_Check(_h2py(h)); -} - -HPyAPI_FUNC HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) -{ - return _py2h(PySlice_New(_h2py(start), _h2py(stop), _h2py(step))); -} - -HPyAPI_FUNC int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - return PySlice_Unpack(_h2py(slice), start, stop, step); -} - -HPyAPI_FUNC HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name) -{ - return _py2h(PyImport_ImportModule(utf8_name)); -} - -HPyAPI_FUNC int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) -{ - return PyCapsule_IsValid(_h2py(capsule), utf8_name); -} - -HPyAPI_FUNC void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) -{ - PyEval_RestoreThread(_h2threads(state)); -} - -HPyAPI_FUNC HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx) -{ - return _threads2h(PyEval_SaveThread()); -} - -HPyAPI_FUNC HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) -{ - return _py2h(PyEval_EvalCode(_h2py(code), _h2py(globals), _h2py(locals))); -} - -HPyAPI_FUNC HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value) -{ - return _py2h(PyContextVar_New(name, _h2py(default_value))); -} - -HPyAPI_FUNC HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) -{ - return _py2h(PyContextVar_Set(_h2py(context_var), _h2py(value))); -} - diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h deleted file mode 100644 index 6f9fb0d7dc..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_ctx.h +++ /dev/null @@ -1,100 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.ctx.cpython_autogen_ctx_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -struct _HPyContext_s { - const char *name; - int abi_version; - HPy h_None; - HPy h_True; - HPy h_False; - HPy h_NotImplemented; - HPy h_Ellipsis; - HPy h_BaseException; - HPy h_Exception; - HPy h_StopAsyncIteration; - HPy h_StopIteration; - HPy h_GeneratorExit; - HPy h_ArithmeticError; - HPy h_LookupError; - HPy h_AssertionError; - HPy h_AttributeError; - HPy h_BufferError; - HPy h_EOFError; - HPy h_FloatingPointError; - HPy h_OSError; - HPy h_ImportError; - HPy h_ModuleNotFoundError; - HPy h_IndexError; - HPy h_KeyError; - HPy h_KeyboardInterrupt; - HPy h_MemoryError; - HPy h_NameError; - HPy h_OverflowError; - HPy h_RuntimeError; - HPy h_RecursionError; - HPy h_NotImplementedError; - HPy h_SyntaxError; - HPy h_IndentationError; - HPy h_TabError; - HPy h_ReferenceError; - HPy h_SystemError; - HPy h_SystemExit; - HPy h_TypeError; - HPy h_UnboundLocalError; - HPy h_UnicodeError; - HPy h_UnicodeEncodeError; - HPy h_UnicodeDecodeError; - HPy h_UnicodeTranslateError; - HPy h_ValueError; - HPy h_ZeroDivisionError; - HPy h_BlockingIOError; - HPy h_BrokenPipeError; - HPy h_ChildProcessError; - HPy h_ConnectionError; - HPy h_ConnectionAbortedError; - HPy h_ConnectionRefusedError; - HPy h_ConnectionResetError; - HPy h_FileExistsError; - HPy h_FileNotFoundError; - HPy h_InterruptedError; - HPy h_IsADirectoryError; - HPy h_NotADirectoryError; - HPy h_PermissionError; - HPy h_ProcessLookupError; - HPy h_TimeoutError; - HPy h_Warning; - HPy h_UserWarning; - HPy h_DeprecationWarning; - HPy h_PendingDeprecationWarning; - HPy h_SyntaxWarning; - HPy h_RuntimeWarning; - HPy h_FutureWarning; - HPy h_ImportWarning; - HPy h_UnicodeWarning; - HPy h_BytesWarning; - HPy h_ResourceWarning; - HPy h_BaseObjectType; - HPy h_TypeType; - HPy h_BoolType; - HPy h_LongType; - HPy h_FloatType; - HPy h_UnicodeType; - HPy h_TupleType; - HPy h_ListType; - HPy h_ComplexType; - HPy h_BytesType; - HPy h_MemoryViewType; - HPy h_CapsuleType; - HPy h_SliceType; - HPy h_Builtins; - HPy h_DictType; -}; diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h deleted file mode 100644 index 852268ee53..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h +++ /dev/null @@ -1,203 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.hpyfunc.autogen_cpython_hpyfunc_trampoline_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -typedef HPy (*_HPyCFunction_NOARGS)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_NOARGS(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *self) \ - { \ - _HPyCFunction_NOARGS func = (_HPyCFunction_NOARGS)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(self))); \ - } -typedef HPy (*_HPyCFunction_O)(HPyContext *, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_O(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *self, cpy_PyObject *arg) \ - { \ - _HPyCFunction_O func = (_HPyCFunction_O)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(self), _py2h(arg))); \ - } -typedef HPy (*_HPyCFunction_UNARYFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_UNARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_UNARYFUNC func = (_HPyCFunction_UNARYFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy (*_HPyCFunction_BINARYFUNC)(HPyContext *, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_BINARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyCFunction_BINARYFUNC func = (_HPyCFunction_BINARYFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), _py2h(arg1))); \ - } -typedef HPy (*_HPyCFunction_TERNARYFUNC)(HPyContext *, HPy, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_TERNARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_TERNARYFUNC func = (_HPyCFunction_TERNARYFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), _py2h(arg2))); \ - } -typedef int (*_HPyCFunction_INQUIRY)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_INQUIRY(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_INQUIRY func = (_HPyCFunction_INQUIRY)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy_ssize_t (*_HPyCFunction_LENFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_LENFUNC(SYM, IMPL) \ - static HPy_ssize_t SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_LENFUNC func = (_HPyCFunction_LENFUNC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy (*_HPyCFunction_SSIZEARGFUNC)(HPyContext *, HPy, HPy_ssize_t); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZEARGFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, HPy_ssize_t arg1) \ - { \ - _HPyCFunction_SSIZEARGFUNC func = (_HPyCFunction_SSIZEARGFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), (arg1))); \ - } -typedef HPy (*_HPyCFunction_SSIZESSIZEARGFUNC)(HPyContext *, HPy, HPy_ssize_t, HPy_ssize_t); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZESSIZEARGFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, HPy_ssize_t arg2) \ - { \ - _HPyCFunction_SSIZESSIZEARGFUNC func = (_HPyCFunction_SSIZESSIZEARGFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), (arg1), (arg2))); \ - } -typedef int (*_HPyCFunction_SSIZEOBJARGPROC)(HPyContext *, HPy, HPy_ssize_t, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZEOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_SSIZEOBJARGPROC func = (_HPyCFunction_SSIZEOBJARGPROC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), (arg1), _py2h(arg2))); \ - } -typedef int (*_HPyCFunction_SSIZESSIZEOBJARGPROC)(HPyContext *, HPy, HPy_ssize_t, HPy_ssize_t, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZESSIZEOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, HPy_ssize_t arg2, cpy_PyObject *arg3) \ - { \ - _HPyCFunction_SSIZESSIZEOBJARGPROC func = (_HPyCFunction_SSIZESSIZEOBJARGPROC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), (arg1), (arg2), _py2h(arg3))); \ - } -typedef int (*_HPyCFunction_OBJOBJARGPROC)(HPyContext *, HPy, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_OBJOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_OBJOBJARGPROC func = (_HPyCFunction_OBJOBJARGPROC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), _py2h(arg2))); \ - } -typedef void (*_HPyCFunction_FREEFUNC)(HPyContext *, void *); -#define _HPyFunc_TRAMPOLINE_HPyFunc_FREEFUNC(SYM, IMPL) \ - static void SYM(void *arg0) \ - { \ - _HPyCFunction_FREEFUNC func = (_HPyCFunction_FREEFUNC)IMPL; \ - func(_HPyGetContext(), (arg0)); \ - return; \ - } -typedef HPy (*_HPyCFunction_GETATTRFUNC)(HPyContext *, HPy, char *); -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETATTRFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, char *arg1) \ - { \ - _HPyCFunction_GETATTRFUNC func = (_HPyCFunction_GETATTRFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), (arg1))); \ - } -typedef HPy (*_HPyCFunction_GETATTROFUNC)(HPyContext *, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETATTROFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyCFunction_GETATTROFUNC func = (_HPyCFunction_GETATTROFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), _py2h(arg1))); \ - } -typedef int (*_HPyCFunction_SETATTRFUNC)(HPyContext *, HPy, char *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETATTRFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, char *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_SETATTRFUNC func = (_HPyCFunction_SETATTRFUNC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), (arg1), _py2h(arg2))); \ - } -typedef int (*_HPyCFunction_SETATTROFUNC)(HPyContext *, HPy, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETATTROFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_SETATTROFUNC func = (_HPyCFunction_SETATTROFUNC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), _py2h(arg2))); \ - } -typedef HPy (*_HPyCFunction_REPRFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_REPRFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_REPRFUNC func = (_HPyCFunction_REPRFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy_hash_t (*_HPyCFunction_HASHFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_HASHFUNC(SYM, IMPL) \ - static HPy_hash_t SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_HASHFUNC func = (_HPyCFunction_HASHFUNC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy (*_HPyCFunction_GETITERFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETITERFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_GETITERFUNC func = (_HPyCFunction_GETITERFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy (*_HPyCFunction_ITERNEXTFUNC)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_ITERNEXTFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_ITERNEXTFUNC func = (_HPyCFunction_ITERNEXTFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0))); \ - } -typedef HPy (*_HPyCFunction_DESCRGETFUNC)(HPyContext *, HPy, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESCRGETFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_DESCRGETFUNC func = (_HPyCFunction_DESCRGETFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), _py2h(arg2))); \ - } -typedef int (*_HPyCFunction_DESCRSETFUNC)(HPyContext *, HPy, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESCRSETFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyCFunction_DESCRSETFUNC func = (_HPyCFunction_DESCRSETFUNC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), _py2h(arg2))); \ - } -typedef HPy (*_HPyCFunction_GETTER)(HPyContext *, HPy, void *); -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETTER(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, void *arg1) \ - { \ - _HPyCFunction_GETTER func = (_HPyCFunction_GETTER)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), (arg1))); \ - } -typedef int (*_HPyCFunction_SETTER)(HPyContext *, HPy, HPy, void *); -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETTER(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, void *arg2) \ - { \ - _HPyCFunction_SETTER func = (_HPyCFunction_SETTER)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), _py2h(arg1), (arg2))); \ - } -typedef int (*_HPyCFunction_OBJOBJPROC)(HPyContext *, HPy, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_OBJOBJPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyCFunction_OBJOBJPROC func = (_HPyCFunction_OBJOBJPROC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), _py2h(arg1))); \ - } -typedef void (*_HPyCFunction_DESTRUCTOR)(HPyContext *, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESTRUCTOR(SYM, IMPL) \ - static void SYM(cpy_PyObject *arg0) \ - { \ - _HPyCFunction_DESTRUCTOR func = (_HPyCFunction_DESTRUCTOR)IMPL; \ - func(_HPyGetContext(), _py2h(arg0)); \ - return; \ - } diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h deleted file mode 100644 index 0e8898360e..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpython/hpyfunc_trampolines.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef HPY_CPYTHON_HPYFUNC_TRAMPOLINES_H -#define HPY_CPYTHON_HPYFUNC_TRAMPOLINES_H - -typedef HPy (*_HPyCFunction_VARARGS)(HPyContext*, HPy, const HPy *, size_t); -#define _HPyFunc_TRAMPOLINE_HPyFunc_VARARGS(SYM, IMPL) \ - static PyObject* \ - SYM(PyObject *self, PyObject *const *args, Py_ssize_t nargs) \ - { \ - _HPyCFunction_VARARGS func = (_HPyCFunction_VARARGS)IMPL; \ - return _h2py(func(_HPyGetContext(), \ - _py2h(self), _arr_py2h(args), nargs)); \ - } - -typedef HPy (*_HPyCFunction_KEYWORDS)(HPyContext*, HPy, const HPy *, size_t, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_KEYWORDS(SYM, IMPL) \ - static PyObject * \ - SYM(PyObject *self, PyObject *const *args, size_t nargsf, \ - PyObject *kwnames) \ - { \ - _HPyCFunction_KEYWORDS func = (_HPyCFunction_KEYWORDS)IMPL; \ - /* We also use HPyFunc_KEYWORDS for HPy_tp_call which is */ \ - /* called via vectorcall and so nargsf may have the flag set */ \ - return _h2py(func(_HPyGetContext(), _py2h(self), _arr_py2h(args), \ - PyVectorcall_NARGS(nargsf), _py2h(kwnames))); \ - } - -typedef int (*_HPyCFunction_INITPROC)(HPyContext*, HPy, const HPy *, HPy_ssize_t, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_INITPROC(SYM, IMPL) \ - static int \ - SYM(PyObject *self, PyObject *args, PyObject *kw) \ - { \ - /* get the tuple elements as an array of "PyObject *", which */ \ - /* is equivalent to an array of "HPy" with enough casting... */ \ - PyObject *const *items = &PyTuple_GET_ITEM(args, 0); \ - Py_ssize_t nargs = PyTuple_GET_SIZE(args); \ - _HPyCFunction_INITPROC func = (_HPyCFunction_INITPROC)IMPL; \ - return func(_HPyGetContext(), _py2h(self), \ - _arr_py2h(items), nargs, _py2h(kw)); \ - } - -typedef HPy (*_HPyCFunction_NEWFUNC)(HPyContext*, HPy, const HPy *, HPy_ssize_t, HPy); -#define _HPyFunc_TRAMPOLINE_HPyFunc_NEWFUNC(SYM, IMPL) \ - static PyObject * \ - SYM(PyObject *self, PyObject *args, PyObject *kw) \ - { \ - /* get the tuple elements as an array of "PyObject *", which */ \ - /* is equivalent to an array of "HPy" with enough casting... */ \ - PyObject *const *items = &PyTuple_GET_ITEM(args, 0); \ - Py_ssize_t nargs = PyTuple_GET_SIZE(args); \ - _HPyCFunction_NEWFUNC func = (_HPyCFunction_NEWFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(self), \ - _arr_py2h(items), nargs, _py2h(kw))); \ - } - -/* special case: the HPy_tp_destroy slot doesn't map to any CPython slot. - Instead, it is called from our own tp_dealloc: see also - hpytype_dealloc(). */ -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESTROYFUNC(SYM, IMPL) \ - static void SYM(void) { abort(); } - -/* this needs to be written manually because HPy has a different type for - "op": HPy_RichCmpOp instead of int */ -typedef HPy (*_HPyCFunction_RICHCMPFUNC)(HPyContext *, HPy, HPy, int); -#define _HPyFunc_TRAMPOLINE_HPyFunc_RICHCMPFUNC(SYM, IMPL) \ - static cpy_PyObject * \ - SYM(PyObject *self, PyObject *obj, int op) \ - { \ - _HPyCFunction_RICHCMPFUNC func = (_HPyCFunction_RICHCMPFUNC)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(self), _py2h(obj), op)); \ - } - -/* With the cpython ABI, Py_buffer and HPy_buffer are ABI-compatible. - * Even though casting between them is technically undefined behavior, it - * should always work. That way, we avoid a costly allocation and copy. */ -typedef int (*_HPyCFunction_GETBUFFERPROC)(HPyContext *, HPy, HPy_buffer *, int); -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETBUFFERPROC(SYM, IMPL) \ - static int SYM(PyObject *arg0, Py_buffer *arg1, int arg2) \ - { \ - _HPyCFunction_GETBUFFERPROC func = (_HPyCFunction_GETBUFFERPROC)IMPL; \ - return (func(_HPyGetContext(), _py2h(arg0), (HPy_buffer*)arg1, arg2)); \ - } - -typedef int (*_HPyCFunction_RELEASEBUFFERPROC)(HPyContext *, HPy, HPy_buffer *); -#define _HPyFunc_TRAMPOLINE_HPyFunc_RELEASEBUFFERPROC(SYM, IMPL) \ - static void SYM(PyObject *arg0, Py_buffer *arg1) \ - { \ - _HPyCFunction_RELEASEBUFFERPROC func = (_HPyCFunction_RELEASEBUFFERPROC)IMPL; \ - func(_HPyGetContext(), _py2h(arg0), (HPy_buffer*)arg1); \ - return; \ - } - - -#define _HPyFunc_TRAMPOLINE_HPyFunc_TRAVERSEPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *self, cpy_visitproc visit, void *arg) \ - { \ - return call_traverseproc_from_trampoline((HPyFunc_traverseproc)IMPL, self, \ - visit, arg); \ - } - -#define HPyCapsule_DESTRUCTOR_TRAMPOLINE(SYM, IMPL) \ - static void SYM(PyObject *capsule) \ - { \ - const char *name = PyCapsule_GetName(capsule); \ - IMPL(name, PyCapsule_GetPointer(capsule, name), \ - PyCapsule_GetContext(capsule)); \ - } - -extern void -_HPyModule_CheckCreateSlotResult(cpy_PyObject **result); - -#define _HPyFunc_TRAMPOLINE_HPyFunc_MOD_CREATE(SYM, IMPL) \ - static cpy_PyObject* SYM(cpy_PyObject *spec, cpy_PyModuleDef *def) \ - { \ - (void) def; /* avoid 'unused' warning */ \ - cpy_PyObject* result = _h2py(IMPL(_HPyGetContext(), _py2h(spec))); \ - _HPyModule_CheckCreateSlotResult(&result); \ - return result; \ - } - -#endif // HPY_CPYTHON_HPYFUNC_TRAMPOLINES_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h b/graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h deleted file mode 100644 index 6df576e7ff..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/cpython/misc.h +++ /dev/null @@ -1,575 +0,0 @@ -#ifndef HPY_CPYTHON_MISC_H -#define HPY_CPYTHON_MISC_H - -#include -#include "hpy.h" -#include "hpy/runtime/ctx_funcs.h" - -static inline PyObject* _h2py(HPy h) { - return (PyObject*) h._i; -} - -static inline HPy _py2h(PyObject *o) { - return _hconv((intptr_t)o); -} - -static inline HPyThreadState _threads2h(PyThreadState *s) { - return _htsconv((intptr_t)s); -} - -static inline PyThreadState* _h2threads(HPyThreadState h) { - return (PyThreadState*) h._i; -} - -static inline HPyField _py2hf(PyObject *obj) -{ - HPy h = _py2h(obj); - return _hfconv( ._i = h._i ); -} - -static inline PyObject * _hf2py(HPyField hf) -{ - HPy h = { ._i = hf._i }; - return _h2py(h); -} - -static inline HPyGlobal _py2hg(PyObject *obj) -{ - HPy h = _py2h(obj); - return _hgconv(._i = h._i); -} - -static inline PyObject * _hg2py(HPyGlobal hf) -{ - HPy h = { ._i = hf._i }; - return _h2py(h); -} - -static inline const HPy *_arr_py2h(PyObject *const *py_arr) { - assert(sizeof(HPy) == sizeof(PyObject *)); - return (const HPy *)py_arr; -} - -/* XXX! should be defined only once, not once for every .c! */ -static struct _HPyContext_s _global_ctx; - -HPyAPI_FUNC HPyContext * _HPyGetContext(void) { - HPyContext *ctx = &_global_ctx; - if (!ctx->name) { - ctx->name = "HPy CPython ABI"; - ctx->abi_version = HPY_ABI_VERSION; - /* Constants */ - ctx->h_None = _py2h(Py_None); - ctx->h_True = _py2h(Py_True); - ctx->h_False = _py2h(Py_False); - ctx->h_NotImplemented = _py2h(Py_NotImplemented); - ctx->h_Ellipsis = _py2h(Py_Ellipsis); - /* Exceptions */ - ctx->h_BaseException = _py2h(PyExc_BaseException); - ctx->h_Exception = _py2h(PyExc_Exception); - ctx->h_StopAsyncIteration = _py2h(PyExc_StopAsyncIteration); - ctx->h_StopIteration = _py2h(PyExc_StopIteration); - ctx->h_GeneratorExit = _py2h(PyExc_GeneratorExit); - ctx->h_ArithmeticError = _py2h(PyExc_ArithmeticError); - ctx->h_LookupError = _py2h(PyExc_LookupError); - ctx->h_AssertionError = _py2h(PyExc_AssertionError); - ctx->h_AttributeError = _py2h(PyExc_AttributeError); - ctx->h_BufferError = _py2h(PyExc_BufferError); - ctx->h_EOFError = _py2h(PyExc_EOFError); - ctx->h_FloatingPointError = _py2h(PyExc_FloatingPointError); - ctx->h_OSError = _py2h(PyExc_OSError); - ctx->h_ImportError = _py2h(PyExc_ImportError); - ctx->h_ModuleNotFoundError = _py2h(PyExc_ModuleNotFoundError); - ctx->h_IndexError = _py2h(PyExc_IndexError); - ctx->h_KeyError = _py2h(PyExc_KeyError); - ctx->h_KeyboardInterrupt = _py2h(PyExc_KeyboardInterrupt); - ctx->h_MemoryError = _py2h(PyExc_MemoryError); - ctx->h_NameError = _py2h(PyExc_NameError); - ctx->h_OverflowError = _py2h(PyExc_OverflowError); - ctx->h_RuntimeError = _py2h(PyExc_RuntimeError); - ctx->h_RecursionError = _py2h(PyExc_RecursionError); - ctx->h_NotImplementedError = _py2h(PyExc_NotImplementedError); - ctx->h_SyntaxError = _py2h(PyExc_SyntaxError); - ctx->h_IndentationError = _py2h(PyExc_IndentationError); - ctx->h_TabError = _py2h(PyExc_TabError); - ctx->h_ReferenceError = _py2h(PyExc_ReferenceError); - ctx->h_SystemError = _py2h(PyExc_SystemError); - ctx->h_SystemExit = _py2h(PyExc_SystemExit); - ctx->h_TypeError = _py2h(PyExc_TypeError); - ctx->h_UnboundLocalError = _py2h(PyExc_UnboundLocalError); - ctx->h_UnicodeError = _py2h(PyExc_UnicodeError); - ctx->h_UnicodeEncodeError = _py2h(PyExc_UnicodeEncodeError); - ctx->h_UnicodeDecodeError = _py2h(PyExc_UnicodeDecodeError); - ctx->h_UnicodeTranslateError = _py2h(PyExc_UnicodeTranslateError); - ctx->h_ValueError = _py2h(PyExc_ValueError); - ctx->h_ZeroDivisionError = _py2h(PyExc_ZeroDivisionError); - ctx->h_BlockingIOError = _py2h(PyExc_BlockingIOError); - ctx->h_BrokenPipeError = _py2h(PyExc_BrokenPipeError); - ctx->h_ChildProcessError = _py2h(PyExc_ChildProcessError); - ctx->h_ConnectionError = _py2h(PyExc_ConnectionError); - ctx->h_ConnectionAbortedError = _py2h(PyExc_ConnectionAbortedError); - ctx->h_ConnectionRefusedError = _py2h(PyExc_ConnectionRefusedError); - ctx->h_ConnectionResetError = _py2h(PyExc_ConnectionResetError); - ctx->h_FileExistsError = _py2h(PyExc_FileExistsError); - ctx->h_FileNotFoundError = _py2h(PyExc_FileNotFoundError); - ctx->h_InterruptedError = _py2h(PyExc_InterruptedError); - ctx->h_IsADirectoryError = _py2h(PyExc_IsADirectoryError); - ctx->h_NotADirectoryError = _py2h(PyExc_NotADirectoryError); - ctx->h_PermissionError = _py2h(PyExc_PermissionError); - ctx->h_ProcessLookupError = _py2h(PyExc_ProcessLookupError); - ctx->h_TimeoutError = _py2h(PyExc_TimeoutError); - /* Warnings */ - ctx->h_Warning = _py2h(PyExc_Warning); - ctx->h_UserWarning = _py2h(PyExc_UserWarning); - ctx->h_DeprecationWarning = _py2h(PyExc_DeprecationWarning); - ctx->h_PendingDeprecationWarning = _py2h(PyExc_PendingDeprecationWarning); - ctx->h_SyntaxWarning = _py2h(PyExc_SyntaxWarning); - ctx->h_RuntimeWarning = _py2h(PyExc_RuntimeWarning); - ctx->h_FutureWarning = _py2h(PyExc_FutureWarning); - ctx->h_ImportWarning = _py2h(PyExc_ImportWarning); - ctx->h_UnicodeWarning = _py2h(PyExc_UnicodeWarning); - ctx->h_BytesWarning = _py2h(PyExc_BytesWarning); - ctx->h_ResourceWarning = _py2h(PyExc_ResourceWarning); - /* Types */ - ctx->h_BaseObjectType = _py2h((PyObject *)&PyBaseObject_Type); - ctx->h_TypeType = _py2h((PyObject *)&PyType_Type); - ctx->h_BoolType = _py2h((PyObject *)&PyBool_Type); - ctx->h_LongType = _py2h((PyObject *)&PyLong_Type); - ctx->h_FloatType = _py2h((PyObject *)&PyFloat_Type); - ctx->h_UnicodeType = _py2h((PyObject *)&PyUnicode_Type); - ctx->h_TupleType = _py2h((PyObject *)&PyTuple_Type); - ctx->h_ListType = _py2h((PyObject *)&PyList_Type); - ctx->h_ComplexType = _py2h((PyObject *)&PyComplex_Type); - ctx->h_BytesType = _py2h((PyObject *)&PyBytes_Type); - ctx->h_MemoryViewType = _py2h((PyObject *)&PyMemoryView_Type); - ctx->h_CapsuleType = _py2h((PyObject *)&PyCapsule_Type); - ctx->h_SliceType = _py2h((PyObject *)&PySlice_Type); - ctx->h_DictType = _py2h((PyObject *)&PyDict_Type); - /* Reflection */ - ctx->h_Builtins = _py2h(PyEval_GetBuiltins()); - } - return ctx; -} - -HPyAPI_FUNC HPy HPy_Dup(HPyContext *ctx, HPy handle) -{ - Py_XINCREF(_h2py(handle)); - return handle; -} - -HPyAPI_FUNC void HPy_Close(HPyContext *ctx, HPy handle) -{ - Py_XDECREF(_h2py(handle)); -} - -HPyAPI_FUNC void HPyField_Store(HPyContext *ctx, HPy target_obj, - HPyField *target_field, HPy h) -{ - PyObject *obj = _h2py(h); - PyObject *target_py_obj = _hf2py(*target_field); - Py_XINCREF(obj); - *target_field = _py2hf(obj); - Py_XDECREF(target_py_obj); -} - -HPyAPI_FUNC HPy HPyField_Load(HPyContext *ctx, HPy source_obj, HPyField source_field) -{ - PyObject *obj = _hf2py(source_field); - Py_INCREF(obj); - return _py2h(obj); -} - -HPyAPI_FUNC void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h) -{ - PyObject *obj = _h2py(h); - Py_XDECREF(_hg2py(*global)); - Py_XINCREF(obj); - *global = _py2hg(obj); -} - -HPyAPI_FUNC HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global) -{ - PyObject *obj = _hg2py(global); - Py_INCREF(obj); - return _py2h(obj); -} - -HPyAPI_FUNC HPy HPy_FromPyObject(HPyContext *ctx, PyObject *obj) -{ - Py_XINCREF(obj); - return _py2h(obj); -} - -HPyAPI_FUNC PyObject * HPy_AsPyObject(HPyContext *ctx, HPy h) -{ - PyObject *result = _h2py(h); - Py_XINCREF(result); - return result; -} - -HPyAPI_FUNC HPy HPyModule_Create(HPyContext *ctx, HPyModuleDef *mdef) -{ - return ctx_Module_Create(ctx, mdef); -} - -HPyAPI_FUNC HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) -{ - return ctx_Type_FromSpec(ctx, spec, params); -} - -HPyAPI_FUNC HPy _HPy_New(HPyContext *ctx, HPy h, void **data) -{ - return ctx_New(ctx, h, data); -} - -HPyAPI_FUNC _HPy_NO_RETURN void HPy_FatalError(HPyContext *ctx, const char *message) -{ - Py_FatalError(message); -} - -HPyAPI_FUNC HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) -{ - return ctx_Type_GenericNew(ctx, type, args, nargs, kw); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Object(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Object(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Legacy(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Legacy(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Type(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Type(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Long(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Long(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Float(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Float(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Unicode(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Unicode(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Tuple(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Tuple(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_List(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_List(ctx, h); -} - -HPyAPI_FUNC void* _HPy_AsStruct_Dict(HPyContext *ctx, HPy h) -{ - return ctx_AsStruct_Dict(ctx, h); -} - -HPyAPI_FUNC HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) -{ - return ctx_CallTupleDict(ctx, callable, args, kw); -} - -#if PY_VERSION_HEX < 0x03090000 -# define PyObject_Vectorcall _PyObject_Vectorcall -#endif - -HPyAPI_FUNC HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) -{ - assert(sizeof(HPy) == sizeof(PyObject *)); - return _py2h(PyObject_Vectorcall(_h2py(callable), (PyObject *const *)args, nargs, _h2py(kwnames))); -} - -#if PY_VERSION_HEX < 0x03090000 -# undef PyObject_Vectorcall -#endif - -HPyAPI_FUNC HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) -{ -#if PY_VERSION_HEX >= 0x03090000 - assert(sizeof(HPy) == sizeof(PyObject *)); - return _py2h(PyObject_VectorcallMethod(_h2py(name), (PyObject *const *)args, nargs, _h2py(kwnames))); -#else - return ctx_CallMethod(ctx, name, args, nargs, kwnames); -#endif -} - -HPyAPI_FUNC void _HPy_Dump(HPyContext *ctx, HPy h) -{ - ctx_Dump(ctx, h); -} - -HPyAPI_FUNC HPy HPy_Type(HPyContext *ctx, HPy h_obj) -{ - PyTypeObject *tp = Py_TYPE(_h2py(h_obj)); - Py_INCREF(tp); - return _py2h((PyObject *)tp); -} - -HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type) -{ - return ctx_TypeCheck(ctx, h_obj, h_type); -} - -HPyAPI_FUNC int HPy_Is(HPyContext *ctx, HPy h_obj, HPy h_other) -{ - return _h2py(h_obj) == _h2py(h_other); -} - -HPyAPI_FUNC HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t initial_size) -{ - return ctx_ListBuilder_New(ctx, initial_size); -} - -HPyAPI_FUNC void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - ctx_ListBuilder_Set(ctx, builder, index, h_item); -} - -HPyAPI_FUNC HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder) -{ - return ctx_ListBuilder_Build(ctx, builder); -} - -HPyAPI_FUNC void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder) -{ - ctx_ListBuilder_Cancel(ctx, builder); -} - -HPyAPI_FUNC HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t initial_size) -{ - return ctx_TupleBuilder_New(ctx, initial_size); -} - -HPyAPI_FUNC void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - ctx_TupleBuilder_Set(ctx, builder, index, h_item); -} - -HPyAPI_FUNC HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder) -{ - return ctx_TupleBuilder_Build(ctx, builder); -} - -HPyAPI_FUNC void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder) -{ - ctx_TupleBuilder_Cancel(ctx, builder); -} - -HPyAPI_FUNC HPy HPyTuple_FromArray(HPyContext *ctx, HPy items[], HPy_ssize_t n) -{ - return ctx_Tuple_FromArray(ctx, items, n); -} - -HPyAPI_FUNC HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size) -{ - return ctx_Tracker_New(ctx, size); -} - -HPyAPI_FUNC int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) -{ - return ctx_Tracker_Add(ctx, ht, h); -} - -HPyAPI_FUNC void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht) -{ - ctx_Tracker_ForgetAll(ctx, ht); -} - -HPyAPI_FUNC void HPyTracker_Close(HPyContext *ctx, HPyTracker ht) -{ - ctx_Tracker_Close(ctx, ht); -} - -HPyAPI_FUNC HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - return ctx_GetItem_i(ctx, obj, idx); -} - -HPyAPI_FUNC HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *key) { - return ctx_GetItem_s(ctx, obj, key); -} - -HPyAPI_FUNC int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) { - return ctx_SetItem_i(ctx, obj, idx, value); -} - -HPyAPI_FUNC int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *key, HPy value) { - return ctx_SetItem_s(ctx, obj, key, value); -} - -HPyAPI_FUNC int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - return ctx_DelItem_i(ctx, obj, idx); -} - -HPyAPI_FUNC int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *key) { - return ctx_DelItem_s(ctx, obj, key); -} - -HPyAPI_FUNC HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *v, HPy_ssize_t len) { - return ctx_Bytes_FromStringAndSize(ctx, v, len); -} - -HPyAPI_FUNC int HPyErr_Occurred(HPyContext *ctx) { - return ctx_Err_Occurred(ctx); -} - -HPyAPI_FUNC HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *name, HPyCapsule_Destructor *destructor) -{ - return ctx_Capsule_New(ctx, pointer, name, destructor); -} - -HPyAPI_FUNC void * HPyCapsule_GetPointer(HPyContext *ctx, HPy capsule, const char *name) -{ - return PyCapsule_GetPointer(_h2py(capsule), name); -} - -HPyAPI_FUNC const char * HPyCapsule_GetName(HPyContext *ctx, HPy capsule) -{ - return PyCapsule_GetName(_h2py(capsule)); -} - -HPyAPI_FUNC void * HPyCapsule_GetContext(HPyContext *ctx, HPy capsule) -{ - return PyCapsule_GetContext(_h2py(capsule)); -} - -HPyAPI_FUNC int HPyCapsule_SetPointer(HPyContext *ctx, HPy capsule, void *pointer) -{ - return PyCapsule_SetPointer(_h2py(capsule), pointer); -} - -HPyAPI_FUNC int HPyCapsule_SetName(HPyContext *ctx, HPy capsule, const char *name) -{ - return PyCapsule_SetName(_h2py(capsule), name); -} - -HPyAPI_FUNC int HPyCapsule_SetContext(HPyContext *ctx, HPy capsule, void *context) -{ - return PyCapsule_SetContext(_h2py(capsule), context); -} - -HPyAPI_FUNC int HPyCapsule_SetDestructor(HPyContext *ctx, HPy capsule, HPyCapsule_Destructor *destructor) -{ - return ctx_Capsule_SetDestructor(ctx, capsule, destructor); -} - -// just for better readability -#define SIZEOF_INT32 4 -#define SIZEOF_INT64 8 - -HPyAPI_FUNC HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value) { -#if SIZEOF_LONG >= SIZEOF_INT32 - return _py2h(PyLong_FromLong((long)value)); -#else - return ctx_Long_FromInt32_t ( ctx, value ); -#endif -} - -HPyAPI_FUNC HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value) { -#if SIZEOF_LONG >= SIZEOF_INT32 - return _py2h(PyLong_FromUnsignedLong((unsigned long)value)); -#else - return ctx_Long_FromUInt32_t ( ctx, value ); -#endif -} - -HPyAPI_FUNC HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v) { -#if SIZEOF_LONG_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromLongLong((long long)v)); -#else - return ctx_Long_FromInt64_t ( ctx, v ); -#endif -} - -HPyAPI_FUNC HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v) { -#if SIZEOF_LONG_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromUnsignedLongLong((unsigned long long)v)); -#else - return ctx_Long_FromUInt64_t ( ctx, v ); -#endif -} - -HPyAPI_FUNC int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h) { -#if SIZEOF_LONG == SIZEOF_INT32 - return (int32_t) PyLong_AsLong(_h2py(h)); -#else - return ctx_Long_AsInt32_t ( ctx, h ); -#endif -} - -HPyAPI_FUNC uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h) { -#if SIZEOF_LONG == SIZEOF_INT32 - return (uint32_t) PyLong_AsUnsignedLong(_h2py(h)); -#else - return ctx_Long_AsUInt32_t ( ctx, h ); -#endif -} - -HPyAPI_FUNC uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h) { - return (uint32_t) PyLong_AsUnsignedLongMask(_h2py(h)); -} - -HPyAPI_FUNC int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h) { -#if SIZEOF_LONG_LONG == SIZEOF_INT64 - return (int64_t) PyLong_AsLongLong(_h2py(h)); -#else - return ctx_Long_AsInt64_t ( ctx, h ); -#endif -} - -HPyAPI_FUNC uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h) { -#if SIZEOF_LONG_LONG == SIZEOF_INT64 - return (uint64_t) PyLong_AsUnsignedLongLong(_h2py(h)); -#else - return ctx_Long_AsUInt64_t ( ctx, h ); -#endif -} - -HPyAPI_FUNC uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h) { - return (uint64_t) PyLong_AsUnsignedLongLongMask(_h2py(h)); -} - -#undef SIZEOF_INT32 -#undef SIZEOF_INT64 - -HPyAPI_FUNC HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) { - return ctx_Compile_s(ctx, utf8_source, utf8_filename, kind); -} - -HPyAPI_FUNC int32_t -HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) { - return ctx_ContextVar_Get(ctx, context_var, default_value, result); -} - -HPyAPI_FUNC const char * -HPyType_GetName(HPyContext *ctx, HPy type) -{ - return ctx_Type_GetName(ctx, type); -} - -HPyAPI_FUNC int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type) -{ - return PyType_IsSubtype((PyTypeObject *)_h2py(sub), - (PyTypeObject *)_h2py(type)); -} - -HPyAPI_FUNC int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func) -{ - return ctx_SetCallFunction(ctx, h, func); -} - -#endif /* !HPY_CPYTHON_MISC_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h b/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h deleted file mode 100644 index ba44575650..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/forbid_python_h/Python.h +++ /dev/null @@ -1,6 +0,0 @@ -// sanity check -#ifndef HPY_ABI_UNIVERSAL -# error "Internal HPy error, something is wrong with your build system. The directory hpy/forbid_python_h has been added to the include_dirs but the target ABI does not seems to be 'universal'" -#endif - -#error "It is forbidden to #include when targeting the HPy Universal ABI" diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpydef.h b/graalpython/hpy/hpy/devel/include/hpy/hpydef.h deleted file mode 100644 index db45de2e80..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/hpydef.h +++ /dev/null @@ -1,461 +0,0 @@ -#ifndef HPY_UNIVERSAL_HPYDEF_H -#define HPY_UNIVERSAL_HPYDEF_H -#ifdef __cplusplus -extern "C" { -#endif - -#include /* to make sure "offsetof" is available for our users */ - -#include "hpy/hpyfunc.h" -#include "hpy/autogen_hpyslot.h" -#include "hpy/cpy_types.h" - -typedef void* (*HPyCFunction)(void); -typedef void (*HPyFunc_Capsule_Destructor)(const char *name, void *pointer, void *context); - -/** - * C structure to define an HPy slot. - * - * It is perfectly fine to fill this structure manually. However, the - * recommended and easier way is to use macro :c:macro:`HPyDef_SLOT`. - */ -typedef struct { - /** - * The slot to fill. - */ - HPySlot_Slot slot; - - /** Function pointer to the slot's implementation */ - HPyCFunction impl; - - /** - * Function pointer to the CPython trampoline function which is used by - * CPython to call the actual HPy function ``impl``. - */ - cpy_PyCFunction cpy_trampoline; -} HPySlot; - -/** - * C structure to define an HPy method. - * - * It is perfectly fine to fill this structure manually. However, the - * recommended and easier way is to use macro :c:macro:`HPyDef_METH`. - */ -typedef struct { - /** The name of Python attribute (UTF-8 encoded) */ - const char *name; - - /** Function pointer of the C function implementation */ - HPyCFunction impl; - - /** - * Function pointer to the CPython trampoline function which is used by - * CPython to call the actual HPy function ``impl``. - */ - cpy_PyCFunction cpy_trampoline; - - /** Indicates the C function's expected signature */ - HPyFunc_Signature signature; - - /** Docstring of the method (UTF-8 encoded; may be ``NULL``) */ - const char *doc; - -} HPyMeth; - -/** - * Describes the type (and therefore also the size) of an HPy member. - */ -typedef enum { - HPyMember_SHORT = 0, - HPyMember_INT = 1, - HPyMember_LONG = 2, - HPyMember_FLOAT = 3, - HPyMember_DOUBLE = 4, - HPyMember_STRING = 5, - HPyMember_OBJECT = 6, - HPyMember_CHAR = 7, /* 1-character string */ - HPyMember_BYTE = 8, /* 8-bit signed int */ - /* unsigned variants: */ - HPyMember_UBYTE = 9, - HPyMember_USHORT = 10, - HPyMember_UINT = 11, - HPyMember_ULONG = 12, - - /* Added by Jack: strings contained in the structure */ - HPyMember_STRING_INPLACE = 13, - - /* Added by Lillo: bools contained in the structure (assumed char) */ - HPyMember_BOOL = 14, - HPyMember_OBJECT_EX = 16, /* Like T_OBJECT, but raises AttributeError - when the value is NULL, instead of - converting to None. */ - HPyMember_LONGLONG = 17, - HPyMember_ULONGLONG = 18, - - HPyMember_HPYSSIZET = 19, /* HPy_ssize_t */ - HPyMember_NONE = 20, /* Value is always None */ - -} HPyMember_FieldType; - -/** - * C structure to define an HPy member. - * - * It is perfectly fine to fill this structure manually. However, the - * recommended and easier way is to use macro :c:macro:`HPyDef_MEMBER`. - */ -typedef struct { - /** The name of Python attribute (UTF-8 encoded) */ - const char *name; - - /** The type of the HPy member (see enum ``HPyMember_FieldType``). */ - HPyMember_FieldType type; - - /** - * The location (byte offset) of the member. Usually computed with - * ``offsetof(type, field)``. - */ - HPy_ssize_t offset; - - /** Flag indicating if the member is read-only */ - int readonly; - - /** Docstring of the member (UTF-8 encoded; may be ``NULL``) */ - const char *doc; -} HPyMember; - -/** - * C structure to define an HPy get/set descriptor. - * - * It is perfectly fine to fill this structure manually. However, the - * recommended and easier way is to use macros :c:macro:`HPyDef_GET` (to create - * a get descriptor only), :c:macro:`HPyDef_SET` (to create a set descriptor - * only), or :c:macro:`HPyDef_GETSET` (to create both). - */ -typedef struct { - /** The name of Python attribute (UTF-8 encoded) */ - const char *name; - - /** Function pointer of the C getter function (may be ``NULL``) */ - HPyCFunction getter_impl; - - /** Function pointer of the C setter function (may be ``NULL``) */ - HPyCFunction setter_impl; - - /** - * Function pointer to the CPython trampoline function for the getter (may - * be ``NULL`` if (and only if) ``getter_impl == NULL``) - */ - cpy_getter getter_cpy_trampoline; - - /** - * Function pointer to the CPython trampoline function for the setter (may - * be ``NULL`` if (and only if) ``setter_impl == NULL``) - */ - cpy_setter setter_cpy_trampoline; - - /** Docstring of the get/set descriptor (UTF-8 encoded; may be ``NULL``) */ - const char *doc; - - /** - * A value that will be passed to the ``getter_impl``/``setter_impl`` - * functions. - */ - void *closure; - -} HPyGetSet; - -/** - * Enum to identify an HPy definition's kind. - */ -typedef enum { - HPyDef_Kind_Slot = 1, - HPyDef_Kind_Meth = 2, - HPyDef_Kind_Member = 3, - HPyDef_Kind_GetSet = 4, -} HPyDef_Kind; - -/** - * Generic structure of an HPy definition. - * - * This struct can be used to define a slot, method, member, or get/set - * descriptor. For details, see embedded structures :c:struct:`HPySlot`, - * :c:struct:`HPyMeth`, :c:struct:`HPyMember`, or :c:struct:`HPyGetSet`. - */ -typedef struct { - /** - * The kind of this definition. - * The value of this field determines which one of the embedded members - * ``slot``, ``meth``, ``member``, or ``getset`` is used. Since those are - * combined in a union, only one can be used at a time. - */ - HPyDef_Kind kind; - - union { - HPySlot slot; - HPyMeth meth; - HPyMember member; - HPyGetSet getset; - }; -} HPyDef; - -typedef struct { - cpy_PyCapsule_Destructor cpy_trampoline; - HPyFunc_Capsule_Destructor impl; -} HPyCapsule_Destructor; - -typedef struct { - cpy_vectorcallfunc cpy_trampoline; - HPyFunc_keywords impl; -} HPyCallFunction; - -// macros to automatically define HPyDefs of various kinds - -/* ~~~ HPySlot_SIG ~~~ - - Macro-magic to automatically determine the HPyFunc_Signature from a - symbolic slot name such as HPy_tp_repr, HPy_nb_add, etc. - */ - -#define HPySlot_SIG(SLOT) _HPySlot_SIG__##SLOT -// Macros such as _HPySlot_SIG__HPy_tp_add &co. are defined in autogen_hpyslot.h - - - -/* ~~~ HPyDef_SLOT ~~~ - - This is the official version of HPyDef_SLOT, which automatically determines - the SIG from the SLOT. The anonymous enum is needed to get a nice - compile-time error in case we pass a SLOT which does not exist, see the - more detailed explanation in the comments around HPyFunc_DECLARE in - hpyfunc.h -*/ -#define HPyDef_SLOT_IMPL(SYM, IMPL, SLOT) \ - enum { SYM##_slot = SLOT }; \ - _HPyDef_SLOT(SYM, IMPL, SLOT, HPySlot_SIG(SLOT)) - -/** - * A convenience macro and recommended way to create a definition for an HPy - * slot. - * - * The macro generates a C global variable and an appropriate CPython - * trampoline function. It will fill an :c:struct:`HPyDef` structure appropriately - * and store it in the global variable. - * - * This macro expects a C function ``SYM_impl`` that will be used as the - * implementing slot function. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param SLOT: The HPy slot identifier. - */ -#define HPyDef_SLOT(SYM, SLOT) \ - HPyDef_SLOT_IMPL(SYM, SYM##_impl, SLOT) - -// this is the actual implementation, after we determined the SIG -#define _HPyDef_SLOT(SYM, IMPL, SLOT, SIG) \ - HPyFunc_DECLARE(IMPL, SIG); \ - HPyFunc_TRAMPOLINE(SYM##_trampoline, IMPL, SIG); \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_Slot, \ - .slot = { \ - .slot = SLOT, \ - .impl = (HPyCFunction)IMPL, \ - .cpy_trampoline = (cpy_PyCFunction)SYM##_trampoline \ - } \ - }; - - -#define HPyDef_METH_IMPL(SYM, NAME, IMPL, SIG, ...) \ - HPyFunc_DECLARE(IMPL, SIG); \ - HPyFunc_TRAMPOLINE(SYM##_trampoline, IMPL, SIG) \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_Meth, \ - .meth = { \ - .name = NAME, \ - .impl = (HPyCFunction)IMPL, \ - .cpy_trampoline = (cpy_PyCFunction)SYM##_trampoline, \ - .signature = SIG, \ - __VA_ARGS__ \ - } \ - }; - -/** - * A convenience macro and recommended way to create a definition for an HPy - * method. - * - * The macro generates a C global variable and an appropriate CPython - * trampoline function. It will fill an :c:struct:`HPyDef` structure appropriately - * and store it in the global variable. - * - * This macro expects a C function ``SYM_impl`` that will be used as the - * implementing C function. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param NAME: The Python attribute name (UTF-8 encoded). - * :param SIG: The implementation's C signature (see - * :c:enum:`HPyFunc_Signature`). - */ -#define HPyDef_METH(SYM, NAME, SIG, ...) \ - HPyDef_METH_IMPL(SYM, NAME, SYM##_impl, SIG, __VA_ARGS__) - -/** - * A convenience macro and recommended way to create a definition for an HPy - * member. - * - * The macro generates a C global variable. It will fill an :c:struct:`HPyDef` - * structure appropriately and store it in the global variable. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param NAME: The Python attribute name (UTF-8 encoded). - * :param TYPE: The implementation's C signature (see - * :c:enum:`HPyFunc_Signature`). - * :param OFFSET: The Python attribute name (UTF-8 encoded). - * :param .readonly: Optional flag indicating if the member is read-only. - * :param .doc: Optional docstring (UTF-8 encoded). - */ -#define HPyDef_MEMBER(SYM, NAME, TYPE, OFFSET, ...) \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_Member, \ - .member = { \ - .name = NAME, \ - .type = TYPE, \ - .offset = OFFSET, \ - __VA_ARGS__ \ - } \ - }; - -#define HPyDef_GET_IMPL(SYM, NAME, GETIMPL, ...) \ - HPyFunc_DECLARE(GETIMPL, HPyFunc_GETTER); \ - HPyFunc_TRAMPOLINE(SYM##_get_trampoline, GETIMPL, HPyFunc_GETTER); \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_GetSet, \ - .getset = { \ - .name = NAME, \ - .getter_impl = (HPyCFunction)GETIMPL, \ - .getter_cpy_trampoline = (cpy_getter)SYM##_get_trampoline, \ - __VA_ARGS__ \ - } \ - }; - -/** - * A convenience macro and recommended way to create a definition for an HPy - * get descriptor. - * - * The macro generates a C global variable. It will fill an :c:struct:`HPyDef` - * structure appropriately and store it in the global variable. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param NAME: The Python attribute name (UTF-8 encoded). - * :param .doc: Optional docstring (UTF-8 encoded). - * :param .closure: Optional pointer, providing additional data for the getter. - */ -#define HPyDef_GET(SYM, NAME, ...) \ - HPyDef_GET_IMPL(SYM, NAME, SYM##_get, __VA_ARGS__) - -#define HPyDef_SET_IMPL(SYM, NAME, SETIMPL, ...) \ - HPyFunc_DECLARE(SETIMPL, HPyFunc_SETTER); \ - HPyFunc_TRAMPOLINE(SYM##_set_trampoline, SETIMPL, HPyFunc_SETTER); \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_GetSet, \ - .getset = { \ - .name = NAME, \ - .setter_impl = (HPyCFunction)SETIMPL, \ - .setter_cpy_trampoline = (cpy_setter)SYM##_set_trampoline, \ - __VA_ARGS__ \ - } \ - }; - -/** - * A convenience macro and recommended way to create a definition for an HPy - * set descriptor. - * - * The macro generates a C global variable. It will fill an :c:struct:`HPyDef` - * structure appropriately and store it in the global variable. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param NAME: The Python attribute name (UTF-8 encoded). - * :param .doc: Optional docstring (UTF-8 encoded). - * :param .closure: Optional pointer, providing additional data for the setter. - */ -#define HPyDef_SET(SYM, NAME, ...) \ - HPyDef_SET_IMPL(SYM, NAME, SYM##_set, __VA_ARGS__) - -#define HPyDef_GETSET_IMPL(SYM, NAME, GETIMPL, SETIMPL, ...) \ - HPyFunc_DECLARE(GETIMPL, HPyFunc_GETTER); \ - HPyFunc_TRAMPOLINE(SYM##_get_trampoline, GETIMPL, HPyFunc_GETTER); \ - HPyFunc_DECLARE(SETIMPL, HPyFunc_SETTER); \ - HPyFunc_TRAMPOLINE(SYM##_set_trampoline, SETIMPL, HPyFunc_SETTER); \ - HPyDef SYM = { \ - .kind = HPyDef_Kind_GetSet, \ - .getset = { \ - .name = NAME, \ - .getter_impl = (HPyCFunction)GETIMPL, \ - .setter_impl = (HPyCFunction)SETIMPL, \ - .getter_cpy_trampoline = (cpy_getter)SYM##_get_trampoline, \ - .setter_cpy_trampoline = (cpy_setter)SYM##_set_trampoline, \ - __VA_ARGS__ \ - } \ - }; - -/** - * A convenience macro and recommended way to create a definition for an HPy - * get/set descriptor. - * - * The macro generates a C global variable. It will fill an :c:struct:`HPyDef` - * structure appropriately and store it in the global variable. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated HPy definition. The variable is defined - * as ``static``. - * :param NAME: The Python attribute name (UTF-8 encoded). - * :param .doc: Optional docstring (UTF-8 encoded). - * :param .closure: Optional pointer, providing additional data for the getter - * and setter. - */ -#define HPyDef_GETSET(SYM, NAME, ...) \ - HPyDef_GETSET_IMPL(SYM, NAME, SYM##_get, SYM##_set, __VA_ARGS__) - -#define HPyCapsule_DESTRUCTOR(SYM) \ - static void SYM##_impl(const char *name, void *pointer, void *context); \ - HPyCapsule_DESTRUCTOR_TRAMPOLINE(SYM##_trampoline, SYM##_impl); \ - static HPyCapsule_Destructor SYM = { \ - .cpy_trampoline = SYM##_trampoline, \ - .impl = SYM##_impl \ - }; - -/** - * A convenience macro and the recommended way to create a call function - * definition. - * - * The macro generates a C global variable with name ``SYM``. It will fill an - * :c:struct:`HPyCallFunction` structure appropriately and store it in the - * global variable. - * - * This macro expects a C function ``SYM_impl`` that will be used as the - * implementing C function. - * - * :param SYM: A C symbol name of the resulting global variable that will - * contain the generated call function definition. The variable is - * defined as ``static``. - */ -#define HPyDef_CALL_FUNCTION(SYM) \ - HPyFunc_DECLARE(SYM##_impl, HPyFunc_KEYWORDS); \ - HPyFunc_TRAMPOLINE(SYM##_trampoline, SYM##_impl, HPyFunc_KEYWORDS); \ - static HPyCallFunction SYM = { \ - .cpy_trampoline = SYM##_trampoline, \ - .impl = SYM##_impl \ - }; - -#ifdef __cplusplus -} -#endif -#endif /* HPY_UNIVERSAL_HPYDEF_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h b/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h deleted file mode 100644 index 9e28d854b2..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/hpyexports.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef HPy_EXPORTS_H -#define HPy_EXPORTS_H - -// Copied from Python's exports.h -#ifndef HPy_EXPORTED_SYMBOL - #if defined(_WIN32) || defined(__CYGWIN__) - #define HPy_EXPORTED_SYMBOL __declspec(dllexport) - #else - #define HPy_EXPORTED_SYMBOL __attribute__ ((visibility ("default"))) - #endif -#endif - -#endif /* HPy_EXPORTS_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h b/graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h deleted file mode 100644 index 4a15a34523..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/hpyfunc.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef HPY_UNIVERSAL_HPYFUNC_H -#define HPY_UNIVERSAL_HPYFUNC_H - -typedef enum { - HPyFunc_VARARGS = 1, // METH_FASTCALL - HPyFunc_KEYWORDS = 2, // METH_FASTCALL | METH_KEYWORDS - HPyFunc_NOARGS = 3, // METH_NOARGS - HPyFunc_O = 4, // METH_O - - HPyFunc_DESTROYFUNC, - - HPyFunc_GETBUFFERPROC, - HPyFunc_RELEASEBUFFERPROC, - HPyFunc_UNARYFUNC, - HPyFunc_BINARYFUNC, - HPyFunc_TERNARYFUNC, - HPyFunc_INQUIRY, - HPyFunc_LENFUNC, - HPyFunc_SSIZEARGFUNC, - HPyFunc_SSIZESSIZEARGFUNC, - HPyFunc_SSIZEOBJARGPROC, - HPyFunc_SSIZESSIZEOBJARGPROC, - HPyFunc_OBJOBJARGPROC, - HPyFunc_FREEFUNC, - HPyFunc_GETATTRFUNC, - HPyFunc_GETATTROFUNC, - HPyFunc_SETATTRFUNC, - HPyFunc_SETATTROFUNC, - HPyFunc_REPRFUNC, - HPyFunc_HASHFUNC, - HPyFunc_RICHCMPFUNC, - HPyFunc_GETITERFUNC, - HPyFunc_ITERNEXTFUNC, - HPyFunc_DESCRGETFUNC, - HPyFunc_DESCRSETFUNC, - HPyFunc_INITPROC, - HPyFunc_NEWFUNC, - HPyFunc_GETTER, - HPyFunc_SETTER, - HPyFunc_OBJOBJPROC, - HPyFunc_TRAVERSEPROC, - HPyFunc_DESTRUCTOR, - HPyFunc_CAPSULE_DESTRUCTOR, - HPyFunc_VECTORCALLFUNC, - - HPyFunc_MOD_CREATE, - -} HPyFunc_Signature; - -/* The typedefs corresponding to the various HPyFunc_Signature members - are produced inside autogen_hpyfunc_declare.h. */ - - -/* ~~~ HPyFunc_DECLARE ~~~ - - Emit a forward declaration for a function SYM having a signature SIG, where - SIG is one of HPyFunc_Signature members. - - Strictly speaking, the anonymous enum is not needed, since it just defines - a constant like Foo_sig which is never used anyway. However, since we try - to use "SIG" in the enum definition, we get a very nice error message in - case we use a SIG value which does not exists. If we didn't use this - trick, we would get a VERY obscure error message, since gcc would see a - function call to something like _HPyFunc_DECLARE_HPyFunc_XXX. -*/ -#define HPyFunc_DECLARE(SYM, SIG) \ - enum { SYM##_sig = SIG }; \ - _HPyFunc_DECLARE_##SIG(SYM) - - -/* ~~~ HPyFunc_TRAMPOLINE ~~~ - - Emit a CPython-compatible trampoline which calls IMPL, where IMPL has the - signature SIG. See above for why we need the anonymous enum. The actual - implementation of trampolines are in hpyfunc_trampolines.h, which is - different for the CPython and Universal cases -*/ -#define HPyFunc_TRAMPOLINE(SYM, IMPL, SIG) \ - enum { SYM##_sig = SIG }; \ - _HPyFunc_TRAMPOLINE_##SIG(SYM, IMPL) - -typedef struct { - void *buf; - HPy obj; /* owned reference */ - HPy_ssize_t len; - HPy_ssize_t itemsize; - int readonly; - int ndim; - char *format; - HPy_ssize_t *shape; - HPy_ssize_t *strides; - HPy_ssize_t *suboffsets; - void *internal; -} HPy_buffer; - -typedef int (*HPyFunc_visitproc)(HPyField *, void *); - -/* COPIED AND ADAPTED FROM CPython. - * Utility macro to help write tp_traverse functions - * To use this macro, the tp_traverse function must name its arguments - * "visit" and "arg". This is intended to keep tp_traverse functions - * looking as much alike as possible. - */ -#define HPy_VISIT(hpyfield) \ - do { \ - if (!HPyField_IsNull(*hpyfield)) { \ - int vret = visit(hpyfield, arg); \ - if (vret) \ - return vret; \ - } \ - } while (0) - - - -#include "autogen_hpyfunc_declare.h" - -#ifdef HPY_ABI_CPYTHON -# include "cpython/hpyfunc_trampolines.h" -# include "cpython/autogen_hpyfunc_trampolines.h" -#else -# include "universal/hpyfunc_trampolines.h" -# include "universal/autogen_hpyfunc_trampolines.h" -#endif // HPY_ABI_CPYTHON - -#endif /* HPY_UNIVERSAL_HPYFUNC_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpymodule.h b/graalpython/hpy/hpy/devel/include/hpy/hpymodule.h deleted file mode 100644 index fc6a72f608..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/hpymodule.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef HPY_UNIVERSAL_HPYMODULE_H -#define HPY_UNIVERSAL_HPYMODULE_H - -/* If 'HPY_EMBEDDED_MODULES' is defined, this means that there will be several - embedded HPy modules (and so, several 'HPy_MODINIT' usages) in the same - binary. In this case, some restrictions apply: (1) all of the module's - methods/member/slots/... must be defined in the same file, and (2) the - embedder *MUST* declare the module to be "embeddable" by using macro - 'HPY_MOD_EMBEDDABLE(modname)'. */ -#ifdef HPY_EMBEDDED_MODULES -#define _HPy_CTX_MODIFIER static -#define HPY_MOD_EMBEDDABLE(modname) \ - _HPy_CTX_MODIFIER HPyContext *_ctx_for_trampolines; -#else -#define _HPy_CTX_MODIFIER _HPy_HIDDEN -/** - * Declares a module to be *embeddable* which means that it and its members can - * be compiled/linked into a binary together with other embeddable HPy modules. - * - * You may declare a module to be *embeddable* if all of its member definitions - * are in the same file. - */ -#define HPY_MOD_EMBEDDABLE(modname) -// this is defined by HPy_MODINIT -extern HPyContext *_ctx_for_trampolines; -#endif - - -/** - * Definition of a Python module. Pointer to this struct is returned from - * the HPy initialization function ``HPyInit_{extname}`` and the Python - * interpreter creates a Python module from it. HPy supports only the - * multi-phase module initialization approach (PEP 451). - * - * There is no HPy API to create a Python module manually, i.e., equivalent - * of ``PyModule_Create`` or ``PyModule_FromDefAndSpec``, for the time being, - * but may be added if a use-case arises. - * - * Note: unlike Python/C API, HPy module definition does not specify module - * name. The name if always taken from the ModuleSpec, which is also the case - * in multi-phase module initialization on Python/C API. - */ -typedef struct { - /** Docstring of the type (UTF-8 encoded; may be ``NULL``) */ - const char* doc; - - /** - * The size (in bytes) of the module state structure. If set to zero, - * then the module will not get allocated and assigned any HPy module state. - * Negative size, unlike in Python/C API, does not have any specific meaning - * and will produce a runtime error. - */ - HPy_ssize_t size; - - /** - * ``NULL``-terminated list of legacy module-level methods. - * In order to enable incremental migration - * from C API to HPy, it is possible to still add *legacy* method - * definitions. Those methods have a C API signature which means that they - * still receive ``PyObject *`` and similar arguments. If legacy methods - * are defined, you cannot create a *universal binary* (i.e. a binary that - * will run on all Python engines). - */ - cpy_PyMethodDef *legacy_methods; - - /** - * Pointer to a ``NULL``-terminated array of pointers to HPy defines (i.e. - * ``HPyDef *``). Note, that some kinds of HPy definitions don't make sense - * for a module. In particular, anything else than methods. - */ - HPyDef **defines; - - /** - * Pointer to a ``NULL``-terminated array of pointers to - * :c:struct:`HPyGlobal` variables. For details, see :doc:`hpy-global`. - */ - HPyGlobal **globals; -} HPyModuleDef; - - -#if defined(__cplusplus) -# define HPy_EXPORTED_FUNC extern "C" HPy_EXPORTED_SYMBOL -#else /* __cplusplus */ -# define HPy_EXPORTED_FUNC HPy_EXPORTED_SYMBOL -#endif /* __cplusplus */ - -#ifdef HPY_ABI_CPYTHON - -// helpers provided by HPy runtime: -#include "hpy/runtime/ctx_module.h" - -// module initialization in the CPython case -#define HPy_MODINIT(ext_name, mod_def) \ - PyMODINIT_FUNC \ - PyInit_##ext_name(void) \ - { \ - return _HPyModuleDef_AsPyInit(&mod_def); \ - } - -#else // HPY_ABI_CPYTHON - -// module initialization in the universal and hybrid case - -/** - * Convenience macro for generating the module initialization code. This will - * generate three functions that are used by to verify an initialize the module - * when loading: - * - * ``get_required_hpy_major_version_`` - * The HPy major version this module was built with. - * - * ``get_required_hpy_minor_version_`` - * The HPy minor version this module was built with. - * - * ``HPyModuleDef* HPyInit_`` - * The init function that will be called by the interpreter. This function - * does not have an access to HPyContext and thus cannot call any HPy APIs. - * The purpose of this function is to return a pointer to a HPyModuleDef - * structure that will serve as a specification of the module that should be - * created by the interpreter. HPy supports only multi-phase module - * initialization (PEP 451). Any module initialization code can be added - * to the HPy_mod_exec slot of the module if needed. - * - * Example: - * - * .. code-block:: c - * - * HPy_MODINIT(myextension_shared_library_filename, my_hpy_module_def) - */ -#define HPy_MODINIT(ext_name, mod_def) \ - HPy_EXPORTED_FUNC uint32_t \ - get_required_hpy_major_version_##ext_name(void); \ - uint32_t \ - get_required_hpy_major_version_##ext_name(void) \ - { \ - return HPY_ABI_VERSION; \ - } \ - HPy_EXPORTED_FUNC uint32_t \ - get_required_hpy_minor_version_##ext_name(void); \ - uint32_t \ - get_required_hpy_minor_version_##ext_name(void) \ - { \ - return HPY_ABI_VERSION_MINOR; \ - } \ - _HPy_CTX_MODIFIER HPyContext *_ctx_for_trampolines; \ - HPy_EXPORTED_FUNC void \ - HPyInitGlobalContext_##ext_name(HPyContext *ctx); \ - void \ - HPyInitGlobalContext_##ext_name(HPyContext *ctx) \ - { \ - _ctx_for_trampolines = ctx; \ - } \ - HPy_EXPORTED_FUNC HPyModuleDef* \ - HPyInit_##ext_name() \ - { \ - return &mod_def; \ - } - -// Implementation note: the global HPyContext is used by the CPython -// trampolines generated by the HPyDef_XXX macros - -#endif // HPY_ABI_CPYTHON - -#endif // HPY_UNIVERSAL_HPYMODULE_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/hpytype.h b/graalpython/hpy/hpy/devel/include/hpy/hpytype.h deleted file mode 100644 index 167bd6def5..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/hpytype.h +++ /dev/null @@ -1,303 +0,0 @@ -#ifndef HPY_UNIVERSAL_HPYTYPE_H -#define HPY_UNIVERSAL_HPYTYPE_H - -#include -#ifdef __GNUC__ -#define HPyAPI_UNUSED __attribute__((unused)) static inline -#else -#define HPyAPI_UNUSED static inline -#endif /* __GNUC__ */ - -// NOTE: HPyType_BuiltinShape_Object == 0, which means it's the default -// if it's not specified in HPyType_spec -typedef enum { - /** - * A type whose struct starts with ``PyObject_HEAD`` or equivalent is a - * legacy type. A legacy type must set - * ``.builtin_shape = HPyType_BuiltinShape_Legacy`` in its - * :c:struct:`HPyType_Spec`. - * - * A type is a non-legacy type, also called HPy pure type, if its struct does - * not include ``PyObject_HEAD``. Using pure types should be preferred. - * Legacy types are available to allow gradual porting of existing CPython - * extensions. - * - * A type with ``.legacy_slots != NULL`` - * (see :c:member:`HPyType_Spec.legacy_slots`) is required to have - * ``HPyType_BuiltinShape_Legacy`` and to include ``PyObject_HEAD`` at the - * start of its struct. It would be easy to relax this requirement on - * CPython (where the ``PyObject_HEAD`` fields are always present) but a - * large burden on other implementations (e.g. PyPy, GraalPy) where a - * struct starting with ``PyObject_HEAD`` might not exist. - * - * Types created via the old Python C API are automatically legacy types. - */ - HPyType_BuiltinShape_Legacy = -1, - - /** The type inherits from built-in type ``object`` (default). */ - HPyType_BuiltinShape_Object = 0, - - /** - * The type inherits from built-in type ``type``. This can be used to - * create metaclasses. If using this shape, you need to specify base class - * ``ctx->h_TypeType``. - */ - HPyType_BuiltinShape_Type = 1, - - /** - * The type inherits from built-in type ``int`` (aka. long object). If using - * this shape, you need to specify base class ``ctx->h_LongType``. - */ - HPyType_BuiltinShape_Long = 2, - - /** - * The type inherits from built-in type ``float``. If using this shape, you - * need to specify base class ``ctx->h_FloatType``. - */ - HPyType_BuiltinShape_Float = 3, - - /** - * The type inherits from built-in type ``str`` (aka. unicode object). If - * using this shape, you need to specify base class ``ctx->h_UnicodeType``. - */ - HPyType_BuiltinShape_Unicode = 4, - - /** - * The type inherits from built-in type ``tuple``. If using this shape, you - * need to specify base class ``ctx->h_TupleType``. - */ - HPyType_BuiltinShape_Tuple = 5, - - /** - * The type inherits from built-in type ``list``. If using this shape, you - * need to specify base class ``ctx->h_ListType``. - */ - HPyType_BuiltinShape_List = 6, - - /** - * The type inherits from built-in type ``dict``. If using this shape, you - * need to specify base class ``ctx->h_DictType``. - */ - HPyType_BuiltinShape_Dict = 7, -} HPyType_BuiltinShape; - -typedef struct { - cpy_vectorcallfunc cpy_trampoline; - HPyCallFunction impl; -} HPyType_Vectorcall; - -typedef struct { - /** The Python name of type (UTF-8 encoded) */ - const char* name; - - /** - * The size in bytes of the types associated native structure. Usually, you - * define some C structure, e.g., ``typedef struct { int a; } MyObject;``, - * and then this field is set to ``sizeof(MyObject)``. - */ - int basicsize; - - /** The size of embedded elements (currently not supported). */ - int itemsize; - - /** - * Type flags (see :c:macro:`HPy_TPFLAGS_DEFAULT`, - * :c:macro:`HPy_TPFLAGS_BASETYPE`, :c:macro:`HPy_TPFLAGS_HAVE_GC`, and - * others if available). - */ - unsigned long flags; - - /** - * The internal *shape* of the type. - * - * The shape gives the necessary hint to compute the offset to the data - * pointer of the object's underlying struct that should be returned when - * calling ``MyObject_AsStruct``. - * - * **ATTENTION**: - * It is also necessary to specify the right base class in - * the type's specification parameters (see :c:struct:`HPyType_SpecParam`). - * - * Assuming that the type's C structure is called ``MyObject``, this field - * should be initialized with ``.builtin_shape = SHAPE(MyObject)``. Note: - * This requires that you use :c:macro:`HPyType_HELPERS` or - * :c:macro:`HPyType_LEGACY_HELPERS`. - * - * Some more explanation: It would be possible to reduce this information - * to a Boolean that specifies if the type is a *legacy* type or not. - * Everything else could be determined by looking at the base classes. - * However, with this information it is possible to do the data pointer - * computation statically and thus is performance critical. - * - * Types that do not define a struct of their own, should set the value of - * ``.builtin_shape`` to the same value as the type they inherit from. If - * they inherit from a built-in type, they must set the corresponding - * ``.builtin_shape``. - */ - HPyType_BuiltinShape builtin_shape; - - /** - * Pointer to a ``NULL``-terminated array of legacy (i.e. ``PyType_Slot``) - * slots. - * - * A type with ``.legacy_slots != NULL`` is required to have - * ``HPyType_BuiltinShape_Legacy`` and to include ``PyObject_HEAD`` at the - * start of its struct. It would be easy to relax this requirement on - * CPython (where the ``PyObject_HEAD`` fields are always present) but a - * large burden on other implementations (e.g. PyPy, GraalPy) where a - * struct starting with ``PyObject_HEAD`` might not exist. - */ - void *legacy_slots; - - /** - * Pointer to a ``NULL``-terminated array of pointers to HPy defines (i.e. - * ``HPyDef *``). - */ - HPyDef **defines; - - /** Docstring of the type (UTF-8 encoded; may be ``NULL``) */ - const char* doc; -} HPyType_Spec; - -typedef enum { - /** - * Specify a base class. This parameter may be repeated but cannot be used - * together with - * :c:enumerator:`HPyType_SpecParam_Kind.HPyType_SpecParam_BasesTuple`. - */ - HPyType_SpecParam_Base = 1, - - /** - * Specify a tuple of base classes. Cannot be used together with - * :c:enumerator:`HPyType_SpecParam_Kind.HPyType_SpecParam_Base` - */ - HPyType_SpecParam_BasesTuple = 2, - - /** Specify a meta class for the type. */ - HPyType_SpecParam_Metaclass = 3, - - //HPyType_SpecParam_Module = 4, -} HPyType_SpecParam_Kind; - -typedef struct { - /** The kind of the type spec param. */ - HPyType_SpecParam_Kind kind; - - /** The value of the type spec param (an HPy handle). */ - HPy object; -} HPyType_SpecParam; - -/* All types are dynamically allocated */ -#define _Py_TPFLAGS_HEAPTYPE (1UL << 9) -#define _Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) - -/** Default type flags for HPy types. */ -#define HPy_TPFLAGS_DEFAULT (_Py_TPFLAGS_HEAPTYPE | _Py_TPFLAGS_HAVE_VERSION_TAG) - -/** Set if the type implements the vectorcall protocol (PEP 590) */ -#define HPy_TPFLAGS_HAVE_VECTORCALL (1UL << 11) - -/** Set if the type allows subclassing */ -#define HPy_TPFLAGS_BASETYPE (1UL << 10) - -/** Set if the type allows subclassing */ -#define HPy_TPFLAGS_BASETYPE (1UL << 10) - -/** If set, the object will be tracked by CPython's GC. Probably irrelevant for - GC-based alternative implementations. */ -#define HPy_TPFLAGS_HAVE_GC (1UL << 14) - -/** Convenience macro which is equivalent to: - ``HPyType_HELPERS(TYPE, HPyType_BuiltinShape_Legacy)`` - For instance, HPyType_LEGACY_HELPERS(DummyMeta) will produce:: - - enum { DummyMeta_SHAPE = (int)HPyType_BuiltinShape_Legacy }; - __attribute__((unused)) static inline - DummyMeta * - DummyMeta_AsStruct(HPyContext *ctx, HPy h) { - return (DummyMeta *) _HPy_AsStruct_Legacy(ctx, h); - } -*/ -#define HPyType_LEGACY_HELPERS(TYPE) \ - HPyType_HELPERS(TYPE, HPyType_BuiltinShape_Legacy) - -#define _HPyType_HELPER_TYPE(TYPE, ...) TYPE * -#define _HPyType_HELPER_FNAME(TYPE, ...) TYPE##_AsStruct -#define _HPyType_HELPER_DEFINE_SHAPE(TYPE, SHAPE, ...) \ - enum { TYPE##_SHAPE = (int)SHAPE } -#define _HPyType_HELPER_AS_STRUCT(TYPE, SHAPE, ...) SHAPE##_AsStruct -// helper macro make MSVC's preprocessor work with our variadic macros -#define _HPyType_HELPER_X(X) X - -/** - A macro for creating (static inline) helper functions for custom types. - - Two versions of the helper exist. One for legacy types and one for pure - HPy types. - - Example for a pure HPy custom type: - - ``HPyType_HELPERS(PointObject)`` - - It is also possible to inherit from some built-in types. The list of - available built-in base types is given in enum `HPyTupe_BuiltinShape`. - In case you want to inherit from one of those, it is necessary to specify - the base built-in type in the `HPyType_HELPERS` macro. Here is an example - for a pure HPy custom type inheriting from a built-in type 'tuple': - - ``HPyType_HELPERS(PointObject, HPyType_BuiltinShape_Tuple)`` - - This would generate the following: - - * ``PointObject * PointObject_AsStruct(HPyContext *ctx, HPy h)``: a static - inline function that uses HPy_AsStruct to return the PointObject struct - associated with a given handle. The behaviour is undefined if `h` - is associated with an object that is not an instance of PointObject. - However, debug mode will catch an incorrect usage. - - * ``SHAPE(PointObject)``: a macro that is meant to be used as static - initializer in the corresponding HPyType_Spec. It is recommended to write - ``.builtin_shape = SHAPE(PointObject)`` such that you don't have to - remember to update the spec when the helpers used changes. - - Example for a legacy custom type: - - ``HPyType_LEGACY_HELPERS(PointObject)`` - - This would generate the same functions and constants as above, except: - - * ``_HPy_AsStruct_Legacy`` is used instead of ``_HPy_AsStruct_Object``. - - * ``SHAPE(PointObject)`` would be ``HPyType_BuiltinShape_Legacy``. - - :param STRUCT: The C structure of the HPy type. - :param SHAPE: Optional. The built-in shape of the type. This defaults to - :c:enumerator:`HPyType_BuiltinShape_Object`. Possible values - are all enumerators of :c:enum:`HPyType_BuiltinShape`. -*/ -#define HPyType_HELPERS(...) \ - \ -_HPyType_HELPER_X( \ - _HPyType_HELPER_DEFINE_SHAPE(__VA_ARGS__, HPyType_BuiltinShape_Object)); \ - \ -HPyAPI_UNUSED _HPyType_HELPER_X(_HPyType_HELPER_TYPE(__VA_ARGS__)) \ -_HPyType_HELPER_X(_HPyType_HELPER_FNAME(__VA_ARGS__))(HPyContext *ctx, HPy h) \ -{ \ - return (_HPyType_HELPER_X(_HPyType_HELPER_TYPE(__VA_ARGS__))) \ - _HPyType_HELPER_X(_HPyType_HELPER_AS_STRUCT(__VA_ARGS__, \ - HPyType_BuiltinShape_Object))(ctx, h); \ -} - -#define SHAPE(TYPE) ((HPyType_BuiltinShape)TYPE##_SHAPE) - -#define HPyType_BuiltinShape_Legacy_AsStruct _HPy_AsStruct_Legacy -#define HPyType_BuiltinShape_Object_AsStruct _HPy_AsStruct_Object -#define HPyType_BuiltinShape_Type_AsStruct _HPy_AsStruct_Type -#define HPyType_BuiltinShape_Long_AsStruct _HPy_AsStruct_Long -#define HPyType_BuiltinShape_Float_AsStruct _HPy_AsStruct_Float -#define HPyType_BuiltinShape_Unicode_AsStruct _HPy_AsStruct_Unicode -#define HPyType_BuiltinShape_Tuple_AsStruct _HPy_AsStruct_Tuple -#define HPyType_BuiltinShape_List_AsStruct _HPy_AsStruct_List -#define HPyType_BuiltinShape_Dict_AsStruct _HPy_AsStruct_Dict - -#endif /* HPY_UNIVERSAL_HPYTYPE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h b/graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h deleted file mode 100644 index ba09657d53..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/inline_helpers.h +++ /dev/null @@ -1,537 +0,0 @@ -#ifndef HPY_INLINE_HELPERS_H -#define HPY_INLINE_HELPERS_H - -#if defined(_MSC_VER) -# include /* for alloca() */ -#endif - -#include - -/** - * Same as :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but passes - * ``HPy_NULL`` to the optional arguments. - * - * :param ctx: - * The execution context. - * :param h_type: - * The exception type to raise. - * - * :return: - * always returns ``HPy_NULL`` - */ -HPyAPI_INLINE_HELPER HPy -HPyErr_SetFromErrno(HPyContext *ctx, HPy h_type) -{ - return HPyErr_SetFromErrnoWithFilenameObjects(ctx, h_type, HPy_NULL, HPy_NULL); -} - -/** - * Same as :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but passes - * ``HPy_NULL`` to the last (optional) argument. - * - * :param ctx: - * The execution context. - * :param h_type: - * The exception type to raise. - * :param filename: - * a filename; may be ``HPy_NULL`` - * - * :return: - * always returns ``HPy_NULL`` - */ -HPyAPI_INLINE_HELPER HPy -HPyErr_SetFromErrnoWithFilenameObject(HPyContext *ctx, HPy h_type, HPy filename) -{ - return HPyErr_SetFromErrnoWithFilenameObjects(ctx, h_type, filename, HPy_NULL); -} - -/** - * Create a tuple from arguments. - * - * A convenience function that will allocate a temporary array of ``HPy`` - * elements and use :c:func:`HPyTuple_FromArray` to create a tuple. - * - * :param ctx: - * The execution context. - * :param n: - * The number of elements to pack into a tuple. - * :param ...: - * Variable number of ``HPy`` arguments. - * - * :return: - * A new tuple with ``n`` elements or ``HPy_NULL`` in case of an error - * occurred. - */ -HPyAPI_INLINE_HELPER HPy -HPyTuple_Pack(HPyContext *ctx, HPy_ssize_t n, ...) -{ - va_list vargs; - HPy_ssize_t i; - - if (n == 0) { - return HPyTuple_FromArray(ctx, (HPy*)NULL, n); - } - HPy *array = (HPy *)alloca(n * sizeof(HPy)); - va_start(vargs, n); - if (array == NULL) { - va_end(vargs); - return HPy_NULL; - } - for (i = 0; i < n; i++) { - array[i] = va_arg(vargs, HPy); - } - va_end(vargs); - return HPyTuple_FromArray(ctx, array, n); -} - -/** - * Delete an attribute. - * - * This is the equivalent of the Python statement ``del o.attr_name``. - * - * :param ctx: - * The execution context. - * :param obj: - * The object with the attribute. - * :param name: - * The name (an unicode object) of the attribute. - * - * :return: - * ``0`` on success; ``-1`` in case of an error. - */ -HPyAPI_INLINE_HELPER int -HPy_DelAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return HPy_SetAttr(ctx, obj, name, HPy_NULL); -} - -/** - * Delete an attribute. - * - * This is the equivalent of the Python statement ``del o.attr_name``. - * - * :param ctx: - * The execution context. - * :param obj: - * The object with the attribute. - * :param utf8_name: - * The name (an UTF-8 encoded C string) of the attribute. - * - * :return: - * ``0`` on success; ``-1`` in case of an error. - */ -HPyAPI_INLINE_HELPER int -HPy_DelAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return HPy_SetAttr_s(ctx, obj, utf8_name, HPy_NULL); -} - -/** - * Create a Python long object from a C ``long`` value. - * - * :param ctx: - * The execution context. - * :param l: - * A C long value. - * - * :return: - * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. - */ -HPyAPI_INLINE_HELPER HPy -HPyLong_FromLong(HPyContext *ctx, long l) -{ - if (sizeof(long) <= sizeof(int32_t)) - return HPyLong_FromInt32_t(ctx, (int32_t)l); - assert(sizeof(long) <= sizeof(int64_t)); - return HPyLong_FromInt64_t(ctx, (int64_t)l); -} - -/** - * Create a Python long object from a C ``unsigned long`` value. - * - * :param ctx: - * The execution context. - * :param l: - * A C ``unsigned long`` value. - * - * :return: - * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. - */ -HPyAPI_INLINE_HELPER HPy -HPyLong_FromUnsignedLong(HPyContext *ctx, unsigned long l) -{ - if (sizeof(unsigned long) <= sizeof(uint32_t)) - return HPyLong_FromUInt32_t(ctx, (uint32_t)l); - assert(sizeof(unsigned long) <= sizeof(uint64_t)); - return HPyLong_FromUInt64_t(ctx, (uint64_t)l); -} - -/** - * Create a Python long object from a C ``long long`` value. - * - * :param ctx: - * The execution context. - * :param l: - * A C ``long long`` value. - * - * :return: - * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. - */ -HPyAPI_INLINE_HELPER HPy -HPyLong_FromLongLong(HPyContext *ctx, long long l) -{ - assert(sizeof(long long) <= sizeof(int64_t)); - return HPyLong_FromInt64_t(ctx, (int64_t)l); -} - -/** - * Create a Python long object from a C ``unsigned long long`` value. - * - * :param ctx: - * The execution context. - * :param l: - * A C ``unsigned long long`` value. - * - * :return: - * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. - */ -HPyAPI_INLINE_HELPER HPy -HPyLong_FromUnsignedLongLong(HPyContext *ctx, unsigned long long l) -{ - assert(sizeof(unsigned long long) <= sizeof(uint64_t)); - return HPyLong_FromUInt64_t(ctx, (uint64_t)l); -} - -/** - * Return a C ``long`` representation of the given Python long object. If the - * object is not an instance of Python long, the object's ``__index__`` method - * (if present) will be used to convert it to a Python long object. - * - * This function will raise an ``OverflowError`` if the value of the object is - * out of range for a C ``long``. - * - * This function will raise a ``TypeError`` if: - * - * * The object is neither an instance of Python long nor it provides an - * ``__index__`` method. - * * If the ``__index__`` method does not return an instance of Python long. - * - * :param ctx: - * The execution context. - * :param h: - * Either an instance of Python long or an object that provides an - * ``__index__`` method (which returns a Python long). - * - * :return: - * A C ``long`` value. Errors will be indicated with return value ``-1``. - * In this case, use :c:func:`HPyErr_Occurred` to disambiguate. - */ -HPyAPI_INLINE_HELPER long -HPyLong_AsLong(HPyContext *ctx, HPy h) -{ - if (sizeof(long) <= sizeof(int32_t)) - return (long) HPyLong_AsInt32_t(ctx, h); - else if (sizeof(long) <= sizeof(int64_t)) - return (long) HPyLong_AsInt64_t(ctx, h); -} - -/** - * Return a C ``unsigned long`` representation of the given Python long object. - * - * This function will raise a ``TypeError`` if the object is not an instance of - * Python long and it will raise an ``OverflowError`` if the object's value is - * negative or out of range for a C ``unsigned long``. - * - * :param ctx: - * The execution context. - * :param h: - * The object to convert to C ``unsigned long`` (must be an instance of - * Python long). - * - * :return: - * A C ``unsigned long`` value. Errors will be indicated with return value - * ``(unsigned long)-1``. In this case, use :c:func:`HPyErr_Occurred` to - * disambiguate. - */ -HPyAPI_INLINE_HELPER unsigned long -HPyLong_AsUnsignedLong(HPyContext *ctx, HPy h) -{ - if (sizeof(unsigned long) <= sizeof(uint32_t)) - return (unsigned long) HPyLong_AsUInt32_t(ctx, h); - else if (sizeof(unsigned long) <= sizeof(uint64_t)) - return (unsigned long) HPyLong_AsUInt64_t(ctx, h); -} - -/** - * Return a C ``unsigned long`` representation of the given Python long object. If the - * object is not an instance of Python long, the object's ``__index__`` method - * (if present) will be used to convert it to a Python long object. - * - * If the object's value is out of range for an ``unsigned long``, return the - * reduction of that value modulo ``ULONG_MAX + 1``. Therefore, this function - * will **NOT** raise an ``OverflowError`` if the value of the object is out of - * range for a C ``unsigned long``. - * - * :param ctx: - * The execution context. - * :param h: - * Either an instance of Python long or an object that provides an - * ``__index__`` method (which returns a Python long). - * - * :return: - * A C ``unsigned long`` value. Errors will be indicated with return value - * ``(unsigned long)-1``. In this case, use :c:func:`HPyErr_Occurred` to - * disambiguate. - */ -HPyAPI_INLINE_HELPER unsigned long -HPyLong_AsUnsignedLongMask(HPyContext *ctx, HPy h) -{ - if (sizeof(unsigned long) <= sizeof(uint32_t)) - return (unsigned long) HPyLong_AsUInt32_tMask(ctx, h); - else if (sizeof(unsigned long) <= sizeof(uint64_t)) - return (unsigned long) HPyLong_AsUInt64_tMask(ctx, h); -} - -/** - * Return a C ``long long`` representation of the given Python long object. If - * the object is not an instance of Python long, the object's ``__index__`` - * method (if present) will be used to convert it to a Python long object. - * - * This function will raise an ``OverflowError`` if the value of the object is - * out of range for a C ``long long``. - * - * This function will raise a ``TypeError`` if: - * - * * The object is neither an instance of Python long nor it provides an - * ``__index__`` method. - * * If the ``__index__`` method does not return an instance of Python long. - * - * :param ctx: - * The execution context. - * :param h: - * Either an instance of Python long or an object that provides an - * ``__index__`` method (which returns a Python long). - * - * :return: - * A C ``long long`` value. Errors will be indicated with return value - * ``-1``. In this case, use :c:func:`HPyErr_Occurred` to disambiguate. - */ -HPyAPI_INLINE_HELPER long long -HPyLong_AsLongLong(HPyContext *ctx, HPy h) -{ - assert(sizeof(long long) <= sizeof(int64_t)); - return (long long) HPyLong_AsInt64_t(ctx, h); -} - -/** - * Return a C ``unsigned long long`` representation of the given Python long - * object. - * - * This function will raise a ``TypeError`` if the object is not an instance of - * Python long and it will raise an ``OverflowError`` if the object's value is - * negative or out of range for a C ``unsigned long``. - * - * :param ctx: - * The execution context. - * :param h: - * The object to convert to C ``unsigned long long`` (must be an instance of - * Python long). - * - * :return: - * A C ``unsigned long long`` value. Errors will be indicated with return - * value ``(unsigned long long)-1``. In this case, use - * :c:func:`HPyErr_Occurred` to disambiguate. - */ -HPyAPI_INLINE_HELPER unsigned long long -HPyLong_AsUnsignedLongLong(HPyContext *ctx, HPy h) -{ - assert(sizeof(unsigned long long) <= sizeof(uint64_t)); - return (unsigned long long) HPyLong_AsUInt64_t(ctx, h); -} - -/** - * Return a C ``unsigned long long`` representation of the given Python long - * object. If the object is not an instance of Python long, the object's - * ``__index__`` method (if present) will be used to convert it to a Python long - * object. - * - * If the object's value is out of range for an ``unsigned long long``, return - * the reduction of that value modulo ``ULLONG_MAX + 1``. Therefore, this - * function will **NOT** raise an ``OverflowError`` if the value of the object - * is out of range for a C ``unsigned long long``. - * - * :param ctx: - * The execution context. - * :param h: - * Either an instance of Python long or an object that provides an - * ``__index__`` method (which returns a Python long). - * - * :return: - * A C ``unsigned long`` value. Errors will be indicated with return value - * ``(unsigned long long)-1``. In this case, use :c:func:`HPyErr_Occurred` - * to disambiguate. - */ -HPyAPI_INLINE_HELPER unsigned long long -HPyLong_AsUnsignedLongLongMask(HPyContext *ctx, HPy h) -{ - assert(sizeof(unsigned long long) <= sizeof(uint64_t)); - return (unsigned long long) HPyLong_AsUInt64_tMask(ctx, h); -} - -/** - * Returns Python ``True`` or ``False`` depending on the truth value of ``v``. - * - * :param ctx: - * The execution context. - * :param v: - * A C ``long`` value. - * - * :return: - * Python ``True`` if ``v != 0``; Python ``False`` otherwise. - */ -HPyAPI_INLINE_HELPER HPy -HPyBool_FromLong(HPyContext *ctx, long v) -{ - return HPyBool_FromBool(ctx, (v ? true : false)); -} - -/** - * Adjust start/end slice indices assuming a sequence of the specified length. - * - * Out of bounds indices are clipped in a manner consistent with the handling of - * normal slices. This function cannot fail and does not call interpreter - * routines. - * - * :param ctx: - * The execution context. - * :param length: - * The length of the sequence that should be assumed for adjusting the - * indices. - * :param start: - * Pointer to the start value (must not be ``NULL``). - * :param stop: - * Pointer to the stop value (must not be ``NULL``). - * :param step: - * The step value of the slice (must not be ``0``) - * - * :return: - * Return the length of the slice. Always successful. Doesn’t call Python code. - */ -HPyAPI_INLINE_HELPER HPy_ssize_t -HPySlice_AdjustIndices(HPyContext *_HPy_UNUSED_ARG(ctx), HPy_ssize_t length, - HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t step) -{ - /* Taken from CPython: Written by Jim Hugunin and Chris Chase. */ - /* this is harder to get right than you might think */ - assert(step != 0); - assert(step >= -HPY_SSIZE_T_MAX); - - if (*start < 0) { - *start += length; - if (*start < 0) { - *start = (step < 0) ? -1 : 0; - } - } - else if (*start >= length) { - *start = (step < 0) ? length - 1 : length; - } - - if (*stop < 0) { - *stop += length; - if (*stop < 0) { - *stop = (step < 0) ? -1 : 0; - } - } - else if (*stop >= length) { - *stop = (step < 0) ? length - 1 : length; - } - - if (step < 0) { - if (*stop < *start) { - return (*start - *stop - 1) / (-step) + 1; - } - } - else { - if (*start < *stop) { - return (*stop - *start - 1) / step + 1; - } - } - return 0; -} - -/** - * Call a method of a Python object. - * - * This is a convenience function for calling a method. It uses - * :c:func:`HPy_GetAttr_s` and :c:func:`HPy_CallTupleDict` to perform the method - * call. - * - * :param ctx: - * The execution context. - * :param utf8_name: - * The name (UTF-8 encoded C string) of the method. Must not be ``NULL``. - * :param receiver: - * A handle to the receiver of the call (i.e. the ``self``). Must not be - * ``HPy_NULL``. - * :param args: - * A handle to a tuple containing the positional arguments (must not be - * ``HPy_NULL`` but can, of course, be empty). - * :param kw: - * A handle to a Python dictionary containing the keyword arguments (may be - * ``HPy_NULL``). - * - * :returns: - * The result of the call on success, or ``HPy_NULL`` in case of an error. - */ -HPyAPI_INLINE_HELPER HPy -HPy_CallMethodTupleDict_s(HPyContext *ctx, const char *utf8_name, HPy receiver, HPy args, HPy kw) -{ - HPy method = HPy_GetAttr_s(ctx, receiver, utf8_name); - if (HPy_IsNull(method)) { - return HPy_NULL; - } - - HPy result = HPy_CallTupleDict(ctx, method, args, kw); - HPy_Close(ctx, method); - return result; -} - -/** - * Call a method of a Python object. - * - * This is a convenience function for calling a method. It uses - * :c:func:`HPy_GetAttr` and :c:func:`HPy_CallTupleDict` to perform the method - * call. - * - * :param ctx: - * The execution context. - * :param name: - * A handle to the name (a Unicode object) of the method. Must not be - * ``HPy_NULL``. - * :param receiver: - * A handle to the receiver of the call (i.e. the ``self``). Must not be - * ``HPy_NULL``. - * :param args: - * A handle to a tuple containing the positional arguments (must not be - * ``HPy_NULL`` but can, of course, be empty). - * :param kw: - * A handle to a Python dictionary containing the keyword arguments (may be - * ``HPy_NULL``). - * - * :returns: - * The result of the call on success, or ``HPy_NULL`` in case of an error. - */ -HPyAPI_INLINE_HELPER HPy -HPy_CallMethodTupleDict(HPyContext *ctx, HPy name, HPy receiver, HPy args, HPy kw) -{ - HPy method = HPy_GetAttr(ctx, receiver, name); - if (HPy_IsNull(method)) { - return HPy_NULL; - } - - HPy result = HPy_CallTupleDict(ctx, method, args, kw); - HPy_Close(ctx, method); - return result; -} - -#endif //HPY_INLINE_HELPERS_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/macros.h b/graalpython/hpy/hpy/devel/include/hpy/macros.h deleted file mode 100644 index 8616930fc1..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/macros.h +++ /dev/null @@ -1,70 +0,0 @@ -/* We define HPy_New as a macro around _HPy_New to suppress a - warning. Usually, we expected it to be called this way: - - PointObject *p; - HPy h = HPy_New(ctx, cls, &p); - - If we call _HPy_New directly, we get a warning because we are implicitly - casting a PointObject** into a void**. The following macro explicitly - casts the third argument to a void**. -*/ - -#define HPy_New(ctx, cls, data) (_HPy_New( \ - (ctx), \ - (cls), \ - ((void**)data) \ - )) - -/* Rich comparison opcodes */ -typedef enum { - HPy_LT = 0, - HPy_LE = 1, - HPy_EQ = 2, - HPy_NE = 3, - HPy_GT = 4, - HPy_GE = 5, -} HPy_RichCmpOp; - -// this needs to be a macro because val1 and val2 can be of arbitrary types -#define HPy_RETURN_RICHCOMPARE(ctx, val1, val2, op) \ - do { \ - bool result; \ - switch (op) { \ - case HPy_EQ: result = ((val1) == (val2)); break; \ - case HPy_NE: result = ((val1) != (val2)); break; \ - case HPy_LT: result = ((val1) < (val2)); break; \ - case HPy_GT: result = ((val1) > (val2)); break; \ - case HPy_LE: result = ((val1) <= (val2)); break; \ - case HPy_GE: result = ((val1) >= (val2)); break; \ - default: \ - HPy_FatalError(ctx, "Invalid value for HPy_RichCmpOp"); \ - } \ - if (result) \ - return HPy_Dup(ctx, ctx->h_True); \ - return HPy_Dup(ctx, ctx->h_False); \ - } while (0) - - -#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT - #define _HPy_PARSE_PID "i" - #define HPyLong_FromPid HPyLong_FromLong - #define HPyLong_AsPid HPyLong_AsLong -#elif SIZEOF_PID_T == SIZEOF_LONG - #define _HPy_PARSE_PID "l" - #define HPyLong_FromPid HPyLong_FromLong - #define HPyLong_AsPid HPyLong_AsLong -#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG - #define _HPy_PARSE_PID "L" - #define HPyLong_FromPid HPyLong_FromLongLong - #define HPyLong_AsPid HPyLong_AsLongLong -#else -#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)" -#endif /* SIZEOF_PID_T */ - -#define HPy_BEGIN_LEAVE_PYTHON(context) { \ - HPyThreadState _token; \ - _token = HPy_LeavePythonExecution(context); - -#define HPy_END_LEAVE_PYTHON(context) \ - HPy_ReenterPythonExecution(context, _token); \ - } diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h deleted file mode 100644 index 5d43db1635..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/argparse.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_ARGPARSE_H -#define HPY_COMMON_RUNTIME_ARGPARSE_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "hpy.h" - -HPyAPI_HELPER int -HPyArg_Parse(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, const char *fmt, ...); - -HPyAPI_HELPER int -HPyArg_ParseKeywords(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, HPy kwnames, const char *fmt, - const char *keywords[], ...); - -HPyAPI_HELPER int -HPyArg_ParseKeywordsDict(HPyContext *ctx, HPyTracker *ht, const HPy *args, - HPy_ssize_t nargs, HPy kw, const char *fmt, - const char *keywords[], ...); - -#ifdef __cplusplus -} -#endif -#endif /* HPY_COMMON_RUNTIME_ARGPARSE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h deleted file mode 100644 index cd5667782c..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/buildvalue.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_BUILDVALUE_H -#define HPY_COMMON_RUNTIME_BUILDVALUE_H - -#include "hpy.h" - -HPyAPI_HELPER HPy -HPy_BuildValue(HPyContext *ctx, const char *fmt, ...); - -#endif /* HPY_COMMON_RUNTIME_BUILDVALUE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h deleted file mode 100644 index d32aa75592..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_funcs.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef HPY_RUNTIME_CTX_FUNCS_H -#define HPY_RUNTIME_CTX_FUNCS_H - -// This file contains the prototypes for all the functions defined in -// hpy/devel/src/runtime/ctx_*.c - -#include "hpy.h" - -// ctx_bytes.c -_HPy_HIDDEN HPy ctx_Bytes_FromStringAndSize(HPyContext *ctx, const char *v, - HPy_ssize_t len); - -// ctx_call.c -_HPy_HIDDEN HPy ctx_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw); -_HPy_HIDDEN HPy ctx_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); -_HPy_HIDDEN HPy ctx_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); - -// ctx_err.c -_HPy_HIDDEN int ctx_Err_Occurred(HPyContext *ctx); - -// ctx_listbuilder.c -_HPy_HIDDEN HPyListBuilder ctx_ListBuilder_New(HPyContext *ctx, - HPy_ssize_t size); -_HPy_HIDDEN void ctx_ListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, - HPy_ssize_t index, HPy h_item); -_HPy_HIDDEN HPy ctx_ListBuilder_Build(HPyContext *ctx, HPyListBuilder builder); -_HPy_HIDDEN void ctx_ListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder); - -// ctx_module.c -_HPy_HIDDEN HPy ctx_Module_Create(HPyContext *ctx, HPyModuleDef *hpydef); - -// ctx_object.c -_HPy_HIDDEN void ctx_Dump(HPyContext *ctx, HPy h); -_HPy_HIDDEN HPy ctx_Type(HPyContext *ctx, HPy h_obj); -_HPy_HIDDEN int ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type); -_HPy_HIDDEN int ctx_Is(HPyContext *ctx, HPy h_obj, HPy h_other); -_HPy_HIDDEN HPy ctx_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); -_HPy_HIDDEN HPy ctx_GetItem_s(HPyContext *ctx, HPy obj, const char *key); -_HPy_HIDDEN int ctx_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value); -_HPy_HIDDEN int ctx_SetItem_s(HPyContext *ctx, HPy obj, const char *key, HPy value); -_HPy_HIDDEN int ctx_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); -_HPy_HIDDEN int ctx_DelItem_s(HPyContext *ctx, HPy obj, const char *key); - -// ctx_tracker.c -_HPy_HIDDEN HPyTracker ctx_Tracker_New(HPyContext *ctx, HPy_ssize_t size); -_HPy_HIDDEN int ctx_Tracker_Add(HPyContext *ctx, HPyTracker ht, HPy h); -_HPy_HIDDEN void ctx_Tracker_ForgetAll(HPyContext *ctx, HPyTracker ht); -_HPy_HIDDEN void ctx_Tracker_Close(HPyContext *ctx, HPyTracker ht); - -// ctx_tuplebuilder.c -_HPy_HIDDEN HPyTupleBuilder ctx_TupleBuilder_New(HPyContext *ctx, - HPy_ssize_t size); -_HPy_HIDDEN void ctx_TupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, - HPy_ssize_t index, HPy h_item); -_HPy_HIDDEN HPy ctx_TupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder); -_HPy_HIDDEN void ctx_TupleBuilder_Cancel(HPyContext *ctx, - HPyTupleBuilder builder); - -// ctx_tuple.c -_HPy_HIDDEN HPy ctx_Tuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n); - -// ctx_capsule.c -_HPy_HIDDEN HPy ctx_Capsule_New(HPyContext *ctx, - void *pointer, - const char *name, - HPyCapsule_Destructor *destructor); -_HPy_HIDDEN int ctx_Capsule_SetDestructor(HPyContext *ctx, - HPy h_capsule, - HPyCapsule_Destructor *destructor); - -#ifndef HPY_ABI_CPYTHON -_HPy_HIDDEN void* ctx_Capsule_Get(HPyContext *ctx, - HPy capsule, - _HPyCapsule_key key, - const char *name); -_HPy_HIDDEN int ctx_Capsule_Set(HPyContext *ctx, - HPy capsule, - _HPyCapsule_key key, - void *value); -#endif - -// ctx_type.c -_HPy_HIDDEN void* ctx_AsStruct_Object(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Legacy(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Type(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Long(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Float(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Unicode(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Tuple(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_List(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Dict(HPyContext *ctx, HPy h); -_HPy_HIDDEN void* ctx_AsStruct_Slow(HPyContext *ctx, HPy h); -_HPy_HIDDEN HPy ctx_Type_FromSpec(HPyContext *ctx, HPyType_Spec *hpyspec, - HPyType_SpecParam *params); -_HPy_HIDDEN HPy ctx_New(HPyContext *ctx, HPy h_type, void **data); -_HPy_HIDDEN HPy ctx_Type_GenericNew(HPyContext *ctx, HPy h_type, - const HPy *args, HPy_ssize_t nargs, HPy kw); -_HPy_HIDDEN HPyType_BuiltinShape ctx_Type_GetBuiltinShape(HPyContext *ctx, - HPy h_type); -_HPy_HIDDEN const char *ctx_Type_GetName(HPyContext *ctx, HPy type); -_HPy_HIDDEN int ctx_SetCallFunction(HPyContext *ctx, HPy h, - HPyCallFunction *func); - - -// ctx_long.c -_HPy_HIDDEN HPy ctx_Long_FromInt32_t(HPyContext *ctx, int32_t value); -_HPy_HIDDEN HPy ctx_Long_FromUInt32_t(HPyContext *ctx, uint32_t value); -_HPy_HIDDEN HPy ctx_Long_FromInt64_t(HPyContext *ctx, int64_t v); -_HPy_HIDDEN HPy ctx_Long_FromUInt64_t(HPyContext *ctx, uint64_t v); -_HPy_HIDDEN int32_t ctx_Long_AsInt32_t(HPyContext *ctx, HPy h); -_HPy_HIDDEN uint32_t ctx_Long_AsUInt32_t(HPyContext *ctx, HPy h); -_HPy_HIDDEN uint32_t ctx_Long_AsUInt32_tMask(HPyContext *ctx, HPy h); -_HPy_HIDDEN int64_t ctx_Long_AsInt64_t(HPyContext *ctx, HPy h); -_HPy_HIDDEN uint64_t ctx_Long_AsUInt64_t(HPyContext *ctx, HPy h); -_HPy_HIDDEN uint64_t ctx_Long_AsUInt64_tMask(HPyContext *ctx, HPy h); - -// ctx_eval.c -_HPy_HIDDEN HPy ctx_Compile_s(HPyContext *ctx, const char *utf8_source, - const char *utf8_filename, HPy_SourceKind kind); - -// ctx_contextvar.c -_HPy_HIDDEN int32_t ctx_ContextVar_Get(HPyContext *ctx, HPy context_var, - HPy default_value, HPy *result); -#endif /* HPY_RUNTIME_CTX_FUNCS_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h deleted file mode 100644 index 8cb6549cc9..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_module.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_CTX_MODULE_H -#define HPY_COMMON_RUNTIME_CTX_MODULE_H - -#include -#include "hpy.h" - -// Helper functions for CPython implementation (both CPython ABI and -// HPy universal module impl for CPython) - -/** Converts HPy module definition to CPython module definition for multiphase - * initialization */ -_HPy_HIDDEN PyModuleDef* -_HPyModuleDef_CreatePyModuleDef(HPyModuleDef *hpydef); - -/** Converts HPy module definition to PyObject that wraps CPython module - * definition for multiphase initialization */ -_HPy_HIDDEN PyObject* -_HPyModuleDef_AsPyInit(HPyModuleDef *hpydef); - -/** Implements the extra HPy specific validation that should be applied to the - * result of the HPy_mod_create slot. */ -_HPy_HIDDEN void -_HPyModule_CheckCreateSlotResult(PyObject **result); - -#endif //HPY_COMMON_RUNTIME_CTX_MODULE_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h deleted file mode 100644 index f8648ae654..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/ctx_type.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_CTX_TYPE_H -#define HPY_COMMON_RUNTIME_CTX_TYPE_H - -#include -#include "hpy.h" -#include "hpy/hpytype.h" - -_HPy_HIDDEN PyMethodDef *create_method_defs(HPyDef *hpydefs[], - PyMethodDef *legacy_methods); - -_HPy_HIDDEN int call_traverseproc_from_trampoline(HPyFunc_traverseproc tp_traverse, - PyObject *self, - cpy_visitproc cpy_visit, - void *cpy_arg); - -#endif /* HPY_COMMON_RUNTIME_CTX_TYPE_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h deleted file mode 100644 index f44135ac43..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/format.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * String formatting helpers. These functions are not part of HPy ABI. The implementation will be linked into HPy extensions. - */ -#ifndef HPY_COMMON_RUNTIME_FORMAT_H -#define HPY_COMMON_RUNTIME_FORMAT_H - -#include "hpy.h" - -HPyAPI_HELPER HPy -HPyUnicode_FromFormat(HPyContext *ctx, const char *fmt, ...); - -HPyAPI_HELPER HPy -HPyUnicode_FromFormatV(HPyContext *ctx, const char *format, va_list vargs); - -HPyAPI_HELPER HPy -HPyErr_Format(HPyContext *ctx, HPy h_type, const char *fmt, ...); - -#endif /* HPY_COMMON_RUNTIME_FORMAT_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h deleted file mode 100644 index 4f5af609ce..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/helpers.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_HELPERS_H -#define HPY_COMMON_RUNTIME_HELPERS_H - -#include "hpy.h" -#include "hpy/hpytype.h" - -HPyAPI_HELPER int -HPyHelpers_AddType(HPyContext *ctx, HPy obj, const char *name, - HPyType_Spec *hpyspec, HPyType_SpecParam *params); - -HPyAPI_HELPER int -HPyHelpers_PackArgsAndKeywords(HPyContext *ctx, const HPy *args, size_t nargs, - HPy kwnames, HPy *out_args_tuple, HPy *out_kwd); - -#endif /* HPY_COMMON_RUNTIME_HELPERS_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h b/graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h deleted file mode 100644 index 700fbcdf7c..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/runtime/structseq.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef HPY_COMMON_RUNTIME_STRUCTSEQ_H -#define HPY_COMMON_RUNTIME_STRUCTSEQ_H - -#include "hpy.h" - -/* - * Struct sequences are subclasses of tuple, so we provide a simplified API to - * create them here. This maps closely to the CPython limited API for creating - * struct sequences. However, in universal mode we use the - * collections.namedtuple type to implement this, which behaves a bit - * differently w.r.t. hidden elements. Thus, the n_in_sequence field available - * in CPython's PyStructSequence_Desc is not available. Also, we use a builder - * API like for tuples and lists so that the struct sequence is guaranteed not - * to be written after it is created. - */ - -/** - * Describes a field of a struct sequence. - */ -typedef struct { - /** - * Name (UTF-8 encoded) for the field or ``NULL`` to end the list of named - * fields. Set the name to :c:var:`HPyStructSequence_UnnamedField` to leave - * it unnamed. - */ - const char *name; - - /** - * Docstring of the field (UTF-8 encoded); may be ``NULL``. - */ - const char *doc; -} HPyStructSequence_Field; - -/** - * Contains the meta information of a struct sequence type to create. - * Struct sequences are subclasses of tuple. The index in the :c:member:`fields` - * array of the descriptor determines which field of the struct sequence is - * described. - */ -typedef struct { - /** - * Name of the struct sequence type (UTF-8 encoded; must not be ``NULL``). - */ - const char *name; - - /** Docstring of the type (UTF-8 encoded); may be ``NULL``. */ - const char *doc; - - /** - * Pointer to ``NULL``-terminated array with field names of the new type - * (must not be ``NULL``). - */ - HPyStructSequence_Field *fields; -} HPyStructSequence_Desc; - -/** - * A marker that can be used as struct sequence field name to indicate that a - * field should be anonymous (i.e. cannot be accessed by a name but only by - * numeric index). - */ -extern const char * const HPyStructSequence_UnnamedField; - -/** - * Create a new struct sequence type from a descriptor. Instances of the - * resulting type can be created with :c:func:`HPyStructSequence_New`. - * - * :param ctx: - * The execution context. - * :param desc: - * The descriptor of the struct sequence type to create (must not be - * ``NULL``): - * - * :returns: - * A handle to the new struct sequence type or ``HPy_NULL`` in case of - * errors. - */ -HPyAPI_HELPER HPy -HPyStructSequence_NewType(HPyContext *ctx, HPyStructSequence_Desc *desc); - -/** - * Creates a new instance of ``type`` initializing it with the given arguments. - * - * Since struct sequences are immutable objects, they need to be initialized at - * instantiation. This function will create a fresh instance of the provided - * struct sequence type. The type must have been created with - * :c:func:`HPyStructSequence_NewType`. - * - * :param ctx: - * The execution context. - * :param type: - * A struct sequence type (must not be ``HPy_NULL``). If the passed object - * is not a type, the behavior is undefined. If the given type is not - * appropriate, a ``TypeError`` will be raised. - * :param nargs: - * The number of arguments in ``args``. If this argument is not exactly the - * number of fields of the struct sequence, a ``TypeError`` will be raised. - * :param args: - * An array of HPy handles to Python objects to be used for initializing - * the struct sequence. If ``nargs > 0`` then this argument must not be - * ``NULL``. - * - * :returns: - * A new instance of ``type`` or ``HPy_NULL`` if an error occurred. - */ -HPyAPI_HELPER HPy -HPyStructSequence_New(HPyContext *ctx, HPy type, HPy_ssize_t nargs, HPy *args); - -#endif /* HPY_COMMON_RUNTIME_STRUCTSEQ_H */ diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h deleted file mode 100644 index 1abb8e5d1c..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_ctx.h +++ /dev/null @@ -1,290 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.ctx.autogen_ctx_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -struct _HPyContext_s { - const char *name; // used just to make debugging and testing easier - void *_private; // used by implementations to store custom data - int abi_version; - HPy h_None; - HPy h_True; - HPy h_False; - HPy h_NotImplemented; - HPy h_Ellipsis; - HPy h_BaseException; - HPy h_Exception; - HPy h_StopAsyncIteration; - HPy h_StopIteration; - HPy h_GeneratorExit; - HPy h_ArithmeticError; - HPy h_LookupError; - HPy h_AssertionError; - HPy h_AttributeError; - HPy h_BufferError; - HPy h_EOFError; - HPy h_FloatingPointError; - HPy h_OSError; - HPy h_ImportError; - HPy h_ModuleNotFoundError; - HPy h_IndexError; - HPy h_KeyError; - HPy h_KeyboardInterrupt; - HPy h_MemoryError; - HPy h_NameError; - HPy h_OverflowError; - HPy h_RuntimeError; - HPy h_RecursionError; - HPy h_NotImplementedError; - HPy h_SyntaxError; - HPy h_IndentationError; - HPy h_TabError; - HPy h_ReferenceError; - HPy h_SystemError; - HPy h_SystemExit; - HPy h_TypeError; - HPy h_UnboundLocalError; - HPy h_UnicodeError; - HPy h_UnicodeEncodeError; - HPy h_UnicodeDecodeError; - HPy h_UnicodeTranslateError; - HPy h_ValueError; - HPy h_ZeroDivisionError; - HPy h_BlockingIOError; - HPy h_BrokenPipeError; - HPy h_ChildProcessError; - HPy h_ConnectionError; - HPy h_ConnectionAbortedError; - HPy h_ConnectionRefusedError; - HPy h_ConnectionResetError; - HPy h_FileExistsError; - HPy h_FileNotFoundError; - HPy h_InterruptedError; - HPy h_IsADirectoryError; - HPy h_NotADirectoryError; - HPy h_PermissionError; - HPy h_ProcessLookupError; - HPy h_TimeoutError; - HPy h_Warning; - HPy h_UserWarning; - HPy h_DeprecationWarning; - HPy h_PendingDeprecationWarning; - HPy h_SyntaxWarning; - HPy h_RuntimeWarning; - HPy h_FutureWarning; - HPy h_ImportWarning; - HPy h_UnicodeWarning; - HPy h_BytesWarning; - HPy h_ResourceWarning; - HPy h_BaseObjectType; - HPy h_TypeType; - HPy h_BoolType; - HPy h_LongType; - HPy h_FloatType; - HPy h_UnicodeType; - HPy h_TupleType; - HPy h_ListType; - HPy (*ctx_Dup)(HPyContext *ctx, HPy h); - void (*ctx_Close)(HPyContext *ctx, HPy h); - HPy (*ctx_Long_FromInt32_t)(HPyContext *ctx, int32_t value); - HPy (*ctx_Long_FromUInt32_t)(HPyContext *ctx, uint32_t value); - HPy (*ctx_Long_FromInt64_t)(HPyContext *ctx, int64_t v); - HPy (*ctx_Long_FromUInt64_t)(HPyContext *ctx, uint64_t v); - HPy (*ctx_Long_FromSize_t)(HPyContext *ctx, size_t value); - HPy (*ctx_Long_FromSsize_t)(HPyContext *ctx, HPy_ssize_t value); - int32_t (*ctx_Long_AsInt32_t)(HPyContext *ctx, HPy h); - uint32_t (*ctx_Long_AsUInt32_t)(HPyContext *ctx, HPy h); - uint32_t (*ctx_Long_AsUInt32_tMask)(HPyContext *ctx, HPy h); - int64_t (*ctx_Long_AsInt64_t)(HPyContext *ctx, HPy h); - uint64_t (*ctx_Long_AsUInt64_t)(HPyContext *ctx, HPy h); - uint64_t (*ctx_Long_AsUInt64_tMask)(HPyContext *ctx, HPy h); - size_t (*ctx_Long_AsSize_t)(HPyContext *ctx, HPy h); - HPy_ssize_t (*ctx_Long_AsSsize_t)(HPyContext *ctx, HPy h); - void *(*ctx_Long_AsVoidPtr)(HPyContext *ctx, HPy h); - double (*ctx_Long_AsDouble)(HPyContext *ctx, HPy h); - HPy (*ctx_Float_FromDouble)(HPyContext *ctx, double v); - double (*ctx_Float_AsDouble)(HPyContext *ctx, HPy h); - HPy (*ctx_Bool_FromBool)(HPyContext *ctx, bool v); - HPy_ssize_t (*ctx_Length)(HPyContext *ctx, HPy h); - int (*ctx_Number_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_Add)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Subtract)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Multiply)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_MatrixMultiply)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_FloorDivide)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_TrueDivide)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Remainder)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Divmod)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Power)(HPyContext *ctx, HPy h1, HPy h2, HPy h3); - HPy (*ctx_Negative)(HPyContext *ctx, HPy h1); - HPy (*ctx_Positive)(HPyContext *ctx, HPy h1); - HPy (*ctx_Absolute)(HPyContext *ctx, HPy h1); - HPy (*ctx_Invert)(HPyContext *ctx, HPy h1); - HPy (*ctx_Lshift)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Rshift)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_And)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Xor)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Or)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_Index)(HPyContext *ctx, HPy h1); - HPy (*ctx_Long)(HPyContext *ctx, HPy h1); - HPy (*ctx_Float)(HPyContext *ctx, HPy h1); - HPy (*ctx_InPlaceAdd)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceSubtract)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceMultiply)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceMatrixMultiply)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceFloorDivide)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceTrueDivide)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceRemainder)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlacePower)(HPyContext *ctx, HPy h1, HPy h2, HPy h3); - HPy (*ctx_InPlaceLshift)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceRshift)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceAnd)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceXor)(HPyContext *ctx, HPy h1, HPy h2); - HPy (*ctx_InPlaceOr)(HPyContext *ctx, HPy h1, HPy h2); - int (*ctx_Callable_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_CallTupleDict)(HPyContext *ctx, HPy callable, HPy args, HPy kw); - void (*ctx_FatalError)(HPyContext *ctx, const char *message); - void (*ctx_Err_SetString)(HPyContext *ctx, HPy h_type, const char *utf8_message); - void (*ctx_Err_SetObject)(HPyContext *ctx, HPy h_type, HPy h_value); - HPy (*ctx_Err_SetFromErrnoWithFilename)(HPyContext *ctx, HPy h_type, const char *filename_fsencoded); - void (*ctx_Err_SetFromErrnoWithFilenameObjects)(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2); - int (*ctx_Err_Occurred)(HPyContext *ctx); - int (*ctx_Err_ExceptionMatches)(HPyContext *ctx, HPy exc); - void (*ctx_Err_NoMemory)(HPyContext *ctx); - void (*ctx_Err_Clear)(HPyContext *ctx); - HPy (*ctx_Err_NewException)(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict); - HPy (*ctx_Err_NewExceptionWithDoc)(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict); - int (*ctx_Err_WarnEx)(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level); - void (*ctx_Err_WriteUnraisable)(HPyContext *ctx, HPy obj); - int (*ctx_IsTrue)(HPyContext *ctx, HPy h); - HPy (*ctx_Type_FromSpec)(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params); - HPy (*ctx_Type_GenericNew)(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); - HPy (*ctx_GetAttr)(HPyContext *ctx, HPy obj, HPy name); - HPy (*ctx_GetAttr_s)(HPyContext *ctx, HPy obj, const char *utf8_name); - int (*ctx_HasAttr)(HPyContext *ctx, HPy obj, HPy name); - int (*ctx_HasAttr_s)(HPyContext *ctx, HPy obj, const char *utf8_name); - int (*ctx_SetAttr)(HPyContext *ctx, HPy obj, HPy name, HPy value); - int (*ctx_SetAttr_s)(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value); - HPy (*ctx_GetItem)(HPyContext *ctx, HPy obj, HPy key); - HPy (*ctx_GetItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx); - HPy (*ctx_GetItem_s)(HPyContext *ctx, HPy obj, const char *utf8_key); - int (*ctx_Contains)(HPyContext *ctx, HPy container, HPy key); - int (*ctx_SetItem)(HPyContext *ctx, HPy obj, HPy key, HPy value); - int (*ctx_SetItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value); - int (*ctx_SetItem_s)(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value); - HPy (*ctx_Type)(HPyContext *ctx, HPy obj); - int (*ctx_TypeCheck)(HPyContext *ctx, HPy obj, HPy type); - int (*ctx_Is)(HPyContext *ctx, HPy obj, HPy other); - void *(*ctx_AsStruct_Object)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Legacy)(HPyContext *ctx, HPy h); - HPy (*ctx_New)(HPyContext *ctx, HPy h_type, void **data); - HPy (*ctx_Repr)(HPyContext *ctx, HPy obj); - HPy (*ctx_Str)(HPyContext *ctx, HPy obj); - HPy (*ctx_ASCII)(HPyContext *ctx, HPy obj); - HPy (*ctx_Bytes)(HPyContext *ctx, HPy obj); - HPy (*ctx_RichCompare)(HPyContext *ctx, HPy v, HPy w, int op); - int (*ctx_RichCompareBool)(HPyContext *ctx, HPy v, HPy w, int op); - HPy_hash_t (*ctx_Hash)(HPyContext *ctx, HPy obj); - int (*ctx_Bytes_Check)(HPyContext *ctx, HPy h); - HPy_ssize_t (*ctx_Bytes_Size)(HPyContext *ctx, HPy h); - HPy_ssize_t (*ctx_Bytes_GET_SIZE)(HPyContext *ctx, HPy h); - const char *(*ctx_Bytes_AsString)(HPyContext *ctx, HPy h); - const char *(*ctx_Bytes_AS_STRING)(HPyContext *ctx, HPy h); - HPy (*ctx_Bytes_FromString)(HPyContext *ctx, const char *bytes); - HPy (*ctx_Bytes_FromStringAndSize)(HPyContext *ctx, const char *bytes, HPy_ssize_t len); - HPy (*ctx_Unicode_FromString)(HPyContext *ctx, const char *utf8); - int (*ctx_Unicode_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_Unicode_AsASCIIString)(HPyContext *ctx, HPy h); - HPy (*ctx_Unicode_AsLatin1String)(HPyContext *ctx, HPy h); - HPy (*ctx_Unicode_AsUTF8String)(HPyContext *ctx, HPy h); - const char *(*ctx_Unicode_AsUTF8AndSize)(HPyContext *ctx, HPy h, HPy_ssize_t *size); - HPy (*ctx_Unicode_FromWideChar)(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size); - HPy (*ctx_Unicode_DecodeFSDefault)(HPyContext *ctx, const char *v); - HPy (*ctx_Unicode_DecodeFSDefaultAndSize)(HPyContext *ctx, const char *v, HPy_ssize_t size); - HPy (*ctx_Unicode_EncodeFSDefault)(HPyContext *ctx, HPy h); - HPy_UCS4 (*ctx_Unicode_ReadChar)(HPyContext *ctx, HPy h, HPy_ssize_t index); - HPy (*ctx_Unicode_DecodeASCII)(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors); - HPy (*ctx_Unicode_DecodeLatin1)(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors); - int (*ctx_List_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_List_New)(HPyContext *ctx, HPy_ssize_t len); - int (*ctx_List_Append)(HPyContext *ctx, HPy h_list, HPy h_item); - int (*ctx_Dict_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_Dict_New)(HPyContext *ctx); - int (*ctx_Tuple_Check)(HPyContext *ctx, HPy h); - HPy (*ctx_Tuple_FromArray)(HPyContext *ctx, const HPy items[], HPy_ssize_t n); - HPy (*ctx_Import_ImportModule)(HPyContext *ctx, const char *utf8_name); - HPy (*ctx_FromPyObject)(HPyContext *ctx, cpy_PyObject *obj); - cpy_PyObject *(*ctx_AsPyObject)(HPyContext *ctx, HPy h); - void (*ctx_CallRealFunctionFromTrampoline)(HPyContext *ctx, HPyFunc_Signature sig, HPyCFunction func, void *args); - HPyListBuilder (*ctx_ListBuilder_New)(HPyContext *ctx, HPy_ssize_t size); - void (*ctx_ListBuilder_Set)(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item); - HPy (*ctx_ListBuilder_Build)(HPyContext *ctx, HPyListBuilder builder); - void (*ctx_ListBuilder_Cancel)(HPyContext *ctx, HPyListBuilder builder); - HPyTupleBuilder (*ctx_TupleBuilder_New)(HPyContext *ctx, HPy_ssize_t size); - void (*ctx_TupleBuilder_Set)(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item); - HPy (*ctx_TupleBuilder_Build)(HPyContext *ctx, HPyTupleBuilder builder); - void (*ctx_TupleBuilder_Cancel)(HPyContext *ctx, HPyTupleBuilder builder); - HPyTracker (*ctx_Tracker_New)(HPyContext *ctx, HPy_ssize_t size); - int (*ctx_Tracker_Add)(HPyContext *ctx, HPyTracker ht, HPy h); - void (*ctx_Tracker_ForgetAll)(HPyContext *ctx, HPyTracker ht); - void (*ctx_Tracker_Close)(HPyContext *ctx, HPyTracker ht); - void (*ctx_Field_Store)(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h); - HPy (*ctx_Field_Load)(HPyContext *ctx, HPy source_object, HPyField source_field); - void (*ctx_ReenterPythonExecution)(HPyContext *ctx, HPyThreadState state); - HPyThreadState (*ctx_LeavePythonExecution)(HPyContext *ctx); - void (*ctx_Global_Store)(HPyContext *ctx, HPyGlobal *global, HPy h); - HPy (*ctx_Global_Load)(HPyContext *ctx, HPyGlobal global); - void (*ctx_Dump)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Type)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Long)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Float)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Unicode)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_Tuple)(HPyContext *ctx, HPy h); - void *(*ctx_AsStruct_List)(HPyContext *ctx, HPy h); - HPyType_BuiltinShape (*ctx_Type_GetBuiltinShape)(HPyContext *ctx, HPy h_type); - int (*ctx_DelItem)(HPyContext *ctx, HPy obj, HPy key); - int (*ctx_DelItem_i)(HPyContext *ctx, HPy obj, HPy_ssize_t idx); - int (*ctx_DelItem_s)(HPyContext *ctx, HPy obj, const char *utf8_key); - HPy h_ComplexType; - HPy h_BytesType; - HPy h_MemoryViewType; - HPy h_CapsuleType; - HPy h_SliceType; - HPy h_Builtins; - HPy (*ctx_Capsule_New)(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); - void *(*ctx_Capsule_Get)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); - int (*ctx_Capsule_IsValid)(HPyContext *ctx, HPy capsule, const char *utf8_name); - int (*ctx_Capsule_Set)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value); - HPy (*ctx_Compile_s)(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); - HPy (*ctx_EvalCode)(HPyContext *ctx, HPy code, HPy globals, HPy locals); - HPy (*ctx_ContextVar_New)(HPyContext *ctx, const char *name, HPy default_value); - int32_t (*ctx_ContextVar_Get)(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result); - HPy (*ctx_ContextVar_Set)(HPyContext *ctx, HPy context_var, HPy value); - const char *(*ctx_Type_GetName)(HPyContext *ctx, HPy type); - int (*ctx_Type_IsSubtype)(HPyContext *ctx, HPy sub, HPy type); - HPy (*ctx_Unicode_FromEncodedObject)(HPyContext *ctx, HPy obj, const char *encoding, const char *errors); - HPy (*ctx_Unicode_Substring)(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end); - HPy (*ctx_Dict_Keys)(HPyContext *ctx, HPy h); - HPy (*ctx_Dict_Copy)(HPyContext *ctx, HPy h); - int (*ctx_Slice_Unpack)(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); - int (*ctx_SetCallFunction)(HPyContext *ctx, HPy h, HPyCallFunction *func); - HPy (*ctx_Call)(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); - HPy (*ctx_CallMethod)(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); - HPy h_DictType; - void *(*ctx_AsStruct_Dict)(HPyContext *ctx, HPy h); - int (*ctx_List_Insert)(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item); - HPy (*ctx_GetSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); - int (*ctx_SetSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); - int (*ctx_DelSlice)(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); - HPy (*ctx_GetIter)(HPyContext *ctx, HPy obj); - HPy (*ctx_Iter_Next)(HPyContext *ctx, HPy obj); - int (*ctx_Iter_Check)(HPyContext *ctx, HPy obj); - HPy (*ctx_Slice_New)(HPyContext *ctx, HPy start, HPy stop, HPy step); -}; diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h deleted file mode 100644 index 568b5621db..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h +++ /dev/null @@ -1,416 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.hpyfunc.autogen_hpyfunc_trampoline_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -typedef struct { - cpy_PyObject *self; - cpy_PyObject * result; -} _HPyFunc_args_NOARGS; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_NOARGS(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *self) \ - { \ - _HPyFunc_args_NOARGS a = { self }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_NOARGS, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *self; - cpy_PyObject *arg; - cpy_PyObject * result; -} _HPyFunc_args_O; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_O(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *self, cpy_PyObject *arg) \ - { \ - _HPyFunc_args_O a = { self, arg }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_O, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject * result; -} _HPyFunc_args_UNARYFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_UNARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_UNARYFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_UNARYFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject * result; -} _HPyFunc_args_BINARYFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_BINARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyFunc_args_BINARYFUNC a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_BINARYFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject *arg2; - cpy_PyObject * result; -} _HPyFunc_args_TERNARYFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_TERNARYFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_TERNARYFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_TERNARYFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - int result; -} _HPyFunc_args_INQUIRY; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_INQUIRY(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_INQUIRY a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_INQUIRY, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_ssize_t result; -} _HPyFunc_args_LENFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_LENFUNC(SYM, IMPL) \ - static HPy_ssize_t SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_LENFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_LENFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_ssize_t arg1; - cpy_PyObject * result; -} _HPyFunc_args_SSIZEARGFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZEARGFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, HPy_ssize_t arg1) \ - { \ - _HPyFunc_args_SSIZEARGFUNC a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SSIZEARGFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_ssize_t arg1; - HPy_ssize_t arg2; - cpy_PyObject * result; -} _HPyFunc_args_SSIZESSIZEARGFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZESSIZEARGFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, HPy_ssize_t arg2) \ - { \ - _HPyFunc_args_SSIZESSIZEARGFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SSIZESSIZEARGFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_ssize_t arg1; - cpy_PyObject *arg2; - int result; -} _HPyFunc_args_SSIZEOBJARGPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZEOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_SSIZEOBJARGPROC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SSIZEOBJARGPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_ssize_t arg1; - HPy_ssize_t arg2; - cpy_PyObject *arg3; - int result; -} _HPyFunc_args_SSIZESSIZEOBJARGPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SSIZESSIZEOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, HPy_ssize_t arg1, HPy_ssize_t arg2, cpy_PyObject *arg3) \ - { \ - _HPyFunc_args_SSIZESSIZEOBJARGPROC a = { arg0, arg1, arg2, arg3 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SSIZESSIZEOBJARGPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject *arg2; - int result; -} _HPyFunc_args_OBJOBJARGPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_OBJOBJARGPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_OBJOBJARGPROC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_OBJOBJARGPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - void *arg0; -} _HPyFunc_args_FREEFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_FREEFUNC(SYM, IMPL) \ - static void SYM(void *arg0) \ - { \ - _HPyFunc_args_FREEFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_FREEFUNC, (HPyCFunction)IMPL, &a); \ - return; \ - } - -typedef struct { - cpy_PyObject *arg0; - char *arg1; - cpy_PyObject * result; -} _HPyFunc_args_GETATTRFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETATTRFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, char *arg1) \ - { \ - _HPyFunc_args_GETATTRFUNC a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_GETATTRFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject * result; -} _HPyFunc_args_GETATTROFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETATTROFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyFunc_args_GETATTROFUNC a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_GETATTROFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - char *arg1; - cpy_PyObject *arg2; - int result; -} _HPyFunc_args_SETATTRFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETATTRFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, char *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_SETATTRFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SETATTRFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject *arg2; - int result; -} _HPyFunc_args_SETATTROFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETATTROFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_SETATTROFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SETATTROFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject * result; -} _HPyFunc_args_REPRFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_REPRFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_REPRFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_REPRFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - HPy_hash_t result; -} _HPyFunc_args_HASHFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_HASHFUNC(SYM, IMPL) \ - static HPy_hash_t SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_HASHFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_HASHFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject * result; -} _HPyFunc_args_GETITERFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETITERFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_GETITERFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_GETITERFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject * result; -} _HPyFunc_args_ITERNEXTFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_ITERNEXTFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_ITERNEXTFUNC a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_ITERNEXTFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject *arg2; - cpy_PyObject * result; -} _HPyFunc_args_DESCRGETFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESCRGETFUNC(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_DESCRGETFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_DESCRGETFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - cpy_PyObject *arg2; - int result; -} _HPyFunc_args_DESCRSETFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESCRSETFUNC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, cpy_PyObject *arg2) \ - { \ - _HPyFunc_args_DESCRSETFUNC a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_DESCRSETFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - void *arg1; - cpy_PyObject * result; -} _HPyFunc_args_GETTER; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETTER(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, void *arg1) \ - { \ - _HPyFunc_args_GETTER a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_GETTER, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - void *arg2; - int result; -} _HPyFunc_args_SETTER; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_SETTER(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1, void *arg2) \ - { \ - _HPyFunc_args_SETTER a = { arg0, arg1, arg2 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_SETTER, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - int result; -} _HPyFunc_args_OBJOBJPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_OBJOBJPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *arg0, cpy_PyObject *arg1) \ - { \ - _HPyFunc_args_OBJOBJPROC a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_OBJOBJPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *arg0; -} _HPyFunc_args_DESTRUCTOR; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESTRUCTOR(SYM, IMPL) \ - static void SYM(cpy_PyObject *arg0) \ - { \ - _HPyFunc_args_DESTRUCTOR a = { arg0 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_DESTRUCTOR, (HPyCFunction)IMPL, &a); \ - return; \ - } - diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h deleted file mode 100644 index 4579b5591b..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/universal/autogen_trampolines.h +++ /dev/null @@ -1,760 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trampolines.autogen_trampolines_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -HPyAPI_FUNC HPy HPy_Dup(HPyContext *ctx, HPy h) { - return ctx->ctx_Dup ( ctx, h ); -} - -HPyAPI_FUNC void HPy_Close(HPyContext *ctx, HPy h) { - ctx->ctx_Close ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value) { - return ctx->ctx_Long_FromInt32_t ( ctx, value ); -} - -HPyAPI_FUNC HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value) { - return ctx->ctx_Long_FromUInt32_t ( ctx, value ); -} - -HPyAPI_FUNC HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v) { - return ctx->ctx_Long_FromInt64_t ( ctx, v ); -} - -HPyAPI_FUNC HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v) { - return ctx->ctx_Long_FromUInt64_t ( ctx, v ); -} - -HPyAPI_FUNC HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value) { - return ctx->ctx_Long_FromSize_t ( ctx, value ); -} - -HPyAPI_FUNC HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) { - return ctx->ctx_Long_FromSsize_t ( ctx, value ); -} - -HPyAPI_FUNC int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsInt32_t ( ctx, h ); -} - -HPyAPI_FUNC uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsUInt32_t ( ctx, h ); -} - -HPyAPI_FUNC uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsUInt32_tMask ( ctx, h ); -} - -HPyAPI_FUNC int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsInt64_t ( ctx, h ); -} - -HPyAPI_FUNC uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsUInt64_t ( ctx, h ); -} - -HPyAPI_FUNC uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsUInt64_tMask ( ctx, h ); -} - -HPyAPI_FUNC size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsSize_t ( ctx, h ); -} - -HPyAPI_FUNC HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsSsize_t ( ctx, h ); -} - -HPyAPI_FUNC void *HPyLong_AsVoidPtr(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsVoidPtr ( ctx, h ); -} - -HPyAPI_FUNC double HPyLong_AsDouble(HPyContext *ctx, HPy h) { - return ctx->ctx_Long_AsDouble ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyFloat_FromDouble(HPyContext *ctx, double v) { - return ctx->ctx_Float_FromDouble ( ctx, v ); -} - -HPyAPI_FUNC double HPyFloat_AsDouble(HPyContext *ctx, HPy h) { - return ctx->ctx_Float_AsDouble ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyBool_FromBool(HPyContext *ctx, bool v) { - return ctx->ctx_Bool_FromBool ( ctx, v ); -} - -HPyAPI_FUNC HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h) { - return ctx->ctx_Length ( ctx, h ); -} - -HPyAPI_FUNC int HPyNumber_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Number_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Add ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Subtract ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Multiply ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_MatrixMultiply ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_FloorDivide ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_TrueDivide ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Remainder ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Divmod ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) { - return ctx->ctx_Power ( ctx, h1, h2, h3 ); -} - -HPyAPI_FUNC HPy HPy_Negative(HPyContext *ctx, HPy h1) { - return ctx->ctx_Negative ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Positive(HPyContext *ctx, HPy h1) { - return ctx->ctx_Positive ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Absolute(HPyContext *ctx, HPy h1) { - return ctx->ctx_Absolute ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Invert(HPyContext *ctx, HPy h1) { - return ctx->ctx_Invert ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Lshift ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Rshift ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_And ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Xor ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Or ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_Index(HPyContext *ctx, HPy h1) { - return ctx->ctx_Index ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Long(HPyContext *ctx, HPy h1) { - return ctx->ctx_Long ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_Float(HPyContext *ctx, HPy h1) { - return ctx->ctx_Float ( ctx, h1 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceAdd ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceSubtract ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceMultiply ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceMatrixMultiply ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceFloorDivide ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceTrueDivide ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceRemainder ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) { - return ctx->ctx_InPlacePower ( ctx, h1, h2, h3 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceLshift ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceRshift ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceAnd ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceXor ( ctx, h1, h2 ); -} - -HPyAPI_FUNC HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_InPlaceOr ( ctx, h1, h2 ); -} - -HPyAPI_FUNC int HPyCallable_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Callable_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) { - return ctx->ctx_CallTupleDict ( ctx, callable, args, kw ); -} - -HPyAPI_FUNC HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) { - return ctx->ctx_Call ( ctx, callable, args, nargs, kwnames ); -} - -HPyAPI_FUNC HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) { - return ctx->ctx_CallMethod ( ctx, name, args, nargs, kwnames ); -} - -HPyAPI_FUNC HPy HPy_GetIter(HPyContext *ctx, HPy obj) { - return ctx->ctx_GetIter ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPyIter_Next(HPyContext *ctx, HPy obj) { - return ctx->ctx_Iter_Next ( ctx, obj ); -} - -HPyAPI_FUNC int HPyIter_Check(HPyContext *ctx, HPy obj) { - return ctx->ctx_Iter_Check ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) { - ctx->ctx_Err_SetString ( ctx, h_type, utf8_message ); return HPy_NULL; -} - -HPyAPI_FUNC HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) { - ctx->ctx_Err_SetObject ( ctx, h_type, h_value ); return HPy_NULL; -} - -HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) { - return ctx->ctx_Err_SetFromErrnoWithFilename ( ctx, h_type, filename_fsencoded ); -} - -HPyAPI_FUNC HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) { - ctx->ctx_Err_SetFromErrnoWithFilenameObjects ( ctx, h_type, filename1, filename2 ); return HPy_NULL; -} - -HPyAPI_FUNC int HPyErr_Occurred(HPyContext *ctx) { - return ctx->ctx_Err_Occurred ( ctx ); -} - -HPyAPI_FUNC int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc) { - return ctx->ctx_Err_ExceptionMatches ( ctx, exc ); -} - -HPyAPI_FUNC HPy HPyErr_NoMemory(HPyContext *ctx) { - ctx->ctx_Err_NoMemory ( ctx ); return HPy_NULL; -} - -HPyAPI_FUNC void HPyErr_Clear(HPyContext *ctx) { - ctx->ctx_Err_Clear ( ctx ); -} - -HPyAPI_FUNC HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) { - return ctx->ctx_Err_NewException ( ctx, utf8_name, base, dict ); -} - -HPyAPI_FUNC HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) { - return ctx->ctx_Err_NewExceptionWithDoc ( ctx, utf8_name, utf8_doc, base, dict ); -} - -HPyAPI_FUNC int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) { - return ctx->ctx_Err_WarnEx ( ctx, category, utf8_message, stack_level ); -} - -HPyAPI_FUNC void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj) { - ctx->ctx_Err_WriteUnraisable ( ctx, obj ); -} - -HPyAPI_FUNC int HPy_IsTrue(HPyContext *ctx, HPy h) { - return ctx->ctx_IsTrue ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, HPyType_SpecParam *params) { - return ctx->ctx_Type_FromSpec ( ctx, spec, params ); -} - -HPyAPI_FUNC HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) { - return ctx->ctx_Type_GenericNew ( ctx, type, args, nargs, kw ); -} - -HPyAPI_FUNC HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name) { - return ctx->ctx_GetAttr ( ctx, obj, name ); -} - -HPyAPI_FUNC HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) { - return ctx->ctx_GetAttr_s ( ctx, obj, utf8_name ); -} - -HPyAPI_FUNC int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name) { - return ctx->ctx_HasAttr ( ctx, obj, name ); -} - -HPyAPI_FUNC int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) { - return ctx->ctx_HasAttr_s ( ctx, obj, utf8_name ); -} - -HPyAPI_FUNC int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) { - return ctx->ctx_SetAttr ( ctx, obj, name, value ); -} - -HPyAPI_FUNC int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) { - return ctx->ctx_SetAttr_s ( ctx, obj, utf8_name, value ); -} - -HPyAPI_FUNC HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key) { - return ctx->ctx_GetItem ( ctx, obj, key ); -} - -HPyAPI_FUNC HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - return ctx->ctx_GetItem_i ( ctx, obj, idx ); -} - -HPyAPI_FUNC HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) { - return ctx->ctx_GetItem_s ( ctx, obj, utf8_key ); -} - -HPyAPI_FUNC HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { - return ctx->ctx_GetSlice ( ctx, obj, start, end ); -} - -HPyAPI_FUNC int HPy_Contains(HPyContext *ctx, HPy container, HPy key) { - return ctx->ctx_Contains ( ctx, container, key ); -} - -HPyAPI_FUNC int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) { - return ctx->ctx_SetItem ( ctx, obj, key, value ); -} - -HPyAPI_FUNC int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) { - return ctx->ctx_SetItem_i ( ctx, obj, idx, value ); -} - -HPyAPI_FUNC int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value) { - return ctx->ctx_SetItem_s ( ctx, obj, utf8_key, value ); -} - -HPyAPI_FUNC int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) { - return ctx->ctx_SetSlice ( ctx, obj, start, end, value ); -} - -HPyAPI_FUNC int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key) { - return ctx->ctx_DelItem ( ctx, obj, key ); -} - -HPyAPI_FUNC int HPy_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - return ctx->ctx_DelItem_i ( ctx, obj, idx ); -} - -HPyAPI_FUNC int HPy_DelItem_s(HPyContext *ctx, HPy obj, const char *utf8_key) { - return ctx->ctx_DelItem_s ( ctx, obj, utf8_key ); -} - -HPyAPI_FUNC int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) { - return ctx->ctx_DelSlice ( ctx, obj, start, end ); -} - -HPyAPI_FUNC HPy HPy_Type(HPyContext *ctx, HPy obj) { - return ctx->ctx_Type ( ctx, obj ); -} - -HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type) { - return ctx->ctx_TypeCheck ( ctx, obj, type ); -} - -HPyAPI_FUNC const char *HPyType_GetName(HPyContext *ctx, HPy type) { - return ctx->ctx_Type_GetName ( ctx, type ); -} - -HPyAPI_FUNC int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type) { - return ctx->ctx_Type_IsSubtype ( ctx, sub, type ); -} - -HPyAPI_FUNC int HPy_Is(HPyContext *ctx, HPy obj, HPy other) { - return ctx->ctx_Is ( ctx, obj, other ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Object(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Object ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Legacy(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Legacy ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Type(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Type ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Long(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Long ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Float(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Float ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Unicode(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Unicode ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Tuple(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Tuple ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_List(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_List ( ctx, h ); -} - -HPyAPI_FUNC void *_HPy_AsStruct_Dict(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct_Dict ( ctx, h ); -} - -HPyAPI_FUNC HPyType_BuiltinShape _HPyType_GetBuiltinShape(HPyContext *ctx, HPy h_type) { - return ctx->ctx_Type_GetBuiltinShape ( ctx, h_type ); -} - -HPyAPI_FUNC HPy HPy_Repr(HPyContext *ctx, HPy obj) { - return ctx->ctx_Repr ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPy_Str(HPyContext *ctx, HPy obj) { - return ctx->ctx_Str ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPy_ASCII(HPyContext *ctx, HPy obj) { - return ctx->ctx_ASCII ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPy_Bytes(HPyContext *ctx, HPy obj) { - return ctx->ctx_Bytes ( ctx, obj ); -} - -HPyAPI_FUNC HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) { - return ctx->ctx_RichCompare ( ctx, v, w, op ); -} - -HPyAPI_FUNC int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) { - return ctx->ctx_RichCompareBool ( ctx, v, w, op ); -} - -HPyAPI_FUNC HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj) { - return ctx->ctx_Hash ( ctx, obj ); -} - -HPyAPI_FUNC int HPyBytes_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Bytes_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h) { - return ctx->ctx_Bytes_Size ( ctx, h ); -} - -HPyAPI_FUNC HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h) { - return ctx->ctx_Bytes_GET_SIZE ( ctx, h ); -} - -HPyAPI_FUNC const char *HPyBytes_AsString(HPyContext *ctx, HPy h) { - return ctx->ctx_Bytes_AsString ( ctx, h ); -} - -HPyAPI_FUNC const char *HPyBytes_AS_STRING(HPyContext *ctx, HPy h) { - return ctx->ctx_Bytes_AS_STRING ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes) { - return ctx->ctx_Bytes_FromString ( ctx, bytes ); -} - -HPyAPI_FUNC HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *bytes, HPy_ssize_t len) { - return ctx->ctx_Bytes_FromStringAndSize ( ctx, bytes, len ); -} - -HPyAPI_FUNC HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8) { - return ctx->ctx_Unicode_FromString ( ctx, utf8 ); -} - -HPyAPI_FUNC int HPyUnicode_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Unicode_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h) { - return ctx->ctx_Unicode_AsASCIIString ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h) { - return ctx->ctx_Unicode_AsLatin1String ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h) { - return ctx->ctx_Unicode_AsUTF8String ( ctx, h ); -} - -HPyAPI_FUNC const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) { - return ctx->ctx_Unicode_AsUTF8AndSize ( ctx, h, size ); -} - -HPyAPI_FUNC HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) { - return ctx->ctx_Unicode_FromWideChar ( ctx, w, size ); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v) { - return ctx->ctx_Unicode_DecodeFSDefault ( ctx, v ); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) { - return ctx->ctx_Unicode_DecodeFSDefaultAndSize ( ctx, v, size ); -} - -HPyAPI_FUNC HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h) { - return ctx->ctx_Unicode_EncodeFSDefault ( ctx, h ); -} - -HPyAPI_FUNC HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) { - return ctx->ctx_Unicode_ReadChar ( ctx, h, index ); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) { - return ctx->ctx_Unicode_DecodeASCII ( ctx, ascii, size, errors ); -} - -HPyAPI_FUNC HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) { - return ctx->ctx_Unicode_DecodeLatin1 ( ctx, latin1, size, errors ); -} - -HPyAPI_FUNC HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) { - return ctx->ctx_Unicode_FromEncodedObject ( ctx, obj, encoding, errors ); -} - -HPyAPI_FUNC HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) { - return ctx->ctx_Unicode_Substring ( ctx, str, start, end ); -} - -HPyAPI_FUNC int HPyList_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_List_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len) { - return ctx->ctx_List_New ( ctx, len ); -} - -HPyAPI_FUNC int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item) { - return ctx->ctx_List_Append ( ctx, h_list, h_item ); -} - -HPyAPI_FUNC int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) { - return ctx->ctx_List_Insert ( ctx, h_list, index, h_item ); -} - -HPyAPI_FUNC int HPyDict_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Dict_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyDict_New(HPyContext *ctx) { - return ctx->ctx_Dict_New ( ctx ); -} - -HPyAPI_FUNC HPy HPyDict_Keys(HPyContext *ctx, HPy h) { - return ctx->ctx_Dict_Keys ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyDict_Copy(HPyContext *ctx, HPy h) { - return ctx->ctx_Dict_Copy ( ctx, h ); -} - -HPyAPI_FUNC int HPyTuple_Check(HPyContext *ctx, HPy h) { - return ctx->ctx_Tuple_Check ( ctx, h ); -} - -HPyAPI_FUNC HPy HPyTuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n) { - return ctx->ctx_Tuple_FromArray ( ctx, items, n ); -} - -HPyAPI_FUNC HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) { - return ctx->ctx_Slice_New ( ctx, start, stop, step ); -} - -HPyAPI_FUNC int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) { - return ctx->ctx_Slice_Unpack ( ctx, slice, start, stop, step ); -} - -HPyAPI_FUNC HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name) { - return ctx->ctx_Import_ImportModule ( ctx, utf8_name ); -} - -HPyAPI_FUNC HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) { - return ctx->ctx_Capsule_New ( ctx, pointer, utf8_name, destructor ); -} - -HPyAPI_FUNC void *HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name) { - return ctx->ctx_Capsule_Get ( ctx, capsule, key, utf8_name ); -} - -HPyAPI_FUNC int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) { - return ctx->ctx_Capsule_IsValid ( ctx, capsule, utf8_name ); -} - -HPyAPI_FUNC int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) { - return ctx->ctx_Capsule_Set ( ctx, capsule, key, value ); -} - -HPyAPI_FUNC HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) { - return ctx->ctx_FromPyObject ( ctx, obj ); -} - -HPyAPI_FUNC cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h) { - return ctx->ctx_AsPyObject ( ctx, h ); -} - -HPyAPI_FUNC void _HPy_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, HPyCFunction func, void *args) { - ctx->ctx_CallRealFunctionFromTrampoline ( ctx, sig, func, args ); -} - -HPyAPI_FUNC HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t size) { - return ctx->ctx_ListBuilder_New ( ctx, size ); -} - -HPyAPI_FUNC void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item) { - ctx->ctx_ListBuilder_Set ( ctx, builder, index, h_item ); -} - -HPyAPI_FUNC HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder) { - return ctx->ctx_ListBuilder_Build ( ctx, builder ); -} - -HPyAPI_FUNC void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder) { - ctx->ctx_ListBuilder_Cancel ( ctx, builder ); -} - -HPyAPI_FUNC HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t size) { - return ctx->ctx_TupleBuilder_New ( ctx, size ); -} - -HPyAPI_FUNC void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item) { - ctx->ctx_TupleBuilder_Set ( ctx, builder, index, h_item ); -} - -HPyAPI_FUNC HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder) { - return ctx->ctx_TupleBuilder_Build ( ctx, builder ); -} - -HPyAPI_FUNC void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder) { - ctx->ctx_TupleBuilder_Cancel ( ctx, builder ); -} - -HPyAPI_FUNC HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size) { - return ctx->ctx_Tracker_New ( ctx, size ); -} - -HPyAPI_FUNC int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) { - return ctx->ctx_Tracker_Add ( ctx, ht, h ); -} - -HPyAPI_FUNC void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht) { - ctx->ctx_Tracker_ForgetAll ( ctx, ht ); -} - -HPyAPI_FUNC void HPyTracker_Close(HPyContext *ctx, HPyTracker ht) { - ctx->ctx_Tracker_Close ( ctx, ht ); -} - -HPyAPI_FUNC void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) { - ctx->ctx_Field_Store ( ctx, target_object, target_field, h ); -} - -HPyAPI_FUNC HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field) { - return ctx->ctx_Field_Load ( ctx, source_object, source_field ); -} - -HPyAPI_FUNC void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) { - ctx->ctx_ReenterPythonExecution ( ctx, state ); -} - -HPyAPI_FUNC HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx) { - return ctx->ctx_LeavePythonExecution ( ctx ); -} - -HPyAPI_FUNC void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h) { - ctx->ctx_Global_Store ( ctx, global, h ); -} - -HPyAPI_FUNC HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global) { - return ctx->ctx_Global_Load ( ctx, global ); -} - -HPyAPI_FUNC void _HPy_Dump(HPyContext *ctx, HPy h) { - ctx->ctx_Dump ( ctx, h ); -} - -HPyAPI_FUNC HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) { - return ctx->ctx_Compile_s ( ctx, utf8_source, utf8_filename, kind ); -} - -HPyAPI_FUNC HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) { - return ctx->ctx_EvalCode ( ctx, code, globals, locals ); -} - -HPyAPI_FUNC HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value) { - return ctx->ctx_ContextVar_New ( ctx, name, default_value ); -} - -HPyAPI_FUNC int32_t HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) { - return ctx->ctx_ContextVar_Get ( ctx, context_var, default_value, result ); -} - -HPyAPI_FUNC HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) { - return ctx->ctx_ContextVar_Set ( ctx, context_var, value ); -} - -HPyAPI_FUNC int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func) { - return ctx->ctx_SetCallFunction ( ctx, h, func ); -} - diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h deleted file mode 100644 index 6d8764f4b8..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/universal/hpyfunc_trampolines.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef HPY_UNIVERSAL_HPYFUNC_TRAMPOLINES_H -#define HPY_UNIVERSAL_HPYFUNC_TRAMPOLINES_H - -/* This file should be autogenerated */ - -typedef struct { - cpy_PyObject *self; - cpy_PyObject *const *args; - HPy_ssize_t nargs; - cpy_PyObject *result; -} _HPyFunc_args_VARARGS; - -typedef struct { - cpy_PyObject *self; - cpy_PyObject *const *args; - /* We also use HPyFunc_KEYWORDS for HPy_tp_call which will be called as - vectorcall function from CPython. Therefore, 'nargsf' may also have bit - 'PY_VECTORCALL_ARGUMENTS_OFFSET' set. */ - size_t nargsf; - cpy_PyObject *kwnames; - cpy_PyObject *result; -} _HPyFunc_args_KEYWORDS; - -typedef struct { - cpy_PyObject *self; - cpy_PyObject *args; - cpy_PyObject *kw; - int result; -} _HPyFunc_args_INITPROC; - -typedef struct { - cpy_PyObject *self; - cpy_PyObject *args; - cpy_PyObject *kw; - cpy_PyObject *result; -} _HPyFunc_args_NEWFUNC; - -typedef struct { - cpy_PyObject *arg0; - cpy_PyObject *arg1; - HPy_RichCmpOp arg2; - cpy_PyObject * result; -} _HPyFunc_args_RICHCMPFUNC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_VARARGS(SYM, IMPL) \ - static cpy_PyObject * \ - SYM(cpy_PyObject *self, cpy_PyObject *const *args, HPy_ssize_t nargs) \ - { \ - _HPyFunc_args_VARARGS a = { self, args, nargs }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_VARARGS, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -#define _HPyFunc_TRAMPOLINE_HPyFunc_KEYWORDS(SYM, IMPL) \ - static cpy_PyObject * \ - SYM(cpy_PyObject *self, cpy_PyObject *const *args, size_t nargs, \ - cpy_PyObject *kwnames) \ - { \ - _HPyFunc_args_KEYWORDS a = { self, args, nargs, kwnames }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_KEYWORDS, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -#define _HPyFunc_TRAMPOLINE_HPyFunc_INITPROC(SYM, IMPL) \ - static int \ - SYM(cpy_PyObject *self, cpy_PyObject *args, cpy_PyObject *kw) \ - { \ - _HPyFunc_args_INITPROC a = { self, args, kw }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_INITPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -#define _HPyFunc_TRAMPOLINE_HPyFunc_NEWFUNC(SYM, IMPL) \ - static cpy_PyObject * \ - SYM(cpy_PyObject *self, cpy_PyObject *args, cpy_PyObject *kw) \ - { \ - _HPyFunc_args_NEWFUNC a = { self, args, kw }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_NEWFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -/* special case: the HPy_tp_destroy slot doesn't map to any CPython slot. - Instead, it is called from our own tp_dealloc: see also - hpytype_dealloc(). */ -#define _HPyFunc_TRAMPOLINE_HPyFunc_DESTROYFUNC(SYM, IMPL) \ - static void SYM(void) { abort(); } - - -/* this needs to be written manually because HPy has a different type for - "op": HPy_RichCmpOp instead of int */ -#define _HPyFunc_TRAMPOLINE_HPyFunc_RICHCMPFUNC(SYM, IMPL) \ - static cpy_PyObject * \ - SYM(cpy_PyObject *self, cpy_PyObject *obj, int op) \ - { \ - _HPyFunc_args_RICHCMPFUNC a = { self, obj, (HPy_RichCmpOp)op }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_RICHCMPFUNC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *self; - cpy_Py_buffer *view; - int flags; - int result; -} _HPyFunc_args_GETBUFFERPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_GETBUFFERPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *self, cpy_Py_buffer *view, int flags) \ - { \ - _HPyFunc_args_GETBUFFERPROC a = {self, view, flags}; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_GETBUFFERPROC, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -typedef struct { - cpy_PyObject *self; - cpy_Py_buffer *view; -} _HPyFunc_args_RELEASEBUFFERPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_RELEASEBUFFERPROC(SYM, IMPL) \ - static void SYM(cpy_PyObject *self, cpy_Py_buffer *view) \ - { \ - _HPyFunc_args_RELEASEBUFFERPROC a = {self, view}; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_RELEASEBUFFERPROC, \ - (HPyCFunction)IMPL, &a); \ - return; \ - } - - -typedef struct { - cpy_PyObject *self; - cpy_visitproc visit; - void *arg; - int result; -} _HPyFunc_args_TRAVERSEPROC; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_TRAVERSEPROC(SYM, IMPL) \ - static int SYM(cpy_PyObject *self, cpy_visitproc visit, void *arg) \ - { \ - _HPyFunc_args_TRAVERSEPROC a = { self, visit, arg }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_TRAVERSEPROC, \ - (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - -#define HPyCapsule_DESTRUCTOR_TRAMPOLINE(SYM, IMPL) \ - static void SYM(cpy_PyObject *capsule) \ - { \ - _HPy_CallRealFunctionFromTrampoline(_ctx_for_trampolines, \ - HPyFunc_CAPSULE_DESTRUCTOR, (HPyCFunction)IMPL, capsule); \ - } - -typedef struct { - cpy_PyObject *spec; - cpy_PyObject *result; -} _HPyFunc_args_MOD_CREATE; - -#define _HPyFunc_TRAMPOLINE_HPyFunc_MOD_CREATE(SYM, IMPL) \ - static cpy_PyObject* SYM(cpy_PyObject *spec, cpy_PyModuleDef *def) \ - { \ - (void) def; /* avoid 'unused' warning */ \ - _HPyFunc_args_UNARYFUNC a = { spec }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_MOD_CREATE, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - - -#endif // HPY_UNIVERSAL_HPYFUNC_TRAMPOLINES_H diff --git a/graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h b/graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h deleted file mode 100644 index f20545bc65..0000000000 --- a/graalpython/hpy/hpy/devel/include/hpy/universal/misc_trampolines.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef HPY_MISC_TRAMPOLINES_H -#define HPY_MISC_TRAMPOLINES_H - -static inline HPy _HPy_New(HPyContext *ctx, HPy h_type, void **data) { - /* Performance hack: the autogenerated version of this trampoline would - simply forward data to ctx_New. - - Suppose you call HPy_New this way: - PointObject *point; - HPy h = HPy_New(ctx, cls, &point); - - If you pass "data" to ctx->New, the C compiler must assume that anybody - could write a different value at any time into this local variable - because a pointer to it escaped. With this hack, it's no longer the - case: what escaped is the address of data_result instead and that local - variable disappears since this function is likely inlined. - - See https://github.com/pyhandle/hpy/pull/22#pullrequestreview-413365845 - */ - void *data_result; - HPy h = ctx->ctx_New(ctx, h_type, &data_result); - *data = data_result; - return h; -} - -static inline _HPy_NO_RETURN void -HPy_FatalError(HPyContext *ctx, const char *message) { - ctx->ctx_FatalError(ctx, message); - /* note: the following abort() is unreachable, but needed because the - _HPy_NO_RETURN doesn't seem to be sufficient. I think that what - occurs is that this function is inlined, after which gcc forgets - that it couldn't return. Having abort() inlined fixes that. */ - abort(); -} - -static inline void * -HPyCapsule_GetPointer(HPyContext *ctx, HPy capsule, const char *name) -{ - return ctx->ctx_Capsule_Get( - ctx, capsule, HPyCapsule_key_Pointer, name); -} - -static inline const char * -HPyCapsule_GetName(HPyContext *ctx, HPy capsule) -{ - return (const char *) ctx->ctx_Capsule_Get( - ctx, capsule, HPyCapsule_key_Name, NULL); -} - -static inline void * -HPyCapsule_GetContext(HPyContext *ctx, HPy capsule) -{ - return ctx->ctx_Capsule_Get( - ctx, capsule, HPyCapsule_key_Context, NULL); -} - -static inline int -HPyCapsule_SetPointer(HPyContext *ctx, HPy capsule, void *pointer) -{ - return ctx->ctx_Capsule_Set( - ctx, capsule, HPyCapsule_key_Pointer, pointer); -} - -static inline int -HPyCapsule_SetName(HPyContext *ctx, HPy capsule, const char *name) -{ - return ctx->ctx_Capsule_Set( - ctx, capsule, HPyCapsule_key_Name, (void *) name); -} - -static inline int -HPyCapsule_SetContext(HPyContext *ctx, HPy capsule, void *context) -{ - return ctx->ctx_Capsule_Set( - ctx, capsule, HPyCapsule_key_Context, context); -} - -static inline int -HPyCapsule_SetDestructor(HPyContext *ctx, HPy capsule, - HPyCapsule_Destructor *destructor) -{ - return ctx->ctx_Capsule_Set( - ctx, capsule, HPyCapsule_key_Destructor, (void *) destructor); -} - -#endif /* HPY_MISC_TRAMPOLINES_H */ diff --git a/graalpython/hpy/hpy/devel/src/runtime/argparse.c b/graalpython/hpy/hpy/devel/src/runtime/argparse.c deleted file mode 100644 index 9f2b972126..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/argparse.c +++ /dev/null @@ -1,819 +0,0 @@ -/** - * Implementation of HPyArg_Parse and HPyArg_ParseKeywords. - * - * Note: those functions are runtime helper functions, i.e., they are not part - * of the HPy context, but are available to HPy extensions to incorporate at - * compile time. - * - * HPyArg_Parse parses positional arguments and replaces PyArg_ParseTuple. - * HPyArg_ParseKeywords parses positional and keyword arguments and - * replaces PyArg_ParseTupleAndKeywords. - * - * HPy intends to only support the simpler format string types (numbers, bools) - * and handles. More complex types (e.g. buffers) should be retrieved as - * handles and then processed further as needed. - * - * Supported Formatting Strings - * ---------------------------- - * - * Numbers - * ~~~~~~~ - * - * ``b (int) [unsigned char]`` - * Convert a nonnegative Python integer to an unsigned tiny int, stored in a C unsigned char. - * - * ``B (int) [unsigned char]`` - * Convert a Python integer to a tiny int without overflow checking, stored in a C unsigned char. - * - * ``h (int) [short int]`` - * Convert a Python integer to a C short int. - * - * ``H (int) [unsigned short int]`` - * Convert a Python integer to a C unsigned short int, without overflow checking. - * - * ``i (int) [int]`` - * Convert a Python integer to a plain C int. - * - * ``I (int) [unsigned int]`` - * Convert a Python integer to a C unsigned int, without overflow checking. - * - * ``l (int) [long int]`` - * Convert a Python integer to a C long int. - * - * ``k (int) [unsigned long]`` - * Convert a Python integer to a C unsigned long without overflow checking. - * - * ``L (int) [long long]`` - * Convert a Python integer to a C long long. - * - * ``K (int) [unsigned long long]`` - * Convert a Python integer to a C unsigned long long without overflow checking. - * - * ``n (int) [HPy_ssize_t]`` - * Convert a Python integer to a C HPy_ssize_t. - * - * ``f (float) [float]`` - * Convert a Python floating point number to a C float. - * - * ``d (float) [double]`` - * Convert a Python floating point number to a C double. - * - * Strings and buffers - * ~~~~~~~~~~~~~~~~~~~~~~~~ - * - * These formats allow accessing an object as a contiguous chunk of memory. - * You don't have to provide raw storage for the returned unicode or bytes - * area. - * - * In general, when a format sets a pointer to a buffer, the pointer is valid - * only until the corresponding HPy handle is closed. - * - * ``s (unicode) [const char*]`` - * - * Convert a Unicode object to a C pointer to a character string. - * A pointer to an existing string is stored in the character pointer - * variable whose address you pass. The C string is NUL-terminated. - * The Python string must not contain embedded null code points; if it does, - * a `ValueError` exception is raised. Unicode objects are converted - * to C strings using 'utf-8' encoding. If this conversion fails, - * a `UnicodeError` is raised. - * - * Note: This format does not accept bytes-like objects and is therefore - * not suitable for filesystem paths. - * - * Handles (Python Objects) - * ~~~~~~~~~~~~~~~~~~~~~~~~ - * - * ``O (object) [HPy]`` - * Store a handle pointing to a generic Python object. - * - * When using O with HPyArg_ParseKeywords, an HPyTracker is created and - * returned via the parameter `ht`. If HPyArg_ParseKeywords returns - * successfully, you must call HPyTracker_Close on `ht` once the - * returned handles are no longer needed. This will close all the handles - * created during argument parsing. There is no need to call - * `HPyTracker_Close` on failure -- the argument parser does this for you. - * - * Miscellaneous - * ~~~~~~~~~~~~~ - * - * ``p (bool) [int]`` - * Tests the value passed in for truth (a boolean predicate) and converts - * the result to its equivalent C true/false integer value. Sets the int to - * 1 if the expression was true and 0 if it was false. This accepts any - * valid Python value. See - * `Truth Value Testing `_ - * for more information about how Python tests values for truth. - * - * Options - * ~~~~~~~ - * - * ``|`` - * Indicates that the remaining arguments in the argument list are optional. - * The C variables corresponding to optional arguments should be initialized - * to their default value — when an optional argument is not specified, the - * contents of the corresponding C variable is not modified. - * - * ``$`` - * HPyArg_ParseKeywords() only: Indicates that the remaining arguments in - * the argument list are keyword-only. Currently, all keyword-only arguments - * must also be optional arguments, so | must always be specified before $ - * in the format string. - * - * ``:`` - * The list of format units ends here; the string after the colon is used as - * the function name in error messages. : and ; are mutually exclusive and - * whichever occurs first takes precedence. - * - * ``;`` - * The list of format units ends here; the string after the semicolon is - * used as the error message instead of the default error message. : and ; - * are mutually exclusive and whichever occurs first takes precedence. - * - * Argument Parsing API - * -------------------- - * - */ - -#include "hpy.h" -#include -#include - -#define _BREAK_IF_OPTIONAL(current_arg) if (HPy_IsNull(current_arg)) break; -#define _ERR_STRING_MAX_LENGTH 512 - - -static const char * -parse_err_fmt(const char *fmt, const char **err_fmt) -{ - const char *fmt1 = fmt; - - for (; *fmt1 != 0; fmt1++) { - if (*fmt1 == ':' || *fmt1 == ';') { - *err_fmt = fmt1; - break; - } - } - return fmt1; -} - - -static void -set_error(HPyContext *ctx, HPy exc, const char *err_fmt, const char *msg) { - char err_buf[_ERR_STRING_MAX_LENGTH]; - if (err_fmt == NULL) { - snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "function %.256s", msg); - } - else if (*err_fmt == ':') { - snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "%.200s() %.256s", err_fmt + 1, msg); - } - else { - snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "%s", err_fmt + 1); - } - HPyErr_SetString(ctx, exc, err_buf); -} - - -static int -parse_item(HPyContext *ctx, HPyTracker *ht, HPy current_arg, int current_arg_tmp, const char **fmt, va_list *vl, const char *err_fmt) -{ - switch (*(*fmt)++) { - - case 'b': { /* unsigned byte -- very short int */ - char *output = va_arg(*vl, char *); - _BREAK_IF_OPTIONAL(current_arg); - long value = HPyLong_AsLong(ctx, current_arg); - if (value == -1 && HPyErr_Occurred(ctx)) - return 0; - if (value < 0) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "unsigned byte integer is less than minimum"); - return 0; - } - if (value > UCHAR_MAX) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "unsigned byte integer is greater than maximum"); - return 0; - } - *output = (char) value; - break; - } - - case 'B': { /* byte sized bitfield - both signed and unsigned - values allowed */ - char *output = va_arg(*vl, char *); - _BREAK_IF_OPTIONAL(current_arg); - unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); - if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = (unsigned char) value; - break; - } - - case 'h': { /* signed short int */ - short *output = va_arg(*vl, short *); - _BREAK_IF_OPTIONAL(current_arg); - long value = HPyLong_AsLong(ctx, current_arg); - if (value == -1 && HPyErr_Occurred(ctx)) - return 0; - if (value < SHRT_MIN) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "signed short integer is less than minimum"); - return 0; - } - if (value > SHRT_MAX) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "signed short integer is greater than maximum"); - return 0; - } - *output = (short) value; - break; - } - - case 'H': { /* short int sized bitfield, both signed and - unsigned allowed */ - unsigned short *output = va_arg(*vl, unsigned short *); - _BREAK_IF_OPTIONAL(current_arg); - unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); - if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = (unsigned short) value; - break; - } - - case 'i': { /* signed int */ - int *output = va_arg(*vl, int *); - _BREAK_IF_OPTIONAL(current_arg); - long value = HPyLong_AsLong(ctx, current_arg); - if (value == -1 && HPyErr_Occurred(ctx)) - return 0; - if (value > INT_MAX) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "signed integer is greater than maximum"); - return 0; - } - if (value < INT_MIN) { - set_error(ctx, ctx->h_OverflowError, err_fmt, - "signed integer is less than minimum"); - return 0; - } - *output = (int)value; - break; - } - - case 'I': { /* int sized bitfield, both signed and - unsigned allowed */ - unsigned int *output = va_arg(*vl, unsigned int *); - _BREAK_IF_OPTIONAL(current_arg); - unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); - if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = (unsigned int) value; - break; - } - - case 'l': { - long *output = va_arg(*vl, long *); - _BREAK_IF_OPTIONAL(current_arg); - long value = HPyLong_AsLong(ctx, current_arg); - if (value == -1 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'k': { /* long sized bitfield */ - unsigned long *output = va_arg(*vl, unsigned long *); - _BREAK_IF_OPTIONAL(current_arg); - unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); - if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'L': { /* long long */ - long long *output = va_arg(*vl, long long *); - _BREAK_IF_OPTIONAL(current_arg); - long long value = HPyLong_AsLongLong(ctx, current_arg); - if (value == (long long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'K': { /* long long sized bitfield */ - unsigned long long *output = va_arg(*vl, unsigned long long *); - _BREAK_IF_OPTIONAL(current_arg); - unsigned long long value = HPyLong_AsUnsignedLongLongMask(ctx, current_arg); - if (value == (unsigned long long)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'n': { /* HPy_ssize_t */ - HPy_ssize_t *output = va_arg(*vl, HPy_ssize_t *); - _BREAK_IF_OPTIONAL(current_arg); - HPy_ssize_t value = HPyLong_AsSsize_t(ctx, current_arg); - if (value == (HPy_ssize_t)-1 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'f': { /* float */ - float *output = va_arg(*vl, float *); - _BREAK_IF_OPTIONAL(current_arg); - double value = HPyFloat_AsDouble(ctx, current_arg); - if (value == -1.0 && HPyErr_Occurred(ctx)) - return 0; - *output = (float) value; - break; - } - - case 'd': { /* double */ - double* output = va_arg(*vl, double *); - _BREAK_IF_OPTIONAL(current_arg); - double value = HPyFloat_AsDouble(ctx, current_arg); - if (value == -1.0 && HPyErr_Occurred(ctx)) - return 0; - *output = value; - break; - } - - case 'O': { - HPy *output = va_arg(*vl, HPy *); - _BREAK_IF_OPTIONAL(current_arg); - if (current_arg_tmp) { - *output = HPy_Dup(ctx, current_arg); - HPyTracker_Add(ctx, *ht, *output); - } - else { - *output = current_arg; - } - break; - } - - case 'p': { /* boolean *p*redicate */ - int *output = va_arg(*vl, int *); - int value = HPy_IsTrue(ctx, current_arg); - if (value < 0) - return 0; - *output = (value > 0) ? 1 : 0; - break; - } - - case 's': { - const char **output = va_arg(*vl, const char **); - if (!HPyUnicode_Check(ctx, current_arg)) { - set_error(ctx, ctx->h_TypeError, err_fmt, "a str is required"); - return 0; - } - HPy_ssize_t size; - const char *data = HPyUnicode_AsUTF8AndSize(ctx, current_arg, &size); - if (data == NULL) { - set_error(ctx, ctx->h_SystemError, err_fmt, "unicode conversion error"); - return 0; - } - // loop bounded by size is more robust/paranoid than strlen - HPy_ssize_t i; - for (i = 0; i < size; ++i) { - if (data[i] == '\0') { - set_error(ctx, ctx->h_ValueError, err_fmt, "embedded null character"); - return 0; - } - } - if (data[i] != '\0') { - set_error(ctx, ctx->h_SystemError, err_fmt, "missing terminating null character"); - return 0; - } - *output = data; - break; - } - - default: { - set_error(ctx, ctx->h_SystemError, err_fmt, "unknown arg format code"); - return 0; - } - - } // switch - - return 1; -} - - -/** - * Parse positional arguments. - * - * :param ctx: - * The execution context. - * :param ht: - * An optional pointer to an HPyTracker. If the format string never - * results in new handles being created, ``ht`` may be ``NULL``. Currently - * only the ``O`` formatting option to this function requires an HPyTracker. - * :param args: - * The array of positional arguments to parse. - * :param nargs: - * The number of elements in ``args``. - * :param fmt: - * The format string to use to parse the arguments. - * :param ...: - * A va_list of references to variables in which to store the parsed - * arguments. The number and types of the arguments should match the - * the format string, ``fmt``. - * - * :returns: ``0`` on failure, ``1`` on success. - * - * If a ``NULL`` pointer is passed to ``ht`` and an HPyTracker is required by - * the format string, a ``SystemError`` will be raised. - * - * If a pointer is provided to ``ht``, the HPyTracker will always be created - * and must be closed with ``HPyTracker_Close`` if parsing succeeds (after all - * handles returned are no longer needed). If parsing fails, this function - * will close the HPyTracker automatically. - * - * Examples: - * - * Using ``HPyArg_Parse`` without an HPyTracker: - * - * .. code-block:: c - * - * long a, b; - * if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - * return HPy_NULL; - * ... - * - * Using ``HPyArg_Parse`` with an HPyTracker: - * - * .. code-block:: c - * - * long a, b; - * HPyTracker ht; - * if (!HPyArg_Parse(ctx, &ht, args, nargs, "ll", &a, &b)) - * return HPy_NULL; - * ... - * HPyTracker_Close(ctx, ht); - * ... - * - * .. note:: - * - * Currently ``HPyArg_Parse`` never requires the use of an HPyTracker. - * The option exists only to support releasing temporary storage used by - * future format string codes (e.g. for character strings). - */ -HPyAPI_HELPER int -HPyArg_Parse(HPyContext *ctx, HPyTracker *ht, const HPy *args, size_t nargs, const char *fmt, ...) -{ - const char *fmt1 = fmt; - const char *err_fmt = NULL; - const char *fmt_end = NULL; - - int optional = 0; - size_t i = 0; - HPy current_arg; - - fmt_end = parse_err_fmt(fmt, &err_fmt); - - if (ht != NULL) { - *ht = HPyTracker_New(ctx, 0); - if (HPy_IsNull(*ht)) { - return 0; - } - } - - va_list vl; - va_start(vl, fmt); - - while (fmt1 != fmt_end) { - if (*fmt1 == '|') { - optional = 1; - fmt1++; - continue; - } - current_arg = HPy_NULL; - if (i < nargs) { - current_arg = args[i]; - } - if (!HPy_IsNull(current_arg) || optional) { - if (!parse_item(ctx, ht, current_arg, 0, &fmt1, &vl, err_fmt)) { - goto error; - } - } - else { - set_error(ctx, ctx->h_TypeError, err_fmt, - "required positional argument missing"); - goto error; - } - i++; - } - if (i < nargs) { - set_error(ctx, ctx->h_TypeError, err_fmt, - "mismatched args (too many arguments for fmt)"); - goto error; - } - - va_end(vl); - return 1; - -error: - va_end(vl); - if (ht != NULL) { - HPyTracker_Close(ctx, *ht); - } - return 0; -} - -static HPy -find_keyword(HPyContext *ctx, HPy kwnames, HPy_ssize_t n_kwnames, const HPy *args, const char *key) -{ - for (HPy_ssize_t i = 0; i < n_kwnames; i++) { - HPy kwname = HPy_GetItem_i(ctx, kwnames, i); - HPy h_key = HPyUnicode_FromString(ctx, key); - int eq = HPy_RichCompareBool(ctx, kwname, h_key, HPy_EQ); - HPy_Close(ctx, h_key); - HPy_Close(ctx, kwname); - if (eq) { - return args[i]; - } - } - return HPy_NULL; -} - -static int -parse_keywords(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, HPy kw, int kwnames, const char *fmt, - const char *keywords[], va_list *p_va) -{ - const char *fmt1 = fmt; - const char *err_fmt = NULL; - const char *fmt_end = NULL; - - int optional = 0; - int keyword_only = 0; - size_t i = 0; - size_t nkw = 0; - HPy_ssize_t n_kwnames = 0; - HPy current_arg; - int current_arg_needs_closing = 0; - - assert(p_va != NULL); - - fmt_end = parse_err_fmt(fmt, &err_fmt); - - // first count positional only arguments - while (keywords[nkw] != NULL && !*keywords[nkw]) { - nkw++; - } - // then check and count the rest - while (keywords[nkw] != NULL) { - if (!*keywords[nkw]) { - set_error(ctx, ctx->h_SystemError, err_fmt, - "empty keyword parameter name"); - return 0; - } - nkw++; - } - - if (ht != NULL) { - *ht = HPyTracker_New(ctx, 0); - if (HPy_IsNull(*ht)) { - return 0; - } - } - - if (kwnames && !HPy_IsNull(kw)) { - n_kwnames = HPy_Length(ctx, kw); - if (n_kwnames < 0) { - set_error(ctx, ctx->h_SystemError, err_fmt, - "could not retrieve length of keyword names tuple"); - return 0; - } - } - - while (fmt1 != fmt_end) { - if (*fmt1 == '|') { - optional = 1; - fmt1++; - continue; - } - if (*fmt1 == '$') { - optional = 1; - keyword_only = 1; - fmt1++; - continue; - } - if (*fmt1 == 'O' && ht == NULL) { - set_error(ctx, ctx->h_SystemError, err_fmt, - "HPyArg_ParseKeywords cannot use the format character 'O' unless" - " an HPyTracker is provided. Please supply an HPyTracker."); - goto error; - } - if (i >= nkw) { - set_error(ctx, ctx->h_TypeError, err_fmt, - "mismatched args (too few keywords for fmt)"); - goto error; - } - current_arg = HPy_NULL; - if (i < nargs) { - if (keyword_only) { - set_error(ctx, ctx->h_TypeError, err_fmt, - "keyword only argument passed as positional argument"); - goto error; - } - current_arg = args[i]; - } - else if (!HPy_IsNull(kw) && *keywords[i]) { - if (kwnames) { - current_arg = find_keyword(ctx, kw, n_kwnames, args+nargs, - keywords[i]); - /* - * Clear any error that was raised. If an error was raised - * current_arg will be HPy_NULL and will be handled - * appropriately below depending on whether the current argument - * is optional or not. - */ - if (HPy_IsNull(current_arg)) { - HPyErr_Clear(ctx); - } - } else { - current_arg = HPy_GetItem_s(ctx, kw, keywords[i]); - /* - * Track the handle or clear any KeyError that was raised (for - * the same reason as explained above). - */ - if (!HPy_IsNull(current_arg)) { - current_arg_needs_closing = 1; - } else { - HPyErr_Clear(ctx); - } - } - } - if (!HPy_IsNull(current_arg) || optional) { - if (!parse_item(ctx, ht, current_arg, 1, &fmt1, p_va, err_fmt)) { - goto error; - } - } - else { - set_error(ctx, ctx->h_TypeError, err_fmt, - "no value for required argument"); - goto error; - } - if (current_arg_needs_closing) { - HPy_Close(ctx, current_arg); - current_arg_needs_closing = 0; - } - i++; - } - if (i != nkw) { - set_error(ctx, ctx->h_TypeError, err_fmt, - "mismatched args (too many keywords for fmt)"); - goto error; - } - return 1; - -error: - if (ht != NULL) { - HPyTracker_Close(ctx, *ht); - } - if (current_arg_needs_closing) { - HPy_Close(ctx, current_arg); - } - return 0; -} - - -/** - * Parse positional and keyword arguments. - * - * :param ctx: - * The execution context. - * :param ht: - * An optional pointer to an HPyTracker. If the format string never - * results in new handles being created, ``ht`` may be ``NULL``. Currently - * only the ``O`` formatting option to this function requires an HPyTracker. - * :param args: - * The array of positional arguments to parse. - * :param nargs: - * The number of elements in ``args``. - * :param kwnames: - * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). - * The values of the keyword arguments are appended to ``args``. Argument - * ``nargs`` does not include the keyword argument count. - * :param fmt: - * The format string to use to parse the arguments. - * :param keywords: - * A ``NULL``-terminated array of argument names. The number of names - * should match the format string provided. Positional only arguments - * should have the name ``""`` (i.e. the null-terminated empty string). - * Positional only arguments must preceded all other arguments. - * :param ...: - * A va_list of references to variables in which to store the parsed - * arguments. The number and types of the arguments should match the - * the format string, ``fmt``. - * - * :returns: ``0`` on failure, ``1`` on success. - * - * If a ``NULL`` pointer is passed to ``ht`` and an HPyTracker is required by - * the format string, a ``SystemError`` will be raised. - * - * If a pointer is provided to ``ht``, the HPyTracker will always be created and - * must be closed with ``HPyTracker_Close`` if parsing succeeds (after all - * handles returned are no longer needed). If parsing fails, this function will - * close the HPyTracker automatically. - * - * Examples: - * - * Using `HPyArg_ParseKeywords` without an `HPyTracker`: - * - * .. code-block:: c - * - * long a, b; - * if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", &a, &b)) - * return HPy_NULL; - * ... - * - * Using `HPyArg_ParseKeywords` with an `HPyTracker`: - * - * .. code-block:: c - * - * HPy a, b; - * HPyTracker ht; - * if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "OO", &a, &b)) - * return HPy_NULL; - * ... - * HPyTracker_Close(ctx, ht); - * ... - * - * .. note:: - * - * Currently ``HPyArg_ParseKeywords`` only requires the use of an - * ``HPyTracker`` when the ``O`` format is used. In future other new format - * string codes (e.g. for character strings) may also require it. - */ -HPyAPI_HELPER int -HPyArg_ParseKeywords(HPyContext *ctx, HPyTracker *ht, const HPy *args, - size_t nargs, HPy kwnames, const char *fmt, - const char *keywords[], ...) -{ - int retval; - va_list va; - - va_start(va, keywords); - retval = parse_keywords(ctx, ht, args, nargs, kwnames, 1, fmt, keywords, &va); - va_end(va); - return retval; -} - -/** - * Parse positional arguments and keyword arguments in a dict. - * - * :param ctx: - * The execution context. - * :param ht: - * An optional pointer to an HPyTracker. If the format string never - * results in new handles being created, ``ht`` may be ``NULL``. Currently - * only the ``O`` formatting option to this function requires an HPyTracker. - * :param args: - * The array of positional arguments to parse. - * :param nargs: - * The number of elements in ``args``. - * :param kw: - * A handle to the dictionary of keyword arguments (may be ``HPy_NULL``). - * :param fmt: - * The format string to use to parse the arguments. - * :param keywords: - * A ``NULL``-terminated array of argument names. The number of names - * should match the format string provided. Positional only arguments - * should have the name ``""`` (i.e. the null-terminated empty string). - * Positional only arguments must preceded all other arguments. - * :param ...: - * A va_list of references to variables in which to store the parsed - * arguments. The number and types of the arguments should match the - * the format string, ``fmt``. - * - * :returns: ``0`` on failure, ``1`` on success. - * - * If a ``NULL`` pointer is passed to ``ht`` and an HPyTracker is required by - * the format string, a ``SystemError`` will be raised. - * - * If a pointer is provided to ``ht``, the HPyTracker will always be created and - * must be closed with ``HPyTracker_Close`` if parsing succeeds (after all - * handles returned are no longer needed). If parsing fails, this function will - * close the HPyTracker automatically. - * - * For examples, see :c:func:`HPyArg_ParseKeywords`. - */ -HPyAPI_HELPER int -HPyArg_ParseKeywordsDict(HPyContext *ctx, HPyTracker *ht, const HPy *args, - HPy_ssize_t nargs, HPy kw, const char *fmt, - const char *keywords[], ...) -{ - int retval; - va_list va; - - va_start(va, keywords); - retval = parse_keywords(ctx, ht, args, nargs, kw, 0, fmt, keywords, &va); - va_end(va); - return retval; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/buildvalue.c b/graalpython/hpy/hpy/devel/src/runtime/buildvalue.c deleted file mode 100644 index 8e786ff4d6..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/buildvalue.c +++ /dev/null @@ -1,431 +0,0 @@ -/** - * Implementation of HPy_BuildValue. - * - * Note: :c:func:`HPy_BuildValue` is a runtime helper functions, i.e., it is not - * a part of the HPy context, but is available to HPy extensions to incorporate - * at compile time. - * - * ``HPy_BuildValue`` creates a new value based on a format string from the - * values passed in variadic arguments. Returns ``HPy_NULL`` in case of an error - * and raises an exception. - * - * ``HPy_BuildValue`` does not always build a tuple. It builds a tuple only if - * its format string contains two or more format units. If the format string is - * empty, it returns ``None``; if it contains exactly one format unit, it - * returns whatever object is described by that format unit. To force it to - * return a tuple of size ``0`` or one, parenthesize the format string. - * - * Building complex values with ``HPy_BuildValue`` is more convenient than the - * equivalent code that uses more granular APIs with proper error handling and - * cleanup. Moreover, ``HPy_BuildValue`` provides straightforward way to port - * existing code that uses ``Py_BuildValue``. - * - * ``HPy_BuildValue`` always returns a new handle that will be owned by the - * caller. Even an artificial example ``HPy_BuildValue(ctx, "O", h)`` does not - * simply forward the value stored in ``h`` but duplicates the handle. - * - * Supported Formatting Strings - * ---------------------------- - * - * Numbers - * ~~~~~~~ - * - * ``i (int) [int]`` - * Convert a plain C int to a Python integer object. - * - * ``l (int) [long int]`` - * Convert a C long int to a Python integer object. - * - * ``I (int) [unsigned int]`` - * Convert a C unsigned int to a Python integer object. - * - * ``k (int) [unsigned long]`` - * Convert a C unsigned long to a Python integer object. - * - * ``L (int) [long long]`` - * Convert a C long long to a Python integer object. - * - * ``K (int) [unsigned long long]`` - * Convert a C unsigned long long to a Python integer object. - * - * ``n (int) [HPy_ssize_t]`` - * Convert a C HPy_ssize_t to a Python integer object. - * - * ``f (float) [float]`` - * Convert a C float to a Python floating point number. - * - * ``d (float) [double]`` - * Convert a C double to a Python floating point number. - * - * Collections - * ~~~~~~~~~~~ - * - * ``(items) (tuple) [matching-items]`` - * Convert a sequence of C values to a Python tuple with the same number of items. - * - * ``[items] (list) [matching-items]`` - * Convert a sequence of C values to a Python list with the same number of items. - * - * ``{key:value} (dict) [matching-items]`` - * Convert a sequence of C values to a Python dict with the same number of items. - * - * Misc - * ~~~~~~~ - * - * ``O (Python object) [HPy]`` - * Pass an untouched Python object represented by the handle. - * - * If the object passed in is a HPy_NULL, it is assumed that this was caused because - * the call producing the argument found an error and set an exception. Therefore, - * HPy_BuildValue will also immediately stop and return HPy_NULL but will not raise - * any new exception. If no exception has been raised yet, SystemError is set. - * - * Any HPy handle passed to HPy_BuildValue is always owned by the caller. HPy_BuildValue - * never closes the handle nor transfers its ownership. If the handle is used, then - * HPy_BuildValue creates a duplicate of the handle. - * - * ``S (Python object) [HPy]`` - * Alias for 'O'. - * - * API - * --- - * - */ - -#include "hpy.h" -#include -#include - -#define MESSAGE_BUF_SIZE 128 - -static HPy_ssize_t count_items(HPyContext *ctx, const char *fmt, char end); -static HPy build_tuple(HPyContext *ctx, const char **fmt, va_list *values, HPy_ssize_t size, char expected_end); -static HPy build_list(HPyContext *ctx, const char **fmt, va_list *values, HPy_ssize_t size); -static HPy build_dict(HPyContext *ctx, const char **fmt, va_list *values); -static HPy build_single(HPyContext *ctx, const char **fmt, va_list *values, int *needs_close); - -/** - * Creates a new value based on a format string from the values passed in - * variadic arguments. - * - * :param ctx: - * The execution context. - * :param fmt: - * The format string (ASCII only; must not be ``NULL``). For details, see - * :ref:`api-reference/build-value:supported formatting strings`. - * :param ...: - * Variable arguments according to the provided format string. - * - * :returns: - * A handle to the built Python value or ``HPy_NULL`` in case of errors. - */ -HPyAPI_HELPER -HPy HPy_BuildValue(HPyContext *ctx, const char *fmt, ...) -{ - va_list values; - HPy result; - va_start(values, fmt); - HPy_ssize_t size = count_items(ctx, fmt, '\0'); - if (size < 0) { - result = HPy_NULL; - } else if (size == 0) { - result = HPy_Dup(ctx, ctx->h_None); - } else if (size == 1) { - int needs_close; - result = build_single(ctx, &fmt, &values, &needs_close); - if (!needs_close) { - result = HPy_Dup(ctx, result); - } - } else { - result = build_tuple(ctx, &fmt, &values, size, '\0'); - } - va_end(values); - return result; -} - -static HPy_ssize_t count_items(HPyContext *ctx, const char *fmt, char end) -{ - HPy_ssize_t level = 0, result = 0; - char top_level_par = 'X'; - while (level != 0 || *fmt != end) { - char c = *fmt++; - switch (c) { - case '\0': { - // Premature end - // We try to provide slightly better diagnostics than CPython - char msg[MESSAGE_BUF_SIZE]; - char par_type; - if (end == ')') { - par_type = '('; - } else if (end == ']') { - par_type = '['; - } else if (end == '}') { - par_type = '{'; - } else { - if (level == 0 || top_level_par == 'X') { - HPyErr_SetString(ctx, ctx->h_SystemError, "internal error in HPy_BuildValue"); - return -1; - } - par_type = top_level_par; - } - snprintf(msg, sizeof(msg), "unmatched '%c' in the format string passed to HPy_BuildValue", par_type); - HPyErr_SetString(ctx, ctx->h_SystemError, msg); - return -1; - } - - case '[': - case '(': - case '{': - if (level == 0) { - top_level_par = c; - result++; - } - level++; - break; - - case ']': - case ')': - case '}': - level--; - break; - - case ',': - case ' ': - break; - - default: - if (level == 0) { - result++; - } - } - } - return result; -} - -static HPy build_single(HPyContext *ctx, const char **fmt, va_list *values, int *needs_close) -{ - char format_char = *(*fmt)++; - *needs_close = 1; - switch (format_char) { - case '(': { - HPy_ssize_t size = count_items(ctx, *fmt, ')'); - if (size < 0) { - return HPy_NULL; - } - return build_tuple(ctx, fmt, values, size, ')'); - } - - case '[': { - HPy_ssize_t size = count_items(ctx, *fmt, ']'); - if (size < 0) { - return HPy_NULL; - } - return build_list(ctx, fmt, values, size); - } - - case '{': { - return build_dict(ctx, fmt, values); - } - - case 'i': - return HPyLong_FromLong(ctx, (long)va_arg(*values, int)); - - case 'I': - return HPyLong_FromUnsignedLong(ctx, (unsigned long)va_arg(*values, unsigned int)); - - case 'k': - return HPyLong_FromUnsignedLong(ctx, va_arg(*values, unsigned long)); - - case 'l': - return HPyLong_FromLong(ctx, va_arg(*values, long)); - - case 'L': - return HPyLong_FromLongLong(ctx, va_arg(*values, long long)); - - case 'K': - return HPyLong_FromUnsignedLongLong(ctx, va_arg(*values, unsigned long long)); - - case 'n': - return HPyLong_FromSsize_t(ctx, va_arg(*values, HPy_ssize_t)); - - case 's': - return HPyUnicode_FromString(ctx, va_arg(*values, const char*)); - - case 'O': - case 'S': { - HPy handle = va_arg(*values, HPy); - if (HPy_IsNull(handle)) { - if (!HPyErr_Occurred(ctx)) { - HPyErr_SetString(ctx, ctx->h_SystemError, "HPy_NULL object passed to HPy_BuildValue"); - } - return handle; - } - *needs_close = 0; - return handle; - } - - case 'N': { - HPyErr_SetString(ctx, ctx->h_SystemError, - "HPy_BuildValue does not support the 'N' formatting unit. " - "Instead, use the 'O' formatting unit and manually close " - "the handle in the caller if necessary. HPy API functions " - "never 'steal' handles and always make a duplicate handle if " - "needed, the 'ownership' of the original handle is never " - "'transferred'. "); - return HPy_NULL; - } - - case 'f': // Note: floats are promoted to doubles when passed in "..." - case 'd': - return HPyFloat_FromDouble(ctx, va_arg(*values, double)); - - default: { - char message[MESSAGE_BUF_SIZE]; - snprintf(message, sizeof(message), "bad format char '%c' in the format string passed to HPy_BuildValue", format_char); - HPyErr_SetString(ctx, ctx->h_SystemError, message); - return HPy_NULL; - } - } // switch -} - -static HPy build_dict(HPyContext *ctx, const char **fmt, va_list *values) -{ - HPy dict = HPyDict_New(ctx); - int expect_comma = 0; - while (**fmt != '}' && **fmt != '\0') { - if (**fmt == ' ') { - (*fmt)++; - continue; - } - if (**fmt == ',') { - if (!expect_comma) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "unexpected ',' in the format string passed to HPy_BuildValue"); - HPy_Close(ctx, dict); - return HPy_NULL; - } - (*fmt)++; - expect_comma = 0; - continue; - } else { - if (expect_comma) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "missing ',' in the format string passed to HPy_BuildValue"); - HPy_Close(ctx, dict); - return HPy_NULL; - } - } - int needs_key_close, needs_value_close; - HPy key = build_single(ctx, fmt, values, &needs_key_close); - if (HPy_IsNull(key)) { - HPy_Close(ctx, dict); - return HPy_NULL; - } - if (**fmt != ':') { - HPyErr_SetString(ctx, ctx->h_SystemError, - "missing ':' in the format string passed to HPy_BuildValue"); - if (needs_key_close) { - HPy_Close(ctx, key); - } - HPy_Close(ctx, dict); - return HPy_NULL; - } else { - (*fmt)++; - } - HPy value = build_single(ctx, fmt, values, &needs_value_close); - if (HPy_IsNull(value)) { - if (needs_key_close) { - HPy_Close(ctx, key); - } - HPy_Close(ctx, dict); - return HPy_NULL; - } - int res = HPy_SetItem(ctx, dict, key, value); - if (needs_key_close) { - HPy_Close(ctx, key); - } - if (needs_value_close) { - HPy_Close(ctx, value); - } - if (res < 0) { - HPy_Close(ctx, dict); - return HPy_NULL; - } - - expect_comma = 1; - } - if (**fmt != '}') { - // count_items does not check the type of the matching paren, that's what we do here - HPy_Close(ctx, dict); - HPyErr_SetString(ctx, ctx->h_SystemError, - "unmatched '{' in the format string passed to HPy_BuildValue"); - return HPy_NULL; - } - ++*fmt; - return dict; -} - -static HPy build_list(HPyContext *ctx, const char **fmt, va_list *values, HPy_ssize_t size) -{ - HPyListBuilder builder = HPyListBuilder_New(ctx, size); - for (HPy_ssize_t i = 0; i < size; ++i) { - int needs_close; - HPy item = build_single(ctx, fmt, values, &needs_close); - if (HPy_IsNull(item)) { - HPyListBuilder_Cancel(ctx, builder); - return HPy_NULL; - } - HPyListBuilder_Set(ctx, builder, i, item); - if (needs_close) { - HPy_Close(ctx, item); - } - if (**fmt == ',') { - (*fmt)++; - } - } - if (**fmt != ']') { - // count_items does not check the type of the matching paren, that's what we do here - HPyListBuilder_Cancel(ctx, builder); - HPyErr_SetString(ctx, ctx->h_SystemError, - "unmatched '[' in the format string passed to HPy_BuildValue"); - return HPy_NULL; - } - ++*fmt; - return HPyListBuilder_Build(ctx, builder); -} - -static HPy build_tuple(HPyContext *ctx, const char **fmt, va_list *values, HPy_ssize_t size, char expected_end) -{ - HPyTupleBuilder builder = HPyTupleBuilder_New(ctx, size); - for (HPy_ssize_t i = 0; i < size; ++i) { - int needs_close; - HPy item = build_single(ctx, fmt, values, &needs_close); - if (HPy_IsNull(item)) { - HPyTupleBuilder_Cancel(ctx, builder); - return HPy_NULL; - } - HPyTupleBuilder_Set(ctx, builder, i, item); - if (needs_close) { - HPy_Close(ctx, item); - } - if (**fmt == ',') { - (*fmt)++; - } - } - if (**fmt != expected_end) { - // count_items does not check the type of the matching paren, that's what we do here - // if expected_end == '\0', then there would have to be a bug in count_items - HPyTupleBuilder_Cancel(ctx, builder); - if (expected_end == '\0') { - HPyErr_SetString(ctx, ctx->h_SystemError, "internal error in HPy_BuildValue"); - } else { - HPyErr_SetString(ctx, ctx->h_SystemError, - "unmatched '[' in the format string passed to HPy_BuildValue"); - } - return HPy_NULL; - } - if (expected_end != '\0') { - ++*fmt; - } - return HPyTupleBuilder_Build(ctx, builder); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c deleted file mode 100644 index 8a4845e015..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_bytes.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "hpy.h" -#include "hpy/runtime/ctx_funcs.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPy -ctx_Bytes_FromStringAndSize(HPyContext *ctx, const char *v, HPy_ssize_t len) -{ - if (v == NULL) { - // The CPython API allows passing a null pointer to - // PyBytes_FromStringAndSize and returns uninitialized memory of the - // requested size which can then be initialized after the call. - // In HPy the underlying memory is opaque and so cannot be initialized - // after the call and so we raise an error instead. - HPyErr_SetString(ctx, ctx->h_ValueError, - "NULL char * passed to HPyBytes_FromStringAndSize"); - return HPy_NULL; - } - return _py2h(PyBytes_FromStringAndSize(v, len)); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_call.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_call.c deleted file mode 100644 index e85fd236b4..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_call.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include "hpy.h" -#if defined(_MSC_VER) -# include /* for alloca() */ -#endif - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN HPy -ctx_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw) -{ - PyObject *obj; - if (!HPy_IsNull(args) && !HPyTuple_Check(ctx, args)) { - HPyErr_SetString(ctx, ctx->h_TypeError, - "HPy_CallTupleDict requires args to be a tuple or null handle"); - return HPy_NULL; - } - if (!HPy_IsNull(kw) && !HPyDict_Check(ctx, kw)) { - HPyErr_SetString(ctx, ctx->h_TypeError, - "HPy_CallTupleDict requires kw to be a dict or null handle"); - return HPy_NULL; - } - if (HPy_IsNull(kw)) { - obj = PyObject_CallObject(_h2py(callable), _h2py(args)); - } - else if (!HPy_IsNull(args)){ - obj = PyObject_Call(_h2py(callable), _h2py(args), _h2py(kw)); - } - else { - // args is null, but kw is not, so we need to create an empty args tuple - // for CPython's PyObject_Call - HPy *items = NULL; - HPy empty_tuple = HPyTuple_FromArray(ctx, items, 0); - obj = PyObject_Call(_h2py(callable), _h2py(empty_tuple), _h2py(kw)); - HPy_Close(ctx, empty_tuple); - } - return _py2h(obj); -} - -#if PY_VERSION_HEX < 0x03090000 -# define PyObject_Vectorcall _PyObject_Vectorcall -#endif - -_HPy_HIDDEN HPy -ctx_Call(HPyContext *ctx, HPy h_callable, const HPy *h_args, size_t nargs, HPy h_kwnames) -{ - PyObject *kwnames; - size_t n_all_args; - - if (HPy_IsNull(h_kwnames)) { - kwnames = NULL; - n_all_args = nargs; - } else { - kwnames = _h2py(h_kwnames); - assert(kwnames != NULL); - assert(PyTuple_Check(kwnames)); - n_all_args = nargs + PyTuple_GET_SIZE(kwnames); - assert(n_all_args >= nargs); - } - - /* Since we already allocate a fresh args array, we make it one element - larger and set PY_VECTORCALL_ARGUMENTS_OFFSET to avoid further - allocations from CPython. */ - PyObject **args = (PyObject **) alloca((n_all_args + 1) * sizeof(PyObject *)); - for (size_t i = 0; i < n_all_args; i++) { - args[i+1] = _h2py(h_args[i]); - } - - return _py2h(PyObject_Vectorcall(_h2py(h_callable), args+1, - nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames)); -} - -#if PY_VERSION_HEX < 0x03090000 -# undef PyObject_Vectorcall -#endif - -_HPy_HIDDEN HPy -ctx_CallMethod(HPyContext *ctx, HPy h_name, const HPy *h_args, size_t nargs, - HPy h_kwnames) -{ - PyObject *result, *kwnames; - size_t n_all_args; - - if (HPy_IsNull(h_kwnames)) { - kwnames = NULL; - n_all_args = nargs; - } else { - kwnames = _h2py(h_kwnames); - assert(kwnames != NULL); - assert(PyTuple_Check(kwnames)); - n_all_args = nargs + PyTuple_GET_SIZE(kwnames); - assert(n_all_args >= nargs); - } - - /* Since we already allocate a fresh args array, we make it one element - larger and set PY_VECTORCALL_ARGUMENTS_OFFSET to avoid further - allocations from CPython. */ - PyObject **args = (PyObject **) alloca( - (n_all_args + 1) * sizeof(PyObject *)); - for (size_t i = 0; i < n_all_args; i++) { - args[i+1] = _h2py(h_args[i]); - } - -#if PY_VERSION_HEX < 0x03090000 - PyObject *method = PyObject_GetAttr(args[1], _h2py(h_name)); - if (method == NULL) - return HPy_NULL; - result = _PyObject_Vectorcall(method, &args[2], - (nargs-1) | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); - Py_DECREF(method); -#else - result = PyObject_VectorcallMethod(_h2py(h_name), args+1, - nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); -#endif - return _py2h(result); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c deleted file mode 100644 index 703b686164..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_capsule.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN HPy -ctx_Capsule_New(HPyContext *ctx, void *pointer, const char *name, - HPyCapsule_Destructor *destructor) -{ - PyObject *res; - if (destructor) { - // If a destructor is given, it is not allowed to omit the functions - if ((destructor->cpy_trampoline == NULL || destructor->impl == NULL)) { - PyErr_SetString(PyExc_ValueError, "Invalid HPyCapsule destructor"); - return HPy_NULL; - } - res = PyCapsule_New(pointer, name, destructor->cpy_trampoline); - } else { - res = PyCapsule_New(pointer, name, NULL); - } - return _py2h(res); -} - -_HPy_HIDDEN int -ctx_Capsule_SetDestructor(HPyContext *ctx, HPy h_capsule, - HPyCapsule_Destructor *destructor) -{ - if (destructor) { - // If a destructor is given, it is not allowed to omit the functions - if ((destructor->cpy_trampoline == NULL || destructor->impl == NULL)) { - PyErr_SetString(PyExc_ValueError, "Invalid HPyCapsule destructor"); - return -1; - } - return PyCapsule_SetDestructor(_h2py(h_capsule), destructor->cpy_trampoline); - } - return PyCapsule_SetDestructor(_h2py(h_capsule), NULL); -} - -#ifndef HPY_ABI_CPYTHON -_HPy_HIDDEN void * -ctx_Capsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *name) -{ - switch (key) - { - case HPyCapsule_key_Pointer: - return PyCapsule_GetPointer(_h2py(capsule), name); - case HPyCapsule_key_Name: - return (void *) PyCapsule_GetName(_h2py(capsule)); - case HPyCapsule_key_Context: - return PyCapsule_GetContext(_h2py(capsule)); - case HPyCapsule_key_Destructor: - PyErr_SetString(PyExc_ValueError, "Invalid operation: get HPyCapsule_key_Destructor"); - return NULL; - } - /* unreachable */ - assert(0); - return NULL; -} - -_HPy_HIDDEN int -ctx_Capsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) -{ - switch (key) - { - case HPyCapsule_key_Pointer: - return PyCapsule_SetPointer(_h2py(capsule), value); - case HPyCapsule_key_Name: - return PyCapsule_SetName(_h2py(capsule), (const char *) value); - case HPyCapsule_key_Context: - return PyCapsule_SetContext(_h2py(capsule), value); - case HPyCapsule_key_Destructor: - return ctx_Capsule_SetDestructor(ctx, capsule, (HPyCapsule_Destructor *) value); - } - /* unreachable */ - assert(0); - return -1; -} -#endif diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c deleted file mode 100644 index d0cc4fc31d..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_contextvar.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN int32_t -ctx_ContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result) -{ - PyObject * py_result; - int32_t ret = PyContextVar_Get(_h2py(context_var), _h2py(default_value), &py_result); - *result = _py2h(py_result); - return ret; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c deleted file mode 100644 index 783683efe5..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_err.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include "hpy.h" -#include "hpy/runtime/ctx_funcs.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN int -ctx_Err_Occurred(HPyContext *ctx) { - return PyErr_Occurred() ? 1 : 0; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c deleted file mode 100644 index 945db30777..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_eval.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -_HPy_HIDDEN HPy -ctx_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - int start; - switch (kind) - { - case HPy_SourceKind_Expr: start = Py_eval_input; break; - case HPy_SourceKind_File: start = Py_file_input; break; - case HPy_SourceKind_Single: start = Py_single_input; break; - default: - PyErr_SetString(PyExc_SystemError, "invalid source kind"); - return HPy_NULL; - } - return _py2h(Py_CompileString(utf8_source, utf8_filename, start)); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c deleted file mode 100644 index d048502023..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_listbuilder.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPyListBuilder -ctx_ListBuilder_New(HPyContext *ctx, HPy_ssize_t size) -{ - PyObject *lst = PyList_New(size); - if (lst == NULL) - PyErr_Clear(); /* delay the MemoryError */ - return (HPyListBuilder){(HPy_ssize_t)lst}; -} - -_HPy_HIDDEN void -ctx_ListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - PyObject *lst = (PyObject *)builder._lst; - if (lst != NULL) { - PyObject *item = _h2py(h_item); - assert(index >= 0 && index < PyList_GET_SIZE(lst)); - assert(PyList_GET_ITEM(lst, index) == NULL); - Py_INCREF(item); - PyList_SET_ITEM(lst, index, item); - } -} - -_HPy_HIDDEN HPy -ctx_ListBuilder_Build(HPyContext *ctx, HPyListBuilder builder) -{ - PyObject *lst = (PyObject *)builder._lst; - if (lst == NULL) { - PyErr_NoMemory(); - return HPy_NULL; - } - builder._lst = 0; - return _py2h(lst); -} - -_HPy_HIDDEN void -ctx_ListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder) -{ - PyObject *lst = (PyObject *)builder._lst; - if (lst == NULL) { - // we don't report the memory error here: the builder - // is being cancelled (so the result of the builder is not being used) - // and likely it's being cancelled during the handling of another error - return; - } - builder._lst = 0; - Py_XDECREF(lst); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_long.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_long.c deleted file mode 100644 index a1609d66d3..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_long.c +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -// just for better readability -#define SIZEOF_INT32 4 -#define SIZEOF_INT64 8 - -HPyAPI_IMPL HPy ctx_Long_FromInt32_t(HPyContext *ctx, int32_t value) { -#if SIZEOF_LONG >= SIZEOF_INT32 - return _py2h(PyLong_FromLong((long)value)); -#else -#error "unsupported SIZEOF_LONG" -#endif -} - -HPyAPI_IMPL HPy ctx_Long_FromUInt32_t(HPyContext *ctx, uint32_t value) { -#if SIZEOF_LONG >= SIZEOF_INT32 - return _py2h(PyLong_FromUnsignedLong((unsigned long)value)); -#else -#error "unsupported SIZEOF_LONG" -#endif -} - -HPyAPI_IMPL HPy ctx_Long_FromInt64_t(HPyContext *ctx, int64_t v) { -#if SIZEOF_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromLong((long)v)); -#elif SIZEOF_LONG_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromLongLong((long long)v)); -#else -#error "unsupported SIZEOF_LONG_LONG" -#endif -} - -HPyAPI_IMPL HPy ctx_Long_FromUInt64_t(HPyContext *ctx, uint64_t v) { -#if SIZEOF_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromUnsignedLong((unsigned long)v)); -#elif SIZEOF_LONG_LONG >= SIZEOF_INT64 - return _py2h(PyLong_FromUnsignedLongLong((unsigned long long)v)); -#else -#error "unsupported SIZEOF_LONG_LONG" -#endif -} - -HPyAPI_IMPL int32_t ctx_Long_AsInt32_t(HPyContext *ctx, HPy h) { - long lres = PyLong_AsLong(_h2py(h)); -#if SIZEOF_LONG == SIZEOF_INT32 - return (int32_t) lres; -#elif SIZEOF_LONG >= SIZEOF_INT32 - int32_t i32res = (int32_t) lres; - if (lres == (long) i32res) - return i32res; - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C int32_t"); - return (int32_t) -1; -#else -#error "unsupported SIZEOF_LONG" -#endif -} - -HPyAPI_IMPL uint32_t ctx_Long_AsUInt32_t(HPyContext *ctx, HPy h) { - unsigned long lres = PyLong_AsUnsignedLong(_h2py(h)); -#if SIZEOF_LONG == SIZEOF_INT32 - return (uint32_t) lres; -#elif SIZEOF_LONG >= SIZEOF_INT32 - uint32_t ui32res = (uint32_t) lres; - if (lres == (unsigned long) ui32res) - return ui32res; - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C uint32_t"); - return (uint32_t) -1; -#else -#error "unsupported SIZEOF_LONG" -#endif -} - -HPyAPI_IMPL uint32_t ctx_Long_AsUInt32_tMask(HPyContext *ctx, HPy h) { - return (uint32_t) PyLong_AsUnsignedLongMask(_h2py(h)); -} - -HPyAPI_IMPL int64_t ctx_Long_AsInt64_t(HPyContext *ctx, HPy h) { - long long lres = PyLong_AsLongLong(_h2py(h)); -#if SIZEOF_LONG_LONG == SIZEOF_INT64 - return (int64_t) lres; -#elif SIZEOF_LONG_LONG >= SIZEOF_INT64 - int64_t i64res = (int64_t) lres; - if (lres == (long long) i64res) - return i64res; - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C int64_t"); - return (int64_t) -1; -#else -#error "unsupported SIZEOF_LONG_LONG" -#endif -} - -HPyAPI_IMPL uint64_t ctx_Long_AsUInt64_t(HPyContext *ctx, HPy h) { - unsigned long long lres = PyLong_AsUnsignedLongLong(_h2py(h)); -#if SIZEOF_LONG_LONG == SIZEOF_INT64 - return (uint64_t) lres; -#elif SIZEOF_LONG_LONG >= SIZEOF_INT64 - uint64_t ui64res = (uint64_t) lres; - if (lres == (unsigned long long) ui64res) - return ui64res; - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert to C uint64_t"); - return (uint64_t) -1; -#else -#error "unsupported SIZEOF_LONG_LONG" -#endif -} - -HPyAPI_IMPL uint64_t ctx_Long_AsUInt64_tMask(HPyContext *ctx, HPy h) { - return (uint64_t) PyLong_AsUnsignedLongLongMask(_h2py(h)); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_module.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_module.c deleted file mode 100644 index 8d318c03eb..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_module.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include "hpy.h" -#include "hpy/runtime/ctx_type.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -#define NON_DEFAULT_MESSAGE \ - "This is not allowed because custom " \ - "HPy_mod_create slot cannot return a builtin module " \ - "object and cannot make any use of any other data " \ - "defined in the HPyModuleDef. Either do not define " \ - "HPy_mod_create slot and let the runtime create a builtin " \ - "module object from the provided HPyModuleDef, or do not define " \ - "anything else but the HPy_mod_create slot." - -static PyModuleDef empty_moduledef = { - PyModuleDef_HEAD_INIT -}; - -static PyModuleDef_Slot* create_mod_slots(HPyModuleDef *hpydef, bool *found_create) -{ - size_t slots_count = 0; - bool found_non_create = false; - for (int i = 0; hpydef->defines[i] != NULL; i++) { - HPyDef *src = hpydef->defines[i]; - if (src->kind != HPyDef_Kind_Slot) { - found_non_create = true; - continue; - } - slots_count++; - if (src->slot.slot == HPy_mod_create) { - if (*found_create) { - PyErr_SetString(PyExc_SystemError, "Multiple definitions " - "of the HPy_mod_create " - "slot in HPyModuleDef.defines."); - return NULL; - } - *found_create = true; - } else if (src->slot.slot != HPy_mod_exec) { - PyErr_Format(PyExc_SystemError, "Unsupported slot in " - "HPyModuleDef.defines (value: %d).", - (int) src->slot.slot); - return NULL; - } else { - assert(src->slot.slot == HPy_mod_exec); - found_non_create = true; - } - } - if (*found_create && found_non_create) { - PyErr_Format(PyExc_SystemError, - "HPyModuleDef defines a HPy_mod_create slot and some other " - "slots or methods. " NON_DEFAULT_MESSAGE); - return NULL; - } - - PyModuleDef_Slot* m_slots = (PyModuleDef_Slot*)PyMem_Calloc( - slots_count + 1, sizeof(PyModuleDef_Slot)); - m_slots[slots_count].slot = 0; - m_slots[slots_count].value = NULL; - size_t slot_index = 0; - for (int i = 0; hpydef->defines[i] != NULL; i++) { - HPyDef *src = hpydef->defines[i]; - if (src->kind != HPyDef_Kind_Slot) - continue; - int py_slot; - if (src->slot.slot == HPy_mod_create) { - py_slot = Py_mod_create; - } else { - assert(src->slot.slot == HPy_mod_exec); - py_slot = Py_mod_exec; - } - m_slots[slot_index].slot = py_slot; - m_slots[slot_index].value = (void*) src->slot.cpy_trampoline; - slot_index++; - } - return m_slots; -} - -_HPy_HIDDEN PyModuleDef* -_HPyModuleDef_CreatePyModuleDef(HPyModuleDef *hpydef) -{ - PyModuleDef *def = (PyModuleDef*)PyMem_Malloc(sizeof(PyModuleDef)); - if (def == NULL) { - PyErr_NoMemory(); - return NULL; - } - memcpy(def, &empty_moduledef, sizeof(PyModuleDef)); - def->m_doc = hpydef->doc; - if (hpydef->size < 0) { - PyErr_SetString(PyExc_SystemError, "HPy does not permit " - "HPyModuleDef.size < 0"); - goto error; - } else if (hpydef->size > 0) { - // GH-328 - PyErr_SetString(PyExc_SystemError, "Module state is not supported yet " - "in HPy, set HPyModuleDef.size = 0 " - "if module state is not needed"); - goto error; - } - - def->m_methods = create_method_defs(hpydef->defines, hpydef->legacy_methods); - if (def->m_methods == NULL) { - goto error; - } - - if (hpydef->defines != NULL) { - bool found_create = false; - def->m_slots = create_mod_slots(hpydef, &found_create); - if (def->m_slots == NULL) { - goto error; - } - if (found_create && (hpydef->legacy_methods || hpydef->size > 0 || - hpydef->doc != NULL || hpydef->globals != NULL)) { - PyErr_Format(PyExc_SystemError, - "HPyModuleDef defines a HPy_mod_create slot and some " - "of the other fields are not set to their default " - "value. " NON_DEFAULT_MESSAGE); - goto error; - } - } - - return def; -error: - if (def != NULL) { - PyMem_Free(def); - } - return NULL; -} - -_HPy_HIDDEN PyObject* -_HPyModuleDef_AsPyInit(HPyModuleDef *hpydef) -{ - PyModuleDef *def = _HPyModuleDef_CreatePyModuleDef(hpydef); - if (def == NULL) { - return NULL; - } - return PyModuleDef_Init(def); -} - -_HPy_HIDDEN void -_HPyModule_CheckCreateSlotResult(PyObject **result) -{ - if (*result != NULL && PyModule_Check(*result)) { - PyErr_SetString(PyExc_SystemError, - "HPy_mod_create slot returned a builtin module object. " - "This is currently not supported."); - *result = NULL; - } -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_object.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_object.c deleted file mode 100644 index 9fa72a205c..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_object.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN void -ctx_Dump(HPyContext *ctx, HPy h) -{ - // just use _PyObject_Dump for now, but we might want to add more info - // about the handle itself in the future. - _PyObject_Dump(_h2py(h)); -} - -_HPy_HIDDEN HPy -ctx_Type(HPyContext *ctx, HPy obj) -{ - PyTypeObject *tp = Py_TYPE(_h2py(obj)); - Py_INCREF(tp); - return _py2h((PyObject *)tp); -} - -/* 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) -{ - return PyObject_TypeCheck(_h2py(h_obj), (PyTypeObject*)_h2py(h_type)); -} - -_HPy_HIDDEN int -ctx_Is(HPyContext *ctx, HPy h_obj, HPy h_other) -{ - return _h2py(h_obj) == _h2py(h_other); -} - -_HPy_HIDDEN HPy -ctx_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - PyObject *py_obj = _h2py(obj); - if (PySequence_Check(py_obj)) { - return _py2h(PySequence_GetItem(py_obj, idx)); - } - PyObject* key = PyLong_FromSsize_t(idx); - if (key == NULL) - return HPy_NULL; - HPy result = _py2h(PyObject_GetItem(py_obj, key)); - Py_DECREF(key); - return result; -} - -_HPy_HIDDEN HPy -ctx_GetItem_s(HPyContext *ctx, HPy obj, const char *key) { - PyObject* key_o = PyUnicode_FromString(key); - if (key_o == NULL) - return HPy_NULL; - HPy result = _py2h(PyObject_GetItem(_h2py(obj), key_o)); - Py_DECREF(key_o); - return result; -} - -_HPy_HIDDEN int -ctx_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value) { - PyObject* key = PyLong_FromSsize_t(idx); - if (key == NULL) - return -1; - int result = PyObject_SetItem(_h2py(obj), key, _h2py(value)); - Py_DECREF(key); - return result; -} - -_HPy_HIDDEN int -ctx_SetItem_s(HPyContext *ctx, HPy obj, const char *key, HPy value) { - PyObject* key_o = PyUnicode_FromString(key); - if (key_o == NULL) - return -1; - int result = PyObject_SetItem(_h2py(obj), key_o, _h2py(value)); - Py_DECREF(key_o); - return result; -} - -_HPy_HIDDEN int -ctx_DelItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx) { - PyObject* key = PyLong_FromSsize_t(idx); - if (key == NULL) - return -1; - int result = PyObject_DelItem(_h2py(obj), key); - Py_DECREF(key); - return result; -} - -_HPy_HIDDEN int -ctx_DelItem_s(HPyContext *ctx, HPy obj, const char *key) { - PyObject* key_o = PyUnicode_FromString(key); - if (key_o == NULL) - return -1; - int result = PyObject_DelItem(_h2py(obj), key_o); - Py_DECREF(key_o); - return result; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c deleted file mode 100644 index 17a3909f8e..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_tracker.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * A manager for HPy handles, allowing handles to be tracked - * and closed as a group. - * - * Note:: - * Calling HPyTracker_New(ctx, n) will ensure that at least n handles - * can be tracked without a call to HPyTracker_Add failing. - * - * If a call to HPyTracker_Add fails, the tracker still guarantees that - * the handle passed to it has been tracked (internally it does this by - * maintaining space for one more handle). - * - * After HPyTracker_Add fails, HPyTracker_Close should be called without - * any further calls to HPyTracker_Add. Calling HPyTracker_Close will close - * all the tracked handles, including the handled passed to the failed call - * to HPyTracker_Add. - * - * Example usage (inside an HPyDef_METH function):: - * - * long i; - * HPy key, value; - * HPyTracker ht; - * - * ht = HPyTracker_New(ctx, 0); // track the key-value pairs - * if (HPy_IsNull(ht)) - * return HPy_NULL; - * - * HPy dict = HPyDict_New(ctx); - * if (HPy_IsNull(dict)) - * goto error; - * - * for (i=0; i<5; i++) { - * key = HPyLong_FromLong(ctx, i); - * if (HPy_IsNull(key)) - * goto error; - * if (HPyTracker_Add(ctx, ht, key) < 0) - * goto error; - * value = HPyLong_FromLong(ctx, i * i); - * if (HPy_IsNull(value)) { - * goto error; - * } - * if (HPyTracker_Add(ctx, ht, value) < 0) - * goto error; - * result = HPy_SetItem(ctx, dict, key, value); - * if (result < 0) - * goto error; - * } - * - * success: - * HPyTracker_Close(ctx, ht); - * return dict; - * - * error: - * HPyTracker_Close(ctx, ht); - * HPy_Close(ctx, dict); - * // HPyErr will already have been set by the error that occurred. - * return HPy_NULL; - */ - -#include "hpy.h" - -static const HPy_ssize_t HPYTRACKER_INITIAL_CAPACITY = 5; - -typedef struct { - HPy_ssize_t capacity; // allocated handles - HPy_ssize_t length; // used handles - HPy *handles; -} _HPyTracker_s; - - -static inline _HPyTracker_s *_ht2hp(HPyTracker ht) { - return (_HPyTracker_s *) (ht)._i; -} -static inline HPyTracker _hp2ht(_HPyTracker_s *hp) { - return (HPyTracker) {(HPy_ssize_t) (hp)}; -} - - -_HPy_HIDDEN HPyTracker -ctx_Tracker_New(HPyContext *ctx, HPy_ssize_t capacity) -{ - _HPyTracker_s *hp; - if (capacity == 0) { - capacity = HPYTRACKER_INITIAL_CAPACITY; - } - capacity++; // always reserve space for an extra handle, see the docs - - hp = (_HPyTracker_s*)malloc(sizeof(_HPyTracker_s)); - if (hp == NULL) { - HPyErr_NoMemory(ctx); - return _hp2ht(0); - } - hp->handles = (HPy*)calloc(capacity, sizeof(HPy)); - if (hp->handles == NULL) { - free(hp); - HPyErr_NoMemory(ctx); - return _hp2ht(0); - } - hp->capacity = capacity; - hp->length = 0; - return _hp2ht(hp); -} - -static int -tracker_resize(HPyContext *ctx, _HPyTracker_s *hp, HPy_ssize_t capacity) -{ - HPy *new_handles; - capacity++; - - if (capacity <= hp->length) { - // refuse a resize that would either 1) lose handles or 2) not leave - // space for one new handle - HPyErr_SetString(ctx, ctx->h_ValueError, "HPyTracker resize would lose handles"); - return -1; - } - new_handles = (HPy*)realloc(hp->handles, capacity * sizeof(HPy)); - if (new_handles == NULL) { - HPyErr_NoMemory(ctx); - return -1; - } - hp->capacity = capacity; - hp->handles = new_handles; - return 0; -} - -_HPy_HIDDEN int -ctx_Tracker_Add(HPyContext *ctx, HPyTracker ht, HPy h) -{ - _HPyTracker_s *hp = _ht2hp(ht); - hp->handles[hp->length++] = h; - if (hp->capacity <= hp->length) { - if (tracker_resize(ctx, hp, hp->capacity * 2 - 1) < 0) - return -1; - } - return 0; -} - -_HPy_HIDDEN void -ctx_Tracker_ForgetAll(HPyContext *ctx, HPyTracker ht) -{ - _HPyTracker_s *hp = _ht2hp(ht); - hp->length = 0; -} - -_HPy_HIDDEN void -ctx_Tracker_Close(HPyContext *ctx, HPyTracker ht) -{ - _HPyTracker_s *hp = _ht2hp(ht); - HPy_ssize_t i; - for (i=0; ilength; i++) { - HPy_Close(ctx, hp->handles[i]); - } - free(hp->handles); - free(hp); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c deleted file mode 100644 index 42661f8fea..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_tuple.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPy -ctx_Tuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n) -{ - PyObject *res = PyTuple_New(n); - if (!res) - return HPy_NULL; - for(HPy_ssize_t i=0; i -#include -#include "hpy.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - - -_HPy_HIDDEN HPyTupleBuilder -ctx_TupleBuilder_New(HPyContext *ctx, HPy_ssize_t size) -{ - PyObject *tup = PyTuple_New(size); - if (tup == NULL) { - PyErr_Clear(); /* delay the MemoryError */ - /* note: it's done this way so that the caller doesn't need to - check if HPyTupleBuilder_New() or every HPyTupleBuilder_Set() - raised. If there is a rare error like a MemoryError somewhere, - further calls to the HPyTupleBuilder are ignored. The final - HPyTupleBuilder_Build() will re-raise the MemoryError and so - it's enough for the caller to check at that point. */ - } - return (HPyTupleBuilder){(HPy_ssize_t)tup}; -} - -_HPy_HIDDEN void -ctx_TupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, - HPy_ssize_t index, HPy h_item) -{ - PyObject *tup = (PyObject *)builder._tup; - if (tup != NULL) { - PyObject *item = _h2py(h_item); - assert(index >= 0 && index < PyTuple_GET_SIZE(tup)); - assert(PyTuple_GET_ITEM(tup, index) == NULL); - Py_INCREF(item); - PyTuple_SET_ITEM(tup, index, item); - } -} - -_HPy_HIDDEN HPy -ctx_TupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder) -{ - PyObject *tup = (PyObject *)builder._tup; - if (tup == NULL) { - PyErr_NoMemory(); - return HPy_NULL; - } - builder._tup = 0; - return _py2h(tup); -} - -_HPy_HIDDEN void -ctx_TupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder) -{ - PyObject *tup = (PyObject *)builder._tup; - if (tup == NULL) { - // we don't report the memory error here: the builder - // is being cancelled (so the result of the builder is not being used) - // and likely it's being cancelled during the handling of another error - return; - } - builder._tup = 0; - Py_XDECREF(tup); -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/ctx_type.c b/graalpython/hpy/hpy/devel/src/runtime/ctx_type.c deleted file mode 100644 index ef89e2590d..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/ctx_type.c +++ /dev/null @@ -1,1633 +0,0 @@ -#include -#include -#include "structmember.h" // for PyMemberDef -#include "hpy.h" -#include "hpy/runtime/ctx_type.h" - -#ifndef HPY_ABI_CPYTHON - // for _h2py and _py2h -# include "handles.h" -#endif - -/* Python 3.8 had "provisional" vectorcall support which was a bit different in - some details. */ -#define PROVISIONAL_VECTORCALL_SUPPORT (PY_VERSION_HEX < 0x03090000) - -/* HPy_TPFLAGS_INTERNAL_IS_HPY_TYPE is set automatically on HPy types created - with HPyType_FromSpec. This is used internally within HPy to distinguish - HPy types. - - Note on the choice of bit: CPython uses bit 0 and all bits from 4 up in - ver. 3.11a. Using a random currently unused bit in type flags is a temporary - solution. Going forward, HPy may ask CPython to reserve one bit for HPy or - find another more reliable solution. -*/ -#define HPy_TPFLAGS_INTERNAL_IS_HPY_TYPE (1UL << 2) - -#define HPy_TYPE_MAGIC 0xba5f - -// these fields are never accessed: they are present just to ensure -// the correct alignment of payload -typedef union { - unsigned char _m_char[1]; - unsigned short _m_short; - unsigned int _m_int; - unsigned long _m_long; - unsigned long long _m_longlong; - float _m_float; - double _m_double; - long double _m_longdouble; - void *_m_pointer; -} _HPy_MaxAlign_t; - -// Helper macro to align a given size to a multiple of sizeof(MAX_ALIGN_T). -#define _HPy_ALIGN(SIZE) \ - (((SIZE) + sizeof(_HPy_MaxAlign_t) - 1) & ~(sizeof(_HPy_MaxAlign_t) - 1)) - -/* The C structs of pure HPy (i.e. non-legacy) custom types do NOT include - * PyObject_HEAD. So, the CPython implementation of HPy_New must allocate a - * memory region which is big enough to contain PyObject_HEAD + any eventual - * extra padding + the actual user struct. We use union alignment to ensure - * that the payload is correctly aligned for every possible struct. - * - * Legacy custom types already include PyObject_HEAD and so do not need to - * allocate extra memory region or use _HPy_PyObject_HEAD_SIZE. - */ -typedef struct { - PyObject_HEAD - _HPy_MaxAlign_t payload; -} _HPy_FullyAlignedSpaceForPyObject_HEAD; - -/* Similar to the case above, if a pure HPy custom type inherits from a - * built-in type, the pure HPy type does not embed the built-in type's struct. - * The CPython implementation of HPy_New must allocate memory that is big - * enough to contain the built-in type's struct + any eventual extra padding + - * the actual user struct. - */ -#define FULLY_ALIGNED_SPACE(TYPE) \ - typedef struct { \ - TYPE ob_base; \ - _HPy_MaxAlign_t payload; \ - } _HPy_FullyAlignedSpaceFor##TYPE; - -FULLY_ALIGNED_SPACE(PyHeapTypeObject) -FULLY_ALIGNED_SPACE(PyLongObject) -FULLY_ALIGNED_SPACE(PyFloatObject) -FULLY_ALIGNED_SPACE(PyUnicodeObject) -FULLY_ALIGNED_SPACE(PyTupleObject) -FULLY_ALIGNED_SPACE(PyListObject) -FULLY_ALIGNED_SPACE(PyDictObject) - -#define _HPy_HEAD_SIZE(HEAD) (offsetof(_HPy_FullyAlignedSpaceFor##HEAD, payload)) - - -static inline HPy_ssize_t -_HPy_GetHeaderSize(HPyType_BuiltinShape shape) -{ - switch (shape) - { - case HPyType_BuiltinShape_Legacy: - return 0; - case HPyType_BuiltinShape_Object: - return _HPy_HEAD_SIZE(PyObject_HEAD); - case HPyType_BuiltinShape_Type: - return _HPy_HEAD_SIZE(PyHeapTypeObject); - case HPyType_BuiltinShape_Long: - return _HPy_HEAD_SIZE(PyLongObject); - case HPyType_BuiltinShape_Float: - return _HPy_HEAD_SIZE(PyFloatObject); - case HPyType_BuiltinShape_Unicode: - return _HPy_HEAD_SIZE(PyUnicodeObject); - case HPyType_BuiltinShape_Tuple: - return _HPy_HEAD_SIZE(PyTupleObject); - case HPyType_BuiltinShape_List: - return _HPy_HEAD_SIZE(PyListObject); - case HPyType_BuiltinShape_Dict: - return _HPy_HEAD_SIZE(PyDictObject); - } - return -1; -} - -#define _HPy_OFFSET(OBJ, OFFSET) ((void*) ((char*) (OBJ) + (OFFSET))) - -// Return a pointer to the area of memory AFTER the header -static inline void* _HPy_Payload(PyObject *obj, const HPyType_BuiltinShape shape) -{ - const HPy_ssize_t header_size = _HPy_GetHeaderSize(shape); - /* Here we may assume that the shape is valid because it is provided from a - trusted source. The shape is validated when creating the type from the - specification. */ - assert(header_size >= 0); - return _HPy_OFFSET(obj, header_size); -} - -static bool has_tp_traverse(HPyType_Spec *hpyspec); -static bool needs_hpytype_dealloc(HPyType_Spec *hpyspec); - -/* This is a hack: we need some extra space to store random data on the - type objects created by HPyType_FromSpec(). We allocate a structure - of type HPyType_Extra_t, which we never free for now. We can access - it because tp->tp_name points to the "name" field at the end... */ -typedef struct { - uint16_t magic; - HPyFunc_traverseproc tp_traverse_impl; - HPyFunc_destroyfunc tp_destroy_impl; - cpy_vectorcallfunc tp_vectorcall_default_trampoline; - HPyType_BuiltinShape shape; - char name[]; -} HPyType_Extra_t; - -static inline bool _is_HPyType(PyTypeObject *tp) { - return tp->tp_flags & HPy_TPFLAGS_INTERNAL_IS_HPY_TYPE; -} - -static inline HPyType_Extra_t *_HPyType_EXTRA(PyTypeObject *tp) { - assert(_is_HPyType(tp)); - HPyType_Extra_t *result = (HPyType_Extra_t *)(tp->tp_name - offsetof(HPyType_Extra_t, name)); - assert(result->magic == HPy_TYPE_MAGIC); - return result; -} - -static inline bool _is_pure_HPyType(PyTypeObject *tp) { - return _is_HPyType(tp) && _HPyType_EXTRA(tp)->shape != HPyType_BuiltinShape_Legacy; -} - -static inline HPyType_BuiltinShape _HPyType_Get_Shape(PyTypeObject *tp) { - return _is_HPyType(tp) ? _HPyType_EXTRA(tp)->shape : HPyType_BuiltinShape_Legacy; -} - -static inline cpy_vectorcallfunc _HPyType_get_vectorcall_default(PyTypeObject *tp) { - return _is_HPyType(tp) ? - _HPyType_EXTRA(tp)->tp_vectorcall_default_trampoline : NULL; -} - -static inline void _HPy_set_vectorcall_func(PyTypeObject *tp, PyObject *o, cpy_vectorcallfunc f) { - const Py_ssize_t offset = tp->tp_vectorcall_offset; - assert(offset > 0); - memcpy((char *) o + offset, &f, sizeof(f)); -} - -/* - * If type 'tp' supports the vectorcall protocol, then retrieve the default - * vectorcall function from the 'HPyType_Extra_t' struct and write it to the - * appropriate offset of 'o'. - */ -static inline void _HPy_vectorcall_init(PyTypeObject *tp, PyObject *o) { - if (PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { - cpy_vectorcallfunc vectorcall_default = _HPyType_get_vectorcall_default(tp); - _HPy_set_vectorcall_func(tp, o, vectorcall_default); - } -} - -static HPyType_Extra_t *_HPyType_Extra_Alloc(const char *name, HPyType_BuiltinShape shape) -{ - size_t name_size = strlen(name) + 1; - size_t size = offsetof(HPyType_Extra_t, name) + name_size; - HPyType_Extra_t *result = (HPyType_Extra_t*)PyMem_Calloc(1, size); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - memcpy(result->name, name, name_size); - result->shape = shape; - result->magic = HPy_TYPE_MAGIC; - /* XXX On Python 3.10 and older, the returned struct is never freed */ - return result; -} - -static inline void *_pyobj_as_struct(PyObject *obj) -{ - return _HPy_Payload(obj, _HPyType_Get_Shape(Py_TYPE(obj))); -} - -static int _decref_visitor(HPyField *pf, void *arg) -{ - PyObject *old_object = _hf2py(*pf); - *pf = HPyField_NULL; - Py_XDECREF(old_object); - return 0; -} - -static void hpytype_clear(PyObject *self) -{ - // call tp_traverse on all the HPy types of the hierarchy - PyTypeObject *tp = Py_TYPE(self); - PyTypeObject *base = tp; - while(base) { - if (_is_HPyType(base)) { - HPyType_Extra_t *extra = _HPyType_EXTRA(base); - assert(extra != NULL); - if (extra->tp_traverse_impl != NULL) { - extra->tp_traverse_impl(_pyobj_as_struct(self), _decref_visitor, NULL); - } - } - base = base->tp_base; - } -} - -/* this is a generic tp_dealloc which we use for all the user-defined HPy - types created by HPyType_FromSpec */ -static void hpytype_dealloc(PyObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - // Call finalizer if it exists - if (tp->tp_finalize) { - // Exit early if resurrected - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - return; - } - } - if (PyType_IS_GC(tp)) - PyObject_GC_UnTrack(self); - - // decref and clear all the HPyFields - hpytype_clear(self); - - // call tp_destroy on all the HPy types of the hierarchy - PyTypeObject *base = tp; - while(base) { - if (_is_HPyType(base)) { - HPyType_Extra_t *extra = _HPyType_EXTRA(base); - assert(extra != NULL); - if (extra->tp_destroy_impl != NULL) { - extra->tp_destroy_impl(_pyobj_as_struct(self)); - } - } - base = base->tp_base; - } - - // deallocate - tp->tp_free(self); - - // decref the type - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); - Py_DECREF(tp); -} - -/* - * A thin decorator around the type base's 'tp_new' function, that will - * initialize the vectorcall member (if appropriate). - */ -static PyObject * -hpyobject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyTypeObject *base = type->tp_base; - PyObject *result = base->tp_new(type, args, kwds); - if (result != NULL) - _HPy_vectorcall_init(type, result); - return result; -} - -static int -sig2flags(HPyFunc_Signature sig) -{ - switch(sig) { - case HPyFunc_VARARGS: return METH_FASTCALL; - case HPyFunc_KEYWORDS: return METH_FASTCALL | METH_KEYWORDS; - case HPyFunc_NOARGS: return METH_NOARGS; - case HPyFunc_O: return METH_O; - default: return -1; - } -} - -static inline bool -is_bf_slot(HPyDef *def) -{ - return def->kind == HPyDef_Kind_Slot && ( - def->slot.slot == HPy_bf_getbuffer || def->slot.slot == HPy_bf_releasebuffer); -} - -static inline bool -is_slot(HPyDef *def, HPySlot_Slot id) -{ - return def->kind == HPyDef_Kind_Slot && def->slot.slot == id; -} - -static inline bool -is_vectorcalloffset_member(const char *name) -{ - return name[0] == '_' && name[1] == '_' && - strcmp(name, "__vectorcalloffset__") == 0; -} - -static HPy_ssize_t -HPyDef_count(HPyDef *defs[], HPyDef_Kind kind) -{ - HPy_ssize_t res = 0; - if (defs == NULL) - return res; - for(int i=0; defs[i] != NULL; i++) - if (defs[i]->kind == kind - && !is_bf_slot(defs[i]) - && !is_slot(defs[i], HPy_tp_destroy) - && !is_slot(defs[i], HPy_tp_call)) - res++; - return res; -} - -static void -legacy_slots_count(PyType_Slot slots[], HPy_ssize_t *slot_count, - PyMethodDef **method_defs, PyMemberDef **member_defs, - PyGetSetDef **getset_defs) -{ - *slot_count = 0; - *method_defs = NULL; - *member_defs = NULL; - *getset_defs = NULL; - if (slots == NULL) - return; - for(int i=0; slots[i].slot != 0; i++) - switch(slots[i].slot) { - case Py_tp_methods: - *method_defs = (PyMethodDef *)slots[i].pfunc; - break; - case Py_tp_members: - *member_defs = (PyMemberDef *)slots[i].pfunc; - break; - case Py_tp_getset: - *getset_defs = (PyGetSetDef *)slots[i].pfunc; - break; - default: - (*slot_count)++; - break; - } -} - -static int -hpy_slot_to_cpy_slot(HPySlot_Slot src) -{ - switch (src) { - case HPy_tp_destroy: return Py_tp_dealloc; - default: return src; /* same numeric value by default */ - } -} - - -/* - * Create a PyMethodDef which contains: - * 1. All HPyMeth contained in hpyspec->defines - * 2. All the PyMethodDef contained inside legacy_methods - * - * Notes: - * - This function is also called from ctx_module.c. - * - This malloc()s a result which will never be freed. Too bad - */ -_HPy_HIDDEN PyMethodDef * -create_method_defs(HPyDef *hpydefs[], PyMethodDef *legacy_methods) -{ - HPy_ssize_t hpymeth_count = HPyDef_count(hpydefs, HPyDef_Kind_Meth); - // count the legacy methods - HPy_ssize_t legacy_count = 0; - if (legacy_methods != NULL) { - while (legacy_methods[legacy_count].ml_name != NULL) - legacy_count++; - } - HPy_ssize_t total_count = hpymeth_count + legacy_count; - - // allocate&fill the result - PyMethodDef *result = (PyMethodDef*)PyMem_Calloc(total_count+1, sizeof(PyMethodDef)); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - // copy the HPy methods - int dst_idx = 0; - if (hpydefs != NULL) { - for(int i=0; hpydefs[i] != NULL; i++) { - HPyDef *src = hpydefs[i]; - if (src->kind != HPyDef_Kind_Meth) - continue; - PyMethodDef *dst = &result[dst_idx++]; - dst->ml_name = src->meth.name; - dst->ml_meth = (PyCFunction)src->meth.cpy_trampoline; - dst->ml_flags = sig2flags(src->meth.signature); - if (dst->ml_flags == -1) { - PyMem_Free(result); - PyErr_SetString(PyExc_ValueError, - "Unsupported HPyMeth signature"); - return NULL; - } - dst->ml_doc = src->meth.doc; - } - } - // copy the legacy methods - for(int i=0; ioffset; - HPyField *field = (HPyField *)(((char *)self) + offset); - if (HPyField_IsNull(*field)) { - Py_INCREF(Py_None); - return Py_None; - } - PyObject *value = _hf2py(*field); - Py_INCREF(value); - return value; -} - -static PyObject *member_object_ex_get(PyObject *self, void *closure) -{ - HPyMember *member = (HPyMember *)closure; - HPy_ssize_t offset = member->offset; - HPyField *field = (HPyField *)(((char *)self) + offset); - if (HPyField_IsNull(*field)) { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%s'", - Py_TYPE(self)->tp_name, member->name); - return NULL; - } - PyObject *value = _hf2py(*field); - Py_INCREF(value); - return value; -} - -static int member_object_set(PyObject *self, PyObject *value, void *closure) -{ - HPyMember *member = (HPyMember *)closure; - HPy_ssize_t offset = member->offset; - HPyField *field = (HPyField *)(((char *)self) + offset); - PyObject *old_value = _hf2py(*field); - Py_XINCREF(value); - *field = _py2hf(value); - Py_XDECREF(old_value); - return 0; -} -#endif - -static PyMemberDef * -create_member_defs(HPyDef *hpydefs[], PyMemberDef *legacy_members, - HPy_ssize_t base_member_offset, PyGetSetDef **getsets, - size_t *vectorcalloffset, HPy_ssize_t basicsize) -{ - /* Will be set to true if '__vectorcalloffset__' was explicitly specified as - HPy or legacy member. */ - bool explicit_vectorcalloffset = false; - /* Will be true if HPy_tp_call was specified and we therefore have an - implicit vectorcall offset. */ - bool implicit_vectorcalloffset = *vectorcalloffset > 0; - HPy_ssize_t hpymember_count = HPyDef_count(hpydefs, HPyDef_Kind_Member); - - // count the legacy members - HPy_ssize_t legacy_count = 0; - if (legacy_members != NULL) { - while (legacy_members[legacy_count].name != NULL) - legacy_count++; - } - HPy_ssize_t total_count = hpymember_count + legacy_count; - - // account for member '__vectorcalloffset__' - if (implicit_vectorcalloffset) - total_count++; - - // Sanity check: the type cannot have members if 'basicsize == 0' - if (basicsize == 0 && total_count > 0) { - PyErr_SetString(PyExc_TypeError, - "Type claims to have basicsize==0 but defines members"); - return NULL; - } - - // allocate&fill the result - PyMemberDef *result = (PyMemberDef*)PyMem_Calloc(total_count+1, sizeof(PyMemberDef)); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - int dst_idx = 0; - - // add vectorcalloffset if 'HPy_tp_call' was specified - if (implicit_vectorcalloffset) { - PyMemberDef *dst = &result[dst_idx++]; - dst->name = "__vectorcalloffset__"; - dst->type = T_PYSSIZET; - dst->offset = *vectorcalloffset; - dst->flags = READONLY; - } - - // copy the HPy members - if (hpydefs != NULL) { - for(int i=0; hpydefs[i] != NULL; i++) { - HPyDef *src = hpydefs[i]; - if (src->kind != HPyDef_Kind_Member) - continue; -#ifndef HPY_ABI_CPYTHON - // for the universal mode, we need to do load the HPyField that is - // stored in the object properly. In CPython ABI mode, these can be - // safely read as PyObject* directly without the overhead of getset. - if (src->member.type == HPyMember_OBJECT || src->member.type == HPyMember_OBJECT_EX) { - int getsetcnt = 0; - while ((*getsets)[getsetcnt].name) { - getsetcnt++; - } - *getsets = (PyGetSetDef*)PyMem_Realloc(*getsets, (getsetcnt + 2) * sizeof(PyGetSetDef)); - if (!*getsets) { - return NULL; - } - PyGetSetDef *dst = &(*getsets)[getsetcnt++]; - dst->name = src->member.name; - if (src->member.type == HPyMember_OBJECT_EX) { - dst->get = member_object_ex_get; - } else { - dst->get = member_object_get; - } - if (!src->member.readonly) { - dst->set = member_object_set; - } else { - dst->set = NULL; - } - dst->doc = src->member.doc; - src->member.offset = src->member.offset + base_member_offset; - dst->closure = (void *)&src->member; - (*getsets)[getsetcnt] = (PyGetSetDef){NULL}; - total_count--; - continue; - } -#endif - PyMemberDef *dst = &result[dst_idx++]; - dst->name = src->member.name; - dst->type = src->member.type; - dst->offset = src->member.offset + base_member_offset; - dst->doc = src->member.doc; - if (src->member.readonly) - dst->flags = READONLY; - else - dst->flags = 0; // read-write - // test if this HPy member was '__vectorcalloffset__' - if (is_vectorcalloffset_member(src->member.name)) { - explicit_vectorcalloffset = true; - *vectorcalloffset = dst->offset; - } - } - } - // copy the legacy members - for(int i=0; i 0); - *vectorcalloffset = legacy_members[i].offset; - } - } - - /* Enforce constraint that we cannot have slot 'HPy_tp_call' and an explicit - member '__vectorcalloffset__'. */ - if (implicit_vectorcalloffset && explicit_vectorcalloffset) { - PyErr_SetString(PyExc_TypeError, - "Cannot have HPy_tp_call and explicit member" - "'__vectorcalloffset__'. Specify just one of them."); - return NULL; - } - - result[dst_idx++] = (PyMemberDef){NULL}; - if (dst_idx != total_count + 1) - Py_FatalError("bogus count in create_member_defs"); - return result; -} - -static PyGetSetDef * -create_getset_defs(HPyDef *hpydefs[], PyGetSetDef *legacy_getsets) -{ - HPy_ssize_t hpygetset_count = HPyDef_count(hpydefs, HPyDef_Kind_GetSet); - // count the legacy members - HPy_ssize_t legacy_count = 0; - if (legacy_getsets != NULL) { - while (legacy_getsets[legacy_count].name != NULL) - legacy_count++; - } - HPy_ssize_t total_count = hpygetset_count + legacy_count; - - // allocate&fill the result - PyGetSetDef *result = (PyGetSetDef*)PyMem_Calloc(total_count+1, sizeof(PyGetSetDef)); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - // copy the HPy members - int dst_idx = 0; - if (hpydefs != NULL) { - for(int i=0; hpydefs[i] != NULL; i++) { - HPyDef *src = hpydefs[i]; - if (src->kind != HPyDef_Kind_GetSet) - continue; - PyGetSetDef *dst = &result[dst_idx++]; - dst->name = src->getset.name; - dst->get = src->getset.getter_cpy_trampoline; - dst->set = src->getset.setter_cpy_trampoline; - dst->doc = src->getset.doc; - dst->closure = src->getset.closure; - } - } - // copy the legacy members - for(int i=0; idefines, HPyDef_Kind_Slot); - // add the legacy slots - HPy_ssize_t legacy_slot_count = 0; - PyMethodDef *legacy_method_defs = NULL; - PyMemberDef *legacy_member_defs = NULL; - PyGetSetDef *legacy_getset_defs = NULL; - legacy_slots_count((PyType_Slot*)hpyspec->legacy_slots, &legacy_slot_count, - &legacy_method_defs, &legacy_member_defs, - &legacy_getset_defs); - bool needs_dealloc = needs_hpytype_dealloc(hpyspec); - size_t vectorcalloffset = 0; - bool has_tp_new = false; -#define ADDITIONAL_SLOTS 3 - /* This accounts for the sentinel and maybe additional slots that HPy - installs automatically for some reason. For example, in case of the - vectorcall protocol is used, we will additionally install 'tp_call' if - the user did not provide it. */ - HPy_ssize_t additional_slots = 1; - - if (hpyspec->doc != NULL) - hpyslot_count++; // Py_tp_doc - hpyslot_count++; // Py_tp_methods - hpyslot_count++; // Py_tp_members - hpyslot_count++; // Py_tp_getset - if (needs_dealloc) - hpyslot_count++; // Py_tp_dealloc - if (has_tp_traverse(hpyspec)) - hpyslot_count++; // Py_tp_clear - - // allocate the result PyType_Slot array - HPy_ssize_t total_slot_count = hpyslot_count + legacy_slot_count; - PyType_Slot *result = (PyType_Slot*)PyMem_Calloc( - total_slot_count+ADDITIONAL_SLOTS, sizeof(PyType_Slot)); - if (result == NULL) { - PyErr_NoMemory(); - return NULL; - } - - // fill the result with non-meth, non-member, non-getset slots - int dst_idx = 0; - if (hpyspec->defines != NULL) { - for (int i = 0; hpyspec->defines[i] != NULL; i++) { - HPyDef *src = hpyspec->defines[i]; - if (src->kind != HPyDef_Kind_Slot || is_bf_slot(src)) - continue; - if (is_slot(src, HPy_tp_destroy)) { - extra->tp_destroy_impl = (HPyFunc_destroyfunc)src->slot.impl; - continue; /* we don't have a trampoline for tp_destroy */ - } - if (is_slot(src, HPy_tp_call)) { - /* Slot 'HPy_tp_call' will add a hidden field to - the type's struct. The field can only be appended which - conflicts with var objects. So, we don't allow this if - itemsize != 0. */ - if (hpyspec->itemsize) { - PyMem_Free(result); - PyErr_SetString(PyExc_TypeError, - "Cannot use HPy call protocol with var objects"); - return NULL; - } - // we only need to remember the CPython trampoline - extra->tp_vectorcall_default_trampoline = - (cpy_vectorcallfunc)src->slot.cpy_trampoline; - /* Adding the hidden field means we increase the CPython type - spec's basic by 'sizeof(vectorcallfunc)'. In case that HPy - type spec's basic size was 0, we now need to adjust the - base_member_offset since that will no longer be inherited - automatically. */ - vectorcalloffset = _HPy_ALIGN(*basicsize == 0 ? head_size : *basicsize); - if (vectorcalloffset > 0) { - *basicsize = vectorcalloffset + sizeof(cpy_vectorcallfunc); - } else { - /* We cannot safely add the hidden field in case of a legacy - type that inherits the basicsize since we don't know it. - In this case, we reject to use HPy_tp_call but since it - is a legacy type, legacy slot Py_tp_call can be used. */ - assert(hpyspec->builtin_shape == HPyType_BuiltinShape_Legacy); - assert(hpyspec->basicsize == 0); - PyMem_Free(result); - PyErr_SetString(PyExc_TypeError, - "Cannot use HPy call protocol with legacy types that" - " inherit the struct. Either set the basicsize to a" - "non-zero value or use legacy slot 'Py_tp_call'."); - return NULL; - } - /* Although there is a corresponding C API slot, we actually - implement HPy_tp_call using CPython's vectorcall protocol. */ - continue; - } - if (is_slot(src, HPy_tp_new)) { - has_tp_new = true; - } else if (is_slot(src, HPy_tp_traverse)) { - extra->tp_traverse_impl = (HPyFunc_traverseproc)src->slot.impl; - /* no 'continue' here: we have a trampoline too */ - } - PyType_Slot *dst = &result[dst_idx++]; - dst->slot = hpy_slot_to_cpy_slot(src->slot.slot); - dst->pfunc = (void*)src->slot.cpy_trampoline; - } - } - - /* Since the basicsize may be modified depending on special HPy slots, we - defer determination of the base_member_offset to this point. */ - base_member_offset = (*basicsize != 0) ? head_size : 0; - - // add a slot for the doc string if present - if (hpyspec->doc != NULL) { - result[dst_idx++] = (PyType_Slot){Py_tp_doc, (void *) hpyspec->doc}; - } - - // add the legacy slots (non-methods, non-members, non-getsets) - if (hpyspec->legacy_slots != NULL) { - PyType_Slot *legacy_slots = (PyType_Slot *)hpyspec->legacy_slots; - for (int i = 0; legacy_slots[i].slot != 0; i++) { - PyType_Slot *src = &legacy_slots[i]; - if (src->slot == Py_tp_methods || src->slot == Py_tp_members || - src->slot == Py_tp_getset) - continue; - PyType_Slot *dst = &result[dst_idx++]; - *dst = *src; - } - } - - // add the "real" methods - PyMethodDef *pymethods = create_method_defs(hpyspec->defines, legacy_method_defs); - if (pymethods == NULL) { - PyMem_Free(result); - return NULL; - } - result[dst_idx++] = (PyType_Slot){Py_tp_methods, pymethods}; - - // prepare the "real" getsets - PyGetSetDef *pygetsets = create_getset_defs(hpyspec->defines, legacy_getset_defs); - if (pygetsets == NULL) { - PyMem_Free(pymethods); - PyMem_Free(result); - return NULL; - } - - // prepare the "real" members, which may introduce getsetdefs in universal mode - PyMemberDef *pymembers = create_member_defs(hpyspec->defines, legacy_member_defs, base_member_offset, &pygetsets, &vectorcalloffset, *basicsize); - if (pymembers == NULL) { - PyMem_Free(pygetsets); - PyMem_Free(pymethods); - PyMem_Free(result); - return NULL; - } - - // if we have seen HPy_tp_call or an explicit member '__vectorcalloffset__' - if (vectorcalloffset > 0) { - /* Since there is no way to set Py_tp_call directly from HPy, we also - always need to specify it if HPy_tp_call is there or a - '__vectorcalloffset__' was specified. */ - additional_slots++; - PyType_Slot *dst = &result[dst_idx++]; - dst->slot = Py_tp_call; - dst->pfunc = (void*)PyVectorcall_Call; - - /* If the user did not provide the new function, we need to install a - special new function that will delegate to the inherited tp_new but - additionally sets the default call function. This is not necessary if - the user provides the new function because he will use 'HPy_New' to - allocate the object which already takes care of that. */ - if (!has_tp_new) { - additional_slots++; - PyType_Slot *dst = &result[dst_idx++]; - dst->slot = Py_tp_new; - dst->pfunc = (void*)hpyobject_new; - } - - *flags |= _Py_TPFLAGS_HAVE_VECTORCALL; - } - - // add both members and getsets - result[dst_idx++] = (PyType_Slot){Py_tp_members, pymembers}; - result[dst_idx++] = (PyType_Slot){Py_tp_getset, pygetsets}; - - // add a dealloc function, if needed - if (needs_dealloc) { - result[dst_idx++] = (PyType_Slot){Py_tp_dealloc, (void*)hpytype_dealloc}; - } - - // add a tp_clear, if the user provided a tp_traverse - if (has_tp_traverse(hpyspec)) { - result[dst_idx++] = (PyType_Slot){Py_tp_clear, (void*)hpytype_clear}; - } - - // add the NULL sentinel at the end - result[dst_idx++] = (PyType_Slot){0, NULL}; - if (dst_idx != total_slot_count + additional_slots) - Py_FatalError("bogus slot count in create_slot_defs"); - return result; -} - -/* Python 3.8 and older is the missing Py_bf_getbuffer and Py_bf_releasebuffer - so we need to define those functions here. Since Python 3.9, we can just use - the function pointer types from Python. */ -#if PY_VERSION_HEX < 0x03009000 -typedef int (*cpy_getbufferproc)(cpy_PyObject *, cpy_Py_buffer *, int); -typedef void (*cpy_releasebufferproc)(cpy_PyObject *, cpy_Py_buffer *); -#else -typedef getbufferproc cpy_getbufferproc; -typedef releasebufferproc cpy_releasebufferproc; -#endif -static PyBufferProcs* -create_buffer_procs(HPyType_Spec *hpyspec) -{ - PyBufferProcs *buffer_procs = NULL; - if (hpyspec->defines != NULL) { - for (int i = 0; hpyspec->defines[i] != NULL; i++) { - HPyDef *src = hpyspec->defines[i]; - if (src->kind != HPyDef_Kind_Slot) - continue; - switch (src->slot.slot) { - case HPy_bf_getbuffer: - if (buffer_procs == NULL) { - buffer_procs = (PyBufferProcs*)PyMem_Calloc(1, sizeof(PyBufferProcs)); - if (buffer_procs == NULL) { - PyErr_NoMemory(); - return NULL; - } - } - buffer_procs->bf_getbuffer = (cpy_getbufferproc)src->slot.cpy_trampoline; - break; - case HPy_bf_releasebuffer: - if (buffer_procs == NULL) { - buffer_procs = (PyBufferProcs*)PyMem_Calloc(1, sizeof(PyBufferProcs)); - if (buffer_procs == NULL) { - PyErr_NoMemory(); - return NULL; - } - } - buffer_procs->bf_releasebuffer = (cpy_releasebufferproc)src->slot.cpy_trampoline; - break; - default: - break; - } - } - } - return buffer_procs; -} - -static int check_unknown_params(HPyType_SpecParam *params, const char *name) -{ - if (params == NULL) - return 0; - - int found_base = 0, found_basestuple = 0; - for (HPyType_SpecParam *p = params; p->kind != 0; p++) { - switch (p->kind) { - case HPyType_SpecParam_Base: - found_base++; - break; - case HPyType_SpecParam_BasesTuple: - found_basestuple++; - break; - case HPyType_SpecParam_Metaclass: - break; - - default: - PyErr_Format(PyExc_TypeError, - "unknown HPyType_SpecParam specification for '%s'", - name); - return -1; - } - } - if (found_basestuple > 1) { - PyErr_SetString(PyExc_TypeError, - "multiple specifications of HPyType_SpecParam_BasesTuple"); - return -1; - } - if (found_base && found_basestuple) { - PyErr_SetString(PyExc_TypeError, - "cannot specify both HPyType_SpecParam_Base and " - "HPytype_SpecParam_BasesTuple"); - return -1; - } - return 0; -} - -static int check_legacy_consistent(HPyType_Spec *hpyspec) -{ - if (hpyspec->legacy_slots && hpyspec->builtin_shape != HPyType_BuiltinShape_Legacy) { - PyErr_SetString(PyExc_TypeError, - "cannot specify .legacy_slots without setting .builtin_shape=HPyType_BuiltinShape_Legacy"); - return -1; - } - if (hpyspec->legacy_slots && needs_hpytype_dealloc(hpyspec)) { - PyType_Slot *legacy_slots = (PyType_Slot *)hpyspec->legacy_slots; - for (int i = 0; legacy_slots[i].slot != 0; i++) { - if (legacy_slots[i].slot == Py_tp_dealloc) { - PyErr_SetString(PyExc_TypeError, - "legacy tp_dealloc is incompatible with HPy_tp_traverse" - " or HPy_tp_destroy."); - return -1; - } - } - } - return 0; -} - -static bool has_tp_traverse(HPyType_Spec *hpyspec) -{ - if (hpyspec->defines != NULL) - for (int i = 0; hpyspec->defines[i] != NULL; i++) { - HPyDef *def = hpyspec->defines[i]; - if (def->kind == HPyDef_Kind_Slot && def->slot.slot == HPy_tp_traverse) - return true; - } - return false; -} - -static bool needs_hpytype_dealloc(HPyType_Spec *hpyspec) -{ - if (hpyspec->defines != NULL) - for (int i = 0; hpyspec->defines[i] != NULL; i++) { - HPyDef *def = hpyspec->defines[i]; - if (def->kind == HPyDef_Kind_Slot && - (def->slot.slot == HPy_tp_destroy || def->slot.slot == HPy_tp_traverse)) - return true; - } - return false; -} - -static int check_have_gc_and_tp_traverse(HPyContext *ctx, HPyType_Spec *hpyspec) -{ - // if we specify HPy_TPFLAGS_HAVE_GC, we must provide a tp_traverse - if (hpyspec->flags & HPy_TPFLAGS_HAVE_GC && !has_tp_traverse(hpyspec)) { - HPyErr_SetString(ctx, ctx->h_ValueError, - "You must provide an HPy_tp_traverse slot if you specify " - "HPy_TPFLAGS_HAVE_GC"); - return -1; - } - return 0; -} - -static int check_inheritance_constraints(PyTypeObject *tp) -{ - int tp_pure = _is_pure_HPyType(tp); - int tp_base_pure = _is_pure_HPyType(tp->tp_base); - if (tp_pure) { - // Pure types may inherit from: - // - // * pure types, or - // * PyBaseObject_Type, or - // * other builtin or legacy types as long as long as they do not - // access the struct layout (e.g. by using HPy_AsStruct or defining - // a deallocator with HPy_tp_destroy). - // - // It would be nice to relax these restrictions or check them here. - // See https://github.com/hpyproject/hpy/issues/169 for details. - } - else { - if (tp_base_pure) { - PyErr_SetString(PyExc_TypeError, - "A legacy type should not inherit its memory layout from a" - " pure type"); - return -1; - } - } - return 0; -} - -static PyObject *build_bases_from_params(HPyType_SpecParam *params) -{ - if (params == NULL) - return NULL; - - PyObject *tup; - int found_base = 0; - for (HPyType_SpecParam *p = params; p->kind != 0; p++) { - switch (p->kind) { - case HPyType_SpecParam_Base: - /* count the base entries (multiple entries are fine) */ - found_base++; - break; - case HPyType_SpecParam_BasesTuple: - /* if there is instead a complete base tuple, just return it */ - /* we increment the reference count of the tuple here to match - the reference counting on the tuple we create below when - there is no HPyType_SpecParam_BasesTuple */ - tup = _h2py(p->object); - Py_INCREF(tup); - return tup; - case HPyType_SpecParam_Metaclass: - // intentionally ignored - break; - } - } - if (found_base == 0) - return NULL; - - tup = PyTuple_New(found_base); - if (tup == NULL) - return NULL; - - found_base = 0; - for (HPyType_SpecParam *p = params; p->kind != 0; p++) { - if (p->kind == HPyType_SpecParam_Base) { - PyObject *base = _h2py(p->object); - Py_INCREF(base); - PyTuple_SET_ITEM(tup, found_base, base); - found_base++; - } - } - return tup; -} - -_HPy_HIDDEN struct _typeobject *get_metatype(HPyType_SpecParam *params) { - struct _typeobject *res = NULL; - if (params != NULL) { - for (HPyType_SpecParam *p = params; p->kind != 0; p++) { - switch (p->kind) { - case HPyType_SpecParam_Metaclass: - if (res) { - PyErr_SetString(PyExc_ValueError, "metaclass was specified multiple times"); - return NULL; - } - res = (struct _typeobject*) _h2py(p->object); - if (!PyType_Check(res)) { - PyErr_Format(PyExc_TypeError, - "Metaclass '%R' is not a subclass of 'type'.", - res); - return NULL; - } - break; - default: - // other values are intentionally ignored - break; - } - } - } - /* Returning NULL here does not indicate an error but that the metaclass - has not explicitly been specified. We could default here to &PyType_Type - but we actually want to use the bare 'PyType_FromSpecWithBases' if - nothing was specified. */ - return res; -} - -#define HAVE_FROM_METACLASS (PY_VERSION_HEX >= 0x030C0000) - -#if !HAVE_FROM_METACLASS - -static inline Py_ssize_t count_members(PyType_Spec *spec, Py_ssize_t *vectorcalloffset) { - Py_ssize_t nmembers = 0; -#if PROVISIONAL_VECTORCALL_SUPPORT - *vectorcalloffset = 0; -#endif /* Python 3.8.x */ - const PyType_Slot *slot; - for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_members) { - nmembers = 0; - for (const PyMemberDef *memb = (const PyMemberDef *)slot->pfunc; memb->name != NULL; memb++) { - nmembers++; -#if PROVISIONAL_VECTORCALL_SUPPORT - /* Python 3.8 already supports vectorcalls but does not - consider the '__vectorcalloffset__' member. So we need to do - it manually. */ - if (strcmp(memb->name, "__vectorcalloffset__") == 0) { - // The PyMemberDef must be a Py_ssize_t and readonly - assert(memb->type == T_PYSSIZET); - assert(memb->flags == READONLY); - *vectorcalloffset = memb->offset; - } -#endif /* Python 3.8.x */ - } - } - } - return nmembers; -} - -/* On older Python versions (before 3.12), we need to workaround the missing - support for metaclasses. We create a temporary heap type using - 'PyType_FromSpecWithBases' and if a metaclass was provided, we use it to - allocate the appropriate type object and memcpy most of the contents from - the heap type to the manually allocated one. Then we clear some key slots - and call 'PyType_Ready' on it to re-initialize everything. The temporary - heap type is then expired. */ -static PyObject* -_PyType_FromMetaclass(PyType_Spec *spec, PyObject *bases, - struct _typeobject *meta) -{ - PyObject *temp, *result; - PyHeapTypeObject *temp_ht, *ht; - PyTypeObject *temp_tp, *tp; - Py_ssize_t nmembers, vectorcalloffset; - const char *s; - -#if PROVISIONAL_VECTORCALL_SUPPORT - /* Python 3.8 does not support specifying the vectorcall offset via the - type spec. Therefore, if the flag is set, 'PyType_Ready' will fail an - assert later on. So, we clear the flag and set the flags manually after - 'PyType_Ready' when 'tp_vectorcall_offset' is also set. */ - unsigned int restore_vectorcall_flag = spec->flags & _Py_TPFLAGS_HAVE_VECTORCALL; - spec->flags &= ~_Py_TPFLAGS_HAVE_VECTORCALL; -#endif /* Python 3.8.x */ - - temp = PyType_FromSpecWithBases(spec, bases); - if (!temp) - return NULL; - - /* If no metaclass was provided, we avoid this path since it is rather - expensive and slow. */ - if (meta) { - result = NULL; - /* We previously tested at this point if 'meta' is a type. That check - was moved to function 'get_metatype'. */ - if (meta->tp_new != PyType_Type.tp_new) { - PyErr_SetString(PyExc_TypeError, - "Metaclasses with custom tp_new are not supported."); - goto fail; - } - temp_ht = (PyHeapTypeObject *) temp; - temp_tp = &temp_ht->ht_type; - - Py_INCREF(temp_ht->ht_name); - Py_INCREF(temp_ht->ht_qualname); - Py_XINCREF(temp_ht->ht_slots); - Py_INCREF(temp_tp->tp_base); - - /* Count the members as 'PyType_FromSpecWithBases' does such that we - can properly allocate the size later when allocating the type. */ - nmembers = count_members(spec, &vectorcalloffset); - - result = meta->tp_alloc(meta, nmembers); - if (!result) - goto fail; - - ht = (PyHeapTypeObject *) result; - tp = &ht->ht_type; - - /* IMPORTANT: CPython debug builds may store additional information in - the object header (i.e. before 'ob_refcnt') for tracing references - or whatever. In this case, we MUST NOT copy the object header. So we - don't copy the whole embedded 'PyVarObject' chunk at the beginning - of the 'PyHeapTypeObject'. The appropriate 'PyVarObject' fields are - set explicitly right below. */ - memcpy(_HPy_OFFSET(tp, sizeof(PyVarObject)), - _HPy_OFFSET(temp_tp, sizeof(PyVarObject)), - sizeof(PyHeapTypeObject) - sizeof(PyVarObject)); - - tp->ob_base.ob_base.ob_type = meta; - tp->ob_base.ob_base.ob_refcnt = 1; - tp->ob_base.ob_size = 0; - tp->tp_as_async = &ht->as_async; - tp->tp_as_number = &ht->as_number; - tp->tp_as_sequence = &ht->as_sequence; - tp->tp_as_mapping = &ht->as_mapping; - tp->tp_as_buffer = &ht->as_buffer; - tp->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; - - tp->tp_dict = NULL; - tp->tp_bases = NULL; - tp->tp_mro = NULL; - tp->tp_cache = NULL; - tp->tp_subclasses = NULL; - tp->tp_weaklist = NULL; - ht->ht_cached_keys = NULL; - tp->tp_version_tag = 0; - - /* Refresh 'tp_doc'. This is necessary because - 'PyType_FromSpecWithBases' allocates its own buffer which will be - free'd. */ - if (temp_tp->tp_doc) { - size_t len = strlen(temp_tp->tp_doc)+1; - char *tp_doc = (char *)PyObject_MALLOC(len); - if (!tp_doc) - goto fail; - memcpy(tp_doc, temp_tp->tp_doc, len); - tp->tp_doc = tp_doc; - } - - /* Sanity check: GC objects need to provide 'tp_traverse' and - 'tp_clear'. */ - assert(!PyType_IS_GC(tp) || tp->tp_traverse != NULL || tp->tp_clear != NULL); - - if (PyType_Ready(tp) < 0) - goto fail; - - /* Restore 'ht_cached_keys' after call to 'PyType_Ready' */ - if (temp_ht->ht_cached_keys) { - Py_INCREF(temp_ht->ht_cached_keys); - ht->ht_cached_keys = temp_ht->ht_cached_keys; - } - - /* The following is the tail of 'PyType_FromSpecWithBases'. */ - - /* Set type.__module__ */ - s = strrchr(spec->name, '.'); - if (s != NULL) { - int err; - PyObject *modname = PyUnicode_FromStringAndSize( - spec->name, (Py_ssize_t)(s - spec->name)); - if (!modname) { - goto fail; - } - err = PyDict_SetItemString(tp->tp_dict, "__module__", modname); - Py_DECREF(modname); - if (err != 0) - goto fail; - } - return result; -fail: - Py_DECREF(temp); - Py_XDECREF(result); - return NULL; -#if PROVISIONAL_VECTORCALL_SUPPORT - } else { - tp = (PyTypeObject *) temp; - nmembers = count_members(spec, &vectorcalloffset); - } - - if (vectorcalloffset) { - tp->tp_vectorcall_offset = vectorcalloffset; - } - - if (restore_vectorcall_flag) { - tp->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; - _PyObject_ASSERT((PyObject *)tp, tp->tp_vectorcall_offset > 0); - _PyObject_ASSERT((PyObject *)tp, tp->tp_call != NULL); -#endif /* Python 3.8.x */ - } - return temp; -} - -#endif /* HAVE_FROM_METACLASS */ - -HPy -ctx_Type_FromSpec(HPyContext *ctx, HPyType_Spec *hpyspec, - HPyType_SpecParam *params) -{ - if (check_unknown_params(params, hpyspec->name) < 0) { - return HPy_NULL; - } - if (check_legacy_consistent(hpyspec) < 0) { - return HPy_NULL; - } - if (check_have_gc_and_tp_traverse(ctx, hpyspec) < 0) { - return HPy_NULL; - } - - PyType_Spec *spec = (PyType_Spec*)PyMem_Calloc(1, sizeof(PyType_Spec)); - if (spec == NULL) { - PyErr_NoMemory(); - return HPy_NULL; - } - /* Create local copies of 'basicsize' and 'flags' because they might be - modified and we must not write into 'hpyspec' since it is not owned by - this function and it could be read-only memory. */ - HPy_ssize_t basicsize; - unsigned long flags = hpyspec->flags; - - HPy_ssize_t head_size = _HPy_GetHeaderSize(hpyspec->builtin_shape); - if (head_size < 0) { - // an invalid shape was specified - PyErr_Format(PyExc_ValueError, "invalid shape: %d", hpyspec->builtin_shape); - return HPy_NULL; - } - - /* _HPy_HEAD_SIZE(base) ensures that the custom struct is correctly - aligned. */ - if (hpyspec->basicsize != 0) { - basicsize = hpyspec->basicsize + head_size; - } - else { - /* If basicsize is 0, it is inherited from the parent type. In this - case, calling *_AsStruct on an inherited type only makes sense if - the parent type is already an HPy extension type. */ - basicsize = 0; - } - - HPyType_Extra_t *extra = _HPyType_Extra_Alloc(hpyspec->name, hpyspec->builtin_shape); - if (extra == NULL) { - PyMem_Free(spec); - return HPy_NULL; - } - spec->name = extra->name; - spec->itemsize = hpyspec->itemsize; - spec->slots = create_slot_defs(hpyspec, extra, head_size, &basicsize, &flags); - if (spec->slots == NULL) { - PyMem_Free(spec); - return HPy_NULL; - } - /* If the vectorcall protocol should be used, set the corresponding - CPython type flag. */ - assert(extra->tp_vectorcall_default_trampoline == NULL || - (flags & _Py_TPFLAGS_HAVE_VECTORCALL)); - spec->flags = flags | HPy_TPFLAGS_INTERNAL_IS_HPY_TYPE; - spec->basicsize = (int)basicsize; - - PyObject *bases = build_bases_from_params(params); - if (PyErr_Occurred()) { - PyMem_Free(spec->slots); - PyMem_Free(spec); - return HPy_NULL; - } - struct _typeobject *metatype = get_metatype(params); - if (metatype == NULL && PyErr_Occurred()) { - PyMem_Free(spec->slots); - PyMem_Free(spec); - return HPy_NULL; - } - -#if HAVE_FROM_METACLASS - /* On Python 3.12 an newer, we can just use 'PyType_FromMetaclass'. */ - PyObject *result = PyType_FromMetaclass(metatype, NULL, spec, bases); -#else - /* On Python 3.11 an older, we need to use our own - '_PyType_FromMetaclass'. */ - PyObject *result = _PyType_FromMetaclass(spec, bases, metatype); -#endif - - /* note that we do NOT free the memory which was allocated by - create_method_defs, because that one is referenced internally by - CPython (which probably assumes it's statically allocated) */ - Py_XDECREF(bases); - PyMem_Free(spec->slots); - PyMem_Free(spec); - if (result == NULL) { - return HPy_NULL; - } - -#if PY_VERSION_HEX >= 0x030B0000 - /* Since Python 3.11, the name will be copied into a fresh buffer such that - the type objects owns this buffer. Hence we need to patch the pointer - again. The nice thing is that Python will then free out HPyType_Extra - for us. The internal field '_ht_tpname' is only used for freeing. So, we - can set it to 'extra'. */ - PyHeapTypeObject *ht = (PyHeapTypeObject *) result; - PyMem_Free(ht->_ht_tpname); - ht->_ht_tpname = (char *) extra; - ht->ht_type.tp_name = (const char *)extra->name; -#endif - - PyBufferProcs* buffer_procs = create_buffer_procs(hpyspec); - if (buffer_procs) { - ((PyTypeObject*)result)->tp_as_buffer = buffer_procs; - } else { - if (PyErr_Occurred()) { - Py_DECREF(result); - return HPy_NULL; - } - } - if (check_inheritance_constraints((PyTypeObject *) result) < 0) { - Py_DECREF(result); - return HPy_NULL; - } - assert(_is_HPyType((PyTypeObject*) result)); - return _py2h(result); -} - -_HPy_HIDDEN HPy -ctx_New(HPyContext *ctx, HPy h_type, void **data) -{ - PyTypeObject *tp = (PyTypeObject*) _h2py(h_type); - assert(tp != NULL); - if (!PyType_Check(tp)) { - PyErr_SetString(PyExc_TypeError, "HPy_New arg 1 must be a type"); - return HPy_NULL; - } - - PyObject *result; - if (PyType_IS_GC(tp)) - result = PyObject_GC_New(PyObject, tp); - else - result = PyObject_New(PyObject, tp); - - // HPy_New guarantees that the memory is zeroed, but PyObject_{GC}_New - // doesn't. But we need to make sure to NOT overwrite ob_refcnt and - // ob_type. See test_HPy_New_initialize_to_zero - const HPyType_BuiltinShape shape = _HPyType_Get_Shape(tp); - HPy_ssize_t payload_size; - void *payload; - if (shape != HPyType_BuiltinShape_Legacy) { - payload_size = tp->tp_basicsize - _HPy_GetHeaderSize(shape); - /* For pure HPy custom types, we return a pointer to only the custom - struct data, without the hidden PyObject header. */ - payload = _HPy_Payload(result, shape); - memset(payload, 0, payload_size); - } else { - /* In case of a legacy type, we still MUST NOT overwrite the object - header otherwise we would clear `ob_type` and `ob_refcnt`. */ - payload_size = tp->tp_basicsize - _HPy_HEAD_SIZE(PyObject_HEAD); - memset(_HPy_Payload(result, HPyType_BuiltinShape_Object), 0, payload_size); - payload = (void *) result; - } - - _HPy_vectorcall_init(tp, result); - - // NOTE: The CPython docs explicitly ask to call GC_Track when all fields - // are initialized, so it's important to do so AFTER zeroing the memory. - if (PyType_IS_GC(tp)) - PyObject_GC_Track(result); - - if (!result) - return HPy_NULL; - - *data = payload; - - return _py2h(result); -} - -_HPy_HIDDEN HPy -ctx_Type_GenericNew(HPyContext *ctx, HPy h_type, const HPy *args, - HPy_ssize_t nargs, HPy kw) -{ - PyObject *tp = _h2py(h_type); - assert(tp != NULL); - if (!PyType_Check(tp)) { - PyErr_SetString(PyExc_TypeError, "HPy_Type_GenericNew arg 1 must be a type"); - return HPy_NULL; - } - - PyObject *res = ((PyTypeObject*) tp)->tp_alloc((PyTypeObject*) tp, 0); - return _py2h(res); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Object(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Object); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Legacy(HPyContext *ctx, HPy h) -{ - return _h2py(h); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Type(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Type); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Long(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Long); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Float(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Float); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Unicode(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Unicode); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Tuple(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Tuple); -} - -_HPy_HIDDEN void* -ctx_AsStruct_List(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_List); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Dict(HPyContext *ctx, HPy h) -{ - return _HPy_Payload(_h2py(h), HPyType_BuiltinShape_Dict); -} - -_HPy_HIDDEN void* -ctx_AsStruct_Slow(HPyContext *ctx, HPy h) -{ - return _pyobj_as_struct(_h2py(h)); -} - - -/* ~~~ call_traverseproc_from_trampoline ~~~ - This is used to implement tp_traverse. - - From the HPy user point of view, the visitor function passed to tp_traverse - takes a ctx and an HPyField*: - - typedef int (*HPyFunc_visitproc)(HPyContext *, HPyField *, void *); - ... - static int my_traverse_impl(HPyContext *ctx, HPy self, - HPyFunc_visitproc hpy_visit, void *arg) - { - MyCustomObject *obj = ...; - hpy_visit(&obj->a, arg); // obj->a is an HPyField - hpy_visit(&obj->b, arg); - ... - } - - However, from the CPython point of view the visitor function passed to - tp_traverse takes a PyObject*: - - typedef int (*visitproc)(cpy_PyObject *, void *); - static int my_traverse(MyCustomObject *self, visitproc cpy_visit, void *arg) - { - cpy_visit(self->a, arg); // self->a is a PyObject* - cpy_visit(self->b, arg); - ... - } - - This is what happens: - - 1. CPython calls the trampoline created by _HPyFunc_TRAMPOLINE_TRAVERSEPROC - passing a visitor function. Let's call it cpy_visit, and remember that - it takes a PyObject*. - - 2. The trampoline invokes _HPy_CallRealFunctionFromTrampoline, which - ultimately calls call_traverseproc_from_trampoline. - - 3. call_traverseproc_from_trampoline invokes the tp_traverse_impl written - by the HPy user, passing hpy2cpy_visit as the visitor function. - - 4. tp_traverse_impl calls hpy2cpy_visit multiple times, once for every HPyField - - 5. hpy2cpy_visit takes an HPyField*, converts it to a PyObject* and invokes - the cpy_visit of point (1) -*/ - -typedef struct { - cpy_visitproc cpy_visit; - void *cpy_arg; -} hpy2cpy_visit_args_t; - -static int hpy2cpy_visit(HPyField *f, void *v_args) -{ - hpy2cpy_visit_args_t *args = (hpy2cpy_visit_args_t *)v_args; - cpy_visitproc cpy_visit = args->cpy_visit; - void *cpy_arg = args->cpy_arg; - PyObject *cpy_obj = _hf2py(*f); - return cpy_visit(cpy_obj, cpy_arg); -} - -_HPy_HIDDEN int call_traverseproc_from_trampoline(HPyFunc_traverseproc tp_traverse, - PyObject *self, - cpy_visitproc cpy_visit, - void *cpy_arg) -{ - hpy2cpy_visit_args_t args = { cpy_visit, cpy_arg }; - return tp_traverse(_pyobj_as_struct(self), hpy2cpy_visit, &args); -} - -_HPy_HIDDEN HPyType_BuiltinShape ctx_Type_GetBuiltinShape(HPyContext *ctx, HPy h_type) -{ - PyTypeObject *tp = (PyTypeObject*) _h2py(h_type); - assert(tp != NULL); - if (!PyType_Check(tp)) { - PyErr_SetString(PyExc_TypeError, "arg must be a type"); - return (HPyType_BuiltinShape) -2; - } - return _HPyType_Get_Shape((PyTypeObject *)tp); -} - -_HPy_HIDDEN const char *ctx_Type_GetName(HPyContext *ctx, HPy type) -{ - PyTypeObject *tp = (PyTypeObject*) _h2py(type); - assert(tp != NULL); - if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) { - PyHeapTypeObject* et = (PyHeapTypeObject*)tp; - return PyUnicode_AsUTF8(et->ht_name); - } - else { - // '_PyType_Name' is at least available from 3.8 to 3.12 - return _PyType_Name(tp); - } -} - -_HPy_HIDDEN int ctx_SetCallFunction(HPyContext *ctx, HPy h, - HPyCallFunction *func) -{ - PyObject *obj = _h2py(h); - assert(obj != NULL); - - PyTypeObject *tp = Py_TYPE(obj); - assert(tp != NULL); - if (!PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { - PyErr_Format(PyExc_TypeError, - "type '%.50s does not implement the HPy call protocol", - tp->tp_name); - return -1; - } - _HPy_set_vectorcall_func(tp, obj, func->cpy_trampoline); - return 0; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/format.c b/graalpython/hpy/hpy/devel/src/runtime/format.c deleted file mode 100644 index 32edd52889..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/format.c +++ /dev/null @@ -1,737 +0,0 @@ -/** - * HPy string formatting helpers. - * - * Note: these functions are runtime helper functions, i.e., they are not - * part of the HPy context ABI, but are available to HPy extensions to - * incorporate at compile time. - * - * The formatting helper functions are: ``HPyUnicode_FromFormat``, - * ``HPyUnicode_FromFormatV``, and ``HPyErr_Format``. - * - * Supported Formatting Units - * -------------------------- - * - * ``%%`` - The literal % character. - * - * Compatible with C (s)printf: - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * ``%c [int]`` - * - * ``%d [int]`` - * - * ``%u [unsigned int]`` - * - * ``%ld [long]`` - * - * ``%li [long]`` - * - * ``%lu [unsigned long]`` - * - * ``%lld [long long]`` - * - * ``%lli [long long]`` - * - * ``%llu [unsigned long long]`` - * - * ``%zd [HPy_ssize_t]`` - * - * ``%zi [HPy_ssize_t]`` - * - * ``%zu [size_t]`` - * - * ``%i [int]`` - * - * ``%x [int]`` - * - * ``%s [const char*]`` - * - * ``%p [const void*]`` - * Guaranteed to start with the literal '0x' regardless of what the - * platform’s printf yields. However, there is no guarantee for - * zero-padding after the '0x' prefix. Some systems pad the pointer - * to 32 or 64 digits depending on the architecture, some do not - * zero pad at all. Moreover, there is no guarantee whether the letters - * will be capitalized or not. - * - * Python specific: - * ~~~~~~~~~~~~~~~~ - * - * ``%A [HPy]`` - * The result of calling ``HPy_Ascii``. - * - * ``%U [HPy]`` - * A Unicode object. - * - * ``%V [HPy, const char*]`` - * A Unicode object (which may be ``HPy_NULL``) and a null-terminated C character - * array as a second parameter (which will be used, if the first parameter - * is ``HPy_NULL``). - * - * ``%S [HPy]`` - * The result of calling ``HPy_Str``. - * - * ``%R [HPy]`` - * The result of calling ``HPy_Repr``. - * - * Additional flags: - * ~~~~~~~~~~~~~~~~~ - * - * The format is ``%[0]{width}.{precision}{formatting-unit}``. - * - * The ``precision`` flag for numbers gives the minimal number of digits - * (i.e., excluding the minus sign). Shorter numbers are padded with zeros. - * For strings it gives the maximum number of characters, i.e., the string - * may be shortened if it is longer than ``precision``. - * - * The ``width`` determines how many characters should be output. If the - * formatting result with ``width`` flag applied is shorter, then it is - * padded from left with spaces. If it is longer, the result will - * *not* be shortened. - * - * The ``0`` flag is supported only for numeric units: if present, the - * number is padded to desired ``width`` with zeros instead of spaces. - * Unlike with spaces padding, the minus sign is shifted to the leftmost - * position with zero padding. - * - * The ``width`` formatter unit is number of characters rather than bytes. - * The precision formatter unit is number of bytes for ``%s`` and ``%V`` - * (if the HPy argument is ``HPy_NULL``), and a number of characters for - * ``%A``, ``%U``, ``%S``, ``%R`` and ``%V`` (if the HPy argument is not - * ``HPy_NULL``). - * - * Compatibility with CPython API - * ------------------------------ - * - * HPy is more strict in these cases: - * - * CPython API ignores width, precision, zero-padding flag for formatting - * units that do not support them: ``%c`` and ``%p``, but HPy raises a system - * error in such cases. - * - * CPython API ignores zero-padding for "string" formatting units, while HPy - * raises a system error in such cases. - * - * Note: users should not rely on these system errors, as HPy may choose - * to support some of those flags in the future. - */ - - -/* Implementation notes: - * - * The implementation was taken from CPython, but was adapted to be to operate - * only with utf-8 encoding, because that is how HPy exposes Python strings - * (i.e., HPyUnicode_AsUTF8AndSize). CPython starts with UCS1 and widens to - * UCS2,3,4 depending on the largest character encountered so far. We keep - * everything in utf-8, or in fact in ascii as long as we do not encounter any - * of the Python specific formatting units such as %S or %V. The only place where - * we actually need to have special handling for utf-8 variable width encoding - * is with the width and precision flags for Python specific formatting units. - * - * ------------------------------------------------------------------ - * CPython copyrights: - * - * Unicode implementation based on original code by Fredrik Lundh, - * modified by Marc-Andre Lemburg . - * - * Major speed upgrades to the method implementations at the Reykjavik - * NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke. - * - * Copyright (c) Corporation for National Research Initiatives. - * - * --------- - * The original string type implementation is: - * Copyright (c) 1999 by Secret Labs AB - * Copyright (c) 1999 by Fredrik Lundh - * - * ------------------------------------------------------------------ - * - * Please see the git history of the following files from CPython source - * code for more authors: - * - * - Objects/unicodeobject.c - * - Modules/_testcapi/unicode.c - */ - - - -#include "hpy.h" -#include -#include -#include - -// Maximum code point of Unicode 6.0: 0x10ffff (1,114,111). -#define MAX_UNICODE 0x10ffff - -/* maximum number of characters required for output of %lld or %p. - We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, - plus 1 for the sign. 53/22 is an upper bound for log10(256). */ -#define MAX_LONG_LONG_CHARS (2 + (sizeof(long long)*53-1) / 22) - -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) - -#define OVERALLOCATE_FACTOR 4 - -typedef struct { - char *data_utf8; - HPy_ssize_t size; - HPy_ssize_t pos; - bool memory_error; -} StrWriter; - -static void StrWriter_Init(StrWriter *writer, HPy_ssize_t init_size) -{ - memset(writer, 0, sizeof(*writer)); - writer->data_utf8 = (char*) malloc(init_size); - writer->size = init_size; -} - -static bool StrWriter_EnsureSpace(StrWriter *writer, HPy_ssize_t len) -{ - if (len < (writer->size - writer->pos)) - return true; - - HPy_ssize_t add = (writer->size / OVERALLOCATE_FACTOR); - if (len > add) - add = len; - writer->size += add; - if (writer->size < 0) - writer->size = HPY_SSIZE_T_MAX; - char *prev = writer->data_utf8; - writer->data_utf8 = (char*) realloc(writer->data_utf8, writer->size); - if (!writer->data_utf8) { - free(prev); - writer->memory_error = true; - return false; - } - return true; -} - -static void StrWriter_WriteCharRaw(StrWriter *writer, const int c) -{ - assert((writer->size - writer->pos) > 0); - writer->data_utf8[writer->pos++] = c; -} - -static bool StrWriter_WriteChar(StrWriter *writer, const int c) -{ - if (!StrWriter_EnsureSpace(writer, 1)) - return false; - StrWriter_WriteCharRaw(writer, c); - return true; -} - -static void StrWriter_WriteCharNRaw(StrWriter *writer, char c, HPy_ssize_t n) -{ - assert((writer->size - writer->pos) >= n); - memset(writer->data_utf8 + writer->pos, c, n); - writer->pos += n; -} - -static void StrWriter_WriteRaw(StrWriter *writer, const char *utf8, HPy_ssize_t len) -{ - assert((writer->size - writer->pos) >= len); - memcpy(writer->data_utf8 + writer->pos, utf8, len); - writer->pos += len; -} - -static bool StrWriter_Write(StrWriter *writer, const char *utf8, HPy_ssize_t len) -{ - if (!StrWriter_EnsureSpace(writer, len)) - return false; - StrWriter_WriteRaw(writer, utf8, len); - return true; -} - -static bool StrWriter_WriteWithWidth(StrWriter *writer, const char *utf8, HPy_ssize_t length, - HPy_ssize_t width, HPy_ssize_t precision) -{ - assert(utf8 != NULL); - if ((precision == -1 || precision >= length) - && width <= length) { - return StrWriter_Write(writer, utf8, length); - } - - if (precision != -1) - length = MIN(precision, length); - - HPy_ssize_t arglen = MAX(length, width); - if (!StrWriter_EnsureSpace(writer, arglen)) - return false; - - if (width > length) { - HPy_ssize_t fill = width - length; - StrWriter_WriteCharNRaw(writer, ' ', fill); - } - - assert((writer->size - writer->pos) >= length); - memcpy(writer->data_utf8 + writer->pos, utf8, length); - writer->pos += length; - return true; -} - -static bool StrWriter_WriteUnicode(HPyContext *ctx, StrWriter *writer, HPy h, - HPy_ssize_t width, HPy_ssize_t precision) -{ - assert(!HPy_IsNull(h) && HPyUnicode_Check(ctx, h)); - HPy_ssize_t u_size; - const char *u_str = HPyUnicode_AsUTF8AndSize(ctx, h, &u_size); - if (!u_str) - return false; - // We cannot use strlen(u_str), this may not be ascii only string - HPy_ssize_t length = HPy_Length(ctx, h); - - if ((precision == -1 || precision >= length) - && width <= length) { - return StrWriter_Write(writer, u_str, u_size); - } - - if (precision != -1) - length = MIN(precision, length); - - HPy_ssize_t extra = length - u_size; - HPy_ssize_t arglen = MAX(length, width) + extra; - if (!StrWriter_EnsureSpace(writer, arglen)) - return false; - - if (width > length) { - HPy_ssize_t fill = width - length; - StrWriter_WriteCharNRaw(writer, ' ', fill); - } - - if (length == u_size || precision == -1) { - return StrWriter_Write(writer, u_str, u_size); - } else { - // we need to take "precision" many characters from the utf-8 string: - HPy_ssize_t chars_count = 0; - while (chars_count < precision) { - assert(chars_count < u_size); - assert((writer->size - writer->pos) > 0); - writer->data_utf8[writer->pos++] = *u_str; - if ((*u_str & 0xc0) != 0x80) - chars_count++; - u_str++; - } - return true; - } -} - -static bool StrWriter_DupAndWriteUnicode(HPyContext *ctx, StrWriter *writer, HPy h_unicode, - HPy_ssize_t width, HPy_ssize_t precision) -{ - // We are dupping the handle, such that we can release the C string - // as soon as possible by closing the handle immediately here - HPy h = HPy_Dup(ctx, h_unicode); - bool u_result = StrWriter_WriteUnicode(ctx, writer, h, width, precision); - HPy_Close(ctx, h); - return u_result; -} - -static bool StrWriter_WriteFunResult(HPyContext *ctx, StrWriter *writer, HPy (fun)(HPyContext*, HPy), HPy arg, - HPy_ssize_t width, HPy_ssize_t precision) -{ - if (HPy_IsNull(arg)) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "HPy_NULL passed as value for formatting unit '%S' or '%R' or '%A'"); - return false; - } - HPy h = fun(ctx, arg); - if (HPy_IsNull(h)) - return false; - bool u_result = StrWriter_WriteUnicode(ctx, writer, h, width, precision); - HPy_Close(ctx, h); - return u_result; -} - -static void StrWriter_Close(StrWriter *writer) -{ - free(writer->data_utf8); - writer->data_utf8 = NULL; -} - -static HPy StrWriter_ToUnicode(HPyContext *ctx, StrWriter *writer) -{ - if (writer->data_utf8 == NULL && !writer->memory_error) { - return HPy_NULL; - } - if (writer->memory_error || !StrWriter_Write(writer, "\0", 1)) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "cannot allocate memory for string format"); - return HPy_NULL; - } - HPy result = HPyUnicode_FromString(ctx, writer->data_utf8); - StrWriter_Close(writer); - return result; -} - -static const char* -unicode_fromformat_arg(HPyContext *ctx, StrWriter *writer, const char *f, va_list *vargs) -{ - HPy_ssize_t len; - HPy_ssize_t width; - HPy_ssize_t precision; - int longflag; - int longlongflag; - int size_tflag; - HPy_ssize_t fill; - - f++; - if (*f == '%') { - if (!StrWriter_WriteChar(writer, '%')) - return NULL; - f++; - return f; - } - - bool zeropad = false; - if (*f == '0') { - zeropad = true; - f++; - } - - /* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */ - width = -1; - if (isdigit(*f)) { - width = *f - '0'; - f++; - while (isdigit((unsigned)*f)) { - if (width > (HPy_ssize_t) (HPY_SSIZE_T_MAX - ((int)*f - '0')) / 10) { - HPyErr_SetString(ctx, ctx->h_ValueError, - "width too big"); - return NULL; - } - width = (width * 10) + (*f - '0'); - f++; - } - } - precision = -1; - if (*f == '.') { - f++; - if (isdigit((unsigned)*f)) { - precision = (*f - '0'); - f++; - while (isdigit((unsigned)*f)) { - if (precision > (HPy_ssize_t) (HPY_SSIZE_T_MAX - ((int)*f - '0')) / 10) { - HPyErr_SetString(ctx, ctx->h_ValueError, - "precision too big"); - return NULL; - } - precision = (precision * 10) + (*f - '0'); - f++; - } - } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; - } - - /* Handle %ld, %lu, %lld and %llu. */ - longflag = 0; - longlongflag = 0; - size_tflag = 0; - if (*f == 'l') { - if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') { - longflag = 1; - ++f; - } - else if (f[1] == 'l' && - (f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) { - longlongflag = 1; - f += 2; - } - } - /* handle the size_t flag. */ - else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) { - size_tflag = 1; - ++f; - } - - if (zeropad) { - switch (*f) { - case 's': - case 'U': - case 'V': - case 'S': - case 'R': - case 'A': - case 'p': - case 'c': - HPyErr_Format(ctx, ctx->h_SystemError, "formatting unit '%%%c' does not support 0-padding", *f); - return NULL; - } - } - - switch (*f) { - case 'c': - { - if (precision != -1 || width != -1) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "formatting unit '%c' does not support width nor precision"); - return NULL; - } - int ordinal = va_arg(*vargs, int); - if (ordinal < 0 || ordinal > MAX_UNICODE) { - HPyErr_SetString(ctx, ctx->h_OverflowError, - "character argument not in range(0x110000)"); - return NULL; - } - if (!StrWriter_WriteChar(writer, ordinal)) - return NULL; - break; - } - - case 'i': - case 'd': - case 'u': - case 'x': - { - /* used by sprintf */ - char buffer[MAX_LONG_LONG_CHARS]; - // size_t arglen; - - if (*f == 'u') { - if (longflag) { - len = snprintf(buffer, sizeof(buffer), "%lu", va_arg(*vargs, unsigned long)); - } - else if (longlongflag) { - len = snprintf(buffer, sizeof(buffer), "%llu", va_arg(*vargs, unsigned long long)); - } - else if (size_tflag) { - len = snprintf(buffer, sizeof(buffer), "%zu", va_arg(*vargs, size_t)); - } - else { - len = snprintf(buffer, sizeof(buffer), "%u", va_arg(*vargs, unsigned int)); - } - } - else if (*f == 'x') { - len = snprintf(buffer, sizeof(buffer), "%x", va_arg(*vargs, int)); - } - else { - if (longflag) { - len = snprintf(buffer, sizeof(buffer), "%li", va_arg(*vargs, long)); - } - else if (longlongflag) { - len = snprintf(buffer, sizeof(buffer), "%lli", va_arg(*vargs, long long)); - } - else if (size_tflag) { - len = snprintf(buffer, sizeof(buffer), "%zi", va_arg(*vargs, HPy_ssize_t)); - } - else { - len = snprintf(buffer, sizeof(buffer), "%i", va_arg(*vargs, int)); - } - } - assert(len >= 0); - len = MIN((HPy_ssize_t) sizeof(buffer), len); - - int negative = (buffer[0] == '-'); - len -= negative; - - precision = MAX(precision, len); - width = MAX(width, precision + negative); - - HPy_ssize_t arglen = MAX(precision, width); - if (!StrWriter_EnsureSpace(writer, arglen)) - return NULL; - - if (width > precision) { - if (negative && zeropad) { - StrWriter_WriteCharRaw(writer, '-'); - } - - fill = width - precision - negative; - char fillchar = zeropad ? '0' : ' '; - StrWriter_WriteCharNRaw(writer, fillchar, fill); - - if (negative && !zeropad) { - StrWriter_WriteCharRaw(writer, '-'); - } - } - if (precision > len) { - fill = precision - len; - StrWriter_WriteCharNRaw(writer, '0', fill); - } - - StrWriter_WriteRaw(writer, &buffer[negative], len); - break; - } - - case 'p': - { - if (precision != -1 || width != -1) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "formatting unit '%p' does not support width nor precision"); - return NULL; - } - - char number[MAX_LONG_LONG_CHARS]; - - len = snprintf(number, sizeof(number), "%p", va_arg(*vargs, void*)); - len = MIN((HPy_ssize_t) sizeof(number), len); - assert(len >= 0); - - /* %p is ill-defined: ensure leading 0x. */ - if (number[1] == 'X') - number[1] = 'x'; - else if (number[1] != 'x') { - memmove(number + 2, number, - strlen(number) + 1); - number[0] = '0'; - number[1] = 'x'; - len += 2; - } - - if (!StrWriter_Write(writer, number, len)) - return NULL; - break; - } - - case 's': - { - /* UTF-8 */ - const char *s = va_arg(*vargs, const char*); - if (!s) { - HPyErr_SetString(ctx, ctx->h_SystemError, "null c string passed as value for formatting unit '%s'"); - return NULL; - } - if (!StrWriter_WriteWithWidth(writer, s, (HPy_ssize_t) strlen(s), width, precision)) - return NULL; - break; - } - - case 'U': - { - HPy h = va_arg(*vargs, HPy); - if (HPy_IsNull(h)) { - HPyErr_SetString(ctx, ctx->h_SystemError, "HPy_NULL passed as value for formatting unit '%U'"); - return NULL; - } - if (!StrWriter_DupAndWriteUnicode(ctx, writer, h, width, precision)) - return NULL; - break; - } - - case 'V': - { - HPy h = va_arg(*vargs, HPy); - const char *str = va_arg(*vargs, const char *); - if (!HPy_IsNull(h)) { - assert(HPyUnicode_Check(ctx, h)); - if (!StrWriter_DupAndWriteUnicode(ctx, writer, h, width, precision)) - return NULL; - } else { - assert(str != NULL); - if (!StrWriter_WriteWithWidth(writer, str, (HPy_ssize_t) strlen(str), width, precision)) - return NULL; - } - break; - } - - case 'S': - { - if (!StrWriter_WriteFunResult(ctx, writer, HPy_Str, va_arg(*vargs, HPy), width, precision)) - return NULL; - break; - } - - case 'R': - { - if (!StrWriter_WriteFunResult(ctx, writer, HPy_Repr, va_arg(*vargs, HPy), width, precision)) - return NULL; - break; - } - - case 'A': - { - if (!StrWriter_WriteFunResult(ctx, writer, HPy_ASCII, va_arg(*vargs, HPy), width, precision)) - return NULL; - break; - } - - default: - HPyErr_SetString(ctx, ctx->h_SystemError, "invalid format string"); - return NULL; - } - - f++; - return f; -} - -HPyAPI_HELPER HPy -HPyUnicode_FromFormatV(HPyContext *ctx, const char *format, va_list vargs) -{ - va_list vargs2; - const char *f; - StrWriter writer; - - StrWriter_Init(&writer, (HPy_ssize_t) (strlen(format) + 100)); - - // Copy varags to be able to pass a reference to a subfunction. - va_copy(vargs2, vargs); - - for (f = format; *f; ) { - if (*f == '%') { - f = unicode_fromformat_arg(ctx, &writer, f, &vargs2); - if (f == NULL) { - StrWriter_Close(&writer); - goto end; - } - } - else { - const char *p; - HPy_ssize_t len; - - p = f; - do - { - if ((unsigned char)*p > 127) { - HPyErr_Format(ctx, ctx->h_ValueError, - "expected an ASCII-encoded format " - "string, got a non-ASCII byte: 0x%02x", - (unsigned char)*p); - StrWriter_Close(&writer); - goto end; - } - p++; - } - while (*p != '\0' && *p != '%'); - len = p - f; - - if (!StrWriter_Write(&writer, f, len)) { - StrWriter_Close(&writer); - goto end; - } - - f = p; - } - } -end: - va_end(vargs2); - return StrWriter_ToUnicode(ctx, &writer); -} - -HPyAPI_HELPER HPy -HPyUnicode_FromFormat(HPyContext *ctx, const char *fmt, ...) -{ - va_list vargs; - va_start(vargs, fmt); - HPy ret = HPyUnicode_FromFormatV(ctx, fmt, vargs); - va_end(vargs); - return ret; -} - -HPyAPI_HELPER HPy -HPyErr_Format(HPyContext *ctx, HPy h_type, const char *fmt, ...) -{ - va_list vargs; - va_start(vargs, fmt); - HPy h_str = HPyUnicode_FromFormatV(ctx, fmt, vargs); - va_end(vargs); - HPyErr_SetObject(ctx, h_type, h_str); - HPy_Close(ctx, h_str); - return HPy_NULL; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/helpers.c b/graalpython/hpy/hpy/devel/src/runtime/helpers.c deleted file mode 100644 index 42e7648f11..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/helpers.c +++ /dev/null @@ -1,154 +0,0 @@ -#include "hpy.h" - -/** - * Create a type and add it as an attribute on the given object. The type is - * created using :c:func:`HPyType_FromSpec`. The object is often a module that the type - * is being added to. - * - * :param ctx: - * The execution context. - * :param obj: - * A handle to the object the type is being added to (often a module). - * :param name: - * The name of the attribute on the object to assign the type to. - * :param hpyspec: - * The type spec to use to create the type. - * :param params: - * The type spec parameters to use to create the type. - * - * :returns: ``0`` on failure, ``1`` on success. - * - * Examples: - * - * Using ``HPyHelpers_AddType`` without any :c:struct:`HPyType_SpecParam` - * parameters: - * - * .. code-block:: c - * - * if (!HPyHelpers_AddType(ctx, module, "MyType", hpyspec, NULL)) - * return HPy_NULL; - * ... - * - * Using `HPyHelpers_AddType` with `HPyType_SpecParam` parameters: - * - * .. code-block:: c - * - * HPyType_SpecParam params[] = { - * { HPyType_SpecParam_Base, ctx->h_LongType }, - * { 0 } - * }; - * - * if (!HPyHelpers_AddType(ctx, module, "MyType", hpyspec, params)) - * return HPy_NULL; - * ... - */ -HPyAPI_HELPER int -HPyHelpers_AddType(HPyContext *ctx, HPy obj, const char *name, - HPyType_Spec *hpyspec, HPyType_SpecParam *params) -{ - HPy h_type = HPyType_FromSpec(ctx, hpyspec, params); - if (HPy_IsNull(h_type)) { - return 0; - } - if (HPy_SetAttr_s(ctx, obj, name, h_type) != 0) { - HPy_Close(ctx, h_type); - return 0; - } - HPy_Close(ctx, h_type); - return 1; -} - -/** - * Convert positional/keyword argument vector to argument tuple and keywords - * dictionary. - * - * This helper function is useful to convert arguments from HPy's calling - * convention to the legacy CPython *tp_call* calling convention. HPy's calling - * convention is similar to CPython's fastcall/vectorcall calling convention - * where positional and keyword arguments are passed as a C array, the number of - * positional arguments is explicitly given by an argument and the names of the - * keyword arguments are provided in a tuple. - * - * For an example on how to use this function, see section - * :ref:`call-migration`. - * - * :param ctx: - * The execution context. - * :param args: - * A pointer to an array of positional and keyword arguments. This argument - * must not be ``NULL`` if ``nargs > 0`` or - * ``HPy_Length(ctx, kwnames) > 0``. - * :param nargs: - * The number of positional arguments in ``args``. - * :param kwnames: - * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). - * The values of the keyword arguments are also passed in ``args`` appended - * to the positional arguments. Argument ``nargs`` does not include the - * keyword argument count. - * :param out_pos_args: - * A pointer to a variable where to write the created positional arguments - * tuple to. If there are no positional arguments (i.e. ``nargs == 0``), - * then ``HPy_NULL`` will be written. The pointer will not be used if any - * error occurs during conversion. - * :param out_kwd: - * A pointer to a variable where to write the created keyword arguments - * dictionary to. If there are not keyword arguments (i.e. - * ``HPy_Length(ctx, kwnames) == 0``), then ``HPy_NULL`` will be written. - * The pointer will not be used if any error occurs during conversion. - * - * :returns: ``0`` on failure, ``1`` on success. - */ -HPyAPI_HELPER int -HPyHelpers_PackArgsAndKeywords(HPyContext *ctx, const HPy *args, size_t nargs, - HPy kwnames, HPy *out_pos_args, HPy *out_kwd) -{ - HPy pos_args, kwd, tmp; - HPy_ssize_t nkw, i; - - if (out_pos_args == NULL) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "argument 'out_pos_args' must not be NULL"); - return 0; - } - if (out_kwd == NULL) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "argument 'out_kwd' must not be NULL"); - return 0; - } - - nkw = HPy_IsNull(kwnames) ? 0 : HPy_Length(ctx, kwnames); - if (nkw < 0) { - return 0; - } else if (nkw > 0) { - kwd = HPyDict_New(ctx); - for (i=0; i < nkw; i++) { - tmp = HPy_GetItem_i(ctx, kwnames, i); - if (HPy_IsNull(tmp)) { - HPy_Close(ctx, kwd); - return 0; - } - if (HPy_SetItem(ctx, kwd, tmp, args[nargs + i]) < 0) { - HPy_Close(ctx, tmp); - HPy_Close(ctx, kwd); - return 0; - } - HPy_Close(ctx, tmp); - } - } else { - assert(nkw == 0); - kwd = HPy_NULL; - } - if (nargs > 0) { - pos_args = HPyTuple_FromArray(ctx, (HPy *)args, nargs); - if (HPy_IsNull(pos_args)) { - HPy_Close(ctx, kwd); - return 0; - } - } else { - pos_args = HPy_NULL; - } - // only write to output variables if everything was successful - *out_pos_args = pos_args; - *out_kwd = kwd; - return 1; -} diff --git a/graalpython/hpy/hpy/devel/src/runtime/structseq.c b/graalpython/hpy/hpy/devel/src/runtime/structseq.c deleted file mode 100644 index 9acd237756..0000000000 --- a/graalpython/hpy/hpy/devel/src/runtime/structseq.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Helper functions to create struct sequences. - * - * These are not part of the HPy context or ABI, but instead are just helpers - * that delegate to the relevant HPy/CPython APIs. - */ - -#include "hpy.h" - -#include // for strncpy/strncpy_s -#include - -const char * const HPyStructSequence_UnnamedField = "_"; - -HPyAPI_HELPER HPy -HPyStructSequence_NewType(HPyContext *ctx, HPyStructSequence_Desc *desc) -{ - HPy_ssize_t i; - - if (desc->name == NULL) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "Struct sequence descriptor does not define the name field."); - return HPy_NULL; - } - - for (i = 0; desc->fields[i].name != NULL; i++) { - } - -#ifndef HPY_ABI_CPYTHON - HPyTracker ht; - HPy fields, args, kwds, defs, docstring, n_fields, h_field, h_modname; - HPy result = HPy_NULL; - const char *name, *s; - char *modname; - - HPy collections = HPyImport_ImportModule(ctx, "collections"); - if (HPy_IsNull(collections)) { - return HPy_NULL; - } - HPy namedtuple = HPy_GetAttr_s(ctx, collections, "namedtuple"); - HPy_Close(ctx, collections); - if (HPy_IsNull(namedtuple)) { - return HPy_NULL; - } - ht = HPyTracker_New(ctx, 9); - HPyTracker_Add(ctx, ht, namedtuple); - - - HPyTupleBuilder argsBuilder = HPyTupleBuilder_New(ctx, 2); - HPyTupleBuilder fieldsBuilder = HPyTupleBuilder_New(ctx, i); - HPyTupleBuilder defsBuilder = HPyTupleBuilder_New(ctx, i); - - HPy h_name = HPyUnicode_FromString(ctx, "tmpname"); - if (HPy_IsNull(h_name)) { - goto error; - } - HPyTupleBuilder_Set(ctx, argsBuilder, 0, h_name); - HPy_Close(ctx, h_name); - - i = 0; - for (name = desc->fields[i].name; name != NULL; name = desc->fields[++i].name) { - h_field = HPyUnicode_FromString(ctx, name); - if (HPy_IsNull(h_field)) { - HPyTupleBuilder_Cancel(ctx, argsBuilder); - HPyTupleBuilder_Cancel(ctx, fieldsBuilder); - HPyTupleBuilder_Cancel(ctx, defsBuilder); - goto error; - } - HPyTupleBuilder_Set(ctx, fieldsBuilder, i, h_field); - HPyTupleBuilder_Set(ctx, defsBuilder, i, ctx->h_None); - HPy_Close(ctx, h_field); - } - fields = HPyTupleBuilder_Build(ctx, fieldsBuilder); - if (HPy_IsNull(fields)) { - HPyTupleBuilder_Cancel(ctx, argsBuilder); - HPyTupleBuilder_Cancel(ctx, defsBuilder); - goto error; - } - HPyTracker_Add(ctx, ht, fields); - - defs = HPyTupleBuilder_Build(ctx, defsBuilder); - if (HPy_IsNull(defs)) { - HPyTupleBuilder_Cancel(ctx, argsBuilder); - goto error; - } - HPyTracker_Add(ctx, ht, defs); - - HPyTupleBuilder_Set(ctx, argsBuilder, 1, fields); - args = HPyTupleBuilder_Build(ctx, argsBuilder); - if (HPy_IsNull(args)) { - goto error; - } - HPyTracker_Add(ctx, ht, args); - - kwds = HPyDict_New(ctx); - if (HPy_IsNull(kwds)) { - goto error; - } - HPyTracker_Add(ctx, ht, kwds); - if (HPy_SetItem_s(ctx, kwds, "rename", ctx->h_True) < 0) { - goto error; - } - if (HPy_SetItem_s(ctx, kwds, "defaults", defs) < 0) { - goto error; - } - - result = HPy_CallTupleDict(ctx, namedtuple, args, kwds); - if (HPy_IsNull(result)) { - goto error; - } - - if (desc->doc) { - docstring = HPyUnicode_FromString(ctx, desc->doc); - if (HPy_IsNull(docstring)) { - goto error; - } - HPyTracker_Add(ctx, ht, docstring); - } else { - docstring = ctx->h_None; - } - if (HPy_SetAttr_s(ctx, result, "__doc__", docstring) < 0) { - goto error; - } - - n_fields = HPyLong_FromSsize_t(ctx, i); - if (HPy_IsNull(n_fields)) { - goto error; - } - HPyTracker_Add(ctx, ht, n_fields); - if (HPy_SetAttr_s(ctx, result, "n_fields", n_fields) < 0) { - goto error; - } - - /* Set the type name and qualname */ - s = strrchr(desc->name, '.'); - if (s == NULL) { - s = desc->name; - modname = NULL; - } - else { - /* TODO: Replace this by using 'HPyUnicode_FromStringAndSize' or similar - once available. */ - const size_t n_modname = s - desc->name; - modname = (char *)malloc((n_modname + 1) * sizeof(char)); -#ifdef _WIN32 - strncpy_s(modname, n_modname + 1, desc->name, n_modname); -#else - strncpy(modname, desc->name, n_modname); -#endif - modname[n_modname] = '\0'; - - // now, advance by one to skip '.' - s++; - } - - h_name = HPyUnicode_FromString(ctx, s); - if (HPy_IsNull(h_name)) { - goto error; - } - HPyTracker_Add(ctx, ht, h_name); - if (HPy_SetAttr_s(ctx, result, "__name__", h_name) < 0 || - HPy_SetAttr_s(ctx, result, "__qualname__", h_name) < 0) { - goto error; - } - - if (modname != NULL) { - h_modname = HPyUnicode_FromString(ctx, modname); - free(modname); - if (HPy_IsNull(h_modname)) { - goto error; - } - HPyTracker_Add(ctx, ht, h_modname); - if (HPy_SetAttr_s(ctx, result, "__module__", h_modname) < 0) { - goto error; - } - } - - HPyTracker_Close(ctx, ht); - return result; - - error: - HPyTracker_Close(ctx, ht); - HPy_Close(ctx, result); - return HPy_NULL; -#else - PyStructSequence_Desc d = { - .name = desc->name, -#if PY_VERSION_HEX < 0x03090000 - // In Python 3.8.x or earlier, the docstring MUST NOT be NULL - .doc = (desc->doc != NULL ? desc->doc : ""), -#else - .doc = desc->doc, -#endif - .fields = (PyStructSequence_Field *)desc->fields, - .n_in_sequence = (int)i - }; - return _py2h((PyObject*) PyStructSequence_NewType(&d)); -#endif -} - -HPyAPI_HELPER HPy -HPyStructSequence_New(HPyContext *ctx, HPy type, HPy_ssize_t nargs, HPy *args) -{ - static const char *s_n_fields = "n_fields"; -#ifndef HPY_ABI_CPYTHON - if (!HPy_HasAttr_s(ctx, type, s_n_fields)) { - HPyErr_Clear(ctx); - HPyErr_Format(ctx, ctx->h_TypeError, - "object '%R' does not look like a struct sequence type ", type); - return HPy_NULL; - } - HPy tuple = HPyTuple_FromArray(ctx, args, nargs); - if (HPy_IsNull(tuple)) { - return HPy_NULL; - } - HPy result = HPy_CallTupleDict(ctx, type, tuple, HPy_NULL); - HPy_Close(ctx, tuple); - return result; -#else - PyTypeObject *tp; - PyObject *name, *v, *seq, *item; - Py_ssize_t n_fields, i; - - tp = (PyTypeObject *)_h2py(type); - name = PyUnicode_FromStringAndSize(s_n_fields, sizeof(s_n_fields)); - // CPython also accesses the dict directly -#if PY_VERSION_HEX >= 0x030C0000 - PyObject *dict = PyType_GetDict(tp); -#else - PyObject *dict = tp->tp_dict; -#endif - v = PyDict_GetItemWithError(dict, name); -#if PY_VERSION_HEX >= 0x030C0000 - Py_DECREF(dict); -#endif - Py_DECREF(name); - if (v == NULL && !PyErr_Occurred()) { - goto type_error; - } - n_fields = PyLong_AsSsize_t(v); - seq = PyStructSequence_New(tp); - if (seq == NULL) { - goto type_error; - } - if (n_fields != nargs) { - PyErr_Format(PyExc_TypeError, - "expected exactly %d arguments but got %d", - n_fields, nargs); - Py_DECREF(seq); - goto error; - } - - for (i = 0; i < nargs; i++) { - item = _h2py(args[i]); - Py_INCREF(item); - PyStructSequence_SetItem(seq, i, item); - } - return _py2h(seq); - -type_error: - /* The error behavior seems not to be consistent. If anything goes - wrong, we will convert it to a TypeError here. */ - PyErr_Clear(); - PyErr_Format(PyExc_TypeError, - "type '%s' does not look like a struct sequence type", - tp->tp_name); - -error: - return HPy_NULL; -#endif -} diff --git a/graalpython/hpy/hpy/tools/autogen/__init__.py b/graalpython/hpy/hpy/tools/autogen/__init__.py deleted file mode 100644 index 81eb61e746..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -import pycparser -from packaging import version - -if version.parse(pycparser.__version__) < version.parse('2.21'): - raise ImportError('You need pycparser>=2.21 to run autogen') - -from .parse import HPyAPI, AUTOGEN_H - - -def generate(generators, *gen_args): - """ - Takes a sequence of autogen generators that will have access to the parse - tree of 'public_api.c' and can then generate files or whatever. - :param generators: A sequence (e.g. tuple) of classes or callables that - will produce objects with a 'write' method. The 'gen_args' will be passed - to the 'write' method on invocation. - :param gen_args: Arguments for the autogen generator instances. - """ - api = HPyAPI.parse(AUTOGEN_H) - for cls in generators: - cls(api).write(*gen_args) diff --git a/graalpython/hpy/hpy/tools/autogen/__main__.py b/graalpython/hpy/hpy/tools/autogen/__main__.py deleted file mode 100644 index aec206741f..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/__main__.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Parse public_api.h and generate various stubs around -""" -import sys -from pathlib import Path - -import pycparser -from packaging import version - -if version.parse(pycparser.__version__) < version.parse('2.21'): - raise ImportError('You need pycparser>=2.21 to run autogen') - -from . import generate -from .ctx import (autogen_ctx_h, - autogen_ctx_def_h, - cpython_autogen_ctx_h) -from .trampolines import (autogen_trampolines_h, - cpython_autogen_api_impl_h, - universal_autogen_ctx_impl_h) -from .hpyfunc import autogen_hpyfunc_declare_h -from .hpyfunc import autogen_hpyfunc_trampoline_h -from .hpyfunc import autogen_ctx_call_i -from .hpyfunc import autogen_cpython_hpyfunc_trampoline_h -from .hpyslot import autogen_hpyslot_h -from .debug import (autogen_debug_ctx_init_h, - autogen_debug_wrappers, - autogen_debug_ctx_call_i) -from .trace import (autogen_tracer_ctx_init_h, - autogen_tracer_wrappers, - autogen_trace_func_table_c) -from .pypy import autogen_pypy_txt -from .doc import (autogen_function_index, - autogen_doc_api_mapping) - -DEFAULT_GENERATORS = (autogen_ctx_h, - autogen_ctx_def_h, - cpython_autogen_ctx_h, - autogen_trampolines_h, - cpython_autogen_api_impl_h, - universal_autogen_ctx_impl_h, - autogen_hpyfunc_declare_h, - autogen_hpyfunc_trampoline_h, - autogen_ctx_call_i, - autogen_cpython_hpyfunc_trampoline_h, - autogen_hpyslot_h, - autogen_debug_ctx_init_h, - autogen_debug_wrappers, - autogen_debug_ctx_call_i, - autogen_tracer_ctx_init_h, - autogen_tracer_wrappers, - autogen_trace_func_table_c, - autogen_pypy_txt, - autogen_function_index, - autogen_doc_api_mapping) - - -def main(): - if len(sys.argv) != 2: - print('Usage: python -m hpy.tools.autogen OUTDIR') - sys.exit(1) - outdir = Path(sys.argv[1]) - - generate(DEFAULT_GENERATORS, outdir) - - -if __name__ == '__main__': - main() diff --git a/graalpython/hpy/hpy/tools/autogen/autogen.h b/graalpython/hpy/hpy/tools/autogen/autogen.h deleted file mode 100644 index 78bae31617..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/autogen.h +++ /dev/null @@ -1,40 +0,0 @@ -#define STRINGIFY(X) #X -#define HPy_ID(X) _Pragma(STRINGIFY(id=X)) \ - -#define AUTOGEN 1 - -// These are not real typedefs: they are there only to make pycparser happy -typedef int HPy; -typedef int HPyContext; -typedef int HPyModuleDef; -typedef int HPyType_Spec; -typedef int HPyType_SpecParam; -typedef int HPyCFunction; -typedef int HPy_ssize_t; -typedef int HPy_hash_t; -typedef int wchar_t; -typedef int size_t; -typedef int HPyFunc_Signature; -typedef int cpy_PyObject; -typedef int HPyField; -typedef int HPyGlobal; -typedef int HPyListBuilder; -typedef int HPyTupleBuilder; -typedef int HPyTracker; -typedef int HPy_RichCmpOp; -typedef int HPy_buffer; -typedef int HPyFunc_visitproc; -typedef int HPy_UCS4; -typedef int HPyThreadState; -typedef int HPyType_BuiltinShape; -typedef int _HPyCapsule_key; -typedef int HPyCapsule_Destructor; -typedef int int32_t; -typedef int uint32_t; -typedef int int64_t; -typedef int uint64_t; -typedef int bool; -typedef int HPy_SourceKind; -typedef int HPyCallFunction; - -#include "public_api.h" diff --git a/graalpython/hpy/hpy/tools/autogen/autogenfile.py b/graalpython/hpy/hpy/tools/autogen/autogenfile.py deleted file mode 100644 index c14c74b6dc..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/autogenfile.py +++ /dev/null @@ -1,43 +0,0 @@ -C_DISCLAIMER = """ -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by {clsname} - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ -""" - - -def resolve_relative_path(root, relative_path): - if hasattr(root, 'join'): - return root.join(relative_path) - return root / relative_path - - -class AutoGenFile: - LANGUAGE = 'C' - PATH = None - DISCLAIMER = None - - def __init__(self, api): - if self.DISCLAIMER is None and self.LANGUAGE == 'C': - self.DISCLAIMER = C_DISCLAIMER - self.api = api - - def generate(self): - raise NotImplementedError - - def write(self, root): - cls = self.__class__ - clsname = '%s.%s' % (cls.__module__, cls.__name__) - target = resolve_relative_path(root, self.PATH) - with target.open('w', encoding='utf-8') as f: - if self.DISCLAIMER is not None: - f.write(self.DISCLAIMER.format(clsname=clsname)) - f.write('\n') - f.write(self.generate()) - f.write('\n') diff --git a/graalpython/hpy/hpy/tools/autogen/conf.py b/graalpython/hpy/hpy/tools/autogen/conf.py deleted file mode 100644 index 5ebf345783..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/conf.py +++ /dev/null @@ -1,211 +0,0 @@ -# Defines parameters for the code generation - -# Handwritten trampolines: -NO_TRAMPOLINES = { - '_HPy_New', - 'HPy_FatalError', -} - -# Generated trampoline returns given constant, -# but the context function is void -RETURN_CONSTANT = { - 'HPyErr_SetString': 'HPy_NULL', - 'HPyErr_SetObject': 'HPy_NULL', - 'HPyErr_SetFromErrnoWithFilenameObjects': 'HPy_NULL', - 'HPyErr_NoMemory': 'HPy_NULL' -} - -# If the HPy function delegates to C Python API of a different name or, in the -# case of None, if the HPy function is implemented by hand -SPECIAL_CASES = { - 'HPy_Dup': None, - 'HPy_Close': None, - 'HPyField_Load': None, - 'HPyField_Store': None, - 'HPyModule_Create': None, - 'HPy_GetAttr': 'PyObject_GetAttr', - 'HPy_GetAttr_s': 'PyObject_GetAttrString', - 'HPy_HasAttr': 'PyObject_HasAttr', - 'HPy_HasAttr_s': 'PyObject_HasAttrString', - 'HPy_SetAttr': 'PyObject_SetAttr', - 'HPy_SetAttr_s': 'PyObject_SetAttrString', - 'HPy_GetIter': 'PyObject_GetIter', - 'HPy_GetItem': 'PyObject_GetItem', - 'HPy_GetItem_i': None, - 'HPy_GetItem_s': None, - 'HPy_GetSlice': 'PySequence_GetSlice', - 'HPy_SetItem': 'PyObject_SetItem', - 'HPy_SetItem_i': None, - 'HPy_SetItem_s': None, - 'HPy_SetSlice': 'PySequence_SetSlice', - 'HPy_DelItem': 'PyObject_DelItem', - 'HPy_DelItem_i': None, - 'HPy_DelItem_s': None, - 'HPy_DelSlice': 'PySequence_DelSlice', - 'HPy_Contains': 'PySequence_Contains', - 'HPy_Length': 'PyObject_Length', - 'HPy_CallTupleDict': None, - 'HPy_Call': None, # 'PyObject_Vectorcall', no auto arg conversion - 'HPy_CallMethod': None, # 'PyObject_VectorcallMethod',no auto arg conversion - 'HPy_FromPyObject': None, - 'HPy_AsPyObject': None, - '_HPy_AsStruct_Object': None, - '_HPy_AsStruct_Type': None, - '_HPy_AsStruct_Long': None, - '_HPy_AsStruct_Float': None, - '_HPy_AsStruct_Unicode': None, - '_HPy_AsStruct_Tuple': None, - '_HPy_AsStruct_List': None, - '_HPy_AsStruct_Dict': None, - '_HPy_AsStruct_Legacy': None, - '_HPyType_GetBuiltinShape': None, - '_HPy_CallRealFunctionFromTrampoline': None, - '_HPy_CallDestroyAndThenDealloc': None, - 'HPyErr_Occurred': None, - 'HPy_FatalError': None, - 'HPy_Add': 'PyNumber_Add', - 'HPy_Subtract': 'PyNumber_Subtract', - 'HPy_Multiply': 'PyNumber_Multiply', - 'HPy_MatrixMultiply': 'PyNumber_MatrixMultiply', - 'HPy_FloorDivide': 'PyNumber_FloorDivide', - 'HPy_TrueDivide': 'PyNumber_TrueDivide', - 'HPy_Remainder': 'PyNumber_Remainder', - 'HPy_Divmod': 'PyNumber_Divmod', - 'HPy_Power': 'PyNumber_Power', - 'HPy_Negative': 'PyNumber_Negative', - 'HPy_Positive': 'PyNumber_Positive', - 'HPy_Absolute': 'PyNumber_Absolute', - 'HPy_Invert': 'PyNumber_Invert', - 'HPy_Lshift': 'PyNumber_Lshift', - 'HPy_Rshift': 'PyNumber_Rshift', - 'HPy_And': 'PyNumber_And', - 'HPy_Xor': 'PyNumber_Xor', - 'HPy_Or': 'PyNumber_Or', - 'HPy_Index': 'PyNumber_Index', - 'HPy_Long': 'PyNumber_Long', - 'HPy_Float': 'PyNumber_Float', - 'HPy_InPlaceAdd': 'PyNumber_InPlaceAdd', - 'HPy_InPlaceSubtract': 'PyNumber_InPlaceSubtract', - 'HPy_InPlaceMultiply': 'PyNumber_InPlaceMultiply', - 'HPy_InPlaceMatrixMultiply': 'PyNumber_InPlaceMatrixMultiply', - 'HPy_InPlaceFloorDivide': 'PyNumber_InPlaceFloorDivide', - 'HPy_InPlaceTrueDivide': 'PyNumber_InPlaceTrueDivide', - 'HPy_InPlaceRemainder': 'PyNumber_InPlaceRemainder', - 'HPy_InPlacePower': 'PyNumber_InPlacePower', - 'HPy_InPlaceLshift': 'PyNumber_InPlaceLshift', - 'HPy_InPlaceRshift': 'PyNumber_InPlaceRshift', - 'HPy_InPlaceAnd': 'PyNumber_InPlaceAnd', - 'HPy_InPlaceXor': 'PyNumber_InPlaceXor', - 'HPy_InPlaceOr': 'PyNumber_InPlaceOr', - '_HPy_New': None, - 'HPyType_FromSpec': None, - 'HPyType_GenericNew': None, - 'HPy_Repr': 'PyObject_Repr', - 'HPy_Str': 'PyObject_Str', - 'HPy_ASCII': 'PyObject_ASCII', - 'HPy_Bytes': 'PyObject_Bytes', - 'HPy_IsTrue': 'PyObject_IsTrue', - 'HPy_RichCompare': 'PyObject_RichCompare', - 'HPy_RichCompareBool': 'PyObject_RichCompareBool', - 'HPy_Hash': 'PyObject_Hash', - 'HPyIter_Next': 'PyIter_Next', - 'HPyIter_Check': 'PyIter_Check', - 'HPyListBuilder_New': None, - 'HPyListBuilder_Set': None, - 'HPyListBuilder_Build': None, - 'HPyListBuilder_Cancel': None, - 'HPyTuple_FromArray': None, - 'HPyTupleBuilder_New': None, - 'HPyTupleBuilder_Set': None, - 'HPyTupleBuilder_Build': None, - 'HPyTupleBuilder_Cancel': None, - 'HPyTracker_New': None, - 'HPyTracker_Add': None, - 'HPyTracker_ForgetAll': None, - 'HPyTracker_Close': None, - '_HPy_Dump': None, - 'HPy_Type': None, - 'HPy_TypeCheck': None, - 'HPy_Is': None, - 'HPyBytes_FromStringAndSize': None, - 'HPy_LeavePythonExecution': 'PyEval_SaveThread', - 'HPy_ReenterPythonExecution': 'PyEval_RestoreThread', - 'HPyGlobal_Load': None, - 'HPyGlobal_Store': None, - 'HPyCapsule_New': None, - 'HPyCapsule_Get': None, - 'HPyCapsule_Set': None, - 'HPyLong_FromInt32_t': None, - 'HPyLong_FromUInt32_t': None, - 'HPyLong_FromInt64_t': None, - 'HPyLong_FromUInt64_t': None, - 'HPyLong_AsInt32_t': None, - 'HPyLong_AsUInt32_t': None, - 'HPyLong_AsUInt32_tMask': None, - 'HPyLong_AsInt64_t': None, - 'HPyLong_AsUInt64_t': None, - 'HPyLong_AsUInt64_tMask': None, - 'HPyBool_FromBool': 'PyBool_FromLong', - 'HPy_Compile_s': None, - 'HPy_EvalCode': 'PyEval_EvalCode', - 'HPyContextVar_Get': None, - 'HPyType_GetName': None, - 'HPyType_IsSubtype': None, - 'HPy_SetCallFunction': None, -} - -################################################################################ -# Configuration for auto-generating docs # -################################################################################ - -# A manual mapping of between CPython C API functions and HPy API functions. -# Most of the mapping will be generated automatically from 'public_api.h' if an -# HPy API function is not a special case (see 'conf.py'). However, in some -# cases, it might be that we have inline helper functions or something similar -# that map to a CPython C API function which cannot be determined automatically. -# In those cases, the mapping can be manually specified here. Also, manual -# mapping will always take precedence over automatically derived mappings. -DOC_MANUAL_API_MAPPING = { - # key = C API function name - # value = HPy API function name - 'Py_FatalError': 'HPy_FatalError', - 'PyContextVar_Get': 'HPyContextVar_Get', - 'PyLong_FromLong': 'HPyLong_FromLong', - 'PyLong_FromLongLong': 'HPyLong_FromLongLong', - 'PyLong_FromUnsignedLong': 'HPyLong_FromUnsignedLong', - 'PyLong_FromUnsignedLongLong': 'HPyLong_FromUnsignedLongLong', - 'PyLong_AsLong': 'HPyLong_AsLong', - 'PyLong_AsLongLong': 'HPyLong_AsLongLong', - 'PyLong_AsUnsignedLong': 'HPyLong_AsUnsignedLong', - 'PyLong_AsUnsignedLongMask': 'HPyLong_AsUnsignedLongMask', - 'PyLong_AsUnsignedLongLong': 'HPyLong_AsUnsignedLongLong', - 'PyLong_AsUnsignedLongLongMask': 'HPyLong_AsUnsignedLongLongMask', - 'PyBool_FromLong': 'HPyBool_FromLong', - 'PyObject_TypeCheck': 'HPy_TypeCheck', - 'PySlice_AdjustIndices': 'HPySlice_AdjustIndices', - 'PyType_IsSubtype': 'HPyType_IsSubtype', - 'PyObject_Call': 'HPy_CallTupleDict', - 'PyObject_Type': 'HPy_Type', - 'PyObject_Vectorcall': 'HPy_Call', - 'PyObject_VectorcallMethod': 'HPy_CallMethod', -} - -# Some C API functions are documented in very different pages. -DOC_C_API_PAGES_SPECIAL_CASES = { - 'Py_FatalError': 'sys', - 'PyEval_SaveThread': 'init', - 'PyEval_RestoreThread': 'init', - 'PyEval_EvalCode': 'veryhigh', - 'PyObject_Call': 'call', - 'PyObject_Vectorcall': 'call', - 'PyObject_VectorcallMethod': 'call', -} - -# We assume that, e.g., prefix 'PyLong_Something' belongs to 'longobject.c' and -# its documentation is in '.../3/c-api/long.html'. In some cases, the prefix -# maps to a different page and this can be specified here. E.g. -# 'PyErr_Something' is documented in page '.../3/c-api/exceptions.html' -DOC_PREFIX_TABLE = { - 'err': 'exceptions', - 'contextvar': 'contextvars' -} \ No newline at end of file diff --git a/graalpython/hpy/hpy/tools/autogen/ctx.py b/graalpython/hpy/hpy/tools/autogen/ctx.py deleted file mode 100644 index 4f569f1f35..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/ctx.py +++ /dev/null @@ -1,106 +0,0 @@ -from copy import deepcopy -from pycparser import c_ast -from .autogenfile import AutoGenFile -from .parse import toC, find_typedecl, maybe_make_void - - -class autogen_ctx_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/universal/autogen_ctx.h' - - ## struct _HPyContext_s { - ## const char *name; - ## void *_private; - ## int abi_version; - ## HPy h_None; - ## ... - ## HPy (*ctx_Module_Create)(HPyContext *ctx, HPyModuleDef *def); - ## ... - ## } - - def generate(self): - # Put all declarations (variables and functions) into one list in order - # to be able to sort them by their given context index. - # We need to remember the output function per item (either - # 'declare_var' or 'declare_func'). So, we create tuples with structure - # '(decl, declare_*)'. - all_decls = [(x, self.declare_var) for x in self.api.variables] - all_decls += [(x, self.declare_func) for x in self.api.functions] - - # sort the list of all declaration by 'decl.ctx_index' - all_decls.sort(key=lambda x: x[0].ctx_index) - - lines = [] - w = lines.append - w('struct _HPyContext_s {') - w(' const char *name; // used just to make debugging and testing easier') - w(' void *_private; // used by implementations to store custom data') - w(' int abi_version;') - for var, cons in all_decls: - w(' %s;' % cons(var)) - w('};') - return '\n'.join(lines) - - def declare_var(self, var): - return toC(var.node) - - def declare_func(self, func): - # e.g. "HPy (*ctx_Module_Create)(HPyContext *ctx, HPyModuleDef *def)" - # - # turn the function declaration into a function POINTER declaration - newnode = deepcopy(func.node) - newnode.type = c_ast.PtrDecl(type=newnode.type, quals=[]) - maybe_make_void(func, newnode) - - # fix the name of the function pointer - typedecl = find_typedecl(newnode) - typedecl.declname = func.ctx_name() - return toC(newnode) - - -class autogen_ctx_def_h(AutoGenFile): - PATH = 'hpy/universal/src/autogen_ctx_def.h' - - ## struct _HPyContext_s g_universal_ctx = { - ## .name = "...", - ## ._private = NULL, - ## .abi_version = HPY_ABI_VERSION, - ## .h_None = {CONSTANT_H_NONE}, - ## ... - ## .ctx_Module_Create = &ctx_Module_Create, - ## ... - ## } - - def generate(self): - lines = [] - w = lines.append - w('struct _HPyContext_s g_universal_ctx = {') - w(' .name = "HPy Universal ABI (CPython backend)",') - w(' ._private = NULL,') - w(' .abi_version = HPY_ABI_VERSION,') - w(' /* h_None & co. are initialized by init_universal_ctx() */') - for func in self.api.functions: - w(' .%s = &%s,' % (func.ctx_name(), func.ctx_name())) - w('};') - return '\n'.join(lines) - - -class cpython_autogen_ctx_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/cpython/autogen_ctx.h' - - def generate(self): - # Put all variable declarations into a list in order - # to be able to sort them by their given context index. - var_decls = list(self.api.variables) - - # sort the list of var declaration by 'decl.ctx_index' - var_decls.sort(key=lambda x: x.ctx_index) - - lines = [] - w = lines.append - w('struct _HPyContext_s {') - w(' const char *name;') - w(' int abi_version;') - for var in var_decls: - w(' %s;' % toC(var.node)) - w('};') - return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/debug.py b/graalpython/hpy/hpy/tools/autogen/debug.py deleted file mode 100644 index eb8783ba0a..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/debug.py +++ /dev/null @@ -1,228 +0,0 @@ -from copy import deepcopy -from pycparser import c_ast -from .autogenfile import AutoGenFile -from .parse import toC, find_typedecl, get_context_return_type, \ - maybe_make_void, make_void, get_return_constant -from .hpyfunc import NO_CALL - - -class HPy_2_DHPy_Visitor(c_ast.NodeVisitor): - "Visitor which renames all HPy types to DHPy" - - def visit_IdentifierType(self, node): - if node.names == ['HPy']: - node.names = ['DHPy'] - - def visit_TypeDecl(self, node): - if node.declname == 'ctx': - node.declname = 'dctx' - self.generic_visit(node) - -def funcnode_with_new_name(node, name): - newnode = deepcopy(node) - typedecl = find_typedecl(newnode) - typedecl.declname = name - return newnode - -def get_debug_wrapper_node(func): - newnode = funcnode_with_new_name(func.node, 'debug_%s' % func.ctx_name()) - maybe_make_void(func, newnode) - # fix all the types - visitor = HPy_2_DHPy_Visitor() - visitor.visit(newnode) - return newnode - - -class autogen_debug_ctx_init_h(AutoGenFile): - PATH = 'hpy/debug/src/autogen_debug_ctx_init.h' - - def generate(self): - lines = [] - w = lines.append - # emit the declarations for all the debug_ctx_* functions - for func in self.api.functions: - w(toC(get_debug_wrapper_node(func)) + ';') - w('') - w('static inline void debug_ctx_init_fields(HPyContext *dctx, HPyContext *uctx)') - w('{') - for var in self.api.variables: - name = var.name - w(f' dctx->{name} = DHPy_open_immortal(dctx, uctx->{name});') - for func in self.api.functions: - name = func.ctx_name() - w(f' dctx->{name} = &debug_{name};') - - w('}') - return '\n'.join(lines) - - -class autogen_debug_wrappers(AutoGenFile): - PATH = 'hpy/debug/src/autogen_debug_wrappers.c' - - NO_WRAPPER = { - '_HPy_CallRealFunctionFromTrampoline', - 'HPy_Close', - 'HPyUnicode_AsUTF8AndSize', - 'HPyTuple_FromArray', - 'HPyType_GenericNew', - 'HPyType_FromSpec', - '_HPy_AsStruct_Legacy', - '_HPy_AsStruct_Object', - '_HPy_AsStruct_Type', - '_HPy_AsStruct_Long', - '_HPy_AsStruct_Float', - '_HPy_AsStruct_Unicode', - '_HPy_AsStruct_Tuple', - '_HPy_AsStruct_List', - '_HPy_AsStruct_Dict', - 'HPyTracker_New', - 'HPyTracker_Add', - 'HPyTracker_ForgetAll', - 'HPyTracker_Close', - 'HPyBytes_AsString', - 'HPyBytes_AS_STRING', - 'HPyTupleBuilder_New', - 'HPyTupleBuilder_Set', - 'HPyTupleBuilder_Build', - 'HPyTupleBuilder_Cancel', - 'HPyListBuilder_New', - 'HPyListBuilder_Set', - 'HPyListBuilder_Build', - 'HPyListBuilder_Cancel', - 'HPy_TypeCheck', - 'HPyContextVar_Get', - 'HPyType_GetName', - 'HPyType_IsSubtype', - 'HPyUnicode_Substring', - 'HPy_Call', - 'HPy_CallMethod', - } - - def generate(self): - lines = [] - w = lines.append - w('#include "debug_internal.h"') - w('') - for func in self.api.functions: - debug_wrapper = self.gen_debug_wrapper(func) - if debug_wrapper: - w(debug_wrapper) - w('') - return '\n'.join(lines) - - def gen_debug_wrapper(self, func): - if func.name in self.NO_WRAPPER: - return - # - assert not func.is_varargs() - node = get_debug_wrapper_node(func) - const_return = get_return_constant(func) - if const_return: - make_void(node) - signature = toC(node) - rettype = get_context_return_type(node, const_return) - # - 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': - 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), '\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' HPy universal_result = {func.name}({params});') - w(' get_ctx_info(dctx)->is_valid = true;') - w(' return DHPy_open(dctx, universal_result);') - else: - 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) - - -class autogen_debug_ctx_call_i(AutoGenFile): - PATH = 'hpy/debug/src/autogen_debug_ctx_call.i' - - def generate(self): - lines = [] - w = lines.append - for hpyfunc in self.api.hpyfunc_typedefs: - name = hpyfunc.base_name() - NAME = name.upper() - if NAME in NO_CALL: - continue - # - c_ret_type = toC(hpyfunc.return_type()) - args = ['next_dctx'] - dhpys = [] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = 'arg%d' % i - if toC(param.type) == 'HPy': - dhpys.append(pname) - args.append(f'dh_{pname}') - else: - args.append(f'a->{pname}') - args = ', '.join(args) - # - w(f' case HPyFunc_{NAME}: {{') - w(f' HPyFunc_{name} f = (HPyFunc_{name})func;') - w(f' _HPyFunc_args_{NAME} *a = (_HPyFunc_args_{NAME}*)args;') - for pname in dhpys: - w(f' DHPy dh_{pname} = _py2dh(dctx, a->{pname});') - # - w(' HPyContext *next_dctx = _switch_to_next_dctx_from_cache(dctx);') - w(' if (next_dctx == NULL) {') - 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(' return;') - w(' }') - # - if c_ret_type == 'void': - w(f' f({args});') - elif c_ret_type == 'HPy': - w(f' DHPy dh_result = f({args});') - else: - w(f' a->result = f({args});') - # - w(' _switch_back_to_original_dctx(dctx, next_dctx);') - # - for pname in dhpys: - w(f' DHPy_close_and_check(dctx, dh_{pname});') - # - if c_ret_type == 'HPy': - w(f' a->result = _dh2py(dctx, dh_result);') - w(f' DHPy_close(dctx, dh_result);') - # - w(f' return;') - w(f' }}') - return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/doc.py b/graalpython/hpy/hpy/tools/autogen/doc.py deleted file mode 100644 index 46f619f874..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/doc.py +++ /dev/null @@ -1,174 +0,0 @@ -import textwrap -import re - -from .autogenfile import AutoGenFile, resolve_relative_path -from .parse import toC -from .ctx import autogen_ctx_h -from .conf import (DOC_C_API_PAGES_SPECIAL_CASES, - DOC_MANUAL_API_MAPPING, - DOC_PREFIX_TABLE) - - -CTX_NAME = '_HPyContext_s' - -RST_DISCLAIMER = """ -.. note: DO NOT EDIT THIS FILE! - This file is automatically generated by {clsname} - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen -""" - -class AutoGenRstFile(AutoGenFile): - LANGUAGE = 'rst' - PATH = None - DISCLAIMER = None - - def __init__(self, api): - if self.DISCLAIMER is None and self.LANGUAGE == 'rst': - self.DISCLAIMER = RST_DISCLAIMER - self.api = api - -class autogen_function_index(AutoGenRstFile): - PATH = 'docs/api-reference/function-index.rst' - LANGUAGE = 'rst' - - def generate(self): - lines = [] - w = lines.append - w('HPy Core API Function Index') - w('###########################') - w('') - functions = list(self.api.functions) - # sort the list of functions by 'func.name' - functions.sort(key=lambda x: x.name) - for func in functions: - if func.name[0] != '_': - w(f'* :c:func:`{func.name}`') - return '\n'.join(lines) - - -class AutoGenFilePart: - PATH = None - BEGIN_MARKER = None - END_MARKER = None - - def __init__(self, api): - self.api = api - - def generate(self, old): - raise NotImplementedError - - def write(self, root): - if not self.BEGIN_MARKER or not self.END_MARKER: - raise RuntimeError("missing BEGIN_MARKER or END_MARKER") - n_begin = len(self.BEGIN_MARKER) - target = resolve_relative_path(root, self.PATH) - with target.open('r', encoding='utf-8') as f: - content = f.read() - start = content.find(self.BEGIN_MARKER) - if start < 0: - raise RuntimeError(f'begin marker "{self.BEGIN_MARKER}" not found' - f'in file {self.PATH}') - end = content.find(self.END_MARKER, start + n_begin) - if end < 0: - raise RuntimeError(f'end marker "{self.END_MARKER}" not found in' - f'file {self.PATH}') - new_content = self.generate(content[(start+n_begin):end]) - with target.open('w', encoding='utf-8') as f: - f.write(content[:start + n_begin] + new_content + content[end:]) - - -GROUP_PATTERN = re.compile('Py(\\w+)_.*') - -class autogen_doc_api_mapping(AutoGenFilePart): - PATH = 'docs/porting-guide.rst' - BEGIN_MARKER = '.. mark: BEGIN API MAPPING\n' - END_MARKER = '.. mark: END API MAPPING\n' - - def _get_page(self, cpython_fun_name): - if cpython_fun_name in DOC_C_API_PAGES_SPECIAL_CASES: - return DOC_C_API_PAGES_SPECIAL_CASES[cpython_fun_name] + '.html' - - first_underscore = cpython_fun_name.find('_') - if cpython_fun_name.startswith('Py') and first_underscore != -1: - prefix = cpython_fun_name[2:first_underscore].lower() - return DOC_PREFIX_TABLE.get(prefix, prefix) + '.html' - else: - return 'abstract.html' - - def generate(self, old_content): - table_directive = '.. _table-mapping:\n.. table:: Safe API function mapping\n' - assert old_content.strip().startswith(table_directive) - - lines = [] - w = lines.append - w(':widths: auto') - w('') - mapping = {x.cpython_name: x.name for x in self.api.functions if x.cpython_name} - mapping.update(DOC_MANUAL_API_MAPPING) - max_width0 = 0 - max_width1 = 0 - rows = [] - cpy_functions = list(mapping.keys()) - # sort the list of functions by 'cpython_name' - cpy_functions.sort() - for cpy_func in cpy_functions: - assert cpy_func - page = self._get_page(cpy_func) - col0 = f'`{cpy_func} `_' - col1 = f':c:func:`{mapping[cpy_func]}`' - rows.append((col0, col1)) - max_width0 = max(max_width0, len(col0)) - max_width1 = max(max_width1, len(col1)) - - sep = '=' * max_width0 + ' ' + '=' * max_width1 - w(sep) - w('C API function'.ljust(max_width0) + ' HPY API function') - w(sep) - for row in rows: - w(f'{row[0].ljust(max_width0)} {row[1]}') - w(sep) - w('') - return table_directive + textwrap.indent('\n'.join(lines), ' ' * 4) - - -class autogen_hpy_ctx(AutoGenRstFile): - PATH = 'docs/api-reference/hpy-ctx.rst' - - def generate(self): - lines = [] - w = lines.append - w(textwrap.dedent( - ''' - HPy Context - =========== - - The ``HPyContext`` structure is also part of the API since it provides handles - for built-in objects. For a high-level description of the context, please also - read :ref:`api:hpycontext`. - - .. warning:: It is fine to use handles from the context (e.g. ``ctx->h_None``) - but it is **STRONGLY** discouraged to directly call any context function. - This is because, for example, when compiling for :term:`CPython ABI`, the - context functions won't be used. - ''')) - # Put all variable declarations into a list in order - # to be able to sort them by their given context index. - var_decls = list(self.api.variables) - - # sort the list of var declaration by 'decl.ctx_index' - var_decls.sort(key=lambda x: x.ctx_index) - - w(f'.. c:struct:: {CTX_NAME}') - w(f' :module: {autogen_ctx_h.PATH}') - w('') - w(f' .. c:member:: const char *{CTX_NAME}.name') - w('') - w(f' .. c:member:: int {CTX_NAME}.abi_version') - for var in var_decls: - w('') - w(f' .. c:member:: {toC(var.node)}') - return '\n'.join(lines) - diff --git a/graalpython/hpy/hpy/tools/autogen/hpyfunc.py b/graalpython/hpy/hpy/tools/autogen/hpyfunc.py deleted file mode 100644 index 1e233277f2..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/hpyfunc.py +++ /dev/null @@ -1,204 +0,0 @@ -from copy import deepcopy -from pycparser import c_ast -from .autogenfile import AutoGenFile -from .parse import toC, find_typedecl - -NO_CALL = ('VARARGS', 'KEYWORDS', 'INITPROC', 'DESTROYFUNC', - 'GETBUFFERPROC', 'RELEASEBUFFERPROC', 'TRAVERSEPROC', 'MOD_CREATE', - 'VECTORCALLFUNC', 'NEWFUNC') -NO_TRAMPOLINE = NO_CALL + ('RICHCMPFUNC',) - -# This is a list of type that can automatically be converted from Python to HPy -# and vice versa. -AUTO_CONVERSION_TYPES = ('HPy', 'HPy_ssize_t', 'void *', 'int', 'char *', - 'HPy_hash_t', 'HPy_RichCmpOp', 'void') - -class autogen_hpyfunc_declare_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/autogen_hpyfunc_declare.h' - - ## #define _HPyFunc_DECLARE_HPyFunc_NOARGS(SYM) \ - ## static HPy SYM(HPyContext *ctx, HPy self) - - def generate(self): - lines = [] - w = lines.append - for hpyfunc in self.api.hpyfunc_typedefs: - # declare a function named 'SYM' of the appropriate type - funcdecl = hpyfunc.node.type.type - symdecl = deepcopy(funcdecl) - if isinstance(symdecl.type, c_ast.PtrDecl): - symdecl.type = symdecl.type.type - symdecl.type.declname = 'SYM' - symdecl = toC(symdecl) - # - # generate a macro emitting 'symdecl' - name = hpyfunc.base_name().upper() - w(f'#define _HPyFunc_DECLARE_HPyFunc_{name}(SYM) static {symdecl}') - w('') - - for hpyfunc in self.api.hpyfunc_typedefs: - # generate the typedef for HPyFunc_{base_name} - w(f'{toC(hpyfunc.node)};') - - return '\n'.join(lines) - - -def hpy_to_cpy(declnode): - if toC(declnode.type) == 'HPy': - declnode = deepcopy(declnode) - declnode.type.type.names = ['cpy_PyObject'] - declnode.type = c_ast.PtrDecl(type=declnode.type, quals=[]) - return declnode - - -class autogen_hpyfunc_trampoline_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/universal/autogen_hpyfunc_trampolines.h' - - def generate(self): - lines = [] - w = lines.append - for hpyfunc in self.api.hpyfunc_typedefs: - NAME = hpyfunc.base_name().upper() - if NAME in NO_TRAMPOLINE: - continue - # - tramp_node = deepcopy(hpyfunc.node.type.type) - if isinstance(tramp_node.type, c_ast.PtrDecl): - tramp_node.type = tramp_node.type.type - tramp_node.type.declname = 'SYM' - tramp_node = hpy_to_cpy(tramp_node) - assert toC(tramp_node.args.params[0].type) in ['void', 'HPyContext *'] - tramp_node.args.params = [hpy_to_cpy(p) - for p in tramp_node.args.params[1:]] - for i, param in enumerate(tramp_node.args.params): - typedecl = find_typedecl(param.type) - if typedecl.declname is None: - param.name = 'arg%d' % i - typedecl.declname = 'arg%d' % i - arg_names = [param.name for param in tramp_node.args.params] - arg_names = ', '.join(arg_names) - # - # generate the struct that will contain all parameters - w(f'typedef struct {{') - for param in tramp_node.args.params: - w(f' {toC(param)};') - if toC(tramp_node.type) != 'void': - w(f' {toC(tramp_node.type)} result;') - w(f'}} _HPyFunc_args_{NAME};') - w('') - # - # generate the trampoline itself - w(f'#define _HPyFunc_TRAMPOLINE_HPyFunc_{NAME}(SYM, IMPL) \\') - w(f' static {toC(tramp_node)} \\') - w(f' {{ \\') - w(f' _HPyFunc_args_{NAME} a = {{ {arg_names} }}; \\') - w(f' _HPy_CallRealFunctionFromTrampoline( \\') - w(f' _ctx_for_trampolines, HPyFunc_{NAME}, (HPyCFunction)IMPL, &a); \\') - if toC(tramp_node.type) == 'void': - w(f' return; \\') - else: - w(f' return a.result; \\') - w(f' }}') - w('') - return '\n'.join(lines) - - -def _py2h(type): - if type == 'HPy': - return '_py2h' - elif type in AUTO_CONVERSION_TYPES: - return '' - raise TypeError(f'cannot generate automatic conversion for type \'{type}\'') - - -def _h2py(type): - if type == 'HPy': - return '_h2py' - elif type in AUTO_CONVERSION_TYPES: - return '' - raise TypeError(f'cannot generate automatic conversion for type \'{type}\'') - - -class autogen_ctx_call_i(AutoGenFile): - PATH = 'hpy/universal/src/autogen_ctx_call.i' - - def generate(self): - lines = [] - w = lines.append - for hpyfunc in self.api.hpyfunc_typedefs: - name = hpyfunc.base_name() - NAME = name.upper() - if NAME in NO_CALL: - continue - # - c_ret_type = toC(hpyfunc.return_type()) - args = ['ctx'] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = 'arg%d' % i - args.append(f'{_py2h(toC(param.type))}(a->{pname})') - args = ', '.join(args) - # - w(f' case HPyFunc_{NAME}: {{') - w(f' HPyFunc_{name} f = (HPyFunc_{name})func;') - w(f' _HPyFunc_args_{NAME} *a = (_HPyFunc_args_{NAME}*)args;') - if c_ret_type == 'void': - w(f' f({args});') - else: - w(f' a->result = {_h2py(c_ret_type)}(f({args}));') - w(f' return;') - w(f' }}') - return '\n'.join(lines) - - -class autogen_cpython_hpyfunc_trampoline_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/cpython/autogen_hpyfunc_trampolines.h' - - def generate(self): - lines = [] - w = lines.append - for hpyfunc in self.api.hpyfunc_typedefs: - name = hpyfunc.base_name() - NAME = name.upper() - if NAME in NO_TRAMPOLINE: - continue - # - tramp_node = deepcopy(hpyfunc.node.type.type) - if isinstance(tramp_node.type, c_ast.PtrDecl): - tramp_node.type = tramp_node.type.type - tramp_node.type.declname = 'SYM' - tramp_node = hpy_to_cpy(tramp_node) - tramp_node.args.params = [hpy_to_cpy(p) - for p in tramp_node.args.params[1:]] - for i, param in enumerate(tramp_node.args.params): - typedecl = find_typedecl(param.type) - if typedecl.declname is None: - param.name = 'arg%d' % i - typedecl.declname = 'arg%d' % i - - result = _h2py(toC(hpyfunc.return_type())) - args = ['_HPyGetContext()'] - func_ptr_ret_type = toC(hpyfunc.return_type()) - func_ptr_sig = ['HPyContext *'] - for i, param in enumerate(hpyfunc.params()[1:]): - pname = param.name - if pname is None: - pname = 'arg%d' % i - func_ptr_sig.append(toC(param.type)) - args.append(f'{_py2h(toC(param.type))}({pname})') - args = ', '.join(args) - func_ptr_sig = ', '.join(func_ptr_sig) - # - w(f'typedef {func_ptr_ret_type} (*_HPyCFunction_{NAME})({func_ptr_sig});') - w(f'#define _HPyFunc_TRAMPOLINE_HPyFunc_{NAME}(SYM, IMPL) \\') - w(f' static {toC(tramp_node)} \\') - w(f' {{ \\') - w(f' _HPyCFunction_{NAME} func = (_HPyCFunction_{NAME})IMPL; \\') - if toC(tramp_node.type) == 'void': - w(f' func({args}); \\') - w(f' return; \\') - else: - w(f' return {result}(func({args})); \\') - w(f' }}') - return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/hpyslot.py b/graalpython/hpy/hpy/tools/autogen/hpyslot.py deleted file mode 100644 index 3eff4d81ca..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/hpyslot.py +++ /dev/null @@ -1,18 +0,0 @@ -from pycparser import c_ast -from .autogenfile import AutoGenFile -from .parse import toC - -class autogen_hpyslot_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/autogen_hpyslot.h' - - def generate(self): - lines = [] - w = lines.append - w('typedef enum {') - for slot in self.api.hpyslots: - w(f' {slot.name} = {slot.value},') - w('} HPySlot_Slot;') - w('') - for slot in self.api.hpyslots: - w(f'#define _HPySlot_SIG__{slot.name} {slot.hpyfunc}') - return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/parse.py b/graalpython/hpy/hpy/tools/autogen/parse.py deleted file mode 100644 index 578317b458..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/parse.py +++ /dev/null @@ -1,278 +0,0 @@ -from copy import deepcopy -import sys -import attr -import re -import pycparser -import shutil -from pathlib import Path -from pycparser import c_ast -from pycparser.c_generator import CGenerator -from sysconfig import get_config_var -from .conf import SPECIAL_CASES, RETURN_CONSTANT - -CURRENT_DIR = Path(__file__).resolve().parent -PUBLIC_API_H = CURRENT_DIR / 'public_api.h' -AUTOGEN_H = CURRENT_DIR / 'autogen.h' - - -def toC(node): - return toC.gen.visit(node) -toC.gen = CGenerator() - -def find_typedecl(node): - while not isinstance(node, c_ast.TypeDecl): - node = node.type - return node - -def get_context_return_type(func_node, const_return): - return 'void' if const_return else toC(func_node.type.type) - -def make_void(func_node): - voidid = c_ast.IdentifierType(names=['void']) - func_node.type.type.type = c_ast.TypeDecl(declname='void', quals=[], align=[], type=voidid) - -def get_return_constant(func): - return RETURN_CONSTANT.get(func.node.name) - -def maybe_make_void(func, node): - if RETURN_CONSTANT.get(func.node.name): - make_void(node) - -@attr.s -class Function: - _BASE_NAME = re.compile(r'^_?HPy_?') - - name = attr.ib() - cpython_name = attr.ib() - ctx_index = attr.ib() - node = attr.ib(repr=False) - - def base_name(self): - return self._BASE_NAME.sub('', self.name) - - def ctx_name(self): - # e.g. "ctx_Module_Create" - return self._BASE_NAME.sub(r'ctx_', self.name) - - def is_varargs(self): - return (len(self.node.type.args.params) > 0 and - isinstance(self.node.type.args.params[-1], c_ast.EllipsisParam)) - - -@attr.s -class GlobalVar: - name = attr.ib() - ctx_index = attr.ib() - node = attr.ib(repr=False) - - def ctx_name(self): - return self.name - - -@attr.s -class HPyFunc: - _BASE_NAME = re.compile(r'^HPyFunc_?') - - name = attr.ib() - node = attr.ib(repr=False) - - def base_name(self): - return self._BASE_NAME.sub('', self.name) - - def params(self): - return self.node.type.type.args.params - - def return_type(self): - return self.node.type.type.type - -@attr.s -class HPySlot: - # represent a declaration contained inside enum HPySlot_Slot, such as: - # HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC) - - name = attr.ib() # "HPy_nb_add" - value = attr.ib() # "7" - hpyfunc = attr.ib() # "HPyFunc_BINARYFUNC" - node = attr.ib(repr=False) - - -class HPyAPIVisitor(pycparser.c_ast.NodeVisitor): - def __init__(self, api, convert_name): - self.api = api - self.convert_name = convert_name - self.cur_index = -1 - self.all_indices = [] - - def _consume_ctx_index(self): - idx = self.cur_index - self.all_indices.append(idx) - self.cur_index = -1 - return idx - - def verify_context_indices(self): - """ - Verifies if context indices are without gaps. This function raises an - assertion error if not. - For example: - [0, 1, 2, 3] is valid - [0, 1, 3] is invalid - """ - self.all_indices.sort() - for i in range(1, len(self.all_indices)): - prev = self.all_indices[i-1] - cur = self.all_indices[i] - assert prev + 1 == cur, \ - "context indices have gaps: %s -> %s" % (prev, cur) - - def _is_function_ptr(self, node): - return (isinstance(node, c_ast.PtrDecl) and - isinstance(node.type, c_ast.FuncDecl)) - - def visit_Decl(self, node): - if isinstance(node.type, c_ast.FuncDecl): - self._visit_function(node) - elif isinstance(node.type, c_ast.TypeDecl): - self._visit_global_var(node) - - def visit_Typedef(self, node): - # find only typedefs to function pointers whose name starts by HPyFunc_ - if node.name.startswith('HPyFunc_') and self._is_function_ptr(node.type): - self._visit_hpyfunc_typedef(node) - elif node.name == 'HPySlot_Slot': - self._visit_hpyslot_slot(node) - - def visit_Pragma(self, node): - parts = node.string.split('=') - if len(parts) != 2: - raise ValueError('invalid pragma: %s' % node) - self.cur_index = int(parts[1]) - - def _visit_function(self, node): - name = node.name - if not name.startswith('HPy') and not name.startswith('_HPy'): - print('WARNING: Ignoring non-hpy declaration: %s' % name) - return - for p in node.type.args.params: - if hasattr(p, 'name') and p.name is None: - raise ValueError("non-named argument in declaration of %s" % - name) - cpy_name = self.convert_name(name) - idx = self._consume_ctx_index() - if idx == -1: - raise ValueError('missing context index for %s' % name) - func = Function(name, cpy_name, idx, node) - self.api.functions.append(func) - - def _visit_global_var(self, node): - name = node.name - if not name.startswith('h_'): - print('WARNING: Ignoring non-hpy variable declaration: %s' % name) - return - assert toC(node.type.type) == "HPy" - idx = self._consume_ctx_index() - if idx == -1: - raise ValueError('missing context index for %s' % name) - var = GlobalVar(name, idx, node) - self.api.variables.append(var) - - def _visit_hpyfunc_typedef(self, node): - hpyfunc = HPyFunc(node.name, node) - self.api.hpyfunc_typedefs.append(hpyfunc) - - def _visit_hpyslot_slot(self, node): - for e in node.type.type.values.enumerators: - call = e.value - assert isinstance(call, c_ast.FuncCall) and call.name.name == 'SLOT' - assert len(call.args.exprs) == 2 - const_value, id_hpyfunc = call.args.exprs - assert isinstance(const_value, c_ast.Constant) and const_value.type == 'int' - assert isinstance(id_hpyfunc, c_ast.ID) - value = const_value.value - hpyfunc = id_hpyfunc.name - self.api.hpyslots.append(HPySlot(e.name, value, hpyfunc, e)) - - -def convert_name(hpy_name): - if hpy_name in SPECIAL_CASES: - return SPECIAL_CASES[hpy_name] - return re.sub(r'^_?HPy_?', 'Py', hpy_name) - - -class HPyAPI: - _r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", - re.DOTALL | re.MULTILINE) - - def __init__(self, filename): - cpp_cmd = get_config_var('CC') - if cpp_cmd: - cpp_cmd = cpp_cmd.split(' ') - elif sys.platform == 'win32': - cpp_cmd = [shutil.which("cl.exe")] - if sys.platform == 'win32': - cpp_cmd += ['/E', '/I%s' % str(CURRENT_DIR)] - else: - cpp_cmd += ['-E', '-I%s' % str(CURRENT_DIR)] - - msvc = "cl.exe" in cpp_cmd[0].casefold() - - csource = pycparser.preprocess_file(str(filename), - cpp_path=str(cpp_cmd[0]), - cpp_args=cpp_cmd[1:]) - - # MSVC preprocesses _Pragma(foo) to __pragma(foo), - # but cparser needs to see a #pragma, not __pragma. - if msvc: - csource = re.sub(r'__pragma\(([^)]+)\)', r'#pragma \1\n', csource) - - # Remove comments. NOTE: this assumes that comments are never inside - # string literals, but there shouldn't be any here. - def replace_keeping_newlines(m): - return ' ' + m.group().count('\n') * '\n' - csource = self._r_comment.sub(replace_keeping_newlines, csource) - self.ast = pycparser.CParser().parse(csource) - ## print(); self.ast.show() - self.collect_declarations() - - @classmethod - def parse(cls, filename): - return cls(filename) - - def get_func(self, name): - return self._lookup(name, self.functions) - - def get_var(self, name): - return self._lookup(name, self.variables) - - def get_hpyfunc_typedef(self, name): - return self._lookup(name, self.hpyfunc_typedefs) - - def get_slot(self, name): - return self._lookup(name, self.hpyslots) - - def _lookup(self, name, collection): - for x in collection: - if x.name == name: - return x - raise KeyError(name) - - def collect_declarations(self): - self.functions = [] - self.variables = [] - self.hpyfunc_typedefs = [] - self.hpyslots = [] - v = HPyAPIVisitor(self, convert_name) - v.visit(self.ast) - - v.verify_context_indices() - - # Sort lists such that the generated files are deterministic. - # List elements are either 'Function', 'GlobalVar', or 'HPyFunc'. All - # of them have a 'node' attribute and the nodes have a 'coord' attr - # that provides the line and column number. We use that to sort. - def node_key(e): - coord = e.node.coord - return coord.line, coord.column - self.functions.sort(key=node_key) - self.variables.sort(key=node_key) - self.hpyfunc_typedefs.sort(key=node_key) - self.hpyslots.sort(key=node_key) diff --git a/graalpython/hpy/hpy/tools/autogen/public_api.h b/graalpython/hpy/hpy/tools/autogen/public_api.h deleted file mode 100644 index b081d943a8..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/public_api.h +++ /dev/null @@ -1,1557 +0,0 @@ -/* HPy public API */ - -/* - * IMPORTANT: In order to ensure backwards compatibility of HPyContext, it is - * necessary to define the order of the context members. To do so, use macro - * 'HPy_ID(idx)' for context handles and functions. When adding members, it - * doesn't matter where they are located in this file. It's just important that - * the maximum context index is incremented by exactly one. - */ - -#ifdef AUTOGEN - -/* Constants */ -HPy_ID(0) HPy h_None; -HPy_ID(1) HPy h_True; -HPy_ID(2) HPy h_False; -HPy_ID(3) HPy h_NotImplemented; -HPy_ID(4) HPy h_Ellipsis; - -/* Exceptions */ -HPy_ID(5) HPy h_BaseException; -HPy_ID(6) HPy h_Exception; -HPy_ID(7) HPy h_StopAsyncIteration; -HPy_ID(8) HPy h_StopIteration; -HPy_ID(9) HPy h_GeneratorExit; -HPy_ID(10) HPy h_ArithmeticError; -HPy_ID(11) HPy h_LookupError; -HPy_ID(12) HPy h_AssertionError; -HPy_ID(13) HPy h_AttributeError; -HPy_ID(14) HPy h_BufferError; -HPy_ID(15) HPy h_EOFError; -HPy_ID(16) HPy h_FloatingPointError; -HPy_ID(17) HPy h_OSError; -HPy_ID(18) HPy h_ImportError; -HPy_ID(19) HPy h_ModuleNotFoundError; -HPy_ID(20) HPy h_IndexError; -HPy_ID(21) HPy h_KeyError; -HPy_ID(22) HPy h_KeyboardInterrupt; -HPy_ID(23) HPy h_MemoryError; -HPy_ID(24) HPy h_NameError; -HPy_ID(25) HPy h_OverflowError; -HPy_ID(26) HPy h_RuntimeError; -HPy_ID(27) HPy h_RecursionError; -HPy_ID(28) HPy h_NotImplementedError; -HPy_ID(29) HPy h_SyntaxError; -HPy_ID(30) HPy h_IndentationError; -HPy_ID(31) HPy h_TabError; -HPy_ID(32) HPy h_ReferenceError; -HPy_ID(33) HPy h_SystemError; -HPy_ID(34) HPy h_SystemExit; -HPy_ID(35) HPy h_TypeError; -HPy_ID(36) HPy h_UnboundLocalError; -HPy_ID(37) HPy h_UnicodeError; -HPy_ID(38) HPy h_UnicodeEncodeError; -HPy_ID(39) HPy h_UnicodeDecodeError; -HPy_ID(40) HPy h_UnicodeTranslateError; -HPy_ID(41) HPy h_ValueError; -HPy_ID(42) HPy h_ZeroDivisionError; -HPy_ID(43) HPy h_BlockingIOError; -HPy_ID(44) HPy h_BrokenPipeError; -HPy_ID(45) HPy h_ChildProcessError; -HPy_ID(46) HPy h_ConnectionError; -HPy_ID(47) HPy h_ConnectionAbortedError; -HPy_ID(48) HPy h_ConnectionRefusedError; -HPy_ID(49) HPy h_ConnectionResetError; -HPy_ID(50) HPy h_FileExistsError; -HPy_ID(51) HPy h_FileNotFoundError; -HPy_ID(52) HPy h_InterruptedError; -HPy_ID(53) HPy h_IsADirectoryError; -HPy_ID(54) HPy h_NotADirectoryError; -HPy_ID(55) HPy h_PermissionError; -HPy_ID(56) HPy h_ProcessLookupError; -HPy_ID(57) HPy h_TimeoutError; -// EnvironmentError, IOError and WindowsError are intentionally omitted (they -// are all aliases of OSError since Python 3.3). - -/* Warnings */ -HPy_ID(58) HPy h_Warning; -HPy_ID(59) HPy h_UserWarning; -HPy_ID(60) HPy h_DeprecationWarning; -HPy_ID(61) HPy h_PendingDeprecationWarning; -HPy_ID(62) HPy h_SyntaxWarning; -HPy_ID(63) HPy h_RuntimeWarning; -HPy_ID(64) HPy h_FutureWarning; -HPy_ID(65) HPy h_ImportWarning; -HPy_ID(66) HPy h_UnicodeWarning; -HPy_ID(67) HPy h_BytesWarning; -HPy_ID(68) HPy h_ResourceWarning; - -/* Types */ -HPy_ID(69) HPy h_BaseObjectType; /* built-in 'object' */ -HPy_ID(70) HPy h_TypeType; /* built-in 'type' */ -HPy_ID(71) HPy h_BoolType; /* built-in 'bool' */ -HPy_ID(72) HPy h_LongType; /* built-in 'int' */ -HPy_ID(73) HPy h_FloatType; /* built-in 'float' */ -HPy_ID(74) HPy h_UnicodeType; /* built-in 'str' */ -HPy_ID(75) HPy h_TupleType; /* built-in 'tuple' */ -HPy_ID(76) HPy h_ListType; /* built-in 'list' */ -HPy_ID(238) HPy h_ComplexType; /* built-in 'complex' */ -HPy_ID(239) HPy h_BytesType; /* built-in 'bytes' */ -HPy_ID(240) HPy h_MemoryViewType; /* built-in 'memoryview' */ -HPy_ID(241) HPy h_CapsuleType; /* built-in 'capsule' */ -HPy_ID(242) HPy h_SliceType; /* built-in 'slice' */ -HPy_ID(263) HPy h_DictType; /* built-in 'dict' */ - -/* Reflection */ -HPy_ID(243) HPy h_Builtins; /* dict of builtins */ - -#endif - -HPy_ID(77) -HPy HPy_Dup(HPyContext *ctx, HPy h); -HPy_ID(78) -void HPy_Close(HPyContext *ctx, HPy h); - -HPy_ID(79) -HPy HPyLong_FromInt32_t(HPyContext *ctx, int32_t value); -HPy_ID(80) -HPy HPyLong_FromUInt32_t(HPyContext *ctx, uint32_t value); -HPy_ID(81) -HPy HPyLong_FromInt64_t(HPyContext *ctx, int64_t v); -HPy_ID(82) -HPy HPyLong_FromUInt64_t(HPyContext *ctx, uint64_t v); -HPy_ID(83) -HPy HPyLong_FromSize_t(HPyContext *ctx, size_t value); -HPy_ID(84) -HPy HPyLong_FromSsize_t(HPyContext *ctx, HPy_ssize_t value); - -HPy_ID(85) -int32_t HPyLong_AsInt32_t(HPyContext *ctx, HPy h); -HPy_ID(86) -uint32_t HPyLong_AsUInt32_t(HPyContext *ctx, HPy h); -HPy_ID(87) -uint32_t HPyLong_AsUInt32_tMask(HPyContext *ctx, HPy h); -HPy_ID(88) -int64_t HPyLong_AsInt64_t(HPyContext *ctx, HPy h); -HPy_ID(89) -uint64_t HPyLong_AsUInt64_t(HPyContext *ctx, HPy h); -HPy_ID(90) -uint64_t HPyLong_AsUInt64_tMask(HPyContext *ctx, HPy h); -HPy_ID(91) -size_t HPyLong_AsSize_t(HPyContext *ctx, HPy h); -HPy_ID(92) -HPy_ssize_t HPyLong_AsSsize_t(HPyContext *ctx, HPy h); -HPy_ID(93) -void* HPyLong_AsVoidPtr(HPyContext *ctx, HPy h); -HPy_ID(94) -double HPyLong_AsDouble(HPyContext *ctx, HPy h); - -HPy_ID(95) -HPy HPyFloat_FromDouble(HPyContext *ctx, double v); -HPy_ID(96) -double HPyFloat_AsDouble(HPyContext *ctx, HPy h); - -HPy_ID(97) -HPy HPyBool_FromBool(HPyContext *ctx, bool v); - - -/* abstract.h */ -HPy_ID(98) -HPy_ssize_t HPy_Length(HPyContext *ctx, HPy h); - -HPy_ID(99) -int HPyNumber_Check(HPyContext *ctx, HPy h); -HPy_ID(100) -HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(101) -HPy HPy_Subtract(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(102) -HPy HPy_Multiply(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(103) -HPy HPy_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(104) -HPy HPy_FloorDivide(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(105) -HPy HPy_TrueDivide(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(106) -HPy HPy_Remainder(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(107) -HPy HPy_Divmod(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(108) -HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3); -HPy_ID(109) -HPy HPy_Negative(HPyContext *ctx, HPy h1); -HPy_ID(110) -HPy HPy_Positive(HPyContext *ctx, HPy h1); -HPy_ID(111) -HPy HPy_Absolute(HPyContext *ctx, HPy h1); -HPy_ID(112) -HPy HPy_Invert(HPyContext *ctx, HPy h1); -HPy_ID(113) -HPy HPy_Lshift(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(114) -HPy HPy_Rshift(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(115) -HPy HPy_And(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(116) -HPy HPy_Xor(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(117) -HPy HPy_Or(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(118) -HPy HPy_Index(HPyContext *ctx, HPy h1); -HPy_ID(119) -HPy HPy_Long(HPyContext *ctx, HPy h1); -HPy_ID(120) -HPy HPy_Float(HPyContext *ctx, HPy h1); - -HPy_ID(121) -HPy HPy_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(122) -HPy HPy_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(123) -HPy HPy_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(124) -HPy HPy_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(125) -HPy HPy_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(126) -HPy HPy_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(127) -HPy HPy_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(128) -HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3); -HPy_ID(129) -HPy HPy_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(130) -HPy HPy_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(131) -HPy HPy_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(132) -HPy HPy_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2); -HPy_ID(133) -HPy HPy_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2); - -HPy_ID(134) -int HPyCallable_Check(HPyContext *ctx, HPy h); - -/** - * Call a Python object. - * - * :param ctx: - * The execution context. - * :param callable: - * A handle to the Python object to call (must not be ``HPy_NULL``). - * :param args: - * A handle to a tuple containing the positional arguments (must not be - * ``HPy_NULL`` but can, of course, be empty). - * :param kw: - * A handle to a Python dictionary containing the keyword arguments (may be - * ``HPy_NULL``). - * - * :returns: - * The result of the call on success, or ``HPy_NULL`` in case of an error. - */ -HPy_ID(135) -HPy HPy_CallTupleDict(HPyContext *ctx, HPy callable, HPy args, HPy kw); - -/** - * Call a Python object. - * - * :param ctx: - * The execution context. - * :param callable: - * A handle to the Python object to call (must not be ``HPy_NULL``). - * :param args: - * A pointer to an array of positional and keyword arguments. This argument - * must not be ``NULL`` if ``nargs > 0`` or - * ``HPy_Length(ctx, kwnames) > 0``. - * :param nargs: - * The number of positional arguments in ``args``. - * :param kwnames: - * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). - * The values of the keyword arguments are also passed in ``args`` appended - * to the positional arguments. Argument ``nargs`` does not include the - * keyword argument count. - * - * :returns: - * The result of the call on success, or ``HPy_NULL`` in case of an error. - */ -HPy_ID(261) -HPy HPy_Call(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); - -/** - * Call a method of a Python object. - * - * :param ctx: - * The execution context. - * :param name: - * A handle to the name (a Unicode object) of the method. Must not be - * ``HPy_NULL``. - * :param args: - * A pointer to an array of the arguments. The receiver is ``args[0]``, and - * the positional and keyword arguments are starting at ``args[1]``. This - * argument must not be ``NULL`` since a receiver is always required. - * :param nargs: - * The number of positional arguments in ``args`` including the receiver at - * ``args[0]`` (therefore, ``nargs`` must be at least ``1``). - * :param kwnames: - * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). - * The values of the keyword arguments are also passed in ``args`` appended - * to the positional arguments. Argument ``nargs`` does not include the - * keyword argument count. - * - * :returns: - * The result of the call on success, or ``HPy_NULL`` in case of an error. - */ -HPy_ID(262) -HPy HPy_CallMethod(HPyContext *ctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); - -/** - * Return a new iterator for iterable object ``obj``. This is the equivalent - * of the Python expression ``iter(obj)``. - * - * :param ctx: - * The execution context. - * :param obj: - * An iterable Python object (must not be ``HPy_NULL``). If the object is - * not iterable, a ``TypeError`` will be raised. - * - * :returns: - * The new iterator, ``obj`` itself if it is already an iterator, or - * ``HPy_NULL`` on failure. - */ -HPy_ID(269) -HPy HPy_GetIter(HPyContext *ctx, HPy obj); - -/** - * Return the next value from iterator ``obj``. - * - * :param ctx: - * The execution context. - * :param obj: - * An iterator Python object (must not be ``HPy_NULL``). This can be - * verified with ``HPy_IterCheck``. Otherwise, the behavior is undefined. - * - * :returns: - * The new value in iterator ``obj``, or ``HPy_NULL`` on failure. If the - * iterator was exhausted normally, an exception will not be set. In - * case of some other error, one will be set. - */ -HPy_ID(270) -HPy HPyIter_Next(HPyContext *ctx, HPy obj); - -/** - * Tests if an object is an instance of a Python iterator. - * - * :param ctx: - * The execution context. - * :param obj: - * A handle to an arbitrary object (must not be ``HPy_NULL``). - * - * :returns: - * Non-zero if object ``obj`` provides the ``Iterator`` protocol, and ``0`` - * otherwise. - */ -HPy_ID(271) -int HPyIter_Check(HPyContext *ctx, HPy obj); - -/* pyerrors.h */ -HPy_ID(136) -void HPy_FatalError(HPyContext *ctx, const char *message); -HPy_ID(137) -HPy HPyErr_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message); -HPy_ID(138) -HPy HPyErr_SetObject(HPyContext *ctx, HPy h_type, HPy h_value); - -/** - * Similar to :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but takes one - * filename (a C string) that will be decoded using - * :c:func:`HPyUnicode_DecodeFSDefault`. - * - * :param ctx: - * The execution context. - * :param h_type: - * The exception type to raise. - * :param filename_fsencoded: - * a filename; may be ``NULL`` - * - * :return: - * always returns ``HPy_NULL`` - */ -HPy_ID(139) -HPy HPyErr_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded); - -/** - * A convenience function to raise an exception when a C library function has - * returned an error and set the C variable ``errno``. It constructs an - * instance of the provided exception type ``h_type`` by calling - * ``h_type(errno, strerror(errno), filename1, 0, filename2)``. The exception - * instance is then raised. - * - * :param ctx: - * The execution context. - * :param h_type: - * The exception type to raise. - * :param filename1: - * A filename; may be ``HPy_NULL``. In the case of ``h_type`` is the - * ``OSError`` exception, this is used to define the filename attribute of - * the exception instance. - * :param filename2: - * another filename argument; may be ``HPy_NULL`` - * - * :return: - * always returns ``HPy_NULL`` - */ -HPy_ID(140) -HPy HPyErr_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2); -/* note: HPyErr_Occurred() returns a flag 0-or-1, instead of a 'PyObject *' */ -HPy_ID(141) -int HPyErr_Occurred(HPyContext *ctx); -HPy_ID(142) -int HPyErr_ExceptionMatches(HPyContext *ctx, HPy exc); -HPy_ID(143) -HPy HPyErr_NoMemory(HPyContext *ctx); -HPy_ID(144) -void HPyErr_Clear(HPyContext *ctx); -HPy_ID(145) -HPy HPyErr_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict); -HPy_ID(146) -HPy HPyErr_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict); -HPy_ID(147) -int HPyErr_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level); -HPy_ID(148) -void HPyErr_WriteUnraisable(HPyContext *ctx, HPy obj); - -/* object.h */ -HPy_ID(149) -int HPy_IsTrue(HPyContext *ctx, HPy h); - -/** - * Create a type from a :c:struct:`HPyType_Spec` and an additional list of - * specification parameters. - * - * :param ctx: - * The execution context. - * :param spec: - * The type spec to use to create the type. - * :param params: - * A 0-terminated list of type specification parameters or ``NULL``. - * - * :returns: a handle of the created type on success, ``HPy_NULL`` on failure. - */ -HPy_ID(150) -HPy HPyType_FromSpec(HPyContext *ctx, HPyType_Spec *spec, - HPyType_SpecParam *params); -HPy_ID(151) -HPy HPyType_GenericNew(HPyContext *ctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); - -HPy_ID(152) -HPy HPy_GetAttr(HPyContext *ctx, HPy obj, HPy name); -HPy_ID(153) -HPy HPy_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name); - -HPy_ID(154) -int HPy_HasAttr(HPyContext *ctx, HPy obj, HPy name); -HPy_ID(155) -int HPy_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name); - -HPy_ID(156) -int HPy_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value); -HPy_ID(157) -int HPy_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value); - -HPy_ID(158) -HPy HPy_GetItem(HPyContext *ctx, HPy obj, HPy key); -HPy_ID(159) -HPy HPy_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx); -HPy_ID(160) -HPy HPy_GetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key); - -/** - * Return the slice of sequence object ``obj`` between ``start`` and ``end``. - * This is the equivalent of the Python expression ``obj[start:end]``. - * - * :param ctx: - * The execution context. - * :param obj: - * A sliceable Python object (must not be ``HPy_NULL`` otherwise a - * ``SystemError`` will be raised). If the object is not sliceable, a - * ``TypeError`` will be raised. - * :param start: - * The start index (inclusive). - * :param end: - * The end index (exclusive). - * - * :returns: - * The requested slice or ``HPy_NULL`` on failure. - */ -HPy_ID(266) -HPy HPy_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); - -HPy_ID(161) -int HPy_Contains(HPyContext *ctx, HPy container, HPy key); - -HPy_ID(162) -int HPy_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value); -HPy_ID(163) -int HPy_SetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx, HPy value); -HPy_ID(164) -int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *utf8_key, HPy value); - -/** - * Assign the sequence object ``value`` to the slice in sequence object ``obj`` - * from ``start`` to ``end``. This is the equivalent of the Python statement - * ``obj[start:end] = value``. - * - * :param ctx: - * The execution context. - * :param obj: - * A sliceable Python object (must not be ``HPy_NULL`` otherwise a - * ``SystemError`` will be raised). If the object is not sliceable, a - * ``TypeError`` will be raised. - * :param start: - * The start index (inclusive). - * :param end: - * The end index (exclusive). - * :param value: - * The sequence object to assign (must not be ``HPy_NULL``). - * - * :returns: - * ``0`` on success; ``-1`` on failure - */ -HPy_ID(267) -int HPy_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); - -HPy_ID(235) -int HPy_DelItem(HPyContext *ctx, HPy obj, HPy key); -HPy_ID(236) -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); - -/** - * Delete the slice of sequence object ``obj`` between ``start`` and ``end``. - * This is the equivalent of the Python statement ``del obj[start:end]``. - * - * :param ctx: - * The execution context. - * :param obj: - * A sliceable Python object (must not be ``HPy_NULL`` otherwise a - * ``SystemError`` will be raised). If the object is not sliceable, a - * ``TypeError`` will be raised. - * :param start: - * The start index (inclusive). - * :param end: - * The end index (exclusive). - * - * :returns: - * ``0`` on success; ``-1`` on failure - */ -HPy_ID(268) -int HPy_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); - -/** - * 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); - -/** - * 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); - -/** - * Return the type's name. - * - * Equivalent to getting the type's ``__name__`` attribute. If you want to - * retrieve the type's name as a handle that refers to a ``str``, then just use - * ``HPy_GetAttr_s(ctx, type, "__name__")``. - * - * :param ctx: - * The execution context. - * :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: - * The name of the type as C string (UTF-8 encoded) or ``NULL`` in case of - * an error. The returned pointer is read-only and guaranteed to be valid as - * long as the handle ``type`` is valid. - */ -HPy_ID(253) -const char *HPyType_GetName(HPyContext *ctx, HPy type); - -/** - * Checks if ``sub`` is a subtype of ``type``. - * - * This function only checks for actual subtypes, which means that - * ``__subclasscheck__()`` is not called on ``type``. - * - * :param ctx: - * The execution context. - * :param sub: - * 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). - * :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 ``sub`` is a subtype of ``type``. - */ -HPy_ID(254) -int HPyType_IsSubtype(HPyContext *ctx, HPy sub, HPy type); - -HPy_ID(167) -int HPy_Is(HPyContext *ctx, HPy obj, HPy other); - -HPy_ID(168) -void* _HPy_AsStruct_Object(HPyContext *ctx, HPy h); -HPy_ID(169) -void* _HPy_AsStruct_Legacy(HPyContext *ctx, HPy h); -HPy_ID(228) -void* _HPy_AsStruct_Type(HPyContext *ctx, HPy h); -HPy_ID(229) -void* _HPy_AsStruct_Long(HPyContext *ctx, HPy h); -HPy_ID(230) -void* _HPy_AsStruct_Float(HPyContext *ctx, HPy h); -HPy_ID(231) -void* _HPy_AsStruct_Unicode(HPyContext *ctx, HPy h); -HPy_ID(232) -void* _HPy_AsStruct_Tuple(HPyContext *ctx, HPy h); -HPy_ID(233) -void* _HPy_AsStruct_List(HPyContext *ctx, HPy h); -HPy_ID(264) -void* _HPy_AsStruct_Dict(HPyContext *ctx, HPy h); -HPy_ID(234) -HPyType_BuiltinShape _HPyType_GetBuiltinShape(HPyContext *ctx, HPy h_type); - -HPy_ID(170) -HPy _HPy_New(HPyContext *ctx, HPy h_type, void **data); - -HPy_ID(171) -HPy HPy_Repr(HPyContext *ctx, HPy obj); -HPy_ID(172) -HPy HPy_Str(HPyContext *ctx, HPy obj); -HPy_ID(173) -HPy HPy_ASCII(HPyContext *ctx, HPy obj); -HPy_ID(174) -HPy HPy_Bytes(HPyContext *ctx, HPy obj); - -HPy_ID(175) -HPy HPy_RichCompare(HPyContext *ctx, HPy v, HPy w, int op); -HPy_ID(176) -int HPy_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op); - -HPy_ID(177) -HPy_hash_t HPy_Hash(HPyContext *ctx, HPy obj); - -/* bytesobject.h */ -HPy_ID(178) -int HPyBytes_Check(HPyContext *ctx, HPy h); -HPy_ID(179) -HPy_ssize_t HPyBytes_Size(HPyContext *ctx, HPy h); -HPy_ID(180) -HPy_ssize_t HPyBytes_GET_SIZE(HPyContext *ctx, HPy h); -HPy_ID(181) -const char* HPyBytes_AsString(HPyContext *ctx, HPy h); -HPy_ID(182) -const char* HPyBytes_AS_STRING(HPyContext *ctx, HPy h); -HPy_ID(183) -HPy HPyBytes_FromString(HPyContext *ctx, const char *bytes); -HPy_ID(184) -HPy HPyBytes_FromStringAndSize(HPyContext *ctx, const char *bytes, HPy_ssize_t len); - -/* unicodeobject.h */ -HPy_ID(185) -HPy HPyUnicode_FromString(HPyContext *ctx, const char *utf8); -HPy_ID(186) -int HPyUnicode_Check(HPyContext *ctx, HPy h); -HPy_ID(187) -HPy HPyUnicode_AsASCIIString(HPyContext *ctx, HPy h); -HPy_ID(188) -HPy HPyUnicode_AsLatin1String(HPyContext *ctx, HPy h); -HPy_ID(189) -HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h); -HPy_ID(190) -const char* HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size); -HPy_ID(191) -HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size); -HPy_ID(192) -HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v); -HPy_ID(193) -HPy HPyUnicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size); -HPy_ID(194) -HPy HPyUnicode_EncodeFSDefault(HPyContext *ctx, HPy h); -HPy_ID(195) -HPy_UCS4 HPyUnicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index); -HPy_ID(196) -HPy HPyUnicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors); -HPy_ID(197) -HPy HPyUnicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors); - -/** - * Decode a bytes-like object to a Unicode object. - * - * The bytes of the bytes-like object are decoded according to the given - * encoding and using the error handling defined by ``errors``. - * - * :param ctx: - * The execution context. - * :param obj: - * A bytes-like object. This can be, for example, Python *bytes*, - * *bytearray*, *memoryview*, *array.array* and objects that support the - * Buffer protocol. If this argument is `HPy_NULL``, a ``SystemError`` will - * be raised. If the argument is not a bytes-like object, a ``TypeError`` - * will be raised. - * :param encoding: - * The name (UTF-8 encoded C string) of the encoding to use. If the encoding - * does not exist, a ``LookupError`` will be raised. If this argument is - * ``NULL``, the default encoding ``UTF-8`` will be used. - * :param errors: - * The error handling (UTF-8 encoded C string) to use when decoding. The - * possible values depend on the used encoding. This argument may be - * ``NULL`` in which case it will default to ``"strict"``. - * - * :returns: - * A handle to a ``str`` object created from the decoded bytes or - * ``HPy_NULL`` in case of errors. - */ -HPy_ID(255) -HPy HPyUnicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors); - -/** - * Return a substring of ``str``, from character index ``start`` (included) to - * character index ``end`` (excluded). - * - * Indices ``start`` and ``end`` must not be negative, otherwise an - * ``IndexError`` will be raised. If ``start >= len(str)`` or if - * ``end < start``, an empty string will be returned. If ``end > len(str)`` then - * ``end == len(str)`` will be assumed. - * - * :param ctx: - * The execution context. - * :param str: - * A Python Unicode object (must not be ``HPy_NULL``). Otherwise, the - * behavior is undefined (verification of the argument is only done in - * debug mode). - * :param start: - * The non-negative start index (inclusive). - * :param end: - * The non-negative end index (exclusive). - * - * :returns: - * The requested substring or ``HPy_NULL`` in case of an error. - */ -HPy_ID(256) -HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end); - -/* listobject.h */ - -/** - * Tests if an object is an instance of a Python list. - * - * :param ctx: - * The execution context. - * :param h: - * A handle to an arbitrary object (must not be ``HPy_NULL``). - * - * :returns: - * Non-zero if object ``h`` is an instance of type ``list`` or an instance - * of a subtype of ``list``, and ``0`` otherwise. - */ -HPy_ID(198) -int HPyList_Check(HPyContext *ctx, HPy h); - -/** - * Creates a new list instance with length ``len``. - * - * :param ctx: - * The execution context. - * :param len: - * A Python list object (must not be ``HPy_NULL``). Otherwise, a - * ``SystemError`` will be raised. - * - * :returns: - * The new list instance on success, or ``HPy_NULL`` on failure. - */ -HPy_ID(199) -HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len); - -/** - * Append item ``h_item`` to list ``h_list``. - * - * :param ctx: - * The execution context. - * :param h_list: - * A Python list object (must not be ``HPy_NULL``). Otherwise, a - * ``SystemError`` will be raised. - * :param h_item: - * The item to append (must not be ``HPy_NULL``). - * - * :returns: - * Return ``0`` if successful; return ``-1`` and set an exception if - * unsuccessful. - */ -HPy_ID(200) -int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item); - -/** - * Insert the item ``h_item`` into list ``h_list`` in front of index ``index``. - * - * :param ctx: - * The execution context. - * :param h_list: - * A Python list object (must not be ``HPy_NULL``). Otherwise, a - * ``SystemError`` will be raised. - * :param index: - * The index where the element should be inserted before. A negative index - * is allowed and is then interpreted to be relative to the end of sequence. - * E.g. ``index == -1`` is the last element. - * If ``index < -n`` (where ``n`` is the length of the list), it will be - * replaced by ``0``. If ``index > n``, it will be replaced by ``n``. - * :param h_item: - * The item to insert (must not be ``HPy_NULL``). - * - * :returns: - * Return ``0`` if successful; return ``-1`` and set an exception if - * unsuccessful. - */ -HPy_ID(265) -int HPyList_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item); - -/* dictobject.h */ - -/** - * Tests if an object is an instance of a Python dict. - * - * :param ctx: - * The execution context. - * :param h: - * A handle to an arbitrary object (must not be ``HPy_NULL``). - * - * :returns: - * Non-zero if object ``h`` is an instance of type ``dict`` or an instance - * of a subtype of ``dict``, and ``0`` otherwise. - */ -HPy_ID(201) -int HPyDict_Check(HPyContext *ctx, HPy h); - -/** - * Creates a new empty Python dictionary. - * - * :param ctx: - * The execution context. - * - * :returns: - * A handle to the new and empty Python dictionary or ``HPy_NULL`` in case - * of an error. - */ -HPy_ID(202) -HPy HPyDict_New(HPyContext *ctx); - -/** - * Returns a list of all keys from the dictionary. - * - * Note: This function will directly access the storage of the dict object and - * therefore ignores if method ``keys`` was overwritten. - * - * :param ctx: - * The execution context. - * :param h: - * A Python dict object. If this argument is ``HPy_NULL`` or not an - * instance of a Python dict, a ``SystemError`` will be raised. - * - * :returns: - * A Python list object containing all keys of the given dictionary or - * ``HPy_NULL`` in case of an error. - */ -HPy_ID(257) -HPy HPyDict_Keys(HPyContext *ctx, HPy h); - -/** - * Creates a copy of the provided Python dict object. - * - * :param ctx: - * The execution context. - * :param h: - * A Python dict object. If this argument is ``HPy_NULL`` or not an - * instance of a Python dict, a ``SystemError`` will be raised. - * - * :returns: - * Return a new dictionary that contains the same key-value pairs as ``h`` - * or ``HPy_NULL`` in case of an error. - */ -HPy_ID(258) -HPy HPyDict_Copy(HPyContext *ctx, HPy h); - -/* tupleobject.h */ - -/** - * Tests if an object is an instance of a Python tuple. - * - * :param ctx: - * The execution context. - * :param h: - * A handle to an arbitrary object (must not be ``HPy_NULL``). - * - * :returns: - * Non-zero if object ``h`` is an instance of type ``tuple`` or an instance - * of a subtype of ``tuple``, and ``0`` otherwise. - */ -HPy_ID(203) -int HPyTuple_Check(HPyContext *ctx, HPy h); - -/** - * Create a tuple from an array. - * - * Note: Consider to use the convenience function :c:func:`HPyTuple_Pack` to - * create a tuple. - * - * :param ctx: - * The execution context. - * :param items: - * An array of items to use for initialization of the tuple. - * :param n: - * The number of elements in array ``items``. - * - * :return: - * A new tuple with ``n`` elements or ``HPy_NULL`` in case of an error - * occurred. - */ -HPy_ID(204) -HPy HPyTuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n); - -/* sliceobject.h */ - -/** - * Creates a new empty Python slice object. - * - * :param ctx: - * The execution context. - * - * :param start: - * A handle to an object to be used as the slice start value. - * :param end: - * A handle to an object to be used as the slice end value. - * :param step: - * A handle to an object to be used as the slice step value. - * - * :returns: - * A handle to the new and empty Python slice object or ``HPy_NULL`` in case - * of an error. - */ -HPy_ID(272) -HPy HPySlice_New(HPyContext *ctx, HPy start, HPy stop, HPy step); - -/** - * Extract the start, stop and step data members from a slice object as C - * integers. - * - * The slice members may be arbitrary int-like objects. If they are not Python - * int objects, they will be coerced to int objects by calling their - * ``__index__`` method. - * - * If a slice member value is out of bounds, it will be set to the maximum value - * of ``HPy_ssize_t`` if the member was a positive number, or to the minimum - * value of ``HPy_ssize_t`` if it was a negative number. - * - * :param ctx: - * The execution context. - * :param slice: - * A handle to a Python slice object. This argument must be a slice object - * and must not be ``HPy_NULL``. Otherwise, behavior is undefined. - * :param start: - * A pointer to a variable where to write the unpacked slice start. Must not - * be ``NULL``. - * :param end: - * A pointer to a variable where to write the unpacked slice end. Must not - * :param step: - * A pointer to a variable where to write the unpacked slice step. Must not - * be ``NULL``. - * - * :returns: - * ``-1`` on error, ``0`` on success - */ - -HPy_ID(259) -int HPySlice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); - -/* import.h */ -HPy_ID(205) -HPy HPyImport_ImportModule(HPyContext *ctx, const char *utf8_name); - -/* pycapsule.h */ -HPy_ID(244) -HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); -HPy_ID(245) -void* HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); -HPy_ID(246) -int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name); -HPy_ID(247) -int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value); - -/* integration with the old CPython API */ -HPy_ID(206) -HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj); -HPy_ID(207) -cpy_PyObject *HPy_AsPyObject(HPyContext *ctx, HPy h); - -/* internal helpers which need to be exposed to modules for practical reasons :( */ -HPy_ID(208) -void _HPy_CallRealFunctionFromTrampoline(HPyContext *ctx, - HPyFunc_Signature sig, - HPyCFunction func, - void *args); - -/* Builders */ - -/** - * Create a new list builder for ``size`` elements. The builder is then able to - * take at most ``size`` elements. This function does not raise any - * exception (even if running out of memory). - * - * :param ctx: - * The execution context. - * :param size: - * The number of elements to hold. - */ -HPy_ID(209) -HPyListBuilder HPyListBuilder_New(HPyContext *ctx, HPy_ssize_t size); - -/** - * Assign an element to a certain index of the builder. Valid indices are in - * range ``0 <= index < size`` where ``size`` is the value passed to - * :c:func:`HPyListBuilder_New`. This function does not raise any exception. - * - * :param ctx: - * The execution context. - * :param builder: - * A list builder handle. - * :param index: - * The index to assign the object to. - * :param h_item: - * An HPy handle of the object to store or ``HPy_NULL``. Please note that - * HPy **never** steals handles and so, ``h_item`` needs to be closed by - * the caller. - */ -HPy_ID(210) -void HPyListBuilder_Set(HPyContext *ctx, HPyListBuilder builder, - HPy_ssize_t index, HPy h_item); - -/** - * Build a list from a list builder. - * - * :param ctx: - * The execution context. - * :param builder: - * A list builder handle. - * - * :returns: - * An HPy handle to a list containing the values inserted with - * :c:func:`HPyListBuilder_Set` or ``HPy_NULL`` in case an error occurred - * during building or earlier when creating the builder or setting the - * items. - */ -HPy_ID(211) -HPy HPyListBuilder_Build(HPyContext *ctx, HPyListBuilder builder); - -/** - * Cancel building of a tuple and free any acquired resources. - * This function ignores if any error occurred previously when using the tuple - * builder. - * - * :param ctx: - * The execution context. - * :param builder: - * A tuple builder handle. - */ -HPy_ID(212) -void HPyListBuilder_Cancel(HPyContext *ctx, HPyListBuilder builder); - -/** - * Create a new tuple builder for ``size`` elements. The builder is then able - * to take at most ``size`` elements. This function does not raise any - * exception (even if running out of memory). - * - * :param ctx: - * The execution context. - * :param size: - * The number of elements to hold. - */ -HPy_ID(213) -HPyTupleBuilder HPyTupleBuilder_New(HPyContext *ctx, HPy_ssize_t size); - -/** - * Assign an element to a certain index of the builder. Valid indices are in - * range ``0 <= index < size`` where ``size`` is the value passed to - * :c:func:`HPyTupleBuilder_New`. This function does not raise * any exception. - * - * :param ctx: - * The execution context. - * :param builder: - * A tuple builder handle. - * :param index: - * The index to assign the object to. - * :param h_item: - * An HPy handle of the object to store or ``HPy_NULL``. Please note that - * HPy **never** steals handles and so, ``h_item`` needs to be closed by - * the caller. - */ -HPy_ID(214) -void HPyTupleBuilder_Set(HPyContext *ctx, HPyTupleBuilder builder, - HPy_ssize_t index, HPy h_item); - -/** - * Build a tuple from a tuple builder. - * - * :param ctx: - * The execution context. - * :param builder: - * A tuple builder handle. - * - * :returns: - * An HPy handle to a tuple containing the values inserted with - * :c:func:`HPyTupleBuilder_Set` or ``HPy_NULL`` in case an error occurred - * during building or earlier when creating the builder or setting the - * items. - */ -HPy_ID(215) -HPy HPyTupleBuilder_Build(HPyContext *ctx, HPyTupleBuilder builder); - -/** - * Cancel building of a tuple and free any acquired resources. - * This function ignores if any error occurred previously when using the tuple - * builder. - * - * :param ctx: - * The execution context. - * :param builder: - * A tuple builder handle. - */ -HPy_ID(216) -void HPyTupleBuilder_Cancel(HPyContext *ctx, HPyTupleBuilder builder); - -/* Helper for correctly closing handles */ - -HPy_ID(217) -HPyTracker HPyTracker_New(HPyContext *ctx, HPy_ssize_t size); -HPy_ID(218) -int HPyTracker_Add(HPyContext *ctx, HPyTracker ht, HPy h); -HPy_ID(219) -void HPyTracker_ForgetAll(HPyContext *ctx, HPyTracker ht); -HPy_ID(220) -void HPyTracker_Close(HPyContext *ctx, HPyTracker ht); - -/** - * HPyFields should be used ONLY in parts of memory which is known to the GC, - * e.g. memory allocated by HPy_New: - * - * - NEVER declare a local variable of type HPyField - * - NEVER use HPyField on a struct allocated by e.g. malloc() - * - * **CPython's note**: contrary to PyObject*, you don't need to manually - * manage refcounting when using HPyField: if you use HPyField_Store to - * overwrite an existing value, the old object will be automatically decrefed. - * This means that you CANNOT use HPyField_Store to write memory which - * contains uninitialized values, because it would try to decref a dangling - * pointer. - * - * Note that HPy_New automatically zeroes the memory it allocates, so - * everything works well out of the box. In case you are using manually - * allocated memory, you should initialize the HPyField to HPyField_NULL. - * - * Note the difference: - * - * - ``obj->f = HPyField_NULL``: this should be used only to initialize - * uninitialized memory. If you use it to overwrite a valid HPyField, you - * will cause a memory leak (at least on CPython) - * - * - HPyField_Store(ctx, &obj->f, HPy_NULL): this does the right thing and - * decref the old value. However, you CANNOT use it if the memory is not - * initialized. - * - * Note: target_object and source_object are there in case an implementation - * needs to add write and/or read barriers on the objects. They are ignored by - * CPython but e.g. PyPy needs a write barrier. -*/ -HPy_ID(221) -void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h); -HPy_ID(222) -HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field); - -/** - * Leaving Python execution: for releasing GIL and other use-cases. - * - * In most situations, users should prefer using convenience macros: - * HPy_BEGIN_LEAVE_PYTHON(context)/HPy_END_LEAVE_PYTHON(context) - * - * HPy extensions may leave Python execution when running Python independent - * code: long-running computations or blocking operations. When an extension - * has left the Python execution it must not call any HPy API other than - * HPy_ReenterPythonExecution. It can access pointers returned by HPy API, - * e.g., HPyUnicode_AsUTF8String, provided that they are valid at the point - * of calling HPy_LeavePythonExecution. - * - * Python execution must be reentered on the same thread as where it was left. - * The leave/enter calls must not be nested. Debug mode will, in the future, - * enforce these constraints. - * - * Python implementations may use this knowledge however they wish. The most - * obvious use case is to release the GIL, in which case the - * HPy_BEGIN_LEAVE_PYTHON/HPy_END_LEAVE_PYTHON becomes equivalent to - * Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS. -*/ -HPy_ID(223) -void HPy_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state); -HPy_ID(224) -HPyThreadState HPy_LeavePythonExecution(HPyContext *ctx); - -/** - * HPyGlobal is an alternative to module state. HPyGlobal must be a statically - * allocated C global variable registered in HPyModuleDef.globals array. - * A HPyGlobal can be used only after the HPy module where it is registered was - * created using HPyModule_Create. - * - * HPyGlobal serves as an identifier of a Python object that should be globally - * available per one Python interpreter. Python objects referenced by HPyGlobals - * are destroyed automatically on the interpreter exit (not necessarily the - * process exit). - * - * HPyGlobal instance does not allow anything else but loading and storing - * a HPy handle using a HPyContext. Even if the HPyGlobal C variable may - * be shared between threads or different interpreter instances within one - * process, the API to load and store a handle from HPyGlobal is thread-safe (but - * like any other HPy API must not be called in HPy_LeavePythonExecution blocks). - * - * Given that a handle to object X1 is stored to HPyGlobal using HPyContext of - * Python interpreter I1, then loading a handle from the same HPyGlobal using - * HPyContext of Python interpreter I1 should give a handle to the same object - * X1. Another Python interpreter I2 running within the same process and using - * the same HPyGlobal variable will not be able to load X1 from it, it will have - * its own view on what is stored in the given HPyGlobal. - * - * Python interpreters may use indirection to isolate different interpreter - * instances, but alternative techniques such as copy-on-write or immortal - * objects can be used to avoid that indirection (even selectively on per - * object basis using tagged pointers). - * - * CPython HPy implementation may even provide configuration option that - * switches between a faster version that directly stores PyObject* to - * HPyGlobal but does not support subinterpreters, or a version that supports - * subinterpreters. For now, CPython HPy always stores PyObject* directly - * to HPyGlobal. - * - * While the standard implementation does not fully enforce the documented - * contract, the HPy debug mode will enforce it (not implemented yet). - * - * **Implementation notes:** - * All Python interpreters running in one process must be compatible, because - * they will share all HPyGlobal C level variables. The internal data stored - * in HPyGlobal are specific for each HPy implementation, each implementation - * is also responsible for handling thread-safety when initializing the - * internal data in HPyModule_Create. Note that HPyModule_Create may be called - * concurrently depending on the semantics of the Python implementation (GIL vs - * no GIL) and also depending on the whether there may be multiple instances of - * given Python interpreter running within the same process. In the future, HPy - * ABI may include a contract that internal data of each HPyGlobal must be - * initialized to its address using atomic write and HPy implementations will - * not be free to choose what to store in HPyGlobal, however, this will allow - * multiple different HPy implementations within one process. This contract may - * also be activated only by some runtime option, letting the HPy implementation - * use more optimized HPyGlobal implementation otherwise. -*/ -HPy_ID(225) -void HPyGlobal_Store(HPyContext *ctx, HPyGlobal *global, HPy h); -HPy_ID(226) -HPy HPyGlobal_Load(HPyContext *ctx, HPyGlobal global); - -/* Debugging helpers */ -HPy_ID(227) -void _HPy_Dump(HPyContext *ctx, HPy h); - -/* Evaluating Python statements/expressions */ - -/** - * Parse and compile the Python source code. - * - * :param ctx: - * The execution context. - * :param utf8_source: - * Python source code given as UTF-8 encoded C string (must not be ``NULL``). - * :param utf8_filename: - * The filename (UTF-8 encoded C string) to use for construction of the code - * object. It may appear in tracebacks or in ``SyntaxError`` exception - * messages. - * :param kind: - * The source kind which tells the parser if a single expression, statement, - * or a whole file should be parsed (see enum :c:enum:`HPy_SourceKind`). - * - * :returns: - * A Python code object resulting from the parsed and compiled Python source - * code or ``HPy_NULL`` in case of errors. - */ -HPy_ID(248) -HPy HPy_Compile_s(HPyContext *ctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); - -/** - * Evaluate a precompiled code object. - * - * Code objects can be compiled from a string using :c:func:`HPy_Compile_s`. - * - * :param ctx: - * The execution context. - * :param code: - * The code object to evaluate. - * :param globals: - * A Python dictionary defining the global variables for the evaluation. - * :param locals: - * A mapping object defining the local variables for the evaluation. - * - * :returns: - * The result produced by the executed code. May be ``HPy_NULL`` in case of - * errors. - */ -HPy_ID(249) -HPy HPy_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals); -HPy_ID(250) -HPy HPyContextVar_New(HPyContext *ctx, const char *name, HPy default_value); -HPy_ID(251) -int32_t HPyContextVar_Get(HPyContext *ctx, HPy context_var, HPy default_value, HPy *result); -HPy_ID(252) -HPy HPyContextVar_Set(HPyContext *ctx, HPy context_var, HPy value); - -/** - * Set the call function for the given object. - * - * By defining slot ``HPy_tp_call`` for some type, instances of this type will - * be callable objects. The specified call function will be used by default for - * every instance. This should account for the most common case (every instance - * of an object uses the same call function) but to still provide the necessary - * flexibility, function ``HPy_SetCallFunction`` allows to set different (maybe - * specialized) call functions for each instance. This must be done in the - * constructor of an object. - * - * A more detailed description on how to use that function can be found in - * section :ref:`porting-guide:calling protocol`. - * - * :param ctx: - * The execution context. - * :param h: - * A handle to an object implementing the call protocol, i.e., the object's - * type must have slot ``HPy_tp_call``. Otherwise, a ``TypeError`` will be - * raised. This argument must not be ``HPy_NULL``. - * :param def: - * A pointer to the call function definition to set (must not be - * ``NULL``). The definition is usually created using - * :c:macro:`HPyDef_CALL_FUNCTION` - * - * :returns: - * ``0`` in case of success and ``-1`` in case of an error. - */ -HPy_ID(260) -int HPy_SetCallFunction(HPyContext *ctx, HPy h, HPyCallFunction *func); - -/* ******* - hpyfunc - ******* - - These typedefs are used to generate the various macros used by - include/common/hpyfunc.h -*/ -typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self); -typedef HPy (*HPyFunc_o)(HPyContext *ctx, HPy self, HPy arg); -typedef HPy (*HPyFunc_varargs)(HPyContext *ctx, HPy self, const HPy *args, size_t nargs); -typedef HPy (*HPyFunc_keywords)(HPyContext *ctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames); - -typedef HPy (*HPyFunc_unaryfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_binaryfunc)(HPyContext *ctx, HPy, HPy); -typedef HPy (*HPyFunc_ternaryfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_inquiry)(HPyContext *ctx, HPy); -typedef HPy_ssize_t (*HPyFunc_lenfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_ssizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t); -typedef HPy (*HPyFunc_ssizessizeargfunc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t); -typedef int (*HPyFunc_ssizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy); -typedef int (*HPyFunc_ssizessizeobjargproc)(HPyContext *ctx, HPy, HPy_ssize_t, HPy_ssize_t, HPy); -typedef int (*HPyFunc_objobjargproc)(HPyContext *ctx, HPy, HPy, HPy); -typedef void (*HPyFunc_freefunc)(HPyContext *ctx, void *); -typedef HPy (*HPyFunc_getattrfunc)(HPyContext *ctx, HPy, char *); -typedef HPy (*HPyFunc_getattrofunc)(HPyContext *ctx, HPy, HPy); -typedef int (*HPyFunc_setattrfunc)(HPyContext *ctx, HPy, char *, HPy); -typedef int (*HPyFunc_setattrofunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef HPy (*HPyFunc_reprfunc)(HPyContext *ctx, HPy); -typedef HPy_hash_t (*HPyFunc_hashfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_richcmpfunc)(HPyContext *ctx, HPy, HPy, HPy_RichCmpOp); -typedef HPy (*HPyFunc_getiterfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_iternextfunc)(HPyContext *ctx, HPy); -typedef HPy (*HPyFunc_descrgetfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_descrsetfunc)(HPyContext *ctx, HPy, HPy, HPy); -typedef int (*HPyFunc_initproc)(HPyContext *ctx, HPy self, - const HPy *args, HPy_ssize_t nargs, HPy kw); -typedef HPy (*HPyFunc_newfunc)(HPyContext *ctx, HPy type, const HPy *args, - HPy_ssize_t nargs, HPy kw); -typedef HPy (*HPyFunc_getter)(HPyContext *ctx, HPy, void *); -typedef int (*HPyFunc_setter)(HPyContext *ctx, HPy, HPy, void *); -typedef int (*HPyFunc_objobjproc)(HPyContext *ctx, HPy, HPy); -typedef int (*HPyFunc_getbufferproc)(HPyContext *ctx, HPy, HPy_buffer *, int); -typedef void (*HPyFunc_releasebufferproc)(HPyContext *ctx, HPy, HPy_buffer *); -typedef int (*HPyFunc_traverseproc)(void *object, HPyFunc_visitproc visit, void *arg); -typedef void (*HPyFunc_destructor)(HPyContext *ctx, HPy); - -typedef void (*HPyFunc_destroyfunc)(void *); - -// Note: separate type, because we need a different trampoline -typedef HPy (*HPyFunc_mod_create)(HPyContext *ctx, HPy); - - -/* ~~~ HPySlot_Slot ~~~ - - The following enum is used to generate autogen_hpyslot.h, which contains: - - - The real definition of the enum HPySlot_Slot - - - the macros #define _HPySlot_SIGNATURE_* - -*/ - -// NOTE: if you uncomment/enable a slot below, make sure to write a corresponding -// test in test_slots.py - -/* Note that the magic numbers are the same as CPython */ -typedef enum { - HPy_bf_getbuffer = SLOT(1, HPyFunc_GETBUFFERPROC), - HPy_bf_releasebuffer = SLOT(2, HPyFunc_RELEASEBUFFERPROC), - HPy_mp_ass_subscript = SLOT(3, HPyFunc_OBJOBJARGPROC), - HPy_mp_length = SLOT(4, HPyFunc_LENFUNC), - HPy_mp_subscript = SLOT(5, HPyFunc_BINARYFUNC), - HPy_nb_absolute = SLOT(6, HPyFunc_UNARYFUNC), - HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), - HPy_nb_and = SLOT(8, HPyFunc_BINARYFUNC), - HPy_nb_bool = SLOT(9, HPyFunc_INQUIRY), - HPy_nb_divmod = SLOT(10, HPyFunc_BINARYFUNC), - HPy_nb_float = SLOT(11, HPyFunc_UNARYFUNC), - HPy_nb_floor_divide = SLOT(12, HPyFunc_BINARYFUNC), - HPy_nb_index = SLOT(13, HPyFunc_UNARYFUNC), - HPy_nb_inplace_add = SLOT(14, HPyFunc_BINARYFUNC), - HPy_nb_inplace_and = SLOT(15, HPyFunc_BINARYFUNC), - HPy_nb_inplace_floor_divide = SLOT(16, HPyFunc_BINARYFUNC), - HPy_nb_inplace_lshift = SLOT(17, HPyFunc_BINARYFUNC), - HPy_nb_inplace_multiply = SLOT(18, HPyFunc_BINARYFUNC), - HPy_nb_inplace_or = SLOT(19, HPyFunc_BINARYFUNC), - HPy_nb_inplace_power = SLOT(20, HPyFunc_TERNARYFUNC), - HPy_nb_inplace_remainder = SLOT(21, HPyFunc_BINARYFUNC), - HPy_nb_inplace_rshift = SLOT(22, HPyFunc_BINARYFUNC), - HPy_nb_inplace_subtract = SLOT(23, HPyFunc_BINARYFUNC), - HPy_nb_inplace_true_divide = SLOT(24, HPyFunc_BINARYFUNC), - HPy_nb_inplace_xor = SLOT(25, HPyFunc_BINARYFUNC), - HPy_nb_int = SLOT(26, HPyFunc_UNARYFUNC), - HPy_nb_invert = SLOT(27, HPyFunc_UNARYFUNC), - HPy_nb_lshift = SLOT(28, HPyFunc_BINARYFUNC), - HPy_nb_multiply = SLOT(29, HPyFunc_BINARYFUNC), - HPy_nb_negative = SLOT(30, HPyFunc_UNARYFUNC), - HPy_nb_or = SLOT(31, HPyFunc_BINARYFUNC), - HPy_nb_positive = SLOT(32, HPyFunc_UNARYFUNC), - HPy_nb_power = SLOT(33, HPyFunc_TERNARYFUNC), - HPy_nb_remainder = SLOT(34, HPyFunc_BINARYFUNC), - HPy_nb_rshift = SLOT(35, HPyFunc_BINARYFUNC), - HPy_nb_subtract = SLOT(36, HPyFunc_BINARYFUNC), - HPy_nb_true_divide = SLOT(37, HPyFunc_BINARYFUNC), - HPy_nb_xor = SLOT(38, HPyFunc_BINARYFUNC), - HPy_sq_ass_item = SLOT(39, HPyFunc_SSIZEOBJARGPROC), - HPy_sq_concat = SLOT(40, HPyFunc_BINARYFUNC), - HPy_sq_contains = SLOT(41, HPyFunc_OBJOBJPROC), - HPy_sq_inplace_concat = SLOT(42, HPyFunc_BINARYFUNC), - HPy_sq_inplace_repeat = SLOT(43, HPyFunc_SSIZEARGFUNC), - HPy_sq_item = SLOT(44, HPyFunc_SSIZEARGFUNC), - HPy_sq_length = SLOT(45, HPyFunc_LENFUNC), - HPy_sq_repeat = SLOT(46, HPyFunc_SSIZEARGFUNC), - //HPy_tp_alloc = SLOT(47, HPyFunc_X), NOT SUPPORTED - //HPy_tp_base = SLOT(48, HPyFunc_X), - //HPy_tp_bases = SLOT(49, HPyFunc_X), - HPy_tp_call = SLOT(50, HPyFunc_KEYWORDS), - //HPy_tp_clear = SLOT(51, HPyFunc_X), NOT SUPPORTED, use tp_traverse - //HPy_tp_dealloc = SLOT(52, HPyFunc_X), NOT SUPPORTED - //HPy_tp_del = SLOT(53, HPyFunc_X), - HPy_tp_descr_get = SLOT(54, HPyFunc_TERNARYFUNC), - //HPy_tp_descr_set = SLOT(55, HPyFunc_X), - //HPy_tp_doc = SLOT(56, HPyFunc_X), - //HPy_tp_getattr = SLOT(57, HPyFunc_X), - //HPy_tp_getattro = SLOT(58, HPyFunc_X), - HPy_tp_hash = SLOT(59, HPyFunc_HASHFUNC), - HPy_tp_init = SLOT(60, HPyFunc_INITPROC), - //HPy_tp_is_gc = SLOT(61, HPyFunc_X), - //HPy_tp_iter = SLOT(62, HPyFunc_X), - //HPy_tp_iternext = SLOT(63, HPyFunc_X), - //HPy_tp_methods = SLOT(64, HPyFunc_X), NOT SUPPORTED - HPy_tp_new = SLOT(65, HPyFunc_NEWFUNC), - HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), - HPy_tp_richcompare = SLOT(67, HPyFunc_RICHCMPFUNC), - //HPy_tp_setattr = SLOT(68, HPyFunc_X), - //HPy_tp_setattro = SLOT(69, HPyFunc_X), - HPy_tp_str = SLOT(70, HPyFunc_REPRFUNC), - HPy_tp_traverse = SLOT(71, HPyFunc_TRAVERSEPROC), - //HPy_tp_members = SLOT(72, HPyFunc_X), NOT SUPPORTED - //HPy_tp_getset = SLOT(73, HPyFunc_X), NOT SUPPORTED - //HPy_tp_free = SLOT(74, HPyFunc_X), NOT SUPPORTED - HPy_nb_matrix_multiply = SLOT(75, HPyFunc_BINARYFUNC), - HPy_nb_inplace_matrix_multiply = SLOT(76, HPyFunc_BINARYFUNC), - //HPy_am_await = SLOT(77, HPyFunc_X), - //HPy_am_aiter = SLOT(78, HPyFunc_X), - //HPy_am_anext = SLOT(79, HPyFunc_X), - HPy_tp_finalize = SLOT(80, HPyFunc_DESTRUCTOR), - - /* extra HPy slots */ - HPy_tp_destroy = SLOT(1000, HPyFunc_DESTROYFUNC), - - /** - * Module create slot: the function receives loader spec and should - * return an HPy handle representing the module. Currently, creating - * real module objects cannot be done by user code, so the only other - * useful thing that this slot can do is to create another object that - * can work as a module, such as SimpleNamespace. - */ - HPy_mod_create = SLOT(2000, HPyFunc_MOD_CREATE), - /** - * Module exec slot: the function receives module object that was created - * by the runtime from HPyModuleDef. This slot can do any initialization - * of the module, such as adding types. There can be multiple exec slots - * and they will be executed in the declaration order. - */ - HPy_mod_exec = SLOT(2001, HPyFunc_INQUIRY), - -} HPySlot_Slot; diff --git a/graalpython/hpy/hpy/tools/autogen/pypy.py b/graalpython/hpy/hpy/tools/autogen/pypy.py deleted file mode 100644 index 702a519e84..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/pypy.py +++ /dev/null @@ -1,40 +0,0 @@ -from .autogenfile import AutoGenFile -from .parse import toC - -# this class should probably be moved somewhere in the PyPy repo -class autogen_pypy_txt(AutoGenFile): - PATH = 'hpy/tools/autogen/autogen_pypy.txt' - LANGUAGE = 'txt' # to avoid inserting the disclaimer - - def generate(self): - lines = [] - w = lines.append - w("typedef struct _HPyContext_s {") - w(" int abi_version;") - for var in self.api.variables: - w(" struct _HPy_s %s;" % var.ctx_name()) - for func in self.api.functions: - w(" void * %s;" % func.ctx_name()) - w("} _struct_HPyContext_s;") - w("") - w("") - # generate stubs for all the API functions - for func in self.api.functions: - w(self.stub(func)) - return '\n'.join(lines) - - def stub(self, func): - signature = toC(func.node) - if func.is_varargs(): - return '# %s' % signature - # - argnames = [p.name for p in func.node.type.args.params] - lines = [] - w = lines.append - w('@API.func("%s")' % signature) - w('def %s(space, %s):' % (func.name, ', '.join(argnames))) - w(' from rpython.rlib.nonconst import NonConstant # for the annotator') - w(' if NonConstant(False): return 0') - w(' raise NotImplementedError') - w('') - return '\n'.join(lines) diff --git a/graalpython/hpy/hpy/tools/autogen/testing/__init__.py b/graalpython/hpy/hpy/tools/autogen/testing/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py b/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py deleted file mode 100644 index 28421d1196..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/testing/test_autogen.py +++ /dev/null @@ -1,223 +0,0 @@ -import textwrap -import difflib -import pytest -from hpy.tools.autogen.parse import HPyAPI -from hpy.tools.autogen.ctx import autogen_ctx_h, autogen_ctx_def_h -from hpy.tools.autogen.trampolines import (autogen_trampolines_h, - cpython_autogen_api_impl_h) -from hpy.tools.autogen.hpyslot import autogen_hpyslot_h - -def src_equal(exp, got): - # try to compare two C sources, ignoring whitespace - exp = textwrap.dedent(exp).strip() - got = textwrap.dedent(got).strip() - if exp.split() != got.split(): - diff = difflib.unified_diff(exp.splitlines(), got.splitlines(), - fromfile='expected', - tofile='got') - print() - for line in diff: - print(line) - return False - return True - -@pytest.mark.usefixtures('initargs') -class BaseTestAutogen: - - @pytest.fixture - def initargs(self, tmp_path): - self.tmpdir = tmp_path - - def parse(self, src): - fname = self.tmpdir / 'test_api.h' - # automatically add useful typedefs - src = """ - #define STRINGIFY(X) #X - #define HPy_ID(X) _Pragma(STRINGIFY(id=X)) \\ - - typedef int HPy; - typedef int HPyContext; - """ + src - fname.write_text(src) - return HPyAPI.parse(fname) - - -class TestHPyAPI(BaseTestAutogen): - - def test_ctx_name(self): - api = self.parse(""" - HPy_ID(0) HPy h_None; - HPy_ID(1) HPy HPy_Dup(HPyContext *ctx, HPy h); - HPy_ID(2) void* _HPy_AsStruct(HPyContext *ctx, HPy h); - """) - assert api.get_var('h_None').ctx_name() == 'h_None' - assert api.get_func('HPy_Dup').ctx_name() == 'ctx_Dup' - assert api.get_func('_HPy_AsStruct').ctx_name() == 'ctx_AsStruct' - - def test_cpython_name(self): - api = self.parse(""" - HPy_ID(0) HPy HPy_Dup(HPyContext *ctx, HPy h); - HPy_ID(1) long HPyLong_AsLong(HPyContext *ctx, HPy h); - HPy_ID(2) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); - """) - assert api.get_func('HPy_Dup').cpython_name is None - assert api.get_func('HPyLong_AsLong').cpython_name == 'PyLong_AsLong' - assert api.get_func('HPy_Add').cpython_name == 'PyNumber_Add' - - def test_hpyslot(self): - api = self.parse(""" - typedef enum { - HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), - HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), - } HPySlot_Slot; - """) - nb_add = api.get_slot('HPy_nb_add') - assert nb_add.value == '7' - assert nb_add.hpyfunc == 'HPyFunc_BINARYFUNC' - # - tp_repr = api.get_slot('HPy_tp_repr') - assert tp_repr.value == '66' - assert tp_repr.hpyfunc == 'HPyFunc_REPRFUNC' - - def test_parse_id(self): - api = self.parse(""" - HPy_ID(0) HPy h_Foo; - HPy_ID(1) - long HPyFoo_Bar(HPyContext *ctx, HPy h); - """) - assert len(api.variables) == 1 - assert len(api.functions) == 1 - assert api.variables[0].ctx_index == 0 - assert api.functions[0].ctx_index == 1 - - # don't allow gaps in the sequence of IDs - with pytest.raises(AssertionError): - self.parse(""" - HPy_ID(0) HPy h_Foo; - HPy_ID(3) long HPyFoo_Bar(HPyContext *ctx, HPy h); - """) - - # don't allow re-using of IDs - with pytest.raises(AssertionError): - self.parse(""" - HPy_ID(0) HPy h_Foo; - HPy_ID(0) HPy h_Foo; - """) - - # all context members must have an ID - with pytest.raises(ValueError): - self.parse("HPy h_Foo;") - - # pragmas must be of form '#pramga key=value' - with pytest.raises(ValueError): - self.parse("#pragma hello\nHPy h_Foo;") - - # pragmas value must be an integer - with pytest.raises(ValueError): - self.parse("#pragma hello=world\nHPy h_Foo;") - -class TestAutoGen(BaseTestAutogen): - - def test_autogen_ctx_h(self): - api = self.parse(""" - HPy_ID(0) HPy h_None; - HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); - """) - got = autogen_ctx_h(api).generate() - exp = """ - struct _HPyContext_s { - const char *name; // used just to make debugging and testing easier - void *_private; // used by implementations to store custom data - int abi_version; - HPy h_None; - HPy (*ctx_Add)(HPyContext *ctx, HPy h1, HPy h2); - }; - """ - assert src_equal(exp, got) - - def test_autogen_ctx_def_h(self): - api = self.parse(""" - HPy_ID(0) HPy h_None; - HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); - """) - got = autogen_ctx_def_h(api).generate() - exp = """ - struct _HPyContext_s g_universal_ctx = { - .name = "HPy Universal ABI (CPython backend)", - ._private = NULL, - .abi_version = HPY_ABI_VERSION, - /* h_None & co. are initialized by init_universal_ctx() */ - .ctx_Add = &ctx_Add, - }; - """ - assert src_equal(exp, got) - - def test_autogen_trampolines_h(self): - api = self.parse(""" - HPy_ID(0) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); - HPy_ID(1) void HPy_Close(HPyContext *ctx, HPy h); - HPy_ID(2) void* _HPy_AsStruct(HPyContext *ctx, HPy h); - """) - got = autogen_trampolines_h(api).generate() - exp = """ - HPyAPI_FUNC HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) { - return ctx->ctx_Add ( ctx, h1, h2 ); - } - - HPyAPI_FUNC void HPy_Close(HPyContext *ctx, HPy h) { - ctx->ctx_Close ( ctx, h ); - } - - HPyAPI_FUNC void *_HPy_AsStruct(HPyContext *ctx, HPy h) { - return ctx->ctx_AsStruct ( ctx, h ); - } - """ - assert src_equal(got, exp) - - def test_cpython_api_impl_h(self): - api = self.parse(""" - HPy_ID(0) HPy HPy_Dup(HPyContext *ctx, HPy h); - HPy_ID(1) HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2); - HPy_ID(2) HPy HPyLong_FromLong(HPyContext *ctx, long value); - HPy_ID(3) char* HPyBytes_AsString(HPyContext *ctx, HPy h); - """) - got = cpython_autogen_api_impl_h(api).generate() - exp = """ - HPyAPI_FUNC - HPy HPy_Add(HPyContext *ctx, HPy h1, HPy h2) - { - return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2))); - } - - HPyAPI_FUNC - HPy HPyLong_FromLong(HPyContext *ctx, long value) - { - return _py2h(PyLong_FromLong(value)); - } - - HPyAPI_FUNC - char *HPyBytes_AsString(HPyContext *ctx, HPy h) - { - return PyBytes_AsString(_h2py(h)); - } - """ - assert src_equal(got, exp) - - def test_autogen_hpyslot_h(self): - api = self.parse(""" - typedef enum { - HPy_nb_add = SLOT(7, HPyFunc_BINARYFUNC), - HPy_tp_repr = SLOT(66, HPyFunc_REPRFUNC), - } HPySlot_Slot; - """) - got = autogen_hpyslot_h(api).generate() - exp = """ - typedef enum { - HPy_nb_add = 7, - HPy_tp_repr = 66, - } HPySlot_Slot; - - #define _HPySlot_SIG__HPy_nb_add HPyFunc_BINARYFUNC - #define _HPySlot_SIG__HPy_tp_repr HPyFunc_REPRFUNC - """ - assert src_equal(got, exp) diff --git a/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py b/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py deleted file mode 100644 index 7e0032979d..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/testing/test_hpyfunc.py +++ /dev/null @@ -1,145 +0,0 @@ -from hpy.tools.autogen.hpyfunc import autogen_hpyfunc_declare_h -from hpy.tools.autogen.hpyfunc import autogen_hpyfunc_trampoline_h -from hpy.tools.autogen.hpyfunc import autogen_ctx_call_i -from hpy.tools.autogen.hpyfunc import autogen_cpython_hpyfunc_trampoline_h -from hpy.tools.autogen.testing.test_autogen import BaseTestAutogen, src_equal - -class TestHPyFunc(BaseTestAutogen): - - def test_parse(self): - api = self.parse(""" - typedef int HPyFunc_Signature; - typedef HPy (*HPyFunc_noargs)(HPyContext *ctx, HPy self); - """) - assert len(api.hpyfunc_typedefs) == 1 - hpyfunc = api.get_hpyfunc_typedef('HPyFunc_noargs') - assert hpyfunc.name == 'HPyFunc_noargs' - assert hpyfunc.base_name() == 'noargs' - - def test_autogen_hpyfunc_declare_h(self): - api = self.parse(""" - typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy self); - typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); - """) - got = autogen_hpyfunc_declare_h(api).generate() - exp = """ - #define _HPyFunc_DECLARE_HPyFunc_FOO(SYM) static HPy SYM(HPyContext *ctx, HPy self) - #define _HPyFunc_DECLARE_HPyFunc_BAR(SYM) static HPy SYM(HPyContext *ctx, HPy, int) - - typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy self); - typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); - """ - assert src_equal(got, exp) - - def test_autogen_hpyfunc_trampoline_h(self): - api = self.parse(""" - typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); - typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); - typedef void (*HPyFunc_proc)(HPyContext *ctx, int x); - """) - got = autogen_hpyfunc_trampoline_h(api).generate() - exp = r""" - typedef struct { - cpy_PyObject *arg; - int xy; - cpy_PyObject * result; - } _HPyFunc_args_FOO; - - #define _HPyFunc_TRAMPOLINE_HPyFunc_FOO(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg, int xy) \ - { \ - _HPyFunc_args_FOO a = { arg, xy }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_FOO, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - - typedef struct { - cpy_PyObject *arg0; - int arg1; - cpy_PyObject * result; - } _HPyFunc_args_BAR; - - #define _HPyFunc_TRAMPOLINE_HPyFunc_BAR(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, int arg1) \ - { \ - _HPyFunc_args_BAR a = { arg0, arg1 }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_BAR, (HPyCFunction)IMPL, &a); \ - return a.result; \ - } - - typedef struct { - int x; - } _HPyFunc_args_PROC; - - #define _HPyFunc_TRAMPOLINE_HPyFunc_PROC(SYM, IMPL) \ - static void SYM(int x) \ - { \ - _HPyFunc_args_PROC a = { x }; \ - _HPy_CallRealFunctionFromTrampoline( \ - _ctx_for_trampolines, HPyFunc_PROC, (HPyCFunction)IMPL, &a); \ - return; \ - } - """ - assert src_equal(got, exp) - - def test_autogen_ctx_call_i(self): - api = self.parse(""" - typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); - typedef int (*HPyFunc_bar)(HPyContext *ctx); - typedef int (*HPyFunc_baz)(HPyContext *ctx, HPy, int); - typedef void (*HPyFunc_proc)(HPyContext *ctx, int x); - """) - got = autogen_ctx_call_i(api).generate() - exp = r""" - case HPyFunc_FOO: { - HPyFunc_foo f = (HPyFunc_foo)func; - _HPyFunc_args_FOO *a = (_HPyFunc_args_FOO*)args; - a->result = _h2py(f(ctx, _py2h(a->arg), a->xy)); - return; - } - case HPyFunc_BAR: { - HPyFunc_bar f = (HPyFunc_bar)func; - _HPyFunc_args_BAR *a = (_HPyFunc_args_BAR*)args; - a->result = f(ctx); - return; - } - case HPyFunc_BAZ: { - HPyFunc_baz f = (HPyFunc_baz)func; - _HPyFunc_args_BAZ *a = (_HPyFunc_args_BAZ*)args; - a->result = f(ctx, _py2h(a->arg0), a->arg1); - return; - } - case HPyFunc_PROC: { - HPyFunc_proc f = (HPyFunc_proc)func; - _HPyFunc_args_PROC *a = (_HPyFunc_args_PROC*)args; - f(ctx, a->x); - return; - } - """ - assert src_equal(got, exp) - - def test_autogen_cpython_hpyfunc_trampoline_h(self): - api = self.parse(""" - typedef HPy (*HPyFunc_foo)(HPyContext *ctx, HPy arg, int xy); - typedef HPy (*HPyFunc_bar)(HPyContext *ctx, HPy, int); - """) - got = autogen_cpython_hpyfunc_trampoline_h(api).generate() - exp = r""" - typedef HPy (*_HPyCFunction_FOO)(HPyContext *, HPy, int); - #define _HPyFunc_TRAMPOLINE_HPyFunc_FOO(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg, int xy) \ - { \ - _HPyCFunction_FOO func = (_HPyCFunction_FOO)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg), xy)); \ - } - typedef HPy (*_HPyCFunction_BAR)(HPyContext *, HPy, int); - #define _HPyFunc_TRAMPOLINE_HPyFunc_BAR(SYM, IMPL) \ - static cpy_PyObject *SYM(cpy_PyObject *arg0, int arg1) \ - { \ - _HPyCFunction_BAR func = (_HPyCFunction_BAR)IMPL; \ - return _h2py(func(_HPyGetContext(), _py2h(arg0), arg1)); \ - } - """ - assert src_equal(got, exp) diff --git a/graalpython/hpy/hpy/tools/autogen/trace.py b/graalpython/hpy/hpy/tools/autogen/trace.py deleted file mode 100644 index 5cdc212081..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/trace.py +++ /dev/null @@ -1,182 +0,0 @@ -from copy import deepcopy -from pycparser import c_ast -from .autogenfile import AutoGenFile -from .parse import toC, find_typedecl, get_context_return_type, \ - maybe_make_void, make_void, get_return_constant - - -# We will call the delegate context's function but we still need to unwrap -# the context. This is in contrast to, e.g., the debug mode, where you would -# manually write a wrapper function. Here we can generate that as well. -NO_WRAPPER = { - '_HPy_CallRealFunctionFromTrampoline', - 'HPy_FatalError', -} - -class Ctx2TctxVisitor(c_ast.NodeVisitor): - """Visitor which renames all ctx to tctx""" - - def visit_TypeDecl(self, node): - if node.declname == 'ctx': - node.declname = 'tctx' - self.generic_visit(node) - -def funcnode_with_new_name(node, name): - newnode = deepcopy(node) - typedecl = find_typedecl(newnode) - typedecl.declname = name - return newnode - -def get_trace_wrapper_node(func): - newnode = funcnode_with_new_name(func.node, 'trace_%s' % func.ctx_name()) - maybe_make_void(func, newnode) - # rename ctx to tctx - visitor = Ctx2TctxVisitor() - visitor.visit(newnode) - return newnode - -class autogen_tracer_ctx_init_h(AutoGenFile): - PATH = 'hpy/trace/src/autogen_trace_ctx_init.h' - - def generate(self): - lines = [] - w = lines.append - # emit the declarations for all the trace_ctx_* functions - for func in self.api.functions: - if func.name not in NO_WRAPPER: - w(toC(get_trace_wrapper_node(func)) + ';') - n_decls = len(self.api.functions) + len(self.api.variables) - w('') - w(f'static inline void trace_ctx_init_info(HPyTraceInfo *info, HPyContext *uctx)') - w('{') - w(f' info->magic_number = HPY_TRACE_MAGIC;') - w(f' info->uctx = uctx;') - w(f' info->call_counts = (uint64_t *)calloc({n_decls}, sizeof(uint64_t));') - w(f' info->durations = (_HPyTime_t *)calloc({n_decls}, sizeof(_HPyTime_t));') - w(f' info->on_enter_func = HPy_NULL;') - w(f' info->on_exit_func = HPy_NULL;') - w('}') - w('') - w(f'static inline void trace_ctx_free_info(HPyTraceInfo *info)') - w('{') - w(f' assert(info->magic_number == HPY_TRACE_MAGIC);') - w(f' free(info->call_counts);') - w(f' free(info->durations);') - w(f' HPy_Close(info->uctx, info->on_enter_func);') - w(f' HPy_Close(info->uctx, info->on_exit_func);') - w('}') - w('') - w(f'static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx)') - w('{') - for var in self.api.variables: - name = var.name - w(f' tctx->{name} = uctx->{name};') - for func in self.api.functions: - if func.name in NO_WRAPPER: - name = func.ctx_name() - w(f' tctx->{name} = uctx->{name};') - else: - name = func.ctx_name() - w(f' tctx->{name} = &trace_{name};') - w('}') - return '\n'.join(lines) - - -class autogen_tracer_wrappers(AutoGenFile): - PATH = 'hpy/trace/src/autogen_trace_wrappers.c' - - def generate(self): - lines = [] - w = lines.append - w('#include "trace_internal.h"') - w('') - for func in self.api.functions: - debug_wrapper = self.gen_trace_wrapper(func) - if debug_wrapper: - w(debug_wrapper) - w('') - return '\n'.join(lines) - - def gen_trace_wrapper(self, func): - if func.name in NO_WRAPPER: - return - - assert not func.is_varargs() - node = get_trace_wrapper_node(func) - const_return = get_return_constant(func) - if const_return: - make_void(node) - signature = toC(node) - rettype = get_context_return_type(node, const_return) - - def get_params(): - lst = [] - for p in node.type.args.params: - if p.name == 'ctx': - lst.append('uctx') - else: - lst.append(p.name) - return ', '.join(lst) - params = get_params() - - lines = [] - w = lines.append - w(signature) - w('{') - w(f' HPyTraceInfo *info = hpy_trace_on_enter(tctx, {func.ctx_index});') - w(f' HPyContext *uctx = info->uctx;') - w(f' _HPyTime_t _ts_start, _ts_end;') - w(f' _HPyClockStatus_t r0, r1;') - w(f' r0 = get_monotonic_clock(&_ts_start);') - if rettype == 'void': - w(f' {func.name}({params});') - else: - w(f' {rettype} res = {func.name}({params});') - w(f' r1 = get_monotonic_clock(&_ts_end);') - w(f' hpy_trace_on_exit(info, {func.ctx_index}, r0, r1, &_ts_start, &_ts_end);') - if rettype != 'void': - w(f' return res;') - w('}') - return '\n'.join(lines) - - -class autogen_trace_func_table_c(AutoGenFile): - PATH = 'hpy/trace/src/autogen_trace_func_table.c' - - def generate(self): - lines = [] - w = lines.append - - n_funcs = len(self.api.functions) - n_decls = n_funcs + len(self.api.variables) - func_table = ['NO_FUNC'] * n_decls - for func in self.api.functions: - name = func.ctx_name() - func_table[func.ctx_index] = f'"{name}"' - - w('#include "trace_internal.h"') - w('') - w(f'#define TRACE_NFUNC {n_funcs}') - w('') - w('#define NO_FUNC ""') - w('static const char *trace_func_table[] = {') - for func in func_table: - w(f' {func},') - w(f' NULL /* sentinel */') - w('};') - w('') - w('int hpy_trace_get_nfunc(void)') - w('{') - w(' return TRACE_NFUNC;') - w('}') - w('') - w('const char * hpy_trace_get_func_name(int idx)') - w('{') - w(f' if (idx >= 0 && idx < {n_decls})') - w(' return trace_func_table[idx];') - w(' return NULL;') - w('}') - w('') - return '\n'.join(lines) - - diff --git a/graalpython/hpy/hpy/tools/autogen/trampolines.py b/graalpython/hpy/hpy/tools/autogen/trampolines.py deleted file mode 100644 index 366f27cd4a..0000000000 --- a/graalpython/hpy/hpy/tools/autogen/trampolines.py +++ /dev/null @@ -1,140 +0,0 @@ -from copy import deepcopy -from .autogenfile import AutoGenFile -from .parse import toC,find_typedecl, get_context_return_type, \ - make_void, get_return_constant -from . import conf - - -class autogen_trampolines_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/universal/autogen_trampolines.h' - - def generate(self): - lines = [] - for func in self.api.functions: - trampoline = self.gen_trampoline(func) - if trampoline: - lines.append(trampoline) - lines.append('') - return '\n'.join(lines) - - def gen_trampoline(self, func): - # HPyAPI_FUNC HPy HPyModule_Create(HPyContext *ctx, HPyModuleDef *def) { - # return ctx->ctx_Module_Create ( ctx, def ); - # } - if func.name in conf.NO_TRAMPOLINES: - return None - const_return = get_return_constant(func) - rettype = get_context_return_type(func.node, const_return) - parts = [] - w = parts.append - w('HPyAPI_FUNC') - w(toC(func.node)) - w('{\n ') - - # trampolines cannot deal with varargs easily - assert not func.is_varargs() - - if rettype == 'void': - w('ctx->%s' % func.ctx_name()) - else: - w('return ctx->%s' % func.ctx_name()) - w('(') - params = [p.name for p in func.node.type.args.params] - w(', '.join(params)) - w(');') - - if const_return: - w('return %s;' % const_return) - - w('\n}') - return ' '.join(parts) - - -class cpython_autogen_api_impl_h(AutoGenFile): - PATH = 'hpy/devel/include/hpy/cpython/autogen_api_impl.h' - GENERATE_CONST_RETURN = True - - def signature(self, func, const_return): - """ - Return the C signature of the impl function. - - In CPython mode, the name it's the same as in public_api: - HPy_Add ==> HPyAPI_FUNC HPy_Add - HPyLong_FromLong ==> HPyAPI_FUNC HPyLong_FromLong - - See also universal_autogen_ctx_impl_h. - """ - sig = toC(func.node) - return 'HPyAPI_FUNC %s' % sig - - def generate(self): - lines = [] - for func in self.api.functions: - if not func.cpython_name: - continue - lines.append(self.gen_implementation(func)) - lines.append('') - return '\n'.join(lines) - - def gen_implementation(self, func): - def call(pyfunc, return_type): - # return _py2h(PyNumber_Add(_h2py(x), _h2py(y))) - args = [] - for p in func.node.type.args.params: - if toC(p.type) == 'HPyContext *': - continue - elif toC(p.type) == 'HPy': - arg = '_h2py(%s)' % p.name - elif toC(p.type) == 'HPyThreadState': - arg = '_h2threads(%s)' % p.name - else: - arg = p.name - args.append(arg) - result = '%s(%s)' % (pyfunc, ', '.join(args)) - if return_type == 'HPy': - result = '_py2h(%s)' % result - elif return_type == 'HPyThreadState': - result = '_threads2h(%s)' % result - return result - # - lines = [] - w = lines.append - pyfunc = func.cpython_name - if not pyfunc: - raise ValueError(f"Cannot generate implementation for {self}") - const_return = get_return_constant(func) - return_type = get_context_return_type(func.node, const_return) - return_stmt = '' if return_type == 'void' else 'return ' - w(self.signature(func, const_return)) - w('{') - w(' %s%s;' % (return_stmt, call(pyfunc, return_type))) - - if self.GENERATE_CONST_RETURN and const_return: - w(' return %s;' % const_return) - - w('}') - return '\n'.join(lines) - - -class universal_autogen_ctx_impl_h(cpython_autogen_api_impl_h): - PATH = 'hpy/universal/src/autogen_ctx_impl.h' - GENERATE_CONST_RETURN = False - - def signature(self, func, const_return): - """ - Return the C signature of the impl function. - - In Universal mode, the name is prefixed by ctx_: - HPy_Add ==> HPyAPI_IMPL ctx_Add - HPyLong_FromLong ==> HPyAPI_IMPL ctx_Long_FromLong - - See also cpython_autogen_api_impl_h. - """ - newnode = deepcopy(func.node) - if const_return: - make_void(newnode) - typedecl = find_typedecl(newnode) - # rename the function - typedecl.declname = func.ctx_name() - sig = toC(newnode) - return 'HPyAPI_IMPL %s' % sig diff --git a/graalpython/hpy/hpy/tools/include_path.py b/graalpython/hpy/hpy/tools/include_path.py deleted file mode 100644 index 61dd06a28d..0000000000 --- a/graalpython/hpy/hpy/tools/include_path.py +++ /dev/null @@ -1,4 +0,0 @@ -"""Prints the include path for the current Python interpreter.""" - -from sysconfig import get_paths as gp -print(gp()['include']) diff --git a/graalpython/hpy/hpy/tools/valgrind/hpy.supp b/graalpython/hpy/hpy/tools/valgrind/hpy.supp deleted file mode 100644 index c1139552a8..0000000000 --- a/graalpython/hpy/hpy/tools/valgrind/hpy.supp +++ /dev/null @@ -1,44 +0,0 @@ -{ - <_HPyModuleDef_CreatePyModuleDef_leak> - Memcheck:Leak - match-leak-kinds: definite,indirect - ... - fun:_HPyModuleDef_CreatePyModuleDef - ... -} - -{ - - Memcheck:Leak - match-leak-kinds: definite - ... - fun:ctx_Type_FromSpec - ... -} - -{ - - Memcheck:Leak - match-leak-kinds: definite - ... - fun:PyUnicode_New.part.42 - ... -} - -{ - - Memcheck:Leak - match-leak-kinds: definite - ... - fun:PyUnicode_New - ... -} - -{ - - Memcheck:Leak - match-leak-kinds: definite - ... - fun:PyLong_FromLong - ... -} diff --git a/graalpython/hpy/hpy/tools/valgrind/python.supp b/graalpython/hpy/hpy/tools/valgrind/python.supp deleted file mode 100644 index 26a6f22c89..0000000000 --- a/graalpython/hpy/hpy/tools/valgrind/python.supp +++ /dev/null @@ -1,389 +0,0 @@ -# -# This is a valgrind suppression file that should be used when using valgrind. -# -# Here's an example of running valgrind: -# -# cd python/dist/src -# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ -# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network -# -# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER -# to use the preferred suppressions with Py_ADDRESS_IN_RANGE. -# -# If you do not want to recompile Python, you can uncomment -# suppressions for PyObject_Free and PyObject_Realloc. -# -# See Misc/README.valgrind for more information. - -# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif -{ - ADDRESS_IN_RANGE/Invalid read of size 4 - Memcheck:Addr4 - fun:Py_ADDRESS_IN_RANGE -} - -{ - ADDRESS_IN_RANGE/Invalid read of size 4 - Memcheck:Value4 - fun:Py_ADDRESS_IN_RANGE -} - -{ - ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64) - Memcheck:Value8 - fun:Py_ADDRESS_IN_RANGE -} - -{ - ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value - Memcheck:Cond - fun:Py_ADDRESS_IN_RANGE -} - -# -# Leaks (including possible leaks) -# Hmmm, I wonder if this masks some real leaks. I think it does. -# Will need to fix that. -# - -{ - Suppress leaking the GIL. Happens once per process, see comment in ceval.c. - Memcheck:Leak - fun:malloc - fun:PyThread_allocate_lock - fun:PyEval_InitThreads -} - -{ - Suppress leaking the GIL after a fork. - Memcheck:Leak - fun:malloc - fun:PyThread_allocate_lock - fun:PyEval_ReInitThreads -} - -{ - Suppress leaking the autoTLSkey. This looks like it shouldn't leak though. - Memcheck:Leak - fun:malloc - fun:PyThread_create_key - fun:_PyGILState_Init - fun:Py_InitializeEx - fun:Py_Main -} - -{ - Hmmm, is this a real leak or like the GIL? - Memcheck:Leak - fun:malloc - fun:PyThread_ReInitTLS -} - -{ - Handle PyMalloc confusing valgrind (possibly leaked) - Memcheck:Leak - fun:realloc - fun:_PyObject_GC_Resize - fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING -} - -{ - Handle PyMalloc confusing valgrind (possibly leaked) - Memcheck:Leak - fun:malloc - fun:_PyObject_GC_New - fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING -} - -{ - Handle PyMalloc confusing valgrind (possibly leaked) - Memcheck:Leak - fun:malloc - fun:_PyObject_GC_NewVar - fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING -} - -# -# Non-python specific leaks -# - -{ - Handle pthread issue (possibly leaked) - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate_tls_storage - fun:_dl_allocate_tls -} - -{ - Handle pthread issue (possibly leaked) - Memcheck:Leak - fun:memalign - fun:_dl_allocate_tls_storage - fun:_dl_allocate_tls -} - -###{ -### ADDRESS_IN_RANGE/Invalid read of size 4 -### Memcheck:Addr4 -### fun:PyObject_Free -###} -### -###{ -### ADDRESS_IN_RANGE/Invalid read of size 4 -### Memcheck:Value4 -### fun:PyObject_Free -###} -### -###{ -### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value -### Memcheck:Cond -### fun:PyObject_Free -###} - -###{ -### ADDRESS_IN_RANGE/Invalid read of size 4 -### Memcheck:Addr4 -### fun:PyObject_Realloc -###} -### -###{ -### ADDRESS_IN_RANGE/Invalid read of size 4 -### Memcheck:Value4 -### fun:PyObject_Realloc -###} -### -###{ -### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value -### Memcheck:Cond -### fun:PyObject_Realloc -###} - -### -### All the suppressions below are for errors that occur within libraries -### that Python uses. The problems to not appear to be related to Python's -### use of the libraries. -### - -{ - Generic ubuntu ld problems - Memcheck:Addr8 - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so - obj:/lib/ld-2.4.so -} - -{ - Generic gentoo ld problems - Memcheck:Cond - obj:/lib/ld-2.3.4.so - obj:/lib/ld-2.3.4.so - obj:/lib/ld-2.3.4.so - obj:/lib/ld-2.3.4.so -} - -{ - DBM problems, see test_dbm - Memcheck:Param - write(buf) - fun:write - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - fun:dbm_close -} - -{ - DBM problems, see test_dbm - Memcheck:Value8 - fun:memmove - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - fun:dbm_store - fun:dbm_ass_sub -} - -{ - DBM problems, see test_dbm - Memcheck:Cond - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - fun:dbm_store - fun:dbm_ass_sub -} - -{ - DBM problems, see test_dbm - Memcheck:Cond - fun:memmove - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - obj:/usr/lib/libdb1.so.2 - fun:dbm_store - fun:dbm_ass_sub -} - -{ - GDBM problems, see test_gdbm - Memcheck:Param - write(buf) - fun:write - fun:gdbm_open - -} - -{ - ZLIB problems, see test_gzip - Memcheck:Cond - obj:/lib/libz.so.1.2.3 - obj:/lib/libz.so.1.2.3 - fun:deflate -} - -{ - Avoid problems w/readline doing a putenv and leaking on exit - Memcheck:Leak - fun:malloc - fun:xmalloc - fun:sh_set_lines_and_columns - fun:_rl_get_screen_size - fun:_rl_init_terminal_io - obj:/lib/libreadline.so.4.3 - fun:rl_initialize -} - -### -### These occur from somewhere within the SSL, when running -### test_socket_sll. They are too general to leave on by default. -### -###{ -### somewhere in SSL stuff -### Memcheck:Cond -### fun:memset -###} -###{ -### somewhere in SSL stuff -### Memcheck:Value4 -### fun:memset -###} -### -###{ -### somewhere in SSL stuff -### Memcheck:Cond -### fun:MD5_Update -###} -### -###{ -### somewhere in SSL stuff -### Memcheck:Value4 -### fun:MD5_Update -###} - -# -# All of these problems come from using test_socket_ssl -# -{ - from test_socket_ssl - Memcheck:Cond - fun:BN_bin2bn -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:BN_num_bits_word -} - -{ - from test_socket_ssl - Memcheck:Value4 - fun:BN_num_bits_word -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:BN_mod_exp_mont_word -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:BN_mod_exp_mont -} - -{ - from test_socket_ssl - Memcheck:Param - write(buf) - fun:write - obj:/usr/lib/libcrypto.so.0.9.7 -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:RSA_verify -} - -{ - from test_socket_ssl - Memcheck:Value4 - fun:RSA_verify -} - -{ - from test_socket_ssl - Memcheck:Value4 - fun:DES_set_key_unchecked -} - -{ - from test_socket_ssl - Memcheck:Value4 - fun:DES_encrypt2 -} - -{ - from test_socket_ssl - Memcheck:Cond - obj:/usr/lib/libssl.so.0.9.7 -} - -{ - from test_socket_ssl - Memcheck:Value4 - obj:/usr/lib/libssl.so.0.9.7 -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:BUF_MEM_grow_clean -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:memcpy - fun:ssl3_read_bytes -} - -{ - from test_socket_ssl - Memcheck:Cond - fun:SHA1_Update -} - -{ - from test_socket_ssl - Memcheck:Value4 - fun:SHA1_Update -} diff --git a/graalpython/hpy/hpy/trace/__init__.py b/graalpython/hpy/hpy/trace/__init__.py deleted file mode 100644 index 83d5308790..0000000000 --- a/graalpython/hpy/hpy/trace/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -import hpy.universal - -get_call_counts = hpy.universal._trace.get_call_counts -get_durations = hpy.universal._trace.get_durations -set_trace_functions = hpy.universal._trace.set_trace_functions -get_frequency = hpy.universal._trace.get_frequency diff --git a/graalpython/hpy/hpy/trace/src/_tracemod.c b/graalpython/hpy/hpy/trace/src/_tracemod.c deleted file mode 100644 index 954a437944..0000000000 --- a/graalpython/hpy/hpy/trace/src/_tracemod.c +++ /dev/null @@ -1,207 +0,0 @@ -// Python-level interface for the _trace module. Written in HPy itself, the -// idea is that it should be reusable by other implementations - -// NOTE: hpy.trace._trace is loaded using the UNIVERSAL ctx. To make it -// clearer, we will use "uctx" and "tctx" to distinguish them. - -#include "hpy.h" -#include "trace_internal.h" - -#ifndef _WIN32 -#include -#define MAX_SEC (LLONG_MAX / FREQ_NSEC) -#endif - -HPY_MOD_EMBEDDABLE(_trace) - -static inline int is_empty(const char *s) -{ - return s[0] == '\0'; -} - -#ifdef _WIN32 -static inline HPy win_time_to_ns(HPyContext *uctx, const LONGLONG to_ns, _HPyTime_t t) -{ - return HPyLong_FromLongLong(uctx, t.QuadPart * to_ns); -} - -#else -static inline HPy posix_time_to_ns(HPyContext *uctx, HPy *s_to_ns, _HPyTime_t t) -{ - /* Fast-path: If we can fit into a signed 64-bit integer, then do the - computation in C. This is the case if we can do 't.tv_sec * FREQ_SEC' - (i.e. converting seconds to nanoseconds) and add 'tv.tv_nsec' without - overflowing. */ - if (t.tv_sec < MAX_SEC) { - return HPyLong_FromLongLong(uctx, (long long)t.tv_sec * FREQ_NSEC + - (long long)t.tv_nsec); - } else { - /* Slow-path: do the computation with an (unbound) Python long */ - if (HPy_IsNull(*s_to_ns)) { - *s_to_ns = HPyLong_FromLongLong(uctx, FREQ_NSEC); - } - - HPy h_tv_sec = HPyLong_FromLongLong(uctx, t.tv_sec); - HPy h_tv_sec_as_ns = HPy_Multiply(uctx, h_tv_sec, *s_to_ns); - HPy_Close(uctx, h_tv_sec); - - HPy tv_nsec = HPyLong_FromLong(uctx, t.tv_nsec); - HPy res = HPy_Add(uctx, h_tv_sec_as_ns, tv_nsec); - HPy_Close(uctx, h_tv_sec_as_ns); - HPy_Close(uctx, tv_nsec); - - return res; - } -} -#endif - -HPyDef_METH(get_durations, "get_durations", HPyFunc_NOARGS) -static HPy get_durations_impl(HPyContext *uctx, HPy self) -{ - HPyContext *tctx = hpy_trace_get_ctx(uctx); - HPyTraceInfo *info = get_info(tctx); - HPyTracker ht = HPyTracker_New(uctx, hpy_trace_get_nfunc()); - -#ifdef _WIN32 - const LONGLONG to_ns = FREQ_NSEC / info->counter_freq.QuadPart; -#else - HPy s_to_ns = HPy_NULL; -#endif - HPy res = HPyDict_New(uctx); - const char *func_name; - for (int i=0; (func_name = hpy_trace_get_func_name(i)); i++) - { - /* skip empty names; those indices denote a context handle */ - if (!is_empty(func_name)) - { -#ifdef _WIN32 - HPy value = win_time_to_ns(uctx, to_ns, info->durations[i]); -#else - HPy value = posix_time_to_ns(uctx, &s_to_ns, info->durations[i]); -#endif - HPyTracker_Add(uctx, ht, value); - if (HPy_IsNull(value)) - goto fail; - if (HPy_SetItem_s(uctx, res, func_name, value) < 0) - goto fail; - } - } -#ifndef _WIN32 - HPy_Close(uctx, s_to_ns); -#endif - HPyTracker_Close(uctx, ht); - return res; -fail: - HPy_Close(uctx, res); - HPyTracker_Close(uctx, ht); - return HPy_NULL; -} - -HPyDef_METH(get_call_counts, "get_call_counts", HPyFunc_NOARGS) -static HPy get_call_counts_impl(HPyContext *uctx, HPy self) -{ - HPyContext *tctx = hpy_trace_get_ctx(uctx); - HPyTraceInfo *info = get_info(tctx); - HPyTracker ht = HPyTracker_New(uctx, hpy_trace_get_nfunc()); - HPy res = HPyDict_New(uctx); - const char *func_name; - for (int i=0; (func_name = hpy_trace_get_func_name(i)); i++) - { - /* skip empty names; those indices denote a context handle */ - if (!is_empty(func_name)) - { - HPy value = HPyLong_FromUnsignedLongLong(uctx, - (unsigned long long)info->call_counts[i]); - HPyTracker_Add(uctx, ht, value); - if (HPy_IsNull(value)) - goto fail; - if (HPy_SetItem_s(uctx, res, func_name, value) < 0) - goto fail; - } - } - HPyTracker_Close(uctx, ht); - return res; -fail: - HPy_Close(uctx, res); - HPyTracker_Close(uctx, ht); - return HPy_NULL; -} - -static int check_and_set_func(HPyContext *uctx, HPy arg, HPy *out) -{ - if (HPy_IsNull(arg)) { - // not provided -> do not change value - return 0; - } else if (HPy_Is(uctx, arg, uctx->h_None)) { - // None -> clear function - *out = HPy_NULL; - return 0; - } else if (!HPyCallable_Check(uctx, arg)) { - // not null, not None, not callable -> error - HPyErr_SetString(uctx, uctx->h_TypeError, "Expected a callable object or None"); - return -1; - } - // a callable -> set function - *out = HPy_Dup(uctx, arg); - return 0; -} - -HPyDef_METH(set_trace_functions, "set_trace_functions", HPyFunc_KEYWORDS, - .doc="Set the functions to call if an HPy API is entered/exited.") -static HPy set_trace_functions_impl(HPyContext *uctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames) -{ - HPy h_on_enter = HPy_NULL; - HPy h_on_exit = HPy_NULL; - HPyContext *dctx = hpy_trace_get_ctx(uctx); - HPyTraceInfo *info = get_info(dctx); - HPyTracker ht; - - static const char *kwlist[] = { "on_enter", "on_exit", NULL }; - if (!HPyArg_ParseKeywords(uctx, &ht, args, nargs, kwnames, "|OO", kwlist, - &h_on_enter, &h_on_exit)) { - return HPy_NULL; - } - - int r = check_and_set_func(uctx, h_on_enter, &info->on_enter_func) < 0 || - check_and_set_func(uctx, h_on_exit, &info->on_exit_func) < 0; - HPyTracker_Close(uctx, ht); - if (r) { - return HPy_NULL; - } - return HPy_Dup(uctx, uctx->h_None); -} - -HPyDef_METH(get_frequency, "get_frequency", HPyFunc_NOARGS, - .doc="Resolution of the used clock in Hertz.") -static HPy get_frequency_impl(HPyContext *uctx, HPy self) -{ - HPyContext *tctx = hpy_trace_get_ctx(uctx); - HPyTraceInfo *info = get_info(tctx); -#ifdef _WIN32 - long long f = (long long) info->counter_freq.QuadPart; -#else - long long f = (long long) info->counter_freq.tv_sec + - (long long)info->counter_freq.tv_nsec * FREQ_NSEC; -#endif - return HPyLong_FromLongLong(uctx, f); -} - - -/* ~~~~~~ definition of the module hpy.trace._trace ~~~~~~~ */ - -static HPyDef *module_defines[] = { - &get_durations, - &get_call_counts, - &set_trace_functions, - &get_frequency, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "HPy trace mode", - .size = 0, - .defines = module_defines -}; - -HPy_MODINIT(_trace, moduledef) diff --git a/graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h b/graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h deleted file mode 100644 index fef5028491..0000000000 --- a/graalpython/hpy/hpy/trace/src/autogen_trace_ctx_init.h +++ /dev/null @@ -1,495 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trace.autogen_tracer_ctx_init_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -HPy trace_ctx_Dup(HPyContext *tctx, HPy h); -void trace_ctx_Close(HPyContext *tctx, HPy h); -HPy trace_ctx_Long_FromInt32_t(HPyContext *tctx, int32_t value); -HPy trace_ctx_Long_FromUInt32_t(HPyContext *tctx, uint32_t value); -HPy trace_ctx_Long_FromInt64_t(HPyContext *tctx, int64_t v); -HPy trace_ctx_Long_FromUInt64_t(HPyContext *tctx, uint64_t v); -HPy trace_ctx_Long_FromSize_t(HPyContext *tctx, size_t value); -HPy trace_ctx_Long_FromSsize_t(HPyContext *tctx, HPy_ssize_t value); -int32_t trace_ctx_Long_AsInt32_t(HPyContext *tctx, HPy h); -uint32_t trace_ctx_Long_AsUInt32_t(HPyContext *tctx, HPy h); -uint32_t trace_ctx_Long_AsUInt32_tMask(HPyContext *tctx, HPy h); -int64_t trace_ctx_Long_AsInt64_t(HPyContext *tctx, HPy h); -uint64_t trace_ctx_Long_AsUInt64_t(HPyContext *tctx, HPy h); -uint64_t trace_ctx_Long_AsUInt64_tMask(HPyContext *tctx, HPy h); -size_t trace_ctx_Long_AsSize_t(HPyContext *tctx, HPy h); -HPy_ssize_t trace_ctx_Long_AsSsize_t(HPyContext *tctx, HPy h); -void *trace_ctx_Long_AsVoidPtr(HPyContext *tctx, HPy h); -double trace_ctx_Long_AsDouble(HPyContext *tctx, HPy h); -HPy trace_ctx_Float_FromDouble(HPyContext *tctx, double v); -double trace_ctx_Float_AsDouble(HPyContext *tctx, HPy h); -HPy trace_ctx_Bool_FromBool(HPyContext *tctx, bool v); -HPy_ssize_t trace_ctx_Length(HPyContext *tctx, HPy h); -int trace_ctx_Number_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_Add(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Subtract(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Multiply(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_MatrixMultiply(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_FloorDivide(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_TrueDivide(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Remainder(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Divmod(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Power(HPyContext *tctx, HPy h1, HPy h2, HPy h3); -HPy trace_ctx_Negative(HPyContext *tctx, HPy h1); -HPy trace_ctx_Positive(HPyContext *tctx, HPy h1); -HPy trace_ctx_Absolute(HPyContext *tctx, HPy h1); -HPy trace_ctx_Invert(HPyContext *tctx, HPy h1); -HPy trace_ctx_Lshift(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Rshift(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_And(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Xor(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Or(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_Index(HPyContext *tctx, HPy h1); -HPy trace_ctx_Long(HPyContext *tctx, HPy h1); -HPy trace_ctx_Float(HPyContext *tctx, HPy h1); -HPy trace_ctx_InPlaceAdd(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceSubtract(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceMultiply(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceMatrixMultiply(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceFloorDivide(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceTrueDivide(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceRemainder(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlacePower(HPyContext *tctx, HPy h1, HPy h2, HPy h3); -HPy trace_ctx_InPlaceLshift(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceRshift(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceAnd(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceXor(HPyContext *tctx, HPy h1, HPy h2); -HPy trace_ctx_InPlaceOr(HPyContext *tctx, HPy h1, HPy h2); -int trace_ctx_Callable_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_CallTupleDict(HPyContext *tctx, HPy callable, HPy args, HPy kw); -HPy trace_ctx_Call(HPyContext *tctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames); -HPy trace_ctx_CallMethod(HPyContext *tctx, HPy name, const HPy *args, size_t nargs, HPy kwnames); -HPy trace_ctx_GetIter(HPyContext *tctx, HPy obj); -HPy trace_ctx_Iter_Next(HPyContext *tctx, HPy obj); -int trace_ctx_Iter_Check(HPyContext *tctx, HPy obj); -void trace_ctx_Err_SetString(HPyContext *tctx, HPy h_type, const char *utf8_message); -void trace_ctx_Err_SetObject(HPyContext *tctx, HPy h_type, HPy h_value); -HPy trace_ctx_Err_SetFromErrnoWithFilename(HPyContext *tctx, HPy h_type, const char *filename_fsencoded); -void trace_ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *tctx, HPy h_type, HPy filename1, HPy filename2); -int trace_ctx_Err_Occurred(HPyContext *tctx); -int trace_ctx_Err_ExceptionMatches(HPyContext *tctx, HPy exc); -void trace_ctx_Err_NoMemory(HPyContext *tctx); -void trace_ctx_Err_Clear(HPyContext *tctx); -HPy trace_ctx_Err_NewException(HPyContext *tctx, const char *utf8_name, HPy base, HPy dict); -HPy trace_ctx_Err_NewExceptionWithDoc(HPyContext *tctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict); -int trace_ctx_Err_WarnEx(HPyContext *tctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level); -void trace_ctx_Err_WriteUnraisable(HPyContext *tctx, HPy obj); -int trace_ctx_IsTrue(HPyContext *tctx, HPy h); -HPy trace_ctx_Type_FromSpec(HPyContext *tctx, HPyType_Spec *spec, HPyType_SpecParam *params); -HPy trace_ctx_Type_GenericNew(HPyContext *tctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw); -HPy trace_ctx_GetAttr(HPyContext *tctx, HPy obj, HPy name); -HPy trace_ctx_GetAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name); -int trace_ctx_HasAttr(HPyContext *tctx, HPy obj, HPy name); -int trace_ctx_HasAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name); -int trace_ctx_SetAttr(HPyContext *tctx, HPy obj, HPy name, HPy value); -int trace_ctx_SetAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name, HPy value); -HPy trace_ctx_GetItem(HPyContext *tctx, HPy obj, HPy key); -HPy trace_ctx_GetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx); -HPy trace_ctx_GetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key); -HPy trace_ctx_GetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); -int trace_ctx_Contains(HPyContext *tctx, HPy container, HPy key); -int trace_ctx_SetItem(HPyContext *tctx, HPy obj, HPy key, HPy value); -int trace_ctx_SetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx, HPy value); -int trace_ctx_SetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key, HPy value); -int trace_ctx_SetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value); -int trace_ctx_DelItem(HPyContext *tctx, HPy obj, HPy key); -int trace_ctx_DelItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx); -int trace_ctx_DelItem_s(HPyContext *tctx, HPy obj, const char *utf8_key); -int trace_ctx_DelSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end); -HPy trace_ctx_Type(HPyContext *tctx, HPy obj); -int trace_ctx_TypeCheck(HPyContext *tctx, HPy obj, HPy type); -const char *trace_ctx_Type_GetName(HPyContext *tctx, HPy type); -int trace_ctx_Type_IsSubtype(HPyContext *tctx, HPy sub, HPy type); -int trace_ctx_Is(HPyContext *tctx, HPy obj, HPy other); -void *trace_ctx_AsStruct_Object(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Legacy(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Type(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Long(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Float(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Unicode(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Tuple(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_List(HPyContext *tctx, HPy h); -void *trace_ctx_AsStruct_Dict(HPyContext *tctx, HPy h); -HPyType_BuiltinShape trace_ctx_Type_GetBuiltinShape(HPyContext *tctx, HPy h_type); -HPy trace_ctx_New(HPyContext *tctx, HPy h_type, void **data); -HPy trace_ctx_Repr(HPyContext *tctx, HPy obj); -HPy trace_ctx_Str(HPyContext *tctx, HPy obj); -HPy trace_ctx_ASCII(HPyContext *tctx, HPy obj); -HPy trace_ctx_Bytes(HPyContext *tctx, HPy obj); -HPy trace_ctx_RichCompare(HPyContext *tctx, HPy v, HPy w, int op); -int trace_ctx_RichCompareBool(HPyContext *tctx, HPy v, HPy w, int op); -HPy_hash_t trace_ctx_Hash(HPyContext *tctx, HPy obj); -int trace_ctx_Bytes_Check(HPyContext *tctx, HPy h); -HPy_ssize_t trace_ctx_Bytes_Size(HPyContext *tctx, HPy h); -HPy_ssize_t trace_ctx_Bytes_GET_SIZE(HPyContext *tctx, HPy h); -const char *trace_ctx_Bytes_AsString(HPyContext *tctx, HPy h); -const char *trace_ctx_Bytes_AS_STRING(HPyContext *tctx, HPy h); -HPy trace_ctx_Bytes_FromString(HPyContext *tctx, const char *bytes); -HPy trace_ctx_Bytes_FromStringAndSize(HPyContext *tctx, const char *bytes, HPy_ssize_t len); -HPy trace_ctx_Unicode_FromString(HPyContext *tctx, const char *utf8); -int trace_ctx_Unicode_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_Unicode_AsASCIIString(HPyContext *tctx, HPy h); -HPy trace_ctx_Unicode_AsLatin1String(HPyContext *tctx, HPy h); -HPy trace_ctx_Unicode_AsUTF8String(HPyContext *tctx, HPy h); -const char *trace_ctx_Unicode_AsUTF8AndSize(HPyContext *tctx, HPy h, HPy_ssize_t *size); -HPy trace_ctx_Unicode_FromWideChar(HPyContext *tctx, const wchar_t *w, HPy_ssize_t size); -HPy trace_ctx_Unicode_DecodeFSDefault(HPyContext *tctx, const char *v); -HPy trace_ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *tctx, const char *v, HPy_ssize_t size); -HPy trace_ctx_Unicode_EncodeFSDefault(HPyContext *tctx, HPy h); -HPy_UCS4 trace_ctx_Unicode_ReadChar(HPyContext *tctx, HPy h, HPy_ssize_t index); -HPy trace_ctx_Unicode_DecodeASCII(HPyContext *tctx, const char *ascii, HPy_ssize_t size, const char *errors); -HPy trace_ctx_Unicode_DecodeLatin1(HPyContext *tctx, const char *latin1, HPy_ssize_t size, const char *errors); -HPy trace_ctx_Unicode_FromEncodedObject(HPyContext *tctx, HPy obj, const char *encoding, const char *errors); -HPy trace_ctx_Unicode_Substring(HPyContext *tctx, HPy str, HPy_ssize_t start, HPy_ssize_t end); -int trace_ctx_List_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_List_New(HPyContext *tctx, HPy_ssize_t len); -int trace_ctx_List_Append(HPyContext *tctx, HPy h_list, HPy h_item); -int trace_ctx_List_Insert(HPyContext *tctx, HPy h_list, HPy_ssize_t index, HPy h_item); -int trace_ctx_Dict_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_Dict_New(HPyContext *tctx); -HPy trace_ctx_Dict_Keys(HPyContext *tctx, HPy h); -HPy trace_ctx_Dict_Copy(HPyContext *tctx, HPy h); -int trace_ctx_Tuple_Check(HPyContext *tctx, HPy h); -HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, const HPy items[], HPy_ssize_t n); -HPy trace_ctx_Slice_New(HPyContext *tctx, HPy start, HPy stop, HPy step); -int trace_ctx_Slice_Unpack(HPyContext *tctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step); -HPy trace_ctx_Import_ImportModule(HPyContext *tctx, const char *utf8_name); -HPy trace_ctx_Capsule_New(HPyContext *tctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor); -void *trace_ctx_Capsule_Get(HPyContext *tctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name); -int trace_ctx_Capsule_IsValid(HPyContext *tctx, HPy capsule, const char *utf8_name); -int trace_ctx_Capsule_Set(HPyContext *tctx, HPy capsule, _HPyCapsule_key key, void *value); -HPy trace_ctx_FromPyObject(HPyContext *tctx, cpy_PyObject *obj); -cpy_PyObject *trace_ctx_AsPyObject(HPyContext *tctx, HPy h); -HPyListBuilder trace_ctx_ListBuilder_New(HPyContext *tctx, HPy_ssize_t size); -void trace_ctx_ListBuilder_Set(HPyContext *tctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item); -HPy trace_ctx_ListBuilder_Build(HPyContext *tctx, HPyListBuilder builder); -void trace_ctx_ListBuilder_Cancel(HPyContext *tctx, HPyListBuilder builder); -HPyTupleBuilder trace_ctx_TupleBuilder_New(HPyContext *tctx, HPy_ssize_t size); -void trace_ctx_TupleBuilder_Set(HPyContext *tctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item); -HPy trace_ctx_TupleBuilder_Build(HPyContext *tctx, HPyTupleBuilder builder); -void trace_ctx_TupleBuilder_Cancel(HPyContext *tctx, HPyTupleBuilder builder); -HPyTracker trace_ctx_Tracker_New(HPyContext *tctx, HPy_ssize_t size); -int trace_ctx_Tracker_Add(HPyContext *tctx, HPyTracker ht, HPy h); -void trace_ctx_Tracker_ForgetAll(HPyContext *tctx, HPyTracker ht); -void trace_ctx_Tracker_Close(HPyContext *tctx, HPyTracker ht); -void trace_ctx_Field_Store(HPyContext *tctx, HPy target_object, HPyField *target_field, HPy h); -HPy trace_ctx_Field_Load(HPyContext *tctx, HPy source_object, HPyField source_field); -void trace_ctx_ReenterPythonExecution(HPyContext *tctx, HPyThreadState state); -HPyThreadState trace_ctx_LeavePythonExecution(HPyContext *tctx); -void trace_ctx_Global_Store(HPyContext *tctx, HPyGlobal *global, HPy h); -HPy trace_ctx_Global_Load(HPyContext *tctx, HPyGlobal global); -void trace_ctx_Dump(HPyContext *tctx, HPy h); -HPy trace_ctx_Compile_s(HPyContext *tctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind); -HPy trace_ctx_EvalCode(HPyContext *tctx, HPy code, HPy globals, HPy locals); -HPy trace_ctx_ContextVar_New(HPyContext *tctx, const char *name, HPy default_value); -int32_t trace_ctx_ContextVar_Get(HPyContext *tctx, HPy context_var, HPy default_value, HPy *result); -HPy trace_ctx_ContextVar_Set(HPyContext *tctx, HPy context_var, HPy value); -int trace_ctx_SetCallFunction(HPyContext *tctx, HPy h, HPyCallFunction *func); - -static inline void trace_ctx_init_info(HPyTraceInfo *info, HPyContext *uctx) -{ - info->magic_number = HPY_TRACE_MAGIC; - info->uctx = uctx; - info->call_counts = (uint64_t *)calloc(273, sizeof(uint64_t)); - info->durations = (_HPyTime_t *)calloc(273, sizeof(_HPyTime_t)); - info->on_enter_func = HPy_NULL; - info->on_exit_func = HPy_NULL; -} - -static inline void trace_ctx_free_info(HPyTraceInfo *info) -{ - assert(info->magic_number == HPY_TRACE_MAGIC); - free(info->call_counts); - free(info->durations); - HPy_Close(info->uctx, info->on_enter_func); - HPy_Close(info->uctx, info->on_exit_func); -} - -static inline void trace_ctx_init_fields(HPyContext *tctx, HPyContext *uctx) -{ - tctx->h_None = uctx->h_None; - tctx->h_True = uctx->h_True; - tctx->h_False = uctx->h_False; - tctx->h_NotImplemented = uctx->h_NotImplemented; - tctx->h_Ellipsis = uctx->h_Ellipsis; - tctx->h_BaseException = uctx->h_BaseException; - tctx->h_Exception = uctx->h_Exception; - tctx->h_StopAsyncIteration = uctx->h_StopAsyncIteration; - tctx->h_StopIteration = uctx->h_StopIteration; - tctx->h_GeneratorExit = uctx->h_GeneratorExit; - tctx->h_ArithmeticError = uctx->h_ArithmeticError; - tctx->h_LookupError = uctx->h_LookupError; - tctx->h_AssertionError = uctx->h_AssertionError; - tctx->h_AttributeError = uctx->h_AttributeError; - tctx->h_BufferError = uctx->h_BufferError; - tctx->h_EOFError = uctx->h_EOFError; - tctx->h_FloatingPointError = uctx->h_FloatingPointError; - tctx->h_OSError = uctx->h_OSError; - tctx->h_ImportError = uctx->h_ImportError; - tctx->h_ModuleNotFoundError = uctx->h_ModuleNotFoundError; - tctx->h_IndexError = uctx->h_IndexError; - tctx->h_KeyError = uctx->h_KeyError; - tctx->h_KeyboardInterrupt = uctx->h_KeyboardInterrupt; - tctx->h_MemoryError = uctx->h_MemoryError; - tctx->h_NameError = uctx->h_NameError; - tctx->h_OverflowError = uctx->h_OverflowError; - tctx->h_RuntimeError = uctx->h_RuntimeError; - tctx->h_RecursionError = uctx->h_RecursionError; - tctx->h_NotImplementedError = uctx->h_NotImplementedError; - tctx->h_SyntaxError = uctx->h_SyntaxError; - tctx->h_IndentationError = uctx->h_IndentationError; - tctx->h_TabError = uctx->h_TabError; - tctx->h_ReferenceError = uctx->h_ReferenceError; - tctx->h_SystemError = uctx->h_SystemError; - tctx->h_SystemExit = uctx->h_SystemExit; - tctx->h_TypeError = uctx->h_TypeError; - tctx->h_UnboundLocalError = uctx->h_UnboundLocalError; - tctx->h_UnicodeError = uctx->h_UnicodeError; - tctx->h_UnicodeEncodeError = uctx->h_UnicodeEncodeError; - tctx->h_UnicodeDecodeError = uctx->h_UnicodeDecodeError; - tctx->h_UnicodeTranslateError = uctx->h_UnicodeTranslateError; - tctx->h_ValueError = uctx->h_ValueError; - tctx->h_ZeroDivisionError = uctx->h_ZeroDivisionError; - tctx->h_BlockingIOError = uctx->h_BlockingIOError; - tctx->h_BrokenPipeError = uctx->h_BrokenPipeError; - tctx->h_ChildProcessError = uctx->h_ChildProcessError; - tctx->h_ConnectionError = uctx->h_ConnectionError; - tctx->h_ConnectionAbortedError = uctx->h_ConnectionAbortedError; - tctx->h_ConnectionRefusedError = uctx->h_ConnectionRefusedError; - tctx->h_ConnectionResetError = uctx->h_ConnectionResetError; - tctx->h_FileExistsError = uctx->h_FileExistsError; - tctx->h_FileNotFoundError = uctx->h_FileNotFoundError; - tctx->h_InterruptedError = uctx->h_InterruptedError; - tctx->h_IsADirectoryError = uctx->h_IsADirectoryError; - tctx->h_NotADirectoryError = uctx->h_NotADirectoryError; - tctx->h_PermissionError = uctx->h_PermissionError; - tctx->h_ProcessLookupError = uctx->h_ProcessLookupError; - tctx->h_TimeoutError = uctx->h_TimeoutError; - tctx->h_Warning = uctx->h_Warning; - tctx->h_UserWarning = uctx->h_UserWarning; - tctx->h_DeprecationWarning = uctx->h_DeprecationWarning; - tctx->h_PendingDeprecationWarning = uctx->h_PendingDeprecationWarning; - tctx->h_SyntaxWarning = uctx->h_SyntaxWarning; - tctx->h_RuntimeWarning = uctx->h_RuntimeWarning; - tctx->h_FutureWarning = uctx->h_FutureWarning; - tctx->h_ImportWarning = uctx->h_ImportWarning; - tctx->h_UnicodeWarning = uctx->h_UnicodeWarning; - tctx->h_BytesWarning = uctx->h_BytesWarning; - tctx->h_ResourceWarning = uctx->h_ResourceWarning; - tctx->h_BaseObjectType = uctx->h_BaseObjectType; - tctx->h_TypeType = uctx->h_TypeType; - tctx->h_BoolType = uctx->h_BoolType; - tctx->h_LongType = uctx->h_LongType; - tctx->h_FloatType = uctx->h_FloatType; - tctx->h_UnicodeType = uctx->h_UnicodeType; - tctx->h_TupleType = uctx->h_TupleType; - tctx->h_ListType = uctx->h_ListType; - tctx->h_ComplexType = uctx->h_ComplexType; - tctx->h_BytesType = uctx->h_BytesType; - tctx->h_MemoryViewType = uctx->h_MemoryViewType; - tctx->h_CapsuleType = uctx->h_CapsuleType; - tctx->h_SliceType = uctx->h_SliceType; - tctx->h_DictType = uctx->h_DictType; - tctx->h_Builtins = uctx->h_Builtins; - tctx->ctx_Dup = &trace_ctx_Dup; - tctx->ctx_Close = &trace_ctx_Close; - tctx->ctx_Long_FromInt32_t = &trace_ctx_Long_FromInt32_t; - tctx->ctx_Long_FromUInt32_t = &trace_ctx_Long_FromUInt32_t; - tctx->ctx_Long_FromInt64_t = &trace_ctx_Long_FromInt64_t; - tctx->ctx_Long_FromUInt64_t = &trace_ctx_Long_FromUInt64_t; - tctx->ctx_Long_FromSize_t = &trace_ctx_Long_FromSize_t; - tctx->ctx_Long_FromSsize_t = &trace_ctx_Long_FromSsize_t; - tctx->ctx_Long_AsInt32_t = &trace_ctx_Long_AsInt32_t; - tctx->ctx_Long_AsUInt32_t = &trace_ctx_Long_AsUInt32_t; - tctx->ctx_Long_AsUInt32_tMask = &trace_ctx_Long_AsUInt32_tMask; - tctx->ctx_Long_AsInt64_t = &trace_ctx_Long_AsInt64_t; - tctx->ctx_Long_AsUInt64_t = &trace_ctx_Long_AsUInt64_t; - tctx->ctx_Long_AsUInt64_tMask = &trace_ctx_Long_AsUInt64_tMask; - tctx->ctx_Long_AsSize_t = &trace_ctx_Long_AsSize_t; - tctx->ctx_Long_AsSsize_t = &trace_ctx_Long_AsSsize_t; - tctx->ctx_Long_AsVoidPtr = &trace_ctx_Long_AsVoidPtr; - tctx->ctx_Long_AsDouble = &trace_ctx_Long_AsDouble; - tctx->ctx_Float_FromDouble = &trace_ctx_Float_FromDouble; - tctx->ctx_Float_AsDouble = &trace_ctx_Float_AsDouble; - tctx->ctx_Bool_FromBool = &trace_ctx_Bool_FromBool; - tctx->ctx_Length = &trace_ctx_Length; - tctx->ctx_Number_Check = &trace_ctx_Number_Check; - tctx->ctx_Add = &trace_ctx_Add; - tctx->ctx_Subtract = &trace_ctx_Subtract; - tctx->ctx_Multiply = &trace_ctx_Multiply; - tctx->ctx_MatrixMultiply = &trace_ctx_MatrixMultiply; - tctx->ctx_FloorDivide = &trace_ctx_FloorDivide; - tctx->ctx_TrueDivide = &trace_ctx_TrueDivide; - tctx->ctx_Remainder = &trace_ctx_Remainder; - tctx->ctx_Divmod = &trace_ctx_Divmod; - tctx->ctx_Power = &trace_ctx_Power; - tctx->ctx_Negative = &trace_ctx_Negative; - tctx->ctx_Positive = &trace_ctx_Positive; - tctx->ctx_Absolute = &trace_ctx_Absolute; - tctx->ctx_Invert = &trace_ctx_Invert; - tctx->ctx_Lshift = &trace_ctx_Lshift; - tctx->ctx_Rshift = &trace_ctx_Rshift; - tctx->ctx_And = &trace_ctx_And; - tctx->ctx_Xor = &trace_ctx_Xor; - tctx->ctx_Or = &trace_ctx_Or; - tctx->ctx_Index = &trace_ctx_Index; - tctx->ctx_Long = &trace_ctx_Long; - tctx->ctx_Float = &trace_ctx_Float; - tctx->ctx_InPlaceAdd = &trace_ctx_InPlaceAdd; - tctx->ctx_InPlaceSubtract = &trace_ctx_InPlaceSubtract; - tctx->ctx_InPlaceMultiply = &trace_ctx_InPlaceMultiply; - tctx->ctx_InPlaceMatrixMultiply = &trace_ctx_InPlaceMatrixMultiply; - tctx->ctx_InPlaceFloorDivide = &trace_ctx_InPlaceFloorDivide; - tctx->ctx_InPlaceTrueDivide = &trace_ctx_InPlaceTrueDivide; - tctx->ctx_InPlaceRemainder = &trace_ctx_InPlaceRemainder; - tctx->ctx_InPlacePower = &trace_ctx_InPlacePower; - tctx->ctx_InPlaceLshift = &trace_ctx_InPlaceLshift; - tctx->ctx_InPlaceRshift = &trace_ctx_InPlaceRshift; - tctx->ctx_InPlaceAnd = &trace_ctx_InPlaceAnd; - tctx->ctx_InPlaceXor = &trace_ctx_InPlaceXor; - tctx->ctx_InPlaceOr = &trace_ctx_InPlaceOr; - tctx->ctx_Callable_Check = &trace_ctx_Callable_Check; - tctx->ctx_CallTupleDict = &trace_ctx_CallTupleDict; - tctx->ctx_Call = &trace_ctx_Call; - tctx->ctx_CallMethod = &trace_ctx_CallMethod; - tctx->ctx_GetIter = &trace_ctx_GetIter; - tctx->ctx_Iter_Next = &trace_ctx_Iter_Next; - tctx->ctx_Iter_Check = &trace_ctx_Iter_Check; - tctx->ctx_FatalError = uctx->ctx_FatalError; - tctx->ctx_Err_SetString = &trace_ctx_Err_SetString; - tctx->ctx_Err_SetObject = &trace_ctx_Err_SetObject; - tctx->ctx_Err_SetFromErrnoWithFilename = &trace_ctx_Err_SetFromErrnoWithFilename; - tctx->ctx_Err_SetFromErrnoWithFilenameObjects = &trace_ctx_Err_SetFromErrnoWithFilenameObjects; - tctx->ctx_Err_Occurred = &trace_ctx_Err_Occurred; - tctx->ctx_Err_ExceptionMatches = &trace_ctx_Err_ExceptionMatches; - tctx->ctx_Err_NoMemory = &trace_ctx_Err_NoMemory; - tctx->ctx_Err_Clear = &trace_ctx_Err_Clear; - tctx->ctx_Err_NewException = &trace_ctx_Err_NewException; - tctx->ctx_Err_NewExceptionWithDoc = &trace_ctx_Err_NewExceptionWithDoc; - tctx->ctx_Err_WarnEx = &trace_ctx_Err_WarnEx; - tctx->ctx_Err_WriteUnraisable = &trace_ctx_Err_WriteUnraisable; - tctx->ctx_IsTrue = &trace_ctx_IsTrue; - tctx->ctx_Type_FromSpec = &trace_ctx_Type_FromSpec; - tctx->ctx_Type_GenericNew = &trace_ctx_Type_GenericNew; - tctx->ctx_GetAttr = &trace_ctx_GetAttr; - tctx->ctx_GetAttr_s = &trace_ctx_GetAttr_s; - tctx->ctx_HasAttr = &trace_ctx_HasAttr; - tctx->ctx_HasAttr_s = &trace_ctx_HasAttr_s; - tctx->ctx_SetAttr = &trace_ctx_SetAttr; - tctx->ctx_SetAttr_s = &trace_ctx_SetAttr_s; - tctx->ctx_GetItem = &trace_ctx_GetItem; - tctx->ctx_GetItem_i = &trace_ctx_GetItem_i; - tctx->ctx_GetItem_s = &trace_ctx_GetItem_s; - tctx->ctx_GetSlice = &trace_ctx_GetSlice; - tctx->ctx_Contains = &trace_ctx_Contains; - tctx->ctx_SetItem = &trace_ctx_SetItem; - tctx->ctx_SetItem_i = &trace_ctx_SetItem_i; - tctx->ctx_SetItem_s = &trace_ctx_SetItem_s; - tctx->ctx_SetSlice = &trace_ctx_SetSlice; - tctx->ctx_DelItem = &trace_ctx_DelItem; - tctx->ctx_DelItem_i = &trace_ctx_DelItem_i; - tctx->ctx_DelItem_s = &trace_ctx_DelItem_s; - tctx->ctx_DelSlice = &trace_ctx_DelSlice; - tctx->ctx_Type = &trace_ctx_Type; - tctx->ctx_TypeCheck = &trace_ctx_TypeCheck; - tctx->ctx_Type_GetName = &trace_ctx_Type_GetName; - tctx->ctx_Type_IsSubtype = &trace_ctx_Type_IsSubtype; - tctx->ctx_Is = &trace_ctx_Is; - tctx->ctx_AsStruct_Object = &trace_ctx_AsStruct_Object; - tctx->ctx_AsStruct_Legacy = &trace_ctx_AsStruct_Legacy; - tctx->ctx_AsStruct_Type = &trace_ctx_AsStruct_Type; - tctx->ctx_AsStruct_Long = &trace_ctx_AsStruct_Long; - tctx->ctx_AsStruct_Float = &trace_ctx_AsStruct_Float; - tctx->ctx_AsStruct_Unicode = &trace_ctx_AsStruct_Unicode; - tctx->ctx_AsStruct_Tuple = &trace_ctx_AsStruct_Tuple; - tctx->ctx_AsStruct_List = &trace_ctx_AsStruct_List; - tctx->ctx_AsStruct_Dict = &trace_ctx_AsStruct_Dict; - tctx->ctx_Type_GetBuiltinShape = &trace_ctx_Type_GetBuiltinShape; - tctx->ctx_New = &trace_ctx_New; - tctx->ctx_Repr = &trace_ctx_Repr; - tctx->ctx_Str = &trace_ctx_Str; - tctx->ctx_ASCII = &trace_ctx_ASCII; - tctx->ctx_Bytes = &trace_ctx_Bytes; - tctx->ctx_RichCompare = &trace_ctx_RichCompare; - tctx->ctx_RichCompareBool = &trace_ctx_RichCompareBool; - tctx->ctx_Hash = &trace_ctx_Hash; - tctx->ctx_Bytes_Check = &trace_ctx_Bytes_Check; - tctx->ctx_Bytes_Size = &trace_ctx_Bytes_Size; - tctx->ctx_Bytes_GET_SIZE = &trace_ctx_Bytes_GET_SIZE; - tctx->ctx_Bytes_AsString = &trace_ctx_Bytes_AsString; - tctx->ctx_Bytes_AS_STRING = &trace_ctx_Bytes_AS_STRING; - tctx->ctx_Bytes_FromString = &trace_ctx_Bytes_FromString; - tctx->ctx_Bytes_FromStringAndSize = &trace_ctx_Bytes_FromStringAndSize; - tctx->ctx_Unicode_FromString = &trace_ctx_Unicode_FromString; - tctx->ctx_Unicode_Check = &trace_ctx_Unicode_Check; - tctx->ctx_Unicode_AsASCIIString = &trace_ctx_Unicode_AsASCIIString; - tctx->ctx_Unicode_AsLatin1String = &trace_ctx_Unicode_AsLatin1String; - tctx->ctx_Unicode_AsUTF8String = &trace_ctx_Unicode_AsUTF8String; - tctx->ctx_Unicode_AsUTF8AndSize = &trace_ctx_Unicode_AsUTF8AndSize; - tctx->ctx_Unicode_FromWideChar = &trace_ctx_Unicode_FromWideChar; - tctx->ctx_Unicode_DecodeFSDefault = &trace_ctx_Unicode_DecodeFSDefault; - tctx->ctx_Unicode_DecodeFSDefaultAndSize = &trace_ctx_Unicode_DecodeFSDefaultAndSize; - tctx->ctx_Unicode_EncodeFSDefault = &trace_ctx_Unicode_EncodeFSDefault; - tctx->ctx_Unicode_ReadChar = &trace_ctx_Unicode_ReadChar; - tctx->ctx_Unicode_DecodeASCII = &trace_ctx_Unicode_DecodeASCII; - tctx->ctx_Unicode_DecodeLatin1 = &trace_ctx_Unicode_DecodeLatin1; - tctx->ctx_Unicode_FromEncodedObject = &trace_ctx_Unicode_FromEncodedObject; - tctx->ctx_Unicode_Substring = &trace_ctx_Unicode_Substring; - tctx->ctx_List_Check = &trace_ctx_List_Check; - tctx->ctx_List_New = &trace_ctx_List_New; - tctx->ctx_List_Append = &trace_ctx_List_Append; - tctx->ctx_List_Insert = &trace_ctx_List_Insert; - tctx->ctx_Dict_Check = &trace_ctx_Dict_Check; - tctx->ctx_Dict_New = &trace_ctx_Dict_New; - tctx->ctx_Dict_Keys = &trace_ctx_Dict_Keys; - tctx->ctx_Dict_Copy = &trace_ctx_Dict_Copy; - tctx->ctx_Tuple_Check = &trace_ctx_Tuple_Check; - tctx->ctx_Tuple_FromArray = &trace_ctx_Tuple_FromArray; - tctx->ctx_Slice_New = &trace_ctx_Slice_New; - tctx->ctx_Slice_Unpack = &trace_ctx_Slice_Unpack; - tctx->ctx_Import_ImportModule = &trace_ctx_Import_ImportModule; - tctx->ctx_Capsule_New = &trace_ctx_Capsule_New; - tctx->ctx_Capsule_Get = &trace_ctx_Capsule_Get; - tctx->ctx_Capsule_IsValid = &trace_ctx_Capsule_IsValid; - tctx->ctx_Capsule_Set = &trace_ctx_Capsule_Set; - tctx->ctx_FromPyObject = &trace_ctx_FromPyObject; - tctx->ctx_AsPyObject = &trace_ctx_AsPyObject; - tctx->ctx_CallRealFunctionFromTrampoline = uctx->ctx_CallRealFunctionFromTrampoline; - tctx->ctx_ListBuilder_New = &trace_ctx_ListBuilder_New; - tctx->ctx_ListBuilder_Set = &trace_ctx_ListBuilder_Set; - tctx->ctx_ListBuilder_Build = &trace_ctx_ListBuilder_Build; - tctx->ctx_ListBuilder_Cancel = &trace_ctx_ListBuilder_Cancel; - tctx->ctx_TupleBuilder_New = &trace_ctx_TupleBuilder_New; - tctx->ctx_TupleBuilder_Set = &trace_ctx_TupleBuilder_Set; - tctx->ctx_TupleBuilder_Build = &trace_ctx_TupleBuilder_Build; - tctx->ctx_TupleBuilder_Cancel = &trace_ctx_TupleBuilder_Cancel; - tctx->ctx_Tracker_New = &trace_ctx_Tracker_New; - tctx->ctx_Tracker_Add = &trace_ctx_Tracker_Add; - tctx->ctx_Tracker_ForgetAll = &trace_ctx_Tracker_ForgetAll; - tctx->ctx_Tracker_Close = &trace_ctx_Tracker_Close; - tctx->ctx_Field_Store = &trace_ctx_Field_Store; - tctx->ctx_Field_Load = &trace_ctx_Field_Load; - tctx->ctx_ReenterPythonExecution = &trace_ctx_ReenterPythonExecution; - tctx->ctx_LeavePythonExecution = &trace_ctx_LeavePythonExecution; - tctx->ctx_Global_Store = &trace_ctx_Global_Store; - tctx->ctx_Global_Load = &trace_ctx_Global_Load; - tctx->ctx_Dump = &trace_ctx_Dump; - tctx->ctx_Compile_s = &trace_ctx_Compile_s; - tctx->ctx_EvalCode = &trace_ctx_EvalCode; - tctx->ctx_ContextVar_New = &trace_ctx_ContextVar_New; - tctx->ctx_ContextVar_Get = &trace_ctx_ContextVar_Get; - tctx->ctx_ContextVar_Set = &trace_ctx_ContextVar_Set; - tctx->ctx_SetCallFunction = &trace_ctx_SetCallFunction; -} diff --git a/graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c b/graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c deleted file mode 100644 index 97d8308d53..0000000000 --- a/graalpython/hpy/hpy/trace/src/autogen_trace_func_table.c +++ /dev/null @@ -1,306 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trace.autogen_trace_func_table_c - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#include "trace_internal.h" - -#define TRACE_NFUNC 189 - -#define NO_FUNC "" -static const char *trace_func_table[] = { - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - "ctx_Dup", - "ctx_Close", - "ctx_Long_FromInt32_t", - "ctx_Long_FromUInt32_t", - "ctx_Long_FromInt64_t", - "ctx_Long_FromUInt64_t", - "ctx_Long_FromSize_t", - "ctx_Long_FromSsize_t", - "ctx_Long_AsInt32_t", - "ctx_Long_AsUInt32_t", - "ctx_Long_AsUInt32_tMask", - "ctx_Long_AsInt64_t", - "ctx_Long_AsUInt64_t", - "ctx_Long_AsUInt64_tMask", - "ctx_Long_AsSize_t", - "ctx_Long_AsSsize_t", - "ctx_Long_AsVoidPtr", - "ctx_Long_AsDouble", - "ctx_Float_FromDouble", - "ctx_Float_AsDouble", - "ctx_Bool_FromBool", - "ctx_Length", - "ctx_Number_Check", - "ctx_Add", - "ctx_Subtract", - "ctx_Multiply", - "ctx_MatrixMultiply", - "ctx_FloorDivide", - "ctx_TrueDivide", - "ctx_Remainder", - "ctx_Divmod", - "ctx_Power", - "ctx_Negative", - "ctx_Positive", - "ctx_Absolute", - "ctx_Invert", - "ctx_Lshift", - "ctx_Rshift", - "ctx_And", - "ctx_Xor", - "ctx_Or", - "ctx_Index", - "ctx_Long", - "ctx_Float", - "ctx_InPlaceAdd", - "ctx_InPlaceSubtract", - "ctx_InPlaceMultiply", - "ctx_InPlaceMatrixMultiply", - "ctx_InPlaceFloorDivide", - "ctx_InPlaceTrueDivide", - "ctx_InPlaceRemainder", - "ctx_InPlacePower", - "ctx_InPlaceLshift", - "ctx_InPlaceRshift", - "ctx_InPlaceAnd", - "ctx_InPlaceXor", - "ctx_InPlaceOr", - "ctx_Callable_Check", - "ctx_CallTupleDict", - "ctx_FatalError", - "ctx_Err_SetString", - "ctx_Err_SetObject", - "ctx_Err_SetFromErrnoWithFilename", - "ctx_Err_SetFromErrnoWithFilenameObjects", - "ctx_Err_Occurred", - "ctx_Err_ExceptionMatches", - "ctx_Err_NoMemory", - "ctx_Err_Clear", - "ctx_Err_NewException", - "ctx_Err_NewExceptionWithDoc", - "ctx_Err_WarnEx", - "ctx_Err_WriteUnraisable", - "ctx_IsTrue", - "ctx_Type_FromSpec", - "ctx_Type_GenericNew", - "ctx_GetAttr", - "ctx_GetAttr_s", - "ctx_HasAttr", - "ctx_HasAttr_s", - "ctx_SetAttr", - "ctx_SetAttr_s", - "ctx_GetItem", - "ctx_GetItem_i", - "ctx_GetItem_s", - "ctx_Contains", - "ctx_SetItem", - "ctx_SetItem_i", - "ctx_SetItem_s", - "ctx_Type", - "ctx_TypeCheck", - "ctx_Is", - "ctx_AsStruct_Object", - "ctx_AsStruct_Legacy", - "ctx_New", - "ctx_Repr", - "ctx_Str", - "ctx_ASCII", - "ctx_Bytes", - "ctx_RichCompare", - "ctx_RichCompareBool", - "ctx_Hash", - "ctx_Bytes_Check", - "ctx_Bytes_Size", - "ctx_Bytes_GET_SIZE", - "ctx_Bytes_AsString", - "ctx_Bytes_AS_STRING", - "ctx_Bytes_FromString", - "ctx_Bytes_FromStringAndSize", - "ctx_Unicode_FromString", - "ctx_Unicode_Check", - "ctx_Unicode_AsASCIIString", - "ctx_Unicode_AsLatin1String", - "ctx_Unicode_AsUTF8String", - "ctx_Unicode_AsUTF8AndSize", - "ctx_Unicode_FromWideChar", - "ctx_Unicode_DecodeFSDefault", - "ctx_Unicode_DecodeFSDefaultAndSize", - "ctx_Unicode_EncodeFSDefault", - "ctx_Unicode_ReadChar", - "ctx_Unicode_DecodeASCII", - "ctx_Unicode_DecodeLatin1", - "ctx_List_Check", - "ctx_List_New", - "ctx_List_Append", - "ctx_Dict_Check", - "ctx_Dict_New", - "ctx_Tuple_Check", - "ctx_Tuple_FromArray", - "ctx_Import_ImportModule", - "ctx_FromPyObject", - "ctx_AsPyObject", - "ctx_CallRealFunctionFromTrampoline", - "ctx_ListBuilder_New", - "ctx_ListBuilder_Set", - "ctx_ListBuilder_Build", - "ctx_ListBuilder_Cancel", - "ctx_TupleBuilder_New", - "ctx_TupleBuilder_Set", - "ctx_TupleBuilder_Build", - "ctx_TupleBuilder_Cancel", - "ctx_Tracker_New", - "ctx_Tracker_Add", - "ctx_Tracker_ForgetAll", - "ctx_Tracker_Close", - "ctx_Field_Store", - "ctx_Field_Load", - "ctx_ReenterPythonExecution", - "ctx_LeavePythonExecution", - "ctx_Global_Store", - "ctx_Global_Load", - "ctx_Dump", - "ctx_AsStruct_Type", - "ctx_AsStruct_Long", - "ctx_AsStruct_Float", - "ctx_AsStruct_Unicode", - "ctx_AsStruct_Tuple", - "ctx_AsStruct_List", - "ctx_Type_GetBuiltinShape", - "ctx_DelItem", - "ctx_DelItem_i", - "ctx_DelItem_s", - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - NO_FUNC, - "ctx_Capsule_New", - "ctx_Capsule_Get", - "ctx_Capsule_IsValid", - "ctx_Capsule_Set", - "ctx_Compile_s", - "ctx_EvalCode", - "ctx_ContextVar_New", - "ctx_ContextVar_Get", - "ctx_ContextVar_Set", - "ctx_Type_GetName", - "ctx_Type_IsSubtype", - "ctx_Unicode_FromEncodedObject", - "ctx_Unicode_Substring", - "ctx_Dict_Keys", - "ctx_Dict_Copy", - "ctx_Slice_Unpack", - "ctx_SetCallFunction", - "ctx_Call", - "ctx_CallMethod", - NO_FUNC, - "ctx_AsStruct_Dict", - "ctx_List_Insert", - "ctx_GetSlice", - "ctx_SetSlice", - "ctx_DelSlice", - "ctx_GetIter", - "ctx_Iter_Next", - "ctx_Iter_Check", - "ctx_Slice_New", - NULL /* sentinel */ -}; - -int hpy_trace_get_nfunc(void) -{ - return TRACE_NFUNC; -} - -const char * hpy_trace_get_func_name(int idx) -{ - if (idx >= 0 && idx < 273) - return trace_func_table[idx]; - return NULL; -} - diff --git a/graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c b/graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c deleted file mode 100644 index 4940a12a9d..0000000000 --- a/graalpython/hpy/hpy/trace/src/autogen_trace_wrappers.c +++ /dev/null @@ -1,2428 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trace.autogen_tracer_wrappers - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -#include "trace_internal.h" - -HPy trace_ctx_Dup(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 77); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Dup(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 77, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Close(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 78); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_Close(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 78, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Long_FromInt32_t(HPyContext *tctx, int32_t value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 79); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromInt32_t(uctx, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 79, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long_FromUInt32_t(HPyContext *tctx, uint32_t value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 80); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromUInt32_t(uctx, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 80, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long_FromInt64_t(HPyContext *tctx, int64_t v) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 81); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromInt64_t(uctx, v); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 81, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long_FromUInt64_t(HPyContext *tctx, uint64_t v) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 82); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromUInt64_t(uctx, v); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 82, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long_FromSize_t(HPyContext *tctx, size_t value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 83); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromSize_t(uctx, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 83, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long_FromSsize_t(HPyContext *tctx, HPy_ssize_t value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 84); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyLong_FromSsize_t(uctx, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 84, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int32_t trace_ctx_Long_AsInt32_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 85); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int32_t res = HPyLong_AsInt32_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 85, r0, r1, &_ts_start, &_ts_end); - return res; -} - -uint32_t trace_ctx_Long_AsUInt32_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 86); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - uint32_t res = HPyLong_AsUInt32_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 86, r0, r1, &_ts_start, &_ts_end); - return res; -} - -uint32_t trace_ctx_Long_AsUInt32_tMask(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 87); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - uint32_t res = HPyLong_AsUInt32_tMask(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 87, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int64_t trace_ctx_Long_AsInt64_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 88); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int64_t res = HPyLong_AsInt64_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 88, r0, r1, &_ts_start, &_ts_end); - return res; -} - -uint64_t trace_ctx_Long_AsUInt64_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 89); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - uint64_t res = HPyLong_AsUInt64_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 89, r0, r1, &_ts_start, &_ts_end); - return res; -} - -uint64_t trace_ctx_Long_AsUInt64_tMask(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 90); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - uint64_t res = HPyLong_AsUInt64_tMask(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 90, r0, r1, &_ts_start, &_ts_end); - return res; -} - -size_t trace_ctx_Long_AsSize_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 91); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - size_t res = HPyLong_AsSize_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 91, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_ssize_t trace_ctx_Long_AsSsize_t(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 92); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_ssize_t res = HPyLong_AsSsize_t(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 92, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_Long_AsVoidPtr(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 93); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = HPyLong_AsVoidPtr(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 93, r0, r1, &_ts_start, &_ts_end); - return res; -} - -double trace_ctx_Long_AsDouble(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 94); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - double res = HPyLong_AsDouble(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 94, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Float_FromDouble(HPyContext *tctx, double v) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 95); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyFloat_FromDouble(uctx, v); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 95, r0, r1, &_ts_start, &_ts_end); - return res; -} - -double trace_ctx_Float_AsDouble(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 96); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - double res = HPyFloat_AsDouble(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 96, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Bool_FromBool(HPyContext *tctx, bool v) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 97); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyBool_FromBool(uctx, v); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 97, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_ssize_t trace_ctx_Length(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 98); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_ssize_t res = HPy_Length(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 98, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Number_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 99); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyNumber_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 99, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Add(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 100); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Add(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 100, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Subtract(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 101); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Subtract(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 101, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Multiply(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 102); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Multiply(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 102, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_MatrixMultiply(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 103); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_MatrixMultiply(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 103, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_FloorDivide(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 104); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_FloorDivide(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 104, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_TrueDivide(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 105); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_TrueDivide(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 105, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Remainder(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 106); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Remainder(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 106, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Divmod(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 107); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Divmod(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 107, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Power(HPyContext *tctx, HPy h1, HPy h2, HPy h3) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 108); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Power(uctx, h1, h2, h3); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 108, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Negative(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 109); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Negative(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 109, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Positive(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 110); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Positive(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 110, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Absolute(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 111); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Absolute(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 111, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Invert(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 112); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Invert(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 112, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Lshift(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 113); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Lshift(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 113, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Rshift(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 114); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Rshift(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 114, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_And(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 115); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_And(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 115, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Xor(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 116); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Xor(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 116, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Or(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 117); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Or(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 117, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Index(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 118); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Index(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 118, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Long(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 119); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Long(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 119, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Float(HPyContext *tctx, HPy h1) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 120); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Float(uctx, h1); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 120, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceAdd(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 121); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceAdd(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 121, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceSubtract(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 122); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceSubtract(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 122, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceMultiply(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 123); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceMultiply(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 123, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceMatrixMultiply(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 124); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceMatrixMultiply(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 124, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceFloorDivide(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 125); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceFloorDivide(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 125, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceTrueDivide(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 126); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceTrueDivide(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 126, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceRemainder(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 127); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceRemainder(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 127, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlacePower(HPyContext *tctx, HPy h1, HPy h2, HPy h3) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 128); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlacePower(uctx, h1, h2, h3); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 128, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceLshift(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 129); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceLshift(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 129, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceRshift(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 130); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceRshift(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 130, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceAnd(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 131); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceAnd(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 131, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceXor(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 132); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceXor(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 132, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_InPlaceOr(HPyContext *tctx, HPy h1, HPy h2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 133); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_InPlaceOr(uctx, h1, h2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 133, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Callable_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 134); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyCallable_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 134, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_CallTupleDict(HPyContext *tctx, HPy callable, HPy args, HPy kw) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 135); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_CallTupleDict(uctx, callable, args, kw); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 135, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Call(HPyContext *tctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 261); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Call(uctx, callable, args, nargs, kwnames); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 261, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_CallMethod(HPyContext *tctx, HPy name, const HPy *args, size_t nargs, HPy kwnames) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 262); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_CallMethod(uctx, name, args, nargs, kwnames); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 262, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetIter(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 269); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetIter(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 269, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Iter_Next(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 270); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyIter_Next(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 270, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Iter_Check(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 271); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyIter_Check(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 271, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Err_SetString(HPyContext *tctx, HPy h_type, const char *utf8_message) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 137); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_SetString(uctx, h_type, utf8_message); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 137, r0, r1, &_ts_start, &_ts_end); -} - -void trace_ctx_Err_SetObject(HPyContext *tctx, HPy h_type, HPy h_value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 138); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_SetObject(uctx, h_type, h_value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 138, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Err_SetFromErrnoWithFilename(HPyContext *tctx, HPy h_type, const char *filename_fsencoded) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 139); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyErr_SetFromErrnoWithFilename(uctx, h_type, filename_fsencoded); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 139, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *tctx, HPy h_type, HPy filename1, HPy filename2) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 140); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_SetFromErrnoWithFilenameObjects(uctx, h_type, filename1, filename2); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 140, r0, r1, &_ts_start, &_ts_end); -} - -int trace_ctx_Err_Occurred(HPyContext *tctx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 141); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyErr_Occurred(uctx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 141, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Err_ExceptionMatches(HPyContext *tctx, HPy exc) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 142); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyErr_ExceptionMatches(uctx, exc); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 142, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Err_NoMemory(HPyContext *tctx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 143); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_NoMemory(uctx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 143, r0, r1, &_ts_start, &_ts_end); -} - -void trace_ctx_Err_Clear(HPyContext *tctx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 144); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_Clear(uctx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 144, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Err_NewException(HPyContext *tctx, const char *utf8_name, HPy base, HPy dict) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 145); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyErr_NewException(uctx, utf8_name, base, dict); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 145, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Err_NewExceptionWithDoc(HPyContext *tctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 146); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyErr_NewExceptionWithDoc(uctx, utf8_name, utf8_doc, base, dict); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 146, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Err_WarnEx(HPyContext *tctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 147); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyErr_WarnEx(uctx, category, utf8_message, stack_level); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 147, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Err_WriteUnraisable(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 148); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyErr_WriteUnraisable(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 148, r0, r1, &_ts_start, &_ts_end); -} - -int trace_ctx_IsTrue(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 149); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_IsTrue(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 149, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Type_FromSpec(HPyContext *tctx, HPyType_Spec *spec, HPyType_SpecParam *params) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 150); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyType_FromSpec(uctx, spec, params); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 150, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Type_GenericNew(HPyContext *tctx, HPy type, const HPy *args, HPy_ssize_t nargs, HPy kw) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 151); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyType_GenericNew(uctx, type, args, nargs, kw); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 151, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetAttr(HPyContext *tctx, HPy obj, HPy name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 152); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetAttr(uctx, obj, name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 152, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 153); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetAttr_s(uctx, obj, utf8_name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 153, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_HasAttr(HPyContext *tctx, HPy obj, HPy name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 154); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_HasAttr(uctx, obj, name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 154, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_HasAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 155); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_HasAttr_s(uctx, obj, utf8_name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 155, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetAttr(HPyContext *tctx, HPy obj, HPy name, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 156); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetAttr(uctx, obj, name, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 156, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetAttr_s(HPyContext *tctx, HPy obj, const char *utf8_name, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 157); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetAttr_s(uctx, obj, utf8_name, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 157, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetItem(HPyContext *tctx, HPy obj, HPy key) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 158); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetItem(uctx, obj, key); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 158, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 159); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetItem_i(uctx, obj, idx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 159, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 160); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetItem_s(uctx, obj, utf8_key); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 160, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_GetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 266); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_GetSlice(uctx, obj, start, end); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 266, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Contains(HPyContext *tctx, HPy container, HPy key) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 161); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_Contains(uctx, container, key); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 161, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetItem(HPyContext *tctx, HPy obj, HPy key, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 162); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetItem(uctx, obj, key, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 162, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 163); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetItem_i(uctx, obj, idx, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 163, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetItem_s(HPyContext *tctx, HPy obj, const char *utf8_key, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 164); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetItem_s(uctx, obj, utf8_key, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 164, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 267); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetSlice(uctx, obj, start, end, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 267, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_DelItem(HPyContext *tctx, HPy obj, HPy key) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 235); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_DelItem(uctx, obj, key); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 235, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_DelItem_i(HPyContext *tctx, HPy obj, HPy_ssize_t idx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 236); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_DelItem_i(uctx, obj, idx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 236, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_DelItem_s(HPyContext *tctx, HPy obj, const char *utf8_key) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 237); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_DelItem_s(uctx, obj, utf8_key); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 237, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_DelSlice(HPyContext *tctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 268); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_DelSlice(uctx, obj, start, end); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 268, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Type(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 165); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Type(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 165, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_TypeCheck(HPyContext *tctx, HPy obj, HPy type) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 166); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_TypeCheck(uctx, obj, type); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 166, r0, r1, &_ts_start, &_ts_end); - return res; -} - -const char *trace_ctx_Type_GetName(HPyContext *tctx, HPy type) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 253); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - const char * res = HPyType_GetName(uctx, type); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 253, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Type_IsSubtype(HPyContext *tctx, HPy sub, HPy type) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 254); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyType_IsSubtype(uctx, sub, type); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 254, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Is(HPyContext *tctx, HPy obj, HPy other) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 167); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_Is(uctx, obj, other); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 167, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Object(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 168); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Object(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 168, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Legacy(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 169); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Legacy(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 169, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Type(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 228); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Type(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 228, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Long(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 229); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Long(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 229, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Float(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 230); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Float(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 230, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Unicode(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 231); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Unicode(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 231, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Tuple(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 232); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Tuple(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 232, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_List(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 233); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_List(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 233, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_AsStruct_Dict(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 264); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = _HPy_AsStruct_Dict(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 264, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPyType_BuiltinShape trace_ctx_Type_GetBuiltinShape(HPyContext *tctx, HPy h_type) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 234); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyType_BuiltinShape res = _HPyType_GetBuiltinShape(uctx, h_type); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 234, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_New(HPyContext *tctx, HPy h_type, void **data) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 170); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = _HPy_New(uctx, h_type, data); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 170, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Repr(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 171); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Repr(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 171, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Str(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 172); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Str(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 172, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_ASCII(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 173); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_ASCII(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 173, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Bytes(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 174); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Bytes(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 174, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_RichCompare(HPyContext *tctx, HPy v, HPy w, int op) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 175); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_RichCompare(uctx, v, w, op); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 175, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_RichCompareBool(HPyContext *tctx, HPy v, HPy w, int op) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 176); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_RichCompareBool(uctx, v, w, op); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 176, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_hash_t trace_ctx_Hash(HPyContext *tctx, HPy obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 177); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_hash_t res = HPy_Hash(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 177, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Bytes_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 178); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyBytes_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 178, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_ssize_t trace_ctx_Bytes_Size(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 179); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_ssize_t res = HPyBytes_Size(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 179, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_ssize_t trace_ctx_Bytes_GET_SIZE(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 180); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_ssize_t res = HPyBytes_GET_SIZE(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 180, r0, r1, &_ts_start, &_ts_end); - return res; -} - -const char *trace_ctx_Bytes_AsString(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 181); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - const char * res = HPyBytes_AsString(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 181, r0, r1, &_ts_start, &_ts_end); - return res; -} - -const char *trace_ctx_Bytes_AS_STRING(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 182); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - const char * res = HPyBytes_AS_STRING(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 182, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Bytes_FromString(HPyContext *tctx, const char *bytes) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 183); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyBytes_FromString(uctx, bytes); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 183, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Bytes_FromStringAndSize(HPyContext *tctx, const char *bytes, HPy_ssize_t len) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 184); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyBytes_FromStringAndSize(uctx, bytes, len); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 184, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_FromString(HPyContext *tctx, const char *utf8) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 185); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_FromString(uctx, utf8); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 185, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Unicode_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 186); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyUnicode_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 186, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_AsASCIIString(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 187); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_AsASCIIString(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 187, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_AsLatin1String(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 188); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_AsLatin1String(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 188, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_AsUTF8String(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 189); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_AsUTF8String(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 189, r0, r1, &_ts_start, &_ts_end); - return res; -} - -const char *trace_ctx_Unicode_AsUTF8AndSize(HPyContext *tctx, HPy h, HPy_ssize_t *size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 190); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - const char * res = HPyUnicode_AsUTF8AndSize(uctx, h, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 190, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_FromWideChar(HPyContext *tctx, const wchar_t *w, HPy_ssize_t size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 191); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_FromWideChar(uctx, w, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 191, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_DecodeFSDefault(HPyContext *tctx, const char *v) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 192); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_DecodeFSDefault(uctx, v); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 192, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *tctx, const char *v, HPy_ssize_t size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 193); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_DecodeFSDefaultAndSize(uctx, v, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 193, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_EncodeFSDefault(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 194); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_EncodeFSDefault(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 194, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy_UCS4 trace_ctx_Unicode_ReadChar(HPyContext *tctx, HPy h, HPy_ssize_t index) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 195); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_UCS4 res = HPyUnicode_ReadChar(uctx, h, index); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 195, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_DecodeASCII(HPyContext *tctx, const char *ascii, HPy_ssize_t size, const char *errors) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 196); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_DecodeASCII(uctx, ascii, size, errors); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 196, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_DecodeLatin1(HPyContext *tctx, const char *latin1, HPy_ssize_t size, const char *errors) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 197); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_DecodeLatin1(uctx, latin1, size, errors); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 197, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_FromEncodedObject(HPyContext *tctx, HPy obj, const char *encoding, const char *errors) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 255); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_FromEncodedObject(uctx, obj, encoding, errors); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 255, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Unicode_Substring(HPyContext *tctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 256); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyUnicode_Substring(uctx, str, start, end); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 256, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_List_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 198); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyList_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 198, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_List_New(HPyContext *tctx, HPy_ssize_t len) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 199); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyList_New(uctx, len); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 199, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_List_Append(HPyContext *tctx, HPy h_list, HPy h_item) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 200); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyList_Append(uctx, h_list, h_item); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 200, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_List_Insert(HPyContext *tctx, HPy h_list, HPy_ssize_t index, HPy h_item) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 265); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyList_Insert(uctx, h_list, index, h_item); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 265, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Dict_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 201); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyDict_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 201, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Dict_New(HPyContext *tctx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 202); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyDict_New(uctx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 202, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Dict_Keys(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 257); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyDict_Keys(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 257, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Dict_Copy(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 258); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyDict_Copy(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 258, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Tuple_Check(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 203); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyTuple_Check(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 203, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Tuple_FromArray(HPyContext *tctx, const HPy items[], HPy_ssize_t n) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 204); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyTuple_FromArray(uctx, items, n); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 204, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Slice_New(HPyContext *tctx, HPy start, HPy stop, HPy step) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 272); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPySlice_New(uctx, start, stop, step); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 272, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Slice_Unpack(HPyContext *tctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 259); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPySlice_Unpack(uctx, slice, start, stop, step); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 259, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Import_ImportModule(HPyContext *tctx, const char *utf8_name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 205); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyImport_ImportModule(uctx, utf8_name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 205, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_Capsule_New(HPyContext *tctx, void *pointer, const char *utf8_name, HPyCapsule_Destructor *destructor) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 244); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyCapsule_New(uctx, pointer, utf8_name, destructor); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 244, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void *trace_ctx_Capsule_Get(HPyContext *tctx, HPy capsule, _HPyCapsule_key key, const char *utf8_name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 245); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - void * res = HPyCapsule_Get(uctx, capsule, key, utf8_name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 245, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Capsule_IsValid(HPyContext *tctx, HPy capsule, const char *utf8_name) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 246); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyCapsule_IsValid(uctx, capsule, utf8_name); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 246, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Capsule_Set(HPyContext *tctx, HPy capsule, _HPyCapsule_key key, void *value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 247); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyCapsule_Set(uctx, capsule, key, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 247, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_FromPyObject(HPyContext *tctx, cpy_PyObject *obj) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 206); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_FromPyObject(uctx, obj); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 206, r0, r1, &_ts_start, &_ts_end); - return res; -} - -cpy_PyObject *trace_ctx_AsPyObject(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 207); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - cpy_PyObject * res = HPy_AsPyObject(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 207, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPyListBuilder trace_ctx_ListBuilder_New(HPyContext *tctx, HPy_ssize_t size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 209); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyListBuilder res = HPyListBuilder_New(uctx, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 209, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_ListBuilder_Set(HPyContext *tctx, HPyListBuilder builder, HPy_ssize_t index, HPy h_item) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 210); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyListBuilder_Set(uctx, builder, index, h_item); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 210, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_ListBuilder_Build(HPyContext *tctx, HPyListBuilder builder) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 211); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyListBuilder_Build(uctx, builder); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 211, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_ListBuilder_Cancel(HPyContext *tctx, HPyListBuilder builder) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 212); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyListBuilder_Cancel(uctx, builder); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 212, r0, r1, &_ts_start, &_ts_end); -} - -HPyTupleBuilder trace_ctx_TupleBuilder_New(HPyContext *tctx, HPy_ssize_t size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 213); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTupleBuilder res = HPyTupleBuilder_New(uctx, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 213, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_TupleBuilder_Set(HPyContext *tctx, HPyTupleBuilder builder, HPy_ssize_t index, HPy h_item) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 214); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTupleBuilder_Set(uctx, builder, index, h_item); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 214, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_TupleBuilder_Build(HPyContext *tctx, HPyTupleBuilder builder) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 215); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyTupleBuilder_Build(uctx, builder); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 215, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_TupleBuilder_Cancel(HPyContext *tctx, HPyTupleBuilder builder) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 216); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTupleBuilder_Cancel(uctx, builder); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 216, r0, r1, &_ts_start, &_ts_end); -} - -HPyTracker trace_ctx_Tracker_New(HPyContext *tctx, HPy_ssize_t size) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 217); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTracker res = HPyTracker_New(uctx, size); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 217, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_Tracker_Add(HPyContext *tctx, HPyTracker ht, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 218); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPyTracker_Add(uctx, ht, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 218, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Tracker_ForgetAll(HPyContext *tctx, HPyTracker ht) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 219); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTracker_ForgetAll(uctx, ht); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 219, r0, r1, &_ts_start, &_ts_end); -} - -void trace_ctx_Tracker_Close(HPyContext *tctx, HPyTracker ht) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 220); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyTracker_Close(uctx, ht); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 220, r0, r1, &_ts_start, &_ts_end); -} - -void trace_ctx_Field_Store(HPyContext *tctx, HPy target_object, HPyField *target_field, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 221); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyField_Store(uctx, target_object, target_field, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 221, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Field_Load(HPyContext *tctx, HPy source_object, HPyField source_field) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 222); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyField_Load(uctx, source_object, source_field); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 222, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_ReenterPythonExecution(HPyContext *tctx, HPyThreadState state) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 223); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy_ReenterPythonExecution(uctx, state); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 223, r0, r1, &_ts_start, &_ts_end); -} - -HPyThreadState trace_ctx_LeavePythonExecution(HPyContext *tctx) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 224); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyThreadState res = HPy_LeavePythonExecution(uctx); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 224, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Global_Store(HPyContext *tctx, HPyGlobal *global, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 225); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPyGlobal_Store(uctx, global, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 225, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Global_Load(HPyContext *tctx, HPyGlobal global) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 226); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyGlobal_Load(uctx, global); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 226, r0, r1, &_ts_start, &_ts_end); - return res; -} - -void trace_ctx_Dump(HPyContext *tctx, HPy h) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 227); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - _HPy_Dump(uctx, h); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 227, r0, r1, &_ts_start, &_ts_end); -} - -HPy trace_ctx_Compile_s(HPyContext *tctx, const char *utf8_source, const char *utf8_filename, HPy_SourceKind kind) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 248); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_Compile_s(uctx, utf8_source, utf8_filename, kind); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 248, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_EvalCode(HPyContext *tctx, HPy code, HPy globals, HPy locals) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 249); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPy_EvalCode(uctx, code, globals, locals); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 249, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_ContextVar_New(HPyContext *tctx, const char *name, HPy default_value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 250); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyContextVar_New(uctx, name, default_value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 250, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int32_t trace_ctx_ContextVar_Get(HPyContext *tctx, HPy context_var, HPy default_value, HPy *result) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 251); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int32_t res = HPyContextVar_Get(uctx, context_var, default_value, result); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 251, r0, r1, &_ts_start, &_ts_end); - return res; -} - -HPy trace_ctx_ContextVar_Set(HPyContext *tctx, HPy context_var, HPy value) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 252); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - HPy res = HPyContextVar_Set(uctx, context_var, value); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 252, r0, r1, &_ts_start, &_ts_end); - return res; -} - -int trace_ctx_SetCallFunction(HPyContext *tctx, HPy h, HPyCallFunction *func) -{ - HPyTraceInfo *info = hpy_trace_on_enter(tctx, 260); - HPyContext *uctx = info->uctx; - _HPyTime_t _ts_start, _ts_end; - _HPyClockStatus_t r0, r1; - r0 = get_monotonic_clock(&_ts_start); - int res = HPy_SetCallFunction(uctx, h, func); - r1 = get_monotonic_clock(&_ts_end); - hpy_trace_on_exit(info, 260, r0, r1, &_ts_start, &_ts_end); - return res; -} - diff --git a/graalpython/hpy/hpy/trace/src/include/hpy_trace.h b/graalpython/hpy/hpy/trace/src/include/hpy_trace.h deleted file mode 100644 index e75b76186e..0000000000 --- a/graalpython/hpy/hpy/trace/src/include/hpy_trace.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HPY_TRACE_H -#define HPY_TRACE_H - -#include "hpy.h" - -/* - This is the main public API for the trace mode, and it's meant to be used - by hpy.universal implementations (including but not limited to the - CPython's version of hpy.universal which is included in this repo). - - The idea is that for every uctx there is a corresponding unique tctx which - wraps it. - - If you call hpy_trace_get_ctx twice on the same uctx, you get the same - result. -*/ - -HPyContext * hpy_trace_get_ctx(HPyContext *uctx); -int hpy_trace_ctx_init(HPyContext *tctx, HPyContext *uctx); -int hpy_trace_ctx_free(HPyContext *tctx); -int hpy_trace_get_nfunc(void); -const char * hpy_trace_get_func_name(int idx); - -// this is the HPy init function created by HPy_MODINIT. In CPython's version -// of hpy.universal the code is embedded inside the extension, so we can call -// this function directly instead of dlopen it. This is similar to what -// CPython does for its own built-in modules. But we must use the same -// signature as HPy_MODINIT - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -HPyModuleDef* HPyInit__trace(); - -#ifdef ___cplusplus -extern "C" -#endif -HPy_EXPORTED_SYMBOL -void HPyInitGlobalContext__trace(HPyContext *ctx); - -#endif /* HPY_TRACE_H */ diff --git a/graalpython/hpy/hpy/trace/src/trace_ctx.c b/graalpython/hpy/hpy/trace/src/trace_ctx.c deleted file mode 100644 index 1b18096fe5..0000000000 --- a/graalpython/hpy/hpy/trace/src/trace_ctx.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "trace_internal.h" -#include "autogen_trace_ctx_init.h" - -static struct _HPyContext_s g_trace_ctx = { - .name = "HPy Trace Mode ABI", - ._private = NULL, - .abi_version = HPY_ABI_VERSION, -}; - -// 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 -// debug wrapper for each of them. -int hpy_trace_ctx_init(HPyContext *tctx, HPyContext *uctx) -{ - if (tctx->_private != NULL) { - // already initialized - assert(get_info(tctx)->uctx == uctx); // sanity check - return 0; - } - // initialize trace_info - // XXX: currently we never free this malloc - HPyTraceInfo *info = malloc(sizeof(HPyTraceInfo)); - if (info == NULL) { - HPyErr_NoMemory(uctx); - return -1; - } -#ifdef _WIN32 - (void)QueryPerformanceFrequency(&info->counter_freq); -#else - clock_getres(CLOCK_MONOTONIC_RAW, &info->counter_freq); -#endif - trace_ctx_init_info(info, uctx); - tctx->_private = info; - trace_ctx_init_fields(tctx, uctx); - return 0; -} - -int hpy_trace_ctx_free(HPyContext *tctx) -{ - trace_ctx_free_info(get_info(tctx)); - return 0; -} - -HPyContext * hpy_trace_get_ctx(HPyContext *uctx) -{ - HPyContext *tctx = &g_trace_ctx; - if (uctx == tctx) { - HPy_FatalError(uctx, "hpy_trace_get_ctx: expected an universal ctx, " - "got a trace ctx"); - } - if (hpy_trace_ctx_init(tctx, uctx) < 0) - return NULL; - return tctx; -} - -void hpy_trace_set_ctx(HPyContext *tctx) -{ - g_trace_ctx = *tctx; -} - -static HPy create_trace_func_args(HPyContext *uctx, int id) -{ - HPy h_name = HPyUnicode_FromString(uctx, hpy_trace_get_func_name(id)); - if (HPy_IsNull(h_name)) - goto fail; - HPy h_args = HPyTuple_FromArray(uctx, &h_name, 1); - if (HPy_IsNull(h_args)) - goto fail; - HPy_Close(uctx, h_name); - return h_args; -fail: - HPy_FatalError(uctx, "could not create arguments for user trace function"); - return HPy_NULL; -} - -static inline void -update_duration(_HPyTime_t *res, _HPyTime_t *start, _HPyTime_t *end) -{ -#ifdef _WIN32 - res->QuadPart += end->QuadPart - start->QuadPart; - assert(res->QuadPart >= 0); -#else - /* Normalize: since the clock is guaranteed to be monotonic, we know that - 'end >= start'. It can still happen that 'end->tv_nsec < start->tv_nsec' - but in this case, we know that 'end->tv_sec > start->tv_sec'. */ - if (end->tv_nsec < start->tv_nsec) { - assert(end->tv_sec > start->tv_sec); - res->tv_sec += end->tv_sec - start->tv_sec - 1, - res->tv_nsec += end->tv_nsec - start->tv_nsec + FREQ_NSEC; - } else { - res->tv_sec += end->tv_sec - start->tv_sec, - res->tv_nsec += end->tv_nsec - start->tv_nsec; - } - assert(res->tv_sec >= 0); - assert(res->tv_nsec >= 0); -#endif -} - -HPyTraceInfo *hpy_trace_on_enter(HPyContext *tctx, int id) -{ - HPyTraceInfo *tctx_info = get_info(tctx); - HPyContext *uctx = tctx_info->uctx; - HPy args, res; - tctx_info->call_counts[id]++; - if(!HPy_IsNull(tctx_info->on_enter_func)) { - args = create_trace_func_args(uctx, id); - res = HPy_CallTupleDict( - uctx, tctx_info->on_enter_func, args, HPy_NULL); - HPy_Close(uctx, args); - if (HPy_IsNull(res)) { - HPy_FatalError(uctx, - "error when executing on-enter trace function"); - } - } - return tctx_info; -} - -#ifdef _WIN32 -#define CLOCK_FAILED(_R0, _R1) (!(_R0) || !(_R1)) -#else -#define CLOCK_FAILED(_R0, _R1) ((_R0) + (_R1)) -#endif - -void hpy_trace_on_exit(HPyTraceInfo *info, int id, _HPyClockStatus_t r0, - _HPyClockStatus_t r1, _HPyTime_t *_ts_start, _HPyTime_t *_ts_end) -{ - HPyContext *uctx = info->uctx; - HPy args, res; - if (CLOCK_FAILED(r0, r1)) - { - printf("Could not get monotonic clock in %s\n", hpy_trace_get_func_name(id)); - fflush(stdout); - HPy_FatalError(uctx, "could not get monotonic clock123"); - } - update_duration(&info->durations[id], _ts_start, _ts_end); - if(!HPy_IsNull(info->on_exit_func)) { - args = create_trace_func_args(uctx, id); - res = HPy_CallTupleDict(uctx, info->on_exit_func, args, HPy_NULL); - HPy_Close(uctx, args); - if (HPy_IsNull(res)) { - HPy_FatalError(uctx, - "error when executing on-exit trace function"); - } - } -} - diff --git a/graalpython/hpy/hpy/trace/src/trace_internal.h b/graalpython/hpy/hpy/trace/src/trace_internal.h deleted file mode 100644 index 5075bb968c..0000000000 --- a/graalpython/hpy/hpy/trace/src/trace_internal.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Internal header for all the files in hpy/debug/src. The public API is in - include/hpy_debug.h -*/ -#ifndef HPY_TRACE_INTERNAL_H -#define HPY_TRACE_INTERNAL_H - -#include -#ifdef _WIN32 -#include -#else -#include -#endif -#include "hpy.h" -#include "hpy_trace.h" - - -#define HPY_TRACE_MAGIC 0xF00BAA5 - -// frequency of nanosecond resolution -#define FREQ_NSEC 1000000000L - -/* === HPyTraceInfo === */ - -#ifdef _WIN32 -typedef LARGE_INTEGER _HPyTime_t; -typedef BOOL _HPyClockStatus_t; -#else -typedef struct timespec _HPyTime_t; -typedef int _HPyClockStatus_t; -#endif - -typedef struct { - long magic_number; // used just for sanity checks - HPyContext *uctx; - /* frequency of the used performance counter */ - _HPyTime_t counter_freq; -#ifdef _WIN32 - /* to_ns = FREQ_NS / counter_freq */ - int64_t to_ns; -#endif - /* call count of the corresponding HPy API function */ - uint64_t *call_counts; - /* durations spent in the corresponding HPy API function */ - _HPyTime_t *durations; - HPy on_enter_func; - HPy on_exit_func; -} HPyTraceInfo; - - -static inline HPyTraceInfo *get_info(HPyContext *tctx) -{ - HPyTraceInfo *info = (HPyTraceInfo*)tctx->_private; - assert(info->magic_number == HPY_TRACE_MAGIC); // sanity check - return info; -} - -/* Get the current value of the monotonic clock. This is a platform-dependent - operation. */ -static inline _HPyClockStatus_t get_monotonic_clock(_HPyTime_t *t) -{ -#ifdef _WIN32 - return (int)QueryPerformanceCounter(t); -#else - return clock_gettime(CLOCK_MONOTONIC_RAW, t); -#endif -} - -HPyTraceInfo *hpy_trace_on_enter(HPyContext *tctx, int id); -void hpy_trace_on_exit(HPyTraceInfo *info, int id, _HPyClockStatus_t r0, - _HPyClockStatus_t r1, _HPyTime_t *_ts_start, _HPyTime_t *_ts_end); - -#endif /* HPY_TRACE_INTERNAL_H */ diff --git a/graalpython/hpy/hpy/universal/src/api.h b/graalpython/hpy/hpy/universal/src/api.h deleted file mode 100644 index ea4b8108eb..0000000000 --- a/graalpython/hpy/hpy/universal/src/api.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef HPY_API_H -#define HPY_API_H - -#include "hpy.h" - -extern struct _HPyContext_s g_universal_ctx; - -/* declare alloca() */ -#if defined(_MSC_VER) -# include /* for alloca() */ -#else -# include -# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) -# include -# endif -#endif - -#endif /* HPY_API_H */ diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i b/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i deleted file mode 100644 index 7c6a759f11..0000000000 --- a/graalpython/hpy/hpy/universal/src/autogen_ctx_call.i +++ /dev/null @@ -1,180 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.hpyfunc.autogen_ctx_call_i - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - - case HPyFunc_NOARGS: { - HPyFunc_noargs f = (HPyFunc_noargs)func; - _HPyFunc_args_NOARGS *a = (_HPyFunc_args_NOARGS*)args; - a->result = _h2py(f(ctx, _py2h(a->self))); - return; - } - case HPyFunc_O: { - HPyFunc_o f = (HPyFunc_o)func; - _HPyFunc_args_O *a = (_HPyFunc_args_O*)args; - a->result = _h2py(f(ctx, _py2h(a->self), _py2h(a->arg))); - return; - } - case HPyFunc_UNARYFUNC: { - HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; - _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_BINARYFUNC: { - HPyFunc_binaryfunc f = (HPyFunc_binaryfunc)func; - _HPyFunc_args_BINARYFUNC *a = (_HPyFunc_args_BINARYFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1))); - return; - } - case HPyFunc_TERNARYFUNC: { - HPyFunc_ternaryfunc f = (HPyFunc_ternaryfunc)func; - _HPyFunc_args_TERNARYFUNC *a = (_HPyFunc_args_TERNARYFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_INQUIRY: { - HPyFunc_inquiry f = (HPyFunc_inquiry)func; - _HPyFunc_args_INQUIRY *a = (_HPyFunc_args_INQUIRY*)args; - a->result = (f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_LENFUNC: { - HPyFunc_lenfunc f = (HPyFunc_lenfunc)func; - _HPyFunc_args_LENFUNC *a = (_HPyFunc_args_LENFUNC*)args; - a->result = (f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_SSIZEARGFUNC: { - HPyFunc_ssizeargfunc f = (HPyFunc_ssizeargfunc)func; - _HPyFunc_args_SSIZEARGFUNC *a = (_HPyFunc_args_SSIZEARGFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); - return; - } - case HPyFunc_SSIZESSIZEARGFUNC: { - HPyFunc_ssizessizeargfunc f = (HPyFunc_ssizessizeargfunc)func; - _HPyFunc_args_SSIZESSIZEARGFUNC *a = (_HPyFunc_args_SSIZESSIZEARGFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1), (a->arg2))); - return; - } - case HPyFunc_SSIZEOBJARGPROC: { - HPyFunc_ssizeobjargproc f = (HPyFunc_ssizeobjargproc)func; - _HPyFunc_args_SSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZEOBJARGPROC*)args; - a->result = (f(ctx, _py2h(a->arg0), (a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_SSIZESSIZEOBJARGPROC: { - HPyFunc_ssizessizeobjargproc f = (HPyFunc_ssizessizeobjargproc)func; - _HPyFunc_args_SSIZESSIZEOBJARGPROC *a = (_HPyFunc_args_SSIZESSIZEOBJARGPROC*)args; - a->result = (f(ctx, _py2h(a->arg0), (a->arg1), (a->arg2), _py2h(a->arg3))); - return; - } - case HPyFunc_OBJOBJARGPROC: { - HPyFunc_objobjargproc f = (HPyFunc_objobjargproc)func; - _HPyFunc_args_OBJOBJARGPROC *a = (_HPyFunc_args_OBJOBJARGPROC*)args; - a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_FREEFUNC: { - HPyFunc_freefunc f = (HPyFunc_freefunc)func; - _HPyFunc_args_FREEFUNC *a = (_HPyFunc_args_FREEFUNC*)args; - f(ctx, (a->arg0)); - return; - } - case HPyFunc_GETATTRFUNC: { - HPyFunc_getattrfunc f = (HPyFunc_getattrfunc)func; - _HPyFunc_args_GETATTRFUNC *a = (_HPyFunc_args_GETATTRFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); - return; - } - case HPyFunc_GETATTROFUNC: { - HPyFunc_getattrofunc f = (HPyFunc_getattrofunc)func; - _HPyFunc_args_GETATTROFUNC *a = (_HPyFunc_args_GETATTROFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1))); - return; - } - case HPyFunc_SETATTRFUNC: { - HPyFunc_setattrfunc f = (HPyFunc_setattrfunc)func; - _HPyFunc_args_SETATTRFUNC *a = (_HPyFunc_args_SETATTRFUNC*)args; - a->result = (f(ctx, _py2h(a->arg0), (a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_SETATTROFUNC: { - HPyFunc_setattrofunc f = (HPyFunc_setattrofunc)func; - _HPyFunc_args_SETATTROFUNC *a = (_HPyFunc_args_SETATTROFUNC*)args; - a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_REPRFUNC: { - HPyFunc_reprfunc f = (HPyFunc_reprfunc)func; - _HPyFunc_args_REPRFUNC *a = (_HPyFunc_args_REPRFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_HASHFUNC: { - HPyFunc_hashfunc f = (HPyFunc_hashfunc)func; - _HPyFunc_args_HASHFUNC *a = (_HPyFunc_args_HASHFUNC*)args; - a->result = (f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_RICHCMPFUNC: { - HPyFunc_richcmpfunc f = (HPyFunc_richcmpfunc)func; - _HPyFunc_args_RICHCMPFUNC *a = (_HPyFunc_args_RICHCMPFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), (a->arg2))); - return; - } - case HPyFunc_GETITERFUNC: { - HPyFunc_getiterfunc f = (HPyFunc_getiterfunc)func; - _HPyFunc_args_GETITERFUNC *a = (_HPyFunc_args_GETITERFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_ITERNEXTFUNC: { - HPyFunc_iternextfunc f = (HPyFunc_iternextfunc)func; - _HPyFunc_args_ITERNEXTFUNC *a = (_HPyFunc_args_ITERNEXTFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0))); - return; - } - case HPyFunc_DESCRGETFUNC: { - HPyFunc_descrgetfunc f = (HPyFunc_descrgetfunc)func; - _HPyFunc_args_DESCRGETFUNC *a = (_HPyFunc_args_DESCRGETFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_DESCRSETFUNC: { - HPyFunc_descrsetfunc f = (HPyFunc_descrsetfunc)func; - _HPyFunc_args_DESCRSETFUNC *a = (_HPyFunc_args_DESCRSETFUNC*)args; - a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), _py2h(a->arg2))); - return; - } - case HPyFunc_GETTER: { - HPyFunc_getter f = (HPyFunc_getter)func; - _HPyFunc_args_GETTER *a = (_HPyFunc_args_GETTER*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0), (a->arg1))); - return; - } - case HPyFunc_SETTER: { - HPyFunc_setter f = (HPyFunc_setter)func; - _HPyFunc_args_SETTER *a = (_HPyFunc_args_SETTER*)args; - a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1), (a->arg2))); - return; - } - case HPyFunc_OBJOBJPROC: { - HPyFunc_objobjproc f = (HPyFunc_objobjproc)func; - _HPyFunc_args_OBJOBJPROC *a = (_HPyFunc_args_OBJOBJPROC*)args; - a->result = (f(ctx, _py2h(a->arg0), _py2h(a->arg1))); - return; - } - case HPyFunc_DESTRUCTOR: { - HPyFunc_destructor f = (HPyFunc_destructor)func; - _HPyFunc_args_DESTRUCTOR *a = (_HPyFunc_args_DESTRUCTOR*)args; - f(ctx, _py2h(a->arg0)); - return; - } diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h b/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h deleted file mode 100644 index 4bdeec338e..0000000000 --- a/graalpython/hpy/hpy/universal/src/autogen_ctx_def.h +++ /dev/null @@ -1,207 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.ctx.autogen_ctx_def_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -struct _HPyContext_s g_universal_ctx = { - .name = "HPy Universal ABI (CPython backend)", - ._private = NULL, - .abi_version = HPY_ABI_VERSION, - /* h_None & co. are initialized by init_universal_ctx() */ - .ctx_Dup = &ctx_Dup, - .ctx_Close = &ctx_Close, - .ctx_Long_FromInt32_t = &ctx_Long_FromInt32_t, - .ctx_Long_FromUInt32_t = &ctx_Long_FromUInt32_t, - .ctx_Long_FromInt64_t = &ctx_Long_FromInt64_t, - .ctx_Long_FromUInt64_t = &ctx_Long_FromUInt64_t, - .ctx_Long_FromSize_t = &ctx_Long_FromSize_t, - .ctx_Long_FromSsize_t = &ctx_Long_FromSsize_t, - .ctx_Long_AsInt32_t = &ctx_Long_AsInt32_t, - .ctx_Long_AsUInt32_t = &ctx_Long_AsUInt32_t, - .ctx_Long_AsUInt32_tMask = &ctx_Long_AsUInt32_tMask, - .ctx_Long_AsInt64_t = &ctx_Long_AsInt64_t, - .ctx_Long_AsUInt64_t = &ctx_Long_AsUInt64_t, - .ctx_Long_AsUInt64_tMask = &ctx_Long_AsUInt64_tMask, - .ctx_Long_AsSize_t = &ctx_Long_AsSize_t, - .ctx_Long_AsSsize_t = &ctx_Long_AsSsize_t, - .ctx_Long_AsVoidPtr = &ctx_Long_AsVoidPtr, - .ctx_Long_AsDouble = &ctx_Long_AsDouble, - .ctx_Float_FromDouble = &ctx_Float_FromDouble, - .ctx_Float_AsDouble = &ctx_Float_AsDouble, - .ctx_Bool_FromBool = &ctx_Bool_FromBool, - .ctx_Length = &ctx_Length, - .ctx_Number_Check = &ctx_Number_Check, - .ctx_Add = &ctx_Add, - .ctx_Subtract = &ctx_Subtract, - .ctx_Multiply = &ctx_Multiply, - .ctx_MatrixMultiply = &ctx_MatrixMultiply, - .ctx_FloorDivide = &ctx_FloorDivide, - .ctx_TrueDivide = &ctx_TrueDivide, - .ctx_Remainder = &ctx_Remainder, - .ctx_Divmod = &ctx_Divmod, - .ctx_Power = &ctx_Power, - .ctx_Negative = &ctx_Negative, - .ctx_Positive = &ctx_Positive, - .ctx_Absolute = &ctx_Absolute, - .ctx_Invert = &ctx_Invert, - .ctx_Lshift = &ctx_Lshift, - .ctx_Rshift = &ctx_Rshift, - .ctx_And = &ctx_And, - .ctx_Xor = &ctx_Xor, - .ctx_Or = &ctx_Or, - .ctx_Index = &ctx_Index, - .ctx_Long = &ctx_Long, - .ctx_Float = &ctx_Float, - .ctx_InPlaceAdd = &ctx_InPlaceAdd, - .ctx_InPlaceSubtract = &ctx_InPlaceSubtract, - .ctx_InPlaceMultiply = &ctx_InPlaceMultiply, - .ctx_InPlaceMatrixMultiply = &ctx_InPlaceMatrixMultiply, - .ctx_InPlaceFloorDivide = &ctx_InPlaceFloorDivide, - .ctx_InPlaceTrueDivide = &ctx_InPlaceTrueDivide, - .ctx_InPlaceRemainder = &ctx_InPlaceRemainder, - .ctx_InPlacePower = &ctx_InPlacePower, - .ctx_InPlaceLshift = &ctx_InPlaceLshift, - .ctx_InPlaceRshift = &ctx_InPlaceRshift, - .ctx_InPlaceAnd = &ctx_InPlaceAnd, - .ctx_InPlaceXor = &ctx_InPlaceXor, - .ctx_InPlaceOr = &ctx_InPlaceOr, - .ctx_Callable_Check = &ctx_Callable_Check, - .ctx_CallTupleDict = &ctx_CallTupleDict, - .ctx_Call = &ctx_Call, - .ctx_CallMethod = &ctx_CallMethod, - .ctx_GetIter = &ctx_GetIter, - .ctx_Iter_Next = &ctx_Iter_Next, - .ctx_Iter_Check = &ctx_Iter_Check, - .ctx_FatalError = &ctx_FatalError, - .ctx_Err_SetString = &ctx_Err_SetString, - .ctx_Err_SetObject = &ctx_Err_SetObject, - .ctx_Err_SetFromErrnoWithFilename = &ctx_Err_SetFromErrnoWithFilename, - .ctx_Err_SetFromErrnoWithFilenameObjects = &ctx_Err_SetFromErrnoWithFilenameObjects, - .ctx_Err_Occurred = &ctx_Err_Occurred, - .ctx_Err_ExceptionMatches = &ctx_Err_ExceptionMatches, - .ctx_Err_NoMemory = &ctx_Err_NoMemory, - .ctx_Err_Clear = &ctx_Err_Clear, - .ctx_Err_NewException = &ctx_Err_NewException, - .ctx_Err_NewExceptionWithDoc = &ctx_Err_NewExceptionWithDoc, - .ctx_Err_WarnEx = &ctx_Err_WarnEx, - .ctx_Err_WriteUnraisable = &ctx_Err_WriteUnraisable, - .ctx_IsTrue = &ctx_IsTrue, - .ctx_Type_FromSpec = &ctx_Type_FromSpec, - .ctx_Type_GenericNew = &ctx_Type_GenericNew, - .ctx_GetAttr = &ctx_GetAttr, - .ctx_GetAttr_s = &ctx_GetAttr_s, - .ctx_HasAttr = &ctx_HasAttr, - .ctx_HasAttr_s = &ctx_HasAttr_s, - .ctx_SetAttr = &ctx_SetAttr, - .ctx_SetAttr_s = &ctx_SetAttr_s, - .ctx_GetItem = &ctx_GetItem, - .ctx_GetItem_i = &ctx_GetItem_i, - .ctx_GetItem_s = &ctx_GetItem_s, - .ctx_GetSlice = &ctx_GetSlice, - .ctx_Contains = &ctx_Contains, - .ctx_SetItem = &ctx_SetItem, - .ctx_SetItem_i = &ctx_SetItem_i, - .ctx_SetItem_s = &ctx_SetItem_s, - .ctx_SetSlice = &ctx_SetSlice, - .ctx_DelItem = &ctx_DelItem, - .ctx_DelItem_i = &ctx_DelItem_i, - .ctx_DelItem_s = &ctx_DelItem_s, - .ctx_DelSlice = &ctx_DelSlice, - .ctx_Type = &ctx_Type, - .ctx_TypeCheck = &ctx_TypeCheck, - .ctx_Type_GetName = &ctx_Type_GetName, - .ctx_Type_IsSubtype = &ctx_Type_IsSubtype, - .ctx_Is = &ctx_Is, - .ctx_AsStruct_Object = &ctx_AsStruct_Object, - .ctx_AsStruct_Legacy = &ctx_AsStruct_Legacy, - .ctx_AsStruct_Type = &ctx_AsStruct_Type, - .ctx_AsStruct_Long = &ctx_AsStruct_Long, - .ctx_AsStruct_Float = &ctx_AsStruct_Float, - .ctx_AsStruct_Unicode = &ctx_AsStruct_Unicode, - .ctx_AsStruct_Tuple = &ctx_AsStruct_Tuple, - .ctx_AsStruct_List = &ctx_AsStruct_List, - .ctx_AsStruct_Dict = &ctx_AsStruct_Dict, - .ctx_Type_GetBuiltinShape = &ctx_Type_GetBuiltinShape, - .ctx_New = &ctx_New, - .ctx_Repr = &ctx_Repr, - .ctx_Str = &ctx_Str, - .ctx_ASCII = &ctx_ASCII, - .ctx_Bytes = &ctx_Bytes, - .ctx_RichCompare = &ctx_RichCompare, - .ctx_RichCompareBool = &ctx_RichCompareBool, - .ctx_Hash = &ctx_Hash, - .ctx_Bytes_Check = &ctx_Bytes_Check, - .ctx_Bytes_Size = &ctx_Bytes_Size, - .ctx_Bytes_GET_SIZE = &ctx_Bytes_GET_SIZE, - .ctx_Bytes_AsString = &ctx_Bytes_AsString, - .ctx_Bytes_AS_STRING = &ctx_Bytes_AS_STRING, - .ctx_Bytes_FromString = &ctx_Bytes_FromString, - .ctx_Bytes_FromStringAndSize = &ctx_Bytes_FromStringAndSize, - .ctx_Unicode_FromString = &ctx_Unicode_FromString, - .ctx_Unicode_Check = &ctx_Unicode_Check, - .ctx_Unicode_AsASCIIString = &ctx_Unicode_AsASCIIString, - .ctx_Unicode_AsLatin1String = &ctx_Unicode_AsLatin1String, - .ctx_Unicode_AsUTF8String = &ctx_Unicode_AsUTF8String, - .ctx_Unicode_AsUTF8AndSize = &ctx_Unicode_AsUTF8AndSize, - .ctx_Unicode_FromWideChar = &ctx_Unicode_FromWideChar, - .ctx_Unicode_DecodeFSDefault = &ctx_Unicode_DecodeFSDefault, - .ctx_Unicode_DecodeFSDefaultAndSize = &ctx_Unicode_DecodeFSDefaultAndSize, - .ctx_Unicode_EncodeFSDefault = &ctx_Unicode_EncodeFSDefault, - .ctx_Unicode_ReadChar = &ctx_Unicode_ReadChar, - .ctx_Unicode_DecodeASCII = &ctx_Unicode_DecodeASCII, - .ctx_Unicode_DecodeLatin1 = &ctx_Unicode_DecodeLatin1, - .ctx_Unicode_FromEncodedObject = &ctx_Unicode_FromEncodedObject, - .ctx_Unicode_Substring = &ctx_Unicode_Substring, - .ctx_List_Check = &ctx_List_Check, - .ctx_List_New = &ctx_List_New, - .ctx_List_Append = &ctx_List_Append, - .ctx_List_Insert = &ctx_List_Insert, - .ctx_Dict_Check = &ctx_Dict_Check, - .ctx_Dict_New = &ctx_Dict_New, - .ctx_Dict_Keys = &ctx_Dict_Keys, - .ctx_Dict_Copy = &ctx_Dict_Copy, - .ctx_Tuple_Check = &ctx_Tuple_Check, - .ctx_Tuple_FromArray = &ctx_Tuple_FromArray, - .ctx_Slice_New = &ctx_Slice_New, - .ctx_Slice_Unpack = &ctx_Slice_Unpack, - .ctx_Import_ImportModule = &ctx_Import_ImportModule, - .ctx_Capsule_New = &ctx_Capsule_New, - .ctx_Capsule_Get = &ctx_Capsule_Get, - .ctx_Capsule_IsValid = &ctx_Capsule_IsValid, - .ctx_Capsule_Set = &ctx_Capsule_Set, - .ctx_FromPyObject = &ctx_FromPyObject, - .ctx_AsPyObject = &ctx_AsPyObject, - .ctx_CallRealFunctionFromTrampoline = &ctx_CallRealFunctionFromTrampoline, - .ctx_ListBuilder_New = &ctx_ListBuilder_New, - .ctx_ListBuilder_Set = &ctx_ListBuilder_Set, - .ctx_ListBuilder_Build = &ctx_ListBuilder_Build, - .ctx_ListBuilder_Cancel = &ctx_ListBuilder_Cancel, - .ctx_TupleBuilder_New = &ctx_TupleBuilder_New, - .ctx_TupleBuilder_Set = &ctx_TupleBuilder_Set, - .ctx_TupleBuilder_Build = &ctx_TupleBuilder_Build, - .ctx_TupleBuilder_Cancel = &ctx_TupleBuilder_Cancel, - .ctx_Tracker_New = &ctx_Tracker_New, - .ctx_Tracker_Add = &ctx_Tracker_Add, - .ctx_Tracker_ForgetAll = &ctx_Tracker_ForgetAll, - .ctx_Tracker_Close = &ctx_Tracker_Close, - .ctx_Field_Store = &ctx_Field_Store, - .ctx_Field_Load = &ctx_Field_Load, - .ctx_ReenterPythonExecution = &ctx_ReenterPythonExecution, - .ctx_LeavePythonExecution = &ctx_LeavePythonExecution, - .ctx_Global_Store = &ctx_Global_Store, - .ctx_Global_Load = &ctx_Global_Load, - .ctx_Dump = &ctx_Dump, - .ctx_Compile_s = &ctx_Compile_s, - .ctx_EvalCode = &ctx_EvalCode, - .ctx_ContextVar_New = &ctx_ContextVar_New, - .ctx_ContextVar_Get = &ctx_ContextVar_Get, - .ctx_ContextVar_Set = &ctx_ContextVar_Set, - .ctx_SetCallFunction = &ctx_SetCallFunction, -}; diff --git a/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h b/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h deleted file mode 100644 index 15c6e35b39..0000000000 --- a/graalpython/hpy/hpy/universal/src/autogen_ctx_impl.h +++ /dev/null @@ -1,612 +0,0 @@ - -/* - DO NOT EDIT THIS FILE! - - This file is automatically generated by hpy.tools.autogen.trampolines.universal_autogen_ctx_impl_h - See also hpy.tools.autogen and hpy/tools/public_api.h - - Run this to regenerate: - make autogen - -*/ - -HPyAPI_IMPL HPy ctx_Long_FromSize_t(HPyContext *ctx, size_t value) -{ - return _py2h(PyLong_FromSize_t(value)); -} - -HPyAPI_IMPL HPy ctx_Long_FromSsize_t(HPyContext *ctx, HPy_ssize_t value) -{ - return _py2h(PyLong_FromSsize_t(value)); -} - -HPyAPI_IMPL size_t ctx_Long_AsSize_t(HPyContext *ctx, HPy h) -{ - return PyLong_AsSize_t(_h2py(h)); -} - -HPyAPI_IMPL HPy_ssize_t ctx_Long_AsSsize_t(HPyContext *ctx, HPy h) -{ - return PyLong_AsSsize_t(_h2py(h)); -} - -HPyAPI_IMPL void *ctx_Long_AsVoidPtr(HPyContext *ctx, HPy h) -{ - return PyLong_AsVoidPtr(_h2py(h)); -} - -HPyAPI_IMPL double ctx_Long_AsDouble(HPyContext *ctx, HPy h) -{ - return PyLong_AsDouble(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Float_FromDouble(HPyContext *ctx, double v) -{ - return _py2h(PyFloat_FromDouble(v)); -} - -HPyAPI_IMPL double ctx_Float_AsDouble(HPyContext *ctx, HPy h) -{ - return PyFloat_AsDouble(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Bool_FromBool(HPyContext *ctx, bool v) -{ - return _py2h(PyBool_FromLong(v)); -} - -HPyAPI_IMPL HPy_ssize_t ctx_Length(HPyContext *ctx, HPy h) -{ - return PyObject_Length(_h2py(h)); -} - -HPyAPI_IMPL int ctx_Number_Check(HPyContext *ctx, HPy h) -{ - return PyNumber_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Add(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Subtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Subtract(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Multiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Multiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_MatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_MatrixMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_FloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_FloorDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_TrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_TrueDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Remainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Remainder(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Divmod(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Divmod(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return _py2h(PyNumber_Power(_h2py(h1), _h2py(h2), _h2py(h3))); -} - -HPyAPI_IMPL HPy ctx_Negative(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Negative(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Positive(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Positive(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Absolute(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Absolute(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Invert(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Invert(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Lshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Lshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Rshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Rshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_And(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_And(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Xor(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Xor(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Or(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_Or(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_Index(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Index(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Long(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Long(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_Float(HPyContext *ctx, HPy h1) -{ - return _py2h(PyNumber_Float(_h2py(h1))); -} - -HPyAPI_IMPL HPy ctx_InPlaceAdd(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceAdd(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceSubtract(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceSubtract(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceMatrixMultiply(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceMatrixMultiply(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceFloorDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceFloorDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceTrueDivide(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceTrueDivide(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceRemainder(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceRemainder(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3) -{ - return _py2h(PyNumber_InPlacePower(_h2py(h1), _h2py(h2), _h2py(h3))); -} - -HPyAPI_IMPL HPy ctx_InPlaceLshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceLshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceRshift(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceRshift(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceAnd(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceAnd(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceXor(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceXor(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL HPy ctx_InPlaceOr(HPyContext *ctx, HPy h1, HPy h2) -{ - return _py2h(PyNumber_InPlaceOr(_h2py(h1), _h2py(h2))); -} - -HPyAPI_IMPL int ctx_Callable_Check(HPyContext *ctx, HPy h) -{ - return PyCallable_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_GetIter(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_GetIter(_h2py(obj))); -} - -HPyAPI_IMPL HPy ctx_Iter_Next(HPyContext *ctx, HPy obj) -{ - return _py2h(PyIter_Next(_h2py(obj))); -} - -HPyAPI_IMPL int ctx_Iter_Check(HPyContext *ctx, HPy obj) -{ - return PyIter_Check(_h2py(obj)); -} - -HPyAPI_IMPL void ctx_Err_SetString(HPyContext *ctx, HPy h_type, const char *utf8_message) -{ - PyErr_SetString(_h2py(h_type), utf8_message); -} - -HPyAPI_IMPL void ctx_Err_SetObject(HPyContext *ctx, HPy h_type, HPy h_value) -{ - PyErr_SetObject(_h2py(h_type), _h2py(h_value)); -} - -HPyAPI_IMPL HPy ctx_Err_SetFromErrnoWithFilename(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) -{ - return _py2h(PyErr_SetFromErrnoWithFilename(_h2py(h_type), filename_fsencoded)); -} - -HPyAPI_IMPL void ctx_Err_SetFromErrnoWithFilenameObjects(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) -{ - PyErr_SetFromErrnoWithFilenameObjects(_h2py(h_type), _h2py(filename1), _h2py(filename2)); -} - -HPyAPI_IMPL int ctx_Err_ExceptionMatches(HPyContext *ctx, HPy exc) -{ - return PyErr_ExceptionMatches(_h2py(exc)); -} - -HPyAPI_IMPL void ctx_Err_NoMemory(HPyContext *ctx) -{ - PyErr_NoMemory(); -} - -HPyAPI_IMPL void ctx_Err_Clear(HPyContext *ctx) -{ - PyErr_Clear(); -} - -HPyAPI_IMPL HPy ctx_Err_NewException(HPyContext *ctx, const char *utf8_name, HPy base, HPy dict) -{ - return _py2h(PyErr_NewException(utf8_name, _h2py(base), _h2py(dict))); -} - -HPyAPI_IMPL HPy ctx_Err_NewExceptionWithDoc(HPyContext *ctx, const char *utf8_name, const char *utf8_doc, HPy base, HPy dict) -{ - return _py2h(PyErr_NewExceptionWithDoc(utf8_name, utf8_doc, _h2py(base), _h2py(dict))); -} - -HPyAPI_IMPL int ctx_Err_WarnEx(HPyContext *ctx, HPy category, const char *utf8_message, HPy_ssize_t stack_level) -{ - return PyErr_WarnEx(_h2py(category), utf8_message, stack_level); -} - -HPyAPI_IMPL void ctx_Err_WriteUnraisable(HPyContext *ctx, HPy obj) -{ - PyErr_WriteUnraisable(_h2py(obj)); -} - -HPyAPI_IMPL int ctx_IsTrue(HPyContext *ctx, HPy h) -{ - return PyObject_IsTrue(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_GetAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return _py2h(PyObject_GetAttr(_h2py(obj), _h2py(name))); -} - -HPyAPI_IMPL HPy ctx_GetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return _py2h(PyObject_GetAttrString(_h2py(obj), utf8_name)); -} - -HPyAPI_IMPL int ctx_HasAttr(HPyContext *ctx, HPy obj, HPy name) -{ - return PyObject_HasAttr(_h2py(obj), _h2py(name)); -} - -HPyAPI_IMPL int ctx_HasAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) -{ - return PyObject_HasAttrString(_h2py(obj), utf8_name); -} - -HPyAPI_IMPL int ctx_SetAttr(HPyContext *ctx, HPy obj, HPy name, HPy value) -{ - return PyObject_SetAttr(_h2py(obj), _h2py(name), _h2py(value)); -} - -HPyAPI_IMPL int ctx_SetAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name, HPy value) -{ - return PyObject_SetAttrString(_h2py(obj), utf8_name, _h2py(value)); -} - -HPyAPI_IMPL HPy ctx_GetItem(HPyContext *ctx, HPy obj, HPy key) -{ - return _py2h(PyObject_GetItem(_h2py(obj), _h2py(key))); -} - -HPyAPI_IMPL HPy ctx_GetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - return _py2h(PySequence_GetSlice(_h2py(obj), start, end)); -} - -HPyAPI_IMPL int ctx_Contains(HPyContext *ctx, HPy container, HPy key) -{ - return PySequence_Contains(_h2py(container), _h2py(key)); -} - -HPyAPI_IMPL int ctx_SetItem(HPyContext *ctx, HPy obj, HPy key, HPy value) -{ - return PyObject_SetItem(_h2py(obj), _h2py(key), _h2py(value)); -} - -HPyAPI_IMPL int ctx_SetSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end, HPy value) -{ - return PySequence_SetSlice(_h2py(obj), start, end, _h2py(value)); -} - -HPyAPI_IMPL int ctx_DelItem(HPyContext *ctx, HPy obj, HPy key) -{ - return PyObject_DelItem(_h2py(obj), _h2py(key)); -} - -HPyAPI_IMPL int ctx_DelSlice(HPyContext *ctx, HPy obj, HPy_ssize_t start, HPy_ssize_t end) -{ - return PySequence_DelSlice(_h2py(obj), start, end); -} - -HPyAPI_IMPL HPy ctx_Repr(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Repr(_h2py(obj))); -} - -HPyAPI_IMPL HPy ctx_Str(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Str(_h2py(obj))); -} - -HPyAPI_IMPL HPy ctx_ASCII(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_ASCII(_h2py(obj))); -} - -HPyAPI_IMPL HPy ctx_Bytes(HPyContext *ctx, HPy obj) -{ - return _py2h(PyObject_Bytes(_h2py(obj))); -} - -HPyAPI_IMPL HPy ctx_RichCompare(HPyContext *ctx, HPy v, HPy w, int op) -{ - return _py2h(PyObject_RichCompare(_h2py(v), _h2py(w), op)); -} - -HPyAPI_IMPL int ctx_RichCompareBool(HPyContext *ctx, HPy v, HPy w, int op) -{ - return PyObject_RichCompareBool(_h2py(v), _h2py(w), op); -} - -HPyAPI_IMPL HPy_hash_t ctx_Hash(HPyContext *ctx, HPy obj) -{ - return PyObject_Hash(_h2py(obj)); -} - -HPyAPI_IMPL int ctx_Bytes_Check(HPyContext *ctx, HPy h) -{ - return PyBytes_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy_ssize_t ctx_Bytes_Size(HPyContext *ctx, HPy h) -{ - return PyBytes_Size(_h2py(h)); -} - -HPyAPI_IMPL HPy_ssize_t ctx_Bytes_GET_SIZE(HPyContext *ctx, HPy h) -{ - return PyBytes_GET_SIZE(_h2py(h)); -} - -HPyAPI_IMPL const char *ctx_Bytes_AsString(HPyContext *ctx, HPy h) -{ - return PyBytes_AsString(_h2py(h)); -} - -HPyAPI_IMPL const char *ctx_Bytes_AS_STRING(HPyContext *ctx, HPy h) -{ - return PyBytes_AS_STRING(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Bytes_FromString(HPyContext *ctx, const char *bytes) -{ - return _py2h(PyBytes_FromString(bytes)); -} - -HPyAPI_IMPL HPy ctx_Unicode_FromString(HPyContext *ctx, const char *utf8) -{ - return _py2h(PyUnicode_FromString(utf8)); -} - -HPyAPI_IMPL int ctx_Unicode_Check(HPyContext *ctx, HPy h) -{ - return PyUnicode_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Unicode_AsASCIIString(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsASCIIString(_h2py(h))); -} - -HPyAPI_IMPL HPy ctx_Unicode_AsLatin1String(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsLatin1String(_h2py(h))); -} - -HPyAPI_IMPL HPy ctx_Unicode_AsUTF8String(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_AsUTF8String(_h2py(h))); -} - -HPyAPI_IMPL const char *ctx_Unicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) -{ - return PyUnicode_AsUTF8AndSize(_h2py(h), size); -} - -HPyAPI_IMPL HPy ctx_Unicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) -{ - return _py2h(PyUnicode_FromWideChar(w, size)); -} - -HPyAPI_IMPL HPy ctx_Unicode_DecodeFSDefault(HPyContext *ctx, const char *v) -{ - return _py2h(PyUnicode_DecodeFSDefault(v)); -} - -HPyAPI_IMPL HPy ctx_Unicode_DecodeFSDefaultAndSize(HPyContext *ctx, const char *v, HPy_ssize_t size) -{ - return _py2h(PyUnicode_DecodeFSDefaultAndSize(v, size)); -} - -HPyAPI_IMPL HPy ctx_Unicode_EncodeFSDefault(HPyContext *ctx, HPy h) -{ - return _py2h(PyUnicode_EncodeFSDefault(_h2py(h))); -} - -HPyAPI_IMPL HPy_UCS4 ctx_Unicode_ReadChar(HPyContext *ctx, HPy h, HPy_ssize_t index) -{ - return PyUnicode_ReadChar(_h2py(h), index); -} - -HPyAPI_IMPL HPy ctx_Unicode_DecodeASCII(HPyContext *ctx, const char *ascii, HPy_ssize_t size, const char *errors) -{ - return _py2h(PyUnicode_DecodeASCII(ascii, size, errors)); -} - -HPyAPI_IMPL HPy ctx_Unicode_DecodeLatin1(HPyContext *ctx, const char *latin1, HPy_ssize_t size, const char *errors) -{ - return _py2h(PyUnicode_DecodeLatin1(latin1, size, errors)); -} - -HPyAPI_IMPL HPy ctx_Unicode_FromEncodedObject(HPyContext *ctx, HPy obj, const char *encoding, const char *errors) -{ - return _py2h(PyUnicode_FromEncodedObject(_h2py(obj), encoding, errors)); -} - -HPyAPI_IMPL HPy ctx_Unicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end) -{ - return _py2h(PyUnicode_Substring(_h2py(str), start, end)); -} - -HPyAPI_IMPL int ctx_List_Check(HPyContext *ctx, HPy h) -{ - return PyList_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_List_New(HPyContext *ctx, HPy_ssize_t len) -{ - return _py2h(PyList_New(len)); -} - -HPyAPI_IMPL int ctx_List_Append(HPyContext *ctx, HPy h_list, HPy h_item) -{ - return PyList_Append(_h2py(h_list), _h2py(h_item)); -} - -HPyAPI_IMPL int ctx_List_Insert(HPyContext *ctx, HPy h_list, HPy_ssize_t index, HPy h_item) -{ - return PyList_Insert(_h2py(h_list), index, _h2py(h_item)); -} - -HPyAPI_IMPL int ctx_Dict_Check(HPyContext *ctx, HPy h) -{ - return PyDict_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Dict_New(HPyContext *ctx) -{ - return _py2h(PyDict_New()); -} - -HPyAPI_IMPL HPy ctx_Dict_Keys(HPyContext *ctx, HPy h) -{ - return _py2h(PyDict_Keys(_h2py(h))); -} - -HPyAPI_IMPL HPy ctx_Dict_Copy(HPyContext *ctx, HPy h) -{ - return _py2h(PyDict_Copy(_h2py(h))); -} - -HPyAPI_IMPL int ctx_Tuple_Check(HPyContext *ctx, HPy h) -{ - return PyTuple_Check(_h2py(h)); -} - -HPyAPI_IMPL HPy ctx_Slice_New(HPyContext *ctx, HPy start, HPy stop, HPy step) -{ - return _py2h(PySlice_New(_h2py(start), _h2py(stop), _h2py(step))); -} - -HPyAPI_IMPL int ctx_Slice_Unpack(HPyContext *ctx, HPy slice, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t *step) -{ - return PySlice_Unpack(_h2py(slice), start, stop, step); -} - -HPyAPI_IMPL HPy ctx_Import_ImportModule(HPyContext *ctx, const char *utf8_name) -{ - return _py2h(PyImport_ImportModule(utf8_name)); -} - -HPyAPI_IMPL int ctx_Capsule_IsValid(HPyContext *ctx, HPy capsule, const char *utf8_name) -{ - return PyCapsule_IsValid(_h2py(capsule), utf8_name); -} - -HPyAPI_IMPL void ctx_ReenterPythonExecution(HPyContext *ctx, HPyThreadState state) -{ - PyEval_RestoreThread(_h2threads(state)); -} - -HPyAPI_IMPL HPyThreadState ctx_LeavePythonExecution(HPyContext *ctx) -{ - return _threads2h(PyEval_SaveThread()); -} - -HPyAPI_IMPL HPy ctx_EvalCode(HPyContext *ctx, HPy code, HPy globals, HPy locals) -{ - return _py2h(PyEval_EvalCode(_h2py(code), _h2py(globals), _h2py(locals))); -} - -HPyAPI_IMPL HPy ctx_ContextVar_New(HPyContext *ctx, const char *name, HPy default_value) -{ - return _py2h(PyContextVar_New(name, _h2py(default_value))); -} - -HPyAPI_IMPL HPy ctx_ContextVar_Set(HPyContext *ctx, HPy context_var, HPy value) -{ - return _py2h(PyContextVar_Set(_h2py(context_var), _h2py(value))); -} - diff --git a/graalpython/hpy/hpy/universal/src/ctx.c b/graalpython/hpy/hpy/universal/src/ctx.c deleted file mode 100644 index 4e9860233b..0000000000 --- a/graalpython/hpy/hpy/universal/src/ctx.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "hpy.h" -#include "handles.h" - -#include "hpy/runtime/ctx_funcs.h" -#include "hpy/runtime/ctx_type.h" -#include "ctx_meth.h" -#include "ctx_misc.h" - -#include "autogen_ctx_impl.h" -#include "autogen_ctx_def.h" diff --git a/graalpython/hpy/hpy/universal/src/ctx_meth.c b/graalpython/hpy/hpy/universal/src/ctx_meth.c deleted file mode 100644 index 923f81e23f..0000000000 --- a/graalpython/hpy/hpy/universal/src/ctx_meth.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include "ctx_meth.h" -#include "hpy/runtime/ctx_type.h" -#include "hpy/runtime/ctx_module.h" -#include "handles.h" - -static void _buffer_h2py(HPyContext *ctx, const HPy_buffer *src, Py_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = HPy_AsPyObject(ctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - dest->internal = src->internal; -} - -static void _buffer_py2h(HPyContext *ctx, const Py_buffer *src, HPy_buffer *dest) -{ - dest->buf = src->buf; - dest->obj = HPy_FromPyObject(ctx, src->obj); - dest->len = src->len; - dest->itemsize = src->itemsize; - dest->readonly = src->readonly; - dest->ndim = src->ndim; - dest->format = src->format; - dest->shape = src->shape; - dest->strides = src->strides; - dest->suboffsets = src->suboffsets; - dest->internal = src->internal; -} - -HPyAPI_IMPL void -ctx_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, - HPyCFunction func, void *args) -{ - switch (sig) { - case HPyFunc_VARARGS: { - HPyFunc_varargs f = (HPyFunc_varargs)func; - _HPyFunc_args_VARARGS *a = (_HPyFunc_args_VARARGS*)args; - HPy *h_args = (HPy *)alloca(a->nargs * sizeof(HPy)); - for (HPy_ssize_t i = 0; i < a->nargs; i++) { - h_args[i] = _py2h(a->args[i]); - } - a->result = _h2py(f(ctx, _py2h(a->self), h_args, a->nargs)); - return; - } - case HPyFunc_KEYWORDS: { - HPyFunc_keywords f = (HPyFunc_keywords)func; - _HPyFunc_args_KEYWORDS *a = (_HPyFunc_args_KEYWORDS*)args; - size_t n_kwnames = a->kwnames != NULL ? PyTuple_GET_SIZE(a->kwnames) : 0; - size_t nargs = PyVectorcall_NARGS(a->nargsf); - size_t nargs_with_kw = nargs + n_kwnames; - HPy *h_args = (HPy *)alloca(nargs_with_kw * sizeof(HPy)); - for (size_t i = 0; i < nargs_with_kw; i++) { - h_args[i] = _py2h(a->args[i]); - } - a->result = _h2py(f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kwnames))); - return; - } - case HPyFunc_INITPROC: { - HPyFunc_initproc f = (HPyFunc_initproc)func; - _HPyFunc_args_INITPROC *a = (_HPyFunc_args_INITPROC*)args; - Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); - HPy *h_args = (HPy *)alloca(nargs * sizeof(HPy)); - for (Py_ssize_t i = 0; i < nargs; i++) { - h_args[i] = _py2h(PyTuple_GET_ITEM(a->args, i)); - } - a->result = f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kw)); - return; - } - case HPyFunc_NEWFUNC: { - HPyFunc_newfunc f = (HPyFunc_newfunc)func; - _HPyFunc_args_NEWFUNC *a = (_HPyFunc_args_NEWFUNC*)args; - Py_ssize_t nargs = PyTuple_GET_SIZE(a->args); - HPy *h_args = (HPy *)alloca(nargs * sizeof(HPy)); - for (Py_ssize_t i = 0; i < nargs; i++) { - h_args[i] = _py2h(PyTuple_GET_ITEM(a->args, i)); - } - a->result = _h2py(f(ctx, _py2h(a->self), h_args, nargs, _py2h(a->kw))); - return; - } - case HPyFunc_GETBUFFERPROC: { - HPyFunc_getbufferproc f = (HPyFunc_getbufferproc)func; - _HPyFunc_args_GETBUFFERPROC *a = (_HPyFunc_args_GETBUFFERPROC*)args; - HPy_buffer hbuf; - a->result = f(ctx, _py2h(a->self), &hbuf, a->flags); - if (a->result < 0) { - a->view->obj = NULL; - return; - } - _buffer_h2py(ctx, &hbuf, a->view); - HPy_Close(ctx, hbuf.obj); - return; - } - case HPyFunc_RELEASEBUFFERPROC: { - HPyFunc_releasebufferproc f = (HPyFunc_releasebufferproc)func; - _HPyFunc_args_RELEASEBUFFERPROC *a = (_HPyFunc_args_RELEASEBUFFERPROC*)args; - HPy_buffer hbuf; - _buffer_py2h(ctx, a->view, &hbuf); - f(ctx, _py2h(a->self), &hbuf); - // XXX: copy back from hbuf? - HPy_Close(ctx, hbuf.obj); - return; - } - case HPyFunc_TRAVERSEPROC: { - HPyFunc_traverseproc f = (HPyFunc_traverseproc)func; - _HPyFunc_args_TRAVERSEPROC *a = (_HPyFunc_args_TRAVERSEPROC*)args; - a->result = call_traverseproc_from_trampoline(f, a->self, - a->visit, a->arg); - return; - } - case HPyFunc_CAPSULE_DESTRUCTOR: { - HPyFunc_Capsule_Destructor f = (HPyFunc_Capsule_Destructor)func; - PyObject *capsule = (PyObject *)args; - const char *name = PyCapsule_GetName(capsule); - f(name, PyCapsule_GetPointer(capsule, name), - PyCapsule_GetContext(capsule)); - return; - } - case HPyFunc_MOD_CREATE: { - HPyFunc_unaryfunc f = (HPyFunc_unaryfunc)func; - _HPyFunc_args_UNARYFUNC *a = (_HPyFunc_args_UNARYFUNC*)args; - a->result = _h2py(f(ctx, _py2h(a->arg0))); - _HPyModule_CheckCreateSlotResult(&a->result); - return; - } -#include "autogen_ctx_call.i" - default: - Py_FatalError("Unsupported HPyFunc_Signature in ctx_meth.c"); - } -} diff --git a/graalpython/hpy/hpy/universal/src/ctx_meth.h b/graalpython/hpy/hpy/universal/src/ctx_meth.h deleted file mode 100644 index 16e8a4b47c..0000000000 --- a/graalpython/hpy/hpy/universal/src/ctx_meth.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "hpy.h" -#include "api.h" - -HPyAPI_IMPL void -ctx_CallRealFunctionFromTrampoline(HPyContext *ctx, HPyFunc_Signature sig, - HPyCFunction func, void *args); diff --git a/graalpython/hpy/hpy/universal/src/ctx_misc.c b/graalpython/hpy/hpy/universal/src/ctx_misc.c deleted file mode 100644 index 753354d43c..0000000000 --- a/graalpython/hpy/hpy/universal/src/ctx_misc.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include "hpy.h" -#include "handles.h" -#include "ctx_misc.h" - -HPyAPI_IMPL HPy -ctx_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) -{ - Py_XINCREF(obj); - return _py2h(obj); -} - -HPyAPI_IMPL cpy_PyObject * -ctx_AsPyObject(HPyContext *ctx, HPy h) -{ - PyObject *obj = _h2py(h); - Py_XINCREF(obj); - return obj; -} - -HPyAPI_IMPL void -ctx_Close(HPyContext *ctx, HPy h) -{ - PyObject *obj = _h2py(h); - Py_XDECREF(obj); -} - -HPyAPI_IMPL HPy -ctx_Dup(HPyContext *ctx, HPy h) -{ - PyObject *obj = _h2py(h); - Py_XINCREF(obj); - return _py2h(obj); -} - -HPyAPI_IMPL void -ctx_Field_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h) -{ - PyObject *obj = _h2py(h); - PyObject *target_py_obj = _hf2py(*target_field); - Py_XINCREF(obj); - *target_field = _py2hf(obj); - Py_XDECREF(target_py_obj); -} - -HPyAPI_IMPL HPy -ctx_Field_Load(HPyContext *ctx, HPy source_object, HPyField source_field) -{ - PyObject *obj = _hf2py(source_field); - Py_INCREF(obj); - return _py2h(obj); -} - - -HPyAPI_IMPL void -ctx_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h) -{ - PyObject *obj = _h2py(h); - Py_XDECREF(_hg2py(*global)); - Py_XINCREF(obj); - *global = _py2hg(obj); -} - -HPyAPI_IMPL HPy -ctx_Global_Load(HPyContext *ctx, HPyGlobal global) -{ - PyObject *obj = _hg2py(global); - Py_INCREF(obj); - return _py2h(obj); -} - -HPyAPI_IMPL void -ctx_FatalError(HPyContext *ctx, const char *message) -{ - Py_FatalError(message); -} - -HPyAPI_IMPL int -ctx_Type_IsSubtype(HPyContext *ctx, HPy sub, HPy type) -{ - return PyType_IsSubtype((PyTypeObject *)_h2py(sub), - (PyTypeObject *)_h2py(type)); -} diff --git a/graalpython/hpy/hpy/universal/src/ctx_misc.h b/graalpython/hpy/hpy/universal/src/ctx_misc.h deleted file mode 100644 index deb27ec5e5..0000000000 --- a/graalpython/hpy/hpy/universal/src/ctx_misc.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef HPY_CTX_MISC_H -#define HPY_CTX_MISC_H - -#include "hpy.h" -#include "api.h" - -HPyAPI_IMPL HPy ctx_FromPyObject(HPyContext *ctx, cpy_PyObject *obj); -HPyAPI_IMPL cpy_PyObject *ctx_AsPyObject(HPyContext *ctx, HPy h); -HPyAPI_IMPL void ctx_Close(HPyContext *ctx, HPy h); -HPyAPI_IMPL HPy ctx_Dup(HPyContext *ctx, HPy h); -HPyAPI_IMPL void ctx_Field_Store(HPyContext *ctx, HPy target_object, - HPyField *target_field, HPy h); -HPyAPI_IMPL HPy ctx_Field_Load(HPyContext *ctx, HPy source_object, - HPyField source_field); -HPyAPI_IMPL void ctx_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h); -HPyAPI_IMPL HPy ctx_Global_Load(HPyContext *ctx, HPyGlobal global); -HPyAPI_IMPL void ctx_FatalError(HPyContext *ctx, const char *message); -HPyAPI_IMPL int ctx_Type_IsSubtype(HPyContext *ctx, HPy sub, HPy type); - -#endif /* HPY_CTX_MISC_H */ diff --git a/graalpython/hpy/hpy/universal/src/handles.h b/graalpython/hpy/hpy/universal/src/handles.h deleted file mode 100644 index 3d0282d786..0000000000 --- a/graalpython/hpy/hpy/universal/src/handles.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HPY_HANDLES_H -#define HPY_HANDLES_H - -#include -#include "hpy.h" - -// The main reason for +1/-1 is to make sure that if people casts HPy to -// PyObject* directly, things explode. Moreover, with this we can easily -// distinguish normal and debug handles in gdb, by only looking at the last -// bit. - -static inline HPy _py2h(PyObject *obj) { - if (obj == NULL) - return HPy_NULL; - return (HPy){(HPy_ssize_t)obj + 1}; -} - -static inline PyObject *_h2py(HPy h) { - if HPy_IsNull(h) - return NULL; - return (PyObject *)(h._i - 1); -} - -static inline HPyField _py2hf(PyObject *obj) -{ - HPy h = _py2h(obj); - return (HPyField){ ._i = h._i }; -} - -static inline PyObject * _hf2py(HPyField hf) -{ - HPy h = { ._i = hf._i }; - return _h2py(h); -} - -static inline HPyThreadState _threads2h(PyThreadState* s) -{ - return (HPyThreadState) { (intptr_t) s }; -} - -static inline PyThreadState* _h2threads(HPyThreadState h) -{ - return (PyThreadState*) h._i; -} - -static inline HPyGlobal _py2hg(PyObject *obj) -{ - HPy h = _py2h(obj); - return (HPyGlobal){ ._i = h._i }; -} - -static inline PyObject * _hg2py(HPyGlobal hf) -{ - HPy h = { ._i = hf._i }; - return _h2py(h); -} - -#endif /* HPY_HANDLES_H */ diff --git a/graalpython/hpy/hpy/universal/src/hpymodule.c b/graalpython/hpy/hpy/universal/src/hpymodule.c deleted file mode 100644 index 6ae8b54859..0000000000 --- a/graalpython/hpy/hpy/universal/src/hpymodule.c +++ /dev/null @@ -1,688 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include -#ifdef MS_WIN32 -# include -# include "misc_win32.h" -#else -# include -// required for strncasecmp -#include -#endif -#include -#include - - -#include "api.h" -#include "handles.h" -#include "hpy/version.h" -#include "hpy_debug.h" -#include "hpy_trace.h" -#include "hpy/runtime/ctx_module.h" - -#ifdef PYPY_VERSION -# error "Cannot build hpy.universal on top of PyPy. PyPy comes with its own version of it" -#endif - -static const char *hpy_mode_names[] = { - "MODE_UNIVERSAL", - "MODE_DEBUG", - "MODE_TRACE", - // "MODE_DEBUG_TRACE", - // "MODE_TRACE_DEBUG", - NULL -}; - -typedef enum { - MODE_INVALID = -1, - MODE_UNIVERSAL = 0, - MODE_DEBUG = 1, - MODE_TRACE = 2, - /* We do currently not test the combinations of debug and trace mode, so we - do not offer them right now. This may change in future. */ - // MODE_DEBUG_TRACE = 3, - // MODE_TRACE_DEBUG = 4 -} HPyMode; - -typedef uint32_t (*VersionGetterFuncPtr)(void); -typedef HPyModuleDef* (*InitFuncPtr)(void); -typedef void (*InitContextFuncPtr)(HPyContext*); - -static const char *init_prefix = "HPyInit"; -static const char *init_ctx_prefix = "HPyInitGlobalContext_"; - -static inline int -_hpy_strncmp_ignore_case(const char *s0, const char *s1, size_t n) -{ -#ifdef MS_WIN32 - return _strnicmp(s0, s1, n); -#else - return strncasecmp(s0, s1, n); -#endif -} - -static HPyContext * get_context(HPyMode mode) -{ - switch (mode) - { - case MODE_INVALID: - return NULL; - case MODE_DEBUG: - return hpy_debug_get_ctx(&g_universal_ctx); - case MODE_TRACE: - return hpy_trace_get_ctx(&g_universal_ctx); - // case MODE_DEBUG_TRACE: - // return hpy_debug_get_ctx(hpy_trace_get_ctx(&g_universal_ctx)); - // case MODE_TRACE_DEBUG: - // return hpy_trace_get_ctx(hpy_debug_get_ctx(&g_universal_ctx)); - default: - return &g_universal_ctx; - } -} - -static PyObject * -get_encoded_name(PyObject *name) { - PyObject *tmp; - PyObject *encoded = NULL; - PyObject *modname = NULL; - Py_ssize_t name_len, lastdot; - - /* Get the short name (substring after last dot) */ - name_len = PyUnicode_GetLength(name); - lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1); - if (lastdot < -1) { - return NULL; - } else if (lastdot >= 0) { - tmp = PyUnicode_Substring(name, lastdot + 1, name_len); - if (tmp == NULL) - return NULL; - name = tmp; - /* "name" now holds a new reference to the substring */ - } else { - Py_INCREF(name); - } - - /* Encode to ASCII */ - encoded = PyUnicode_AsEncodedString(name, "ascii", NULL); - if (encoded != NULL) { - } else { - goto error; - } - - /* Replace '-' by '_' */ - modname = PyObject_CallMethod(encoded, "replace", "cc", '-', '_'); - if (modname == NULL) - goto error; - - Py_DECREF(name); - Py_DECREF(encoded); - return modname; -error: - Py_DECREF(name); - Py_XDECREF(encoded); - return NULL; -} - -static bool validate_abi_tag(const char *shortname, const char *soname, - uint32_t required_major_version, uint32_t required_minor_version) { - char *substr = strstr(soname, ".hpy"); - if (substr != NULL) { - substr += strlen(".hpy"); - if (*substr >= '0' && *substr <= '9') { - // It is a number w/o sign and whitespace, we can now parse it with atoi - uint32_t abi_tag = (uint32_t) atoi(substr); - if (abi_tag == required_major_version) { - return true; - } - PyErr_Format(PyExc_RuntimeError, - "HPy extension module '%s' at path '%s': mismatch between the " - "HPy ABI tag encoded in the filename and the major version requested " - "by the HPy extension itself. Major version tag parsed from " - "filename: %" PRIu32 ". Requested version: %" PRIu32 ".%" PRIu32 ".", - shortname, soname, abi_tag, required_major_version, required_minor_version); - return false; - } - } - PyErr_Format(PyExc_RuntimeError, - "HPy extension module '%s' at path '%s': could not find " - "HPy ABI tag encoded in the filename. The extension claims to be compiled with " - "HPy ABI version: %" PRIu32 ".%" PRIu32 ".", - shortname, soname, required_major_version, required_minor_version); - return false; -} - -static void dlsym_error(const char *soname, const char *symbol_name) { - const char *error = dlerror(); - if (error == NULL) - error = "no error message provided by the system"; - PyErr_Format(PyExc_RuntimeError, - "Error during loading of the HPy extension module at " - "path '%s' while trying to find symbol '%s'. Did you use" - "the HPy_MODINIT macro to register your module? Error " - "message from dlsym/WinAPI: %s", soname, symbol_name, error); -} - -static PyObject *do_load(PyObject *name_unicode, PyObject *path, HPyMode mode, PyObject *spec) -{ - PyObject *name = NULL; - PyObject *pathbytes = NULL; - PyModuleDef *pydef = NULL; - PyObject *py_mod = NULL; - - name = get_encoded_name(name_unicode); - if (name == NULL) { - goto error; - } - - pathbytes = PyUnicode_EncodeFSDefault(path); - if (pathbytes == NULL) - goto error; - const char *soname = PyBytes_AS_STRING(pathbytes); - - void *mylib = dlopen(soname, RTLD_NOW); // who closes this? - if (mylib == NULL) { - const char *error = dlerror(); - if (error == NULL) - error = "no error message provided by the system"; - PyErr_Format(PyExc_RuntimeError, - "Error during loading of the HPy extension module at path " - "'%s'. Error message from dlopen/WinAPI: %s", soname, error); - goto error; - } - - const char *shortname = PyBytes_AS_STRING(name); - char minor_version_symbol_name[258]; - char major_version_symbol_name[258]; - PyOS_snprintf(minor_version_symbol_name, sizeof(minor_version_symbol_name), - "get_required_hpy_minor_version_%.200s", shortname); - PyOS_snprintf(major_version_symbol_name, sizeof(major_version_symbol_name), - "get_required_hpy_major_version_%.200s", shortname); - void *minor_version_ptr = dlsym(mylib, minor_version_symbol_name); - void *major_version_ptr = dlsym(mylib, major_version_symbol_name); - if (minor_version_ptr == NULL || major_version_ptr == NULL) { - const char *error = dlerror(); - if (error == NULL) - error = "no error message provided by the system"; - PyErr_Format(PyExc_RuntimeError, - "Error during loading of the HPy extension module at path " - "'%s'. Cannot locate the required minimal HPy versions as symbols '%s' and `%s`. " - "Error message from dlopen/WinAPI: %s", - soname, minor_version_symbol_name, major_version_symbol_name, error); - goto error; - } - uint32_t required_minor_version = ((VersionGetterFuncPtr) minor_version_ptr)(); - uint32_t required_major_version = ((VersionGetterFuncPtr) major_version_ptr)(); - if (required_major_version != HPY_ABI_VERSION || required_minor_version > HPY_ABI_VERSION_MINOR) { - // For now, we have only one major version, but in the future at this - // point we would decide which HPyContext to create - PyErr_Format(PyExc_RuntimeError, - "HPy extension module '%s' requires unsupported version of the HPy runtime. " - "Requested version: %" PRIu32 ".%" PRIu32 ". Current HPy version: %" PRIu32 ".%" PRIu32 ".", - shortname, required_major_version, required_minor_version, - HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR); - goto error; - } - - // Sanity check of the tag in the shared object filename - if (!validate_abi_tag(shortname, soname, required_major_version, required_minor_version)) { - goto error; - } - - HPyContext *ctx = get_context(mode); - if (ctx == NULL) - goto error; - - char init_ctx_name[258]; - PyOS_snprintf(init_ctx_name, sizeof(init_ctx_name), "%.20s_%.200s", - init_ctx_prefix, shortname); - void *initctxfn = dlsym(mylib, init_ctx_name); - if (initctxfn == NULL) { - dlsym_error(soname, init_ctx_name); - goto error; - } - ((InitContextFuncPtr)initctxfn)(ctx); - - char init_name[258]; - PyOS_snprintf(init_name, sizeof(init_name), "%.20s_%.200s", - init_prefix, shortname); - void *initfn = dlsym(mylib, init_name); - if (initfn == NULL) { - dlsym_error(soname, init_name); - goto error; - } - - HPyModuleDef* hpydef = ((InitFuncPtr)initfn)(); - if (hpydef == NULL) { - PyErr_Format(PyExc_RuntimeError, - "Error during loading of the HPy extension module at " - "path '%s'. Function '%s' returned NULL.", soname, init_name); - goto error; - } - - pydef = _HPyModuleDef_CreatePyModuleDef(hpydef); - if (pydef == NULL) { - goto error; - } - - py_mod = PyModule_FromDefAndSpec(pydef, spec); - if (py_mod == NULL) - goto error; - - if (PyModule_Check(py_mod)) { - if (PyModule_ExecDef(py_mod, pydef) != 0) - goto error; - } - - Py_XDECREF(name); - Py_XDECREF(pathbytes); - return py_mod; -error: - Py_XDECREF(py_mod); - if (pydef != NULL) - PyMem_Free(pydef); - Py_XDECREF(name); - Py_XDECREF(pathbytes); - return NULL; -} - -static PyObject *load(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"name", "path", "spec", "debug", "mode", NULL}; - PyObject *name_unicode; - PyObject *path; - PyObject *spec; - int debug = 0; - int mode = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO|pi", kwlist, - &name_unicode, &path, &spec, &debug, &mode)) { - return NULL; - } - HPyMode hmode = debug ? MODE_DEBUG : MODE_UNIVERSAL; - // 'mode' just overwrites 'debug' - if (mode > 0) - { - hmode = (HPyMode) mode; - } - return do_load(name_unicode, path, hmode, spec); -} - -static HPyMode get_mode_from_string(const char *s, Py_ssize_t n) -{ - if (_hpy_strncmp_ignore_case("debug", s, n) == 0) - return MODE_DEBUG; - if (_hpy_strncmp_ignore_case("trace", s, n) == 0) - return MODE_TRACE; - // if (_hpy_strncmp_ignore_case("debug+trace", s, n) == 0) - // return MODE_DEBUG_TRACE; - // if (_hpy_strncmp_ignore_case("trace+debug", s, n) == 0) - // return MODE_TRACE_DEBUG; - if (_hpy_strncmp_ignore_case("universal", s, n) == 0) - return MODE_UNIVERSAL; - return MODE_INVALID; -} - -/* - * A little helper that does a fast-path if 'mapping' is a dict. - */ -static int mapping_get_item(PyObject *mapping, const char *skey, PyObject **value) -{ - PyObject *key = PyUnicode_FromString(skey); - if (key == NULL) - return 1; - - // fast-path if 'mapping' is a dict - if (PyDict_Check(mapping)) { - *value = PyDict_GetItem(mapping, key); - Py_DECREF(key); - /* 'NULL' means, the key is not present in the dict, so just return - 'NULL'. Since PyDict_GetItem does not set an error, we don't need to - clear any error. */ - } else { - *value = PyObject_GetItem(mapping, key); - Py_DECREF(key); - if (*value == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Clear(); - } else { - return 1; - } - } - } - return 0; -} - -/* - * HPY_MODE := MODE | (MODULE_NAME ':' MODE { ',' MODULE_NAME ':' MODE }) - * MODULE_NAME := IDENTIFIER - * MODE := 'debug' | 'trace' | 'universal' - */ -static HPyMode get_hpy_mode_from_environ(const char *s_name, PyObject *env) -{ - PyObject *value; - Py_ssize_t size; - HPyMode res; - const char *s_value; - - if (mapping_get_item(env, "HPY", &value)) { - return MODE_INVALID; - } - - /* 'value == NULL' is not an error; this just means that the key was not - present in 'env'. */ - if (value == NULL) { - return MODE_UNIVERSAL; - } - - s_value = PyUnicode_AsUTF8AndSize(value, &size); - if (s_value == NULL) { - Py_DECREF(value); - return MODE_INVALID; - } - res = MODE_INVALID; - char *colon = strchr(s_value, ':'); - if (colon) { - // case 2: modes are specified per module - char *name_start = (char *)s_value; - char *comma; - size_t mode_len; - while (colon) { - comma = strchr(colon + 1, ','); - if (comma) { - mode_len = comma - colon - 1; - } else { - mode_len = (s_value + size) - colon - 1; - } - if (strncmp(s_name, name_start, colon - name_start) == 0) { - res = get_mode_from_string(colon + 1, mode_len); - break; - } - if (comma) { - name_start = comma + 1; - colon = strchr(name_start, ':'); - } else { - colon = NULL; - } - } - } else { - // case 1: mode was globally specified - res = get_mode_from_string(s_value, size); - } - - if (res == MODE_INVALID) - PyErr_Format(PyExc_ValueError, "invalid HPy mode: %.50s", s_value); - Py_DECREF(value); - return res; -} - -static PyObject * -load_bootstrap(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"name", "ext_name", "package", "file", "loader", "spec", - "env", NULL}; - PyObject *module_name, *name, *package, *file, *loader, *spec, *env; - PyObject *log_obj, *m; - HPyMode hmode; - const char *s_module_name, *log_msg; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOOOOO", kwlist, - &module_name, &name, &package, &file, - &loader, &spec, &env)) { - return NULL; - } - - s_module_name = PyUnicode_AsUTF8AndSize(module_name, NULL); - if (s_module_name == NULL) { - return NULL; - } - - hmode = get_hpy_mode_from_environ(s_module_name, env); - if (hmode == MODE_INVALID) - return NULL; - - if (mapping_get_item(env, "HPY_LOG", &log_obj)) - return NULL; - - if (log_obj != NULL) { - Py_DECREF(log_obj); - switch (hmode) { - case MODE_DEBUG: - log_msg = " with a debug context"; - break; - case MODE_TRACE: - log_msg = " with a trace context"; - break; - case MODE_UNIVERSAL: - log_msg = ""; - break; - default: - // that's not possible but required for the compiler - return NULL; - } - PySys_FormatStdout("Loading '%.200s' in HPy universal mode%.200s\n", - s_module_name, log_msg); - } - - m = do_load(module_name, file, hmode, spec); - if (m == NULL) - return NULL; - - PyObject_SetAttrString(m, "__file__", file); - PyObject_SetAttrString(m, "__loader__", loader); - PyObject_SetAttrString(m, "__name__", name); - PyObject_SetAttrString(m, "__package__", package); - PyObject_SetAttrString(spec, "origin", file); - PyObject_SetAttrString(m, "__spec__", spec); - - return m; -} - -static PyObject *get_version(PyObject *self, PyObject *ignored) -{ - return Py_BuildValue("ss", HPY_VERSION, HPY_GIT_REVISION); -} - -PyDoc_STRVAR(load_bootstrap_doc, "Internal function intended to be used by " - "the stub loader. This function will honor env var 'HPY' and correctly" - " set the attributes of the module."); - -static PyMethodDef HPyMethods[] = { - {"load", (PyCFunction)load, METH_VARARGS | METH_KEYWORDS, - ("Load a ." HPY_ABI_TAG ".so file")}, - {"_load_bootstrap", (PyCFunction)load_bootstrap, - METH_VARARGS | METH_KEYWORDS, load_bootstrap_doc}, - {"get_version", (PyCFunction)get_version, METH_NOARGS, - "Return a tuple ('version', 'git revision')"}, - {NULL, NULL, 0, NULL} -}; - - -static int exec_module(PyObject *mod); -static PyModuleDef_Slot hpymodule_slots[] = { - {Py_mod_exec, exec_module}, - {0, NULL}, -}; - -static struct PyModuleDef hpy_pydef = { - PyModuleDef_HEAD_INIT, - .m_name = "hpy.universal", - .m_doc = "HPy universal runtime for CPython", - .m_size = 0, - .m_methods = HPyMethods, - .m_slots = hpymodule_slots, -}; - -static int initialize_module(HPyContext *ctx, PyObject *hpy_universal, const char* name, - const char *full_name, HPyModuleDef *hpydef, - PyObject* spec_from_file_and_location, PyObject *location) -{ - PyObject *spec = NULL, *new_mod = NULL; - int result = -1; - - spec = PyObject_CallFunction(spec_from_file_and_location, "sO", full_name, location); - PyModuleDef *pydef = _HPyModuleDef_CreatePyModuleDef(hpydef); - new_mod = PyModule_FromDefAndSpec(pydef, spec); - if (new_mod == NULL) - goto cleanup; - - if (PyModule_ExecDef(new_mod, pydef) != 0) - goto cleanup; - - Py_INCREF(new_mod); // PyModule_AddObject steals the reference - if (PyModule_AddObject(hpy_universal, name, new_mod) < 0) - goto cleanup; - - result = 0; - -cleanup: - Py_XDECREF(new_mod); - Py_XDECREF(spec); - return result; -} - -// module initialization function -int exec_module(PyObject* mod) { - HPyContext *ctx = &g_universal_ctx; - - PyObject *importlib_util = PyImport_ImportModule("importlib.util"); - if (importlib_util == NULL) - return -1; - - PyObject *spec_from_file_and_location = PyObject_GetAttrString(importlib_util, "spec_from_file_location"); - Py_DecRef(importlib_util); - if (spec_from_file_and_location == NULL) - return -1; - - PyObject *current_mod_spec = PyObject_GetAttrString(mod, "__spec__"); - if (current_mod_spec == NULL) - return -1; - - PyObject *location = PyObject_GetAttrString(current_mod_spec, "origin"); - if (location == NULL) - return -1; - - HPyInitGlobalContext__debug(ctx); - int result = initialize_module(ctx, mod, "_debug", "hpy.debug._debug", - HPyInit__debug(), spec_from_file_and_location, location); - if (result != 0) - return result; - - HPyInitGlobalContext__trace(ctx); - result = initialize_module(ctx, mod, "_trace", "hpy.trace._trace", - HPyInit__trace(), spec_from_file_and_location, location); - if (result != 0) - return result; - - for (int i=0; hpy_mode_names[i]; i++) - { - if (PyModule_AddIntConstant(mod, hpy_mode_names[i], i) < 0) - return -1; - } - - return 0; -} - -static void init_universal_ctx(HPyContext *ctx) -{ - if (!HPy_IsNull(ctx->h_None)) - // already initialized - return; - - // XXX this code is basically the same as found in cpython/hpy.h. We - // should probably share and/or autogenerate both versions - /* Constants */ - ctx->h_None = _py2h(Py_None); - ctx->h_True = _py2h(Py_True); - ctx->h_False = _py2h(Py_False); - ctx->h_NotImplemented = _py2h(Py_NotImplemented); - ctx->h_Ellipsis = _py2h(Py_Ellipsis); - /* Exceptions */ - ctx->h_BaseException = _py2h(PyExc_BaseException); - ctx->h_Exception = _py2h(PyExc_Exception); - ctx->h_StopAsyncIteration = _py2h(PyExc_StopAsyncIteration); - ctx->h_StopIteration = _py2h(PyExc_StopIteration); - ctx->h_GeneratorExit = _py2h(PyExc_GeneratorExit); - ctx->h_ArithmeticError = _py2h(PyExc_ArithmeticError); - ctx->h_LookupError = _py2h(PyExc_LookupError); - ctx->h_AssertionError = _py2h(PyExc_AssertionError); - ctx->h_AttributeError = _py2h(PyExc_AttributeError); - ctx->h_BufferError = _py2h(PyExc_BufferError); - ctx->h_EOFError = _py2h(PyExc_EOFError); - ctx->h_FloatingPointError = _py2h(PyExc_FloatingPointError); - ctx->h_OSError = _py2h(PyExc_OSError); - ctx->h_ImportError = _py2h(PyExc_ImportError); - ctx->h_ModuleNotFoundError = _py2h(PyExc_ModuleNotFoundError); - ctx->h_IndexError = _py2h(PyExc_IndexError); - ctx->h_KeyError = _py2h(PyExc_KeyError); - ctx->h_KeyboardInterrupt = _py2h(PyExc_KeyboardInterrupt); - ctx->h_MemoryError = _py2h(PyExc_MemoryError); - ctx->h_NameError = _py2h(PyExc_NameError); - ctx->h_OverflowError = _py2h(PyExc_OverflowError); - ctx->h_RuntimeError = _py2h(PyExc_RuntimeError); - ctx->h_RecursionError = _py2h(PyExc_RecursionError); - ctx->h_NotImplementedError = _py2h(PyExc_NotImplementedError); - ctx->h_SyntaxError = _py2h(PyExc_SyntaxError); - ctx->h_IndentationError = _py2h(PyExc_IndentationError); - ctx->h_TabError = _py2h(PyExc_TabError); - ctx->h_ReferenceError = _py2h(PyExc_ReferenceError); - ctx->h_SystemError = _py2h(PyExc_SystemError); - ctx->h_SystemExit = _py2h(PyExc_SystemExit); - ctx->h_TypeError = _py2h(PyExc_TypeError); - ctx->h_UnboundLocalError = _py2h(PyExc_UnboundLocalError); - ctx->h_UnicodeError = _py2h(PyExc_UnicodeError); - ctx->h_UnicodeEncodeError = _py2h(PyExc_UnicodeEncodeError); - ctx->h_UnicodeDecodeError = _py2h(PyExc_UnicodeDecodeError); - ctx->h_UnicodeTranslateError = _py2h(PyExc_UnicodeTranslateError); - ctx->h_ValueError = _py2h(PyExc_ValueError); - ctx->h_ZeroDivisionError = _py2h(PyExc_ZeroDivisionError); - ctx->h_BlockingIOError = _py2h(PyExc_BlockingIOError); - ctx->h_BrokenPipeError = _py2h(PyExc_BrokenPipeError); - ctx->h_ChildProcessError = _py2h(PyExc_ChildProcessError); - ctx->h_ConnectionError = _py2h(PyExc_ConnectionError); - ctx->h_ConnectionAbortedError = _py2h(PyExc_ConnectionAbortedError); - ctx->h_ConnectionRefusedError = _py2h(PyExc_ConnectionRefusedError); - ctx->h_ConnectionResetError = _py2h(PyExc_ConnectionResetError); - ctx->h_FileExistsError = _py2h(PyExc_FileExistsError); - ctx->h_FileNotFoundError = _py2h(PyExc_FileNotFoundError); - ctx->h_InterruptedError = _py2h(PyExc_InterruptedError); - ctx->h_IsADirectoryError = _py2h(PyExc_IsADirectoryError); - ctx->h_NotADirectoryError = _py2h(PyExc_NotADirectoryError); - ctx->h_PermissionError = _py2h(PyExc_PermissionError); - ctx->h_ProcessLookupError = _py2h(PyExc_ProcessLookupError); - ctx->h_TimeoutError = _py2h(PyExc_TimeoutError); - /* Warnings */ - ctx->h_Warning = _py2h(PyExc_Warning); - ctx->h_UserWarning = _py2h(PyExc_UserWarning); - ctx->h_DeprecationWarning = _py2h(PyExc_DeprecationWarning); - ctx->h_PendingDeprecationWarning = _py2h(PyExc_PendingDeprecationWarning); - ctx->h_SyntaxWarning = _py2h(PyExc_SyntaxWarning); - ctx->h_RuntimeWarning = _py2h(PyExc_RuntimeWarning); - ctx->h_FutureWarning = _py2h(PyExc_FutureWarning); - ctx->h_ImportWarning = _py2h(PyExc_ImportWarning); - ctx->h_UnicodeWarning = _py2h(PyExc_UnicodeWarning); - ctx->h_BytesWarning = _py2h(PyExc_BytesWarning); - ctx->h_ResourceWarning = _py2h(PyExc_ResourceWarning); - /* Types */ - ctx->h_BaseObjectType = _py2h((PyObject *)&PyBaseObject_Type); - ctx->h_TypeType = _py2h((PyObject *)&PyType_Type); - ctx->h_BoolType = _py2h((PyObject *)&PyBool_Type); - ctx->h_LongType = _py2h((PyObject *)&PyLong_Type); - ctx->h_FloatType = _py2h((PyObject *)&PyFloat_Type); - ctx->h_UnicodeType = _py2h((PyObject *)&PyUnicode_Type); - ctx->h_TupleType = _py2h((PyObject *)&PyTuple_Type); - ctx->h_ListType = _py2h((PyObject *)&PyList_Type); - ctx->h_ComplexType = _py2h((PyObject *)&PyComplex_Type); - ctx->h_BytesType = _py2h((PyObject *)&PyBytes_Type); - ctx->h_MemoryViewType = _py2h((PyObject *)&PyMemoryView_Type); - ctx->h_CapsuleType = _py2h((PyObject *)&PyCapsule_Type); - ctx->h_SliceType = _py2h((PyObject *)&PySlice_Type); - ctx->h_DictType = _py2h((PyObject *)&PyDict_Type); - /* Reflection */ - ctx->h_Builtins = _py2h(PyEval_GetBuiltins()); -} - - -PyMODINIT_FUNC -PyInit_universal(void) -{ - init_universal_ctx(&g_universal_ctx); - PyObject *mod = PyModuleDef_Init(&hpy_pydef); - return mod; -} diff --git a/graalpython/hpy/hpy/universal/src/misc_win32.h b/graalpython/hpy/hpy/universal/src/misc_win32.h deleted file mode 100644 index d267e758e7..0000000000 --- a/graalpython/hpy/hpy/universal/src/misc_win32.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************/ -/* Emulate dlopen()&co. from the Windows API */ - -#define RTLD_LAZY 0 -#define RTLD_NOW 0 -#define RTLD_GLOBAL 0 -#define RTLD_LOCAL 0 - -static void *dlopen(const char *filename, int flag) -{ - return (void *)LoadLibraryA(filename); -} - -static void *dlopenW(const wchar_t *filename) -{ - return (void *)LoadLibraryW(filename); -} - -static void *dlsym(void *handle, const char *symbol) -{ - void *address = GetProcAddress((HMODULE)handle, symbol); -#ifndef MS_WIN64 - if (!address) { - /* If 'symbol' is not found, then try '_symbol@N' for N in - (0, 4, 8, 12, ..., 124). Unlike ctypes, we try to do that - for any symbol, although in theory it should only be done - for __stdcall functions. - */ - int i; - char mangled_name[1 + strlen(symbol) + 1 + 3 + 1]; - for (i = 0; i < 32; i++) { - sprintf(mangled_name, "_%s@%d", symbol, i * 4); - address = GetProcAddress((HMODULE)handle, mangled_name); - if (address) - break; - } - } -#endif - return address; -} - -static int dlclose(void *handle) -{ - return FreeLibrary((HMODULE)handle) ? 0 : -1; -} - -static const char *dlerror(void) -{ - static char buf[32]; - DWORD dw = GetLastError(); - if (dw == 0) - return NULL; - sprintf(buf, "error 0x%x", (unsigned int)dw); - return buf; -} diff --git a/graalpython/hpy/microbench/README.md b/graalpython/hpy/microbench/README.md deleted file mode 100644 index c25916088c..0000000000 --- a/graalpython/hpy/microbench/README.md +++ /dev/null @@ -1,29 +0,0 @@ -To run the microbenchmarks --------------------------- - -1. You need to have `hpy` installed in your virtuanenv. The easiest way - to do it is: - - $ cd /path/to/hpy - $ python setup.py develop - -2. Build the extension modules needed for the microbenchmarks - - $ cd /path/to/hpy/microbench - $ pip install cffi # needed to build _valgrind - $ python setup.py build_ext --inplace - -2. `py.test -v` - -3. To run only cpy or hpy tests, use -m (to select markers): - - $ py.test -v -m hpy - $ py.test -v -m cpy - -4. Step (2) build `hpy_simple` using the CPython ABI by default. If you want - to benchmark the universal mode, you need to build it explicitly: - - $ cd /path/to/hpy/microbench - $ rm *.so # make sure to delete CPython-ABI versions - $ python setup.py --hpy-abi=universal build_ext --inplace - $ py.test -v diff --git a/graalpython/hpy/microbench/_valgrind_build.py b/graalpython/hpy/microbench/_valgrind_build.py deleted file mode 100644 index 4cbbc1ec7d..0000000000 --- a/graalpython/hpy/microbench/_valgrind_build.py +++ /dev/null @@ -1,29 +0,0 @@ -from cffi import FFI -ffibuilder = FFI() - -ffibuilder.cdef(""" - void callgrind_start(void); - void callgrind_stop(void); - int is_running_on_valgrind(void); -""") - - -ffibuilder.set_source("_valgrind", """ -#include -void callgrind_start(void) { - CALLGRIND_START_INSTRUMENTATION; -} - -void callgrind_stop(void) { - CALLGRIND_STOP_INSTRUMENTATION; - CALLGRIND_DUMP_STATS; -} - -int is_running_on_valgrind(void) { - return RUNNING_ON_VALGRIND; -} -""", - libraries=[]) - -if __name__ == "__main__": - ffibuilder.compile(verbose=True) diff --git a/graalpython/hpy/microbench/conftest.py b/graalpython/hpy/microbench/conftest.py deleted file mode 100644 index 8e553ffe76..0000000000 --- a/graalpython/hpy/microbench/conftest.py +++ /dev/null @@ -1,124 +0,0 @@ -import re -import time -from collections import defaultdict -import pytest -import _valgrind - -class Timer: - - def __init__(self, nodeid): - self.nodeid = nodeid - self.start = None - self.stop = None - - def __enter__(self): - if self.start is not None: - raise ValueError('You cannot use "with timer:" more than once') - _valgrind.lib.callgrind_start() - self.start = time.time() - - def __exit__(self, etype, evalue, tb): - self.stop = time.time() - _valgrind.lib.callgrind_stop() - - def __str__(self): - if self.start is None: - return '[NO TIMING]' - if self.stop is None: - return '[IN-PROGRESS]' - usec = (self.stop - self.start) * 1000 - return f'{usec:.2f} us' - - @property - def elapsed(self): - if self.start is not None and self.stop is not None: - return self.stop - self.start - return None - - -class TimerSession: - - NODEID = re.compile(r'(.*)\[(.*)\]') - - def __init__(self): - self.apis = set() # ['cpy', 'hpy', ...] - self.table = defaultdict(dict) # {shortid: {api: timer}} - self.timers = {} # nodeid -> Timer - - def new_timer(self, nodeid): - shortid, api = self.split_nodeid(nodeid) - timer = Timer(nodeid) - self.apis.add(api) - self.table[shortid][api] = timer - self.timers[nodeid] = timer - return timer - - def get_timer(self, nodeid): - return self.timers.get(nodeid) - - def split_nodeid(self, nodeid): - shortid = '::'.join(nodeid.split('::')[-2:]) # take only class::function - m = self.NODEID.match(shortid) - if not m: - return shortid, '' - return m.group(1), m.group(2) - - def format_ratio(self, reference, value): - if reference and reference.elapsed and value and value.elapsed: - ratio = value.elapsed / reference.elapsed - return f'[{ratio:.2f}]' - return '' - - def display_summary(self, tr): - w = tr.write_line - w('') - tr.write_sep('=', 'BENCHMARKS', cyan=True) - w(' '*40 + ' cpy hpy') - w(' '*40 + '---------------- -------------------') - for shortid, timings in self.table.items(): - cpy = timings.get('cpy') - hpy = timings.get('hpy') - hpy_ratio = self.format_ratio(cpy, hpy) - cpy = cpy or '' - hpy = hpy or '' - w(f'{shortid:<40} {cpy!s:>15} {hpy!s:>15} {hpy_ratio}') - w('') - - - -@pytest.fixture -def timer(request, api): - nodeid = request.node.nodeid - return request.config._timersession.new_timer(nodeid) - -def pytest_configure(config): - config._timersession = TimerSession() - config.addinivalue_line("markers", "hpy: mark modules using the HPy API") - config.addinivalue_line("markers", "cpy: mark modules using the old Python/C API") - -def pytest_addoption(parser): - parser.addoption( - "--fast", action="store_true", default=False, help="run microbench faster" - ) - parser.addoption( - "--slow", action="store_true", default=False, help="run microbench slower" - ) - - -VERBOSE_TEST_NAME_LENGTH = 90 - -@pytest.hookimpl(hookwrapper=True) -def pytest_report_teststatus(report, config): - outcome = yield - category, letter, word = outcome.get_result() - timer = config._timersession.get_timer(report.nodeid) - if category == 'passed' and timer: - L = VERBOSE_TEST_NAME_LENGTH - len(report.nodeid) - word = str(timer).rjust(L) - markup = None - if timer.elapsed is None: - markup = {'yellow': True} - outcome.force_result((category, letter, (word, markup))) - -def pytest_terminal_summary(terminalreporter, config): - config._timersession.display_summary(terminalreporter) diff --git a/graalpython/hpy/microbench/pytest_valgrind.sh b/graalpython/hpy/microbench/pytest_valgrind.sh deleted file mode 100755 index 8271381d0b..0000000000 --- a/graalpython/hpy/microbench/pytest_valgrind.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -valgrind --tool=callgrind --instr-atstart=no python3-dbg -m pytest "$@" diff --git a/graalpython/hpy/microbench/setup.py b/graalpython/hpy/microbench/setup.py deleted file mode 100644 index 16988b0aef..0000000000 --- a/graalpython/hpy/microbench/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -from setuptools import setup, Extension - -setup( - name="hpy.microbench", - setup_requires=['cffi', 'hpy'], - ext_modules = [ - Extension('cpy_simple', - ['src/cpy_simple.c'], - extra_compile_args=['-g']) - ], - hpy_ext_modules = [ - Extension('hpy_simple', - ['src/hpy_simple.c'], - extra_compile_args=['-g']), - ], - cffi_modules=["_valgrind_build.py:ffibuilder"], -) diff --git a/graalpython/hpy/microbench/src/cpy_simple.c b/graalpython/hpy/microbench/src/cpy_simple.c deleted file mode 100644 index dc754de64e..0000000000 --- a/graalpython/hpy/microbench/src/cpy_simple.c +++ /dev/null @@ -1,174 +0,0 @@ -#include - -/* module-level functions */ - -static PyObject* noargs(PyObject* self, PyObject* args) -{ - Py_RETURN_NONE; -} - -static PyObject* onearg(PyObject* self, PyObject* arg) -{ - Py_RETURN_NONE; -} - -static PyObject* varargs(PyObject* self, PyObject* args) -{ - Py_RETURN_NONE; -} - -static PyObject* call_with_tuple(PyObject* self, PyObject* args) -{ - PyObject* f; - PyObject* f_args; - f = PyTuple_GetItem(args, 0); - if (f == NULL) - Py_RETURN_NONE; - f_args = PyTuple_GetItem(args, 1); - if (f_args == NULL) - Py_RETURN_NONE; - return PyObject_CallObject(f, f_args); -} - -static PyObject* call_with_tuple_and_dict(PyObject* self, PyObject* args) -{ - PyObject* f; - PyObject* f_args; - PyObject* f_kw; - f = PyTuple_GetItem(args, 0); - if (f == NULL) - Py_RETURN_NONE; - f_args = PyTuple_GetItem(args, 1); - if (f_args == NULL) - Py_RETURN_NONE; - f_kw = PyTuple_GetItem(args, 2); - if (f_kw == NULL) - Py_RETURN_NONE; - return PyObject_Call(f, f_args, f_kw); -} - -static PyObject* allocate_int(PyObject* self, PyObject* args) -{ - return PyLong_FromLong(2048); -} - -static PyObject* allocate_tuple(PyObject* self, PyObject* args) -{ - return Py_BuildValue("ii", 2048, 2049); -} - -static PyObject * Foo_getitem(PyObject *self, Py_ssize_t i) -{ - Py_RETURN_NONE; -} - -static Py_ssize_t Foo_len(PyObject *self) -{ - return 42; -} - -static PyMethodDef SimpleMethods[] = { - {"noargs", (PyCFunction)noargs, METH_NOARGS, ""}, - {"onearg", (PyCFunction)onearg, METH_O, ""}, - {"varargs", (PyCFunction)varargs, METH_VARARGS, ""}, - {"call_with_tuple", (PyCFunction)call_with_tuple, METH_VARARGS, ""}, - {"call_with_tuple_and_dict", (PyCFunction)call_with_tuple_and_dict, METH_VARARGS, ""}, - {"allocate_int", (PyCFunction)allocate_int, METH_NOARGS, ""}, - {"allocate_tuple", (PyCFunction)allocate_tuple, METH_NOARGS, ""}, - {NULL, NULL, 0, NULL} -}; - - -static PySequenceMethods FooSequence = { - .sq_length = (lenfunc)Foo_len, - .sq_item = (ssizeargfunc)Foo_getitem, - NULL, -}; - - -/* types */ - -typedef struct { - PyObject_HEAD -} FooObject; - -static PyTypeObject Foo_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "cpy_simple.Foo", /* tp_name */ - sizeof(FooObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &FooSequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - "Foo objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - SimpleMethods, /* tp_methods, reuse the same functions */ -}; - - -static PyType_Slot HTFoo_slots[] = { - {Py_tp_doc, "HTFoo objects"}, - {Py_tp_methods, SimpleMethods}, - {Py_sq_item, Foo_getitem}, - {Py_sq_length, Foo_len}, - {0, 0} -}; - -static PyType_Spec HTFoo_Type_spec = { - .name = "cpy_simple.Foo", - .basicsize = sizeof(FooObject), - .itemsize = 0, - .flags = Py_TPFLAGS_DEFAULT, - .slots = HTFoo_slots -}; - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "cpy_simple", - "Module Doc", - -1, - SimpleMethods, - NULL, - NULL, - NULL, - NULL, -}; - -PyMODINIT_FUNC -PyInit_cpy_simple(void) -{ - PyObject* m; - Foo_Type.tp_new = PyType_GenericNew; - if (PyType_Ready(&Foo_Type) < 0) - return NULL; - m = PyModule_Create(&moduledef); - if (m == NULL) - return NULL; - Py_INCREF(&Foo_Type); - PyModule_AddObject(m, "Foo", (PyObject *)&Foo_Type); - - PyObject *HTFoo_Type = PyType_FromSpec(&HTFoo_Type_spec); - if (HTFoo_Type == NULL) - return NULL; - PyModule_AddObject(m, "HTFoo", HTFoo_Type); - - return m; -} diff --git a/graalpython/hpy/microbench/src/hpy_simple.c b/graalpython/hpy/microbench/src/hpy_simple.c deleted file mode 100644 index a5dddadd63..0000000000 --- a/graalpython/hpy/microbench/src/hpy_simple.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "hpy.h" - -/* module-level functions */ - -HPyDef_METH(noargs, "noargs", HPyFunc_NOARGS) -static HPy noargs_impl(HPyContext *ctx, HPy self) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_METH(onearg, "onearg", HPyFunc_O) -static HPy onearg_impl(HPyContext *ctx, HPy self, HPy arg) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_METH(varargs, "varargs", HPyFunc_VARARGS) -static HPy varargs_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_METH(call_with_tuple, "call_with_tuple", HPyFunc_VARARGS) -static HPy call_with_tuple_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - HPy f, f_args; - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "call_with_tuple requires two arguments"); - return HPy_NULL; - } - f = args[0]; - f_args = args[1]; - return HPy_CallTupleDict(ctx, f, f_args, HPy_NULL); -} - -HPyDef_METH(call_with_tuple_and_dict, "call_with_tuple_and_dict", HPyFunc_VARARGS) -static HPy call_with_tuple_and_dict_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - HPy f, f_args, f_kw; - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, "call_with_tuple_and_dict requires three arguments"); - return HPy_NULL; - } - f = args[0]; - f_args = args[1]; - f_kw = args[2]; - return HPy_CallTupleDict(ctx, f, f_args, f_kw); -} - -HPyDef_METH(allocate_int, "allocate_int", HPyFunc_NOARGS) -static HPy allocate_int_impl(HPyContext *ctx, HPy self) -{ - return HPyLong_FromLong(ctx, 2048); -} - -HPyDef_METH(allocate_tuple, "allocate_tuple", HPyFunc_NOARGS) -static HPy allocate_tuple_impl(HPyContext *ctx, HPy self) -{ - return HPy_BuildValue(ctx, "ii", 2048, 2049); -} - - -/* Foo type */ - -typedef struct { - long x; - long y; -} FooObject; - -HPyDef_SLOT(Foo_getitem, HPy_sq_item) -static HPy Foo_getitem_impl(HPyContext *ctx, HPy self, HPy_ssize_t i) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_SLOT(Foo_len, HPy_sq_length) -static HPy_ssize_t Foo_len_impl(HPyContext *ctx, HPy self) -{ - return 42; -} - - -// note that we can reuse the same HPyDef for both module-level and type-level -// methods -static HPyDef *foo_defines[] = { - &noargs, - &onearg, - &varargs, - &allocate_int, - &allocate_tuple, - &Foo_getitem, - &Foo_len, -}; - - -static HPyType_Spec Foo_spec = { - .name = "hpy_simple.Foo", - .basicsize = sizeof(FooObject), - .flags = HPy_TPFLAGS_DEFAULT, - .defines = foo_defines -}; - - -/* Module defines */ - -HPyDef_SLOT(init_hpy_simple, HPy_mod_exec) -static int init_hpy_simple_impl(HPyContext *ctx, HPy m) -{ - HPy h_Foo = HPyType_FromSpec(ctx, &Foo_spec, NULL); - if (HPy_IsNull(h_Foo)) - return -1; - HPy_SetAttr_s(ctx, m, "Foo", h_Foo); - HPy_SetAttr_s(ctx, m, "HTFoo", h_Foo); - return 0; -} - -static HPyDef *module_defines[] = { - &noargs, - &onearg, - &varargs, - &call_with_tuple, - &call_with_tuple_and_dict, - &allocate_int, - &allocate_tuple, - &init_hpy_simple, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "HPy microbenchmarks", - .size = 0, - .defines = module_defines, -}; - -HPy_MODINIT(hpy_simple, moduledef) diff --git a/graalpython/hpy/microbench/test_microbench.py b/graalpython/hpy/microbench/test_microbench.py deleted file mode 100644 index ed59a243f0..0000000000 --- a/graalpython/hpy/microbench/test_microbench.py +++ /dev/null @@ -1,226 +0,0 @@ -""" -These are not real tests, but microbenchmarks. The machinery to record the -timing and display the results is inside conftest.py -""" - -import pytest -import _valgrind - -API_PARAMS = [ - pytest.param('cpy', marks=pytest.mark.cpy), - pytest.param('hpy', marks=pytest.mark.hpy) - ] - -@pytest.fixture(params=API_PARAMS) -def api(request): - return request.param - -@pytest.fixture -def simple(request, api): - if api == 'cpy': - import cpy_simple - return cpy_simple - elif api == 'hpy': - import hpy_simple - return hpy_simple - else: - assert False, 'Unkown param: %s' % request.param - -@pytest.fixture -def N(request): - n = 10000000 - if request.config.option.fast: - n //= 100 - if request.config.option.slow: - n *= 10 - if _valgrind.lib.is_running_on_valgrind(): - n //= 100 - return n - - -class TestModule: - - def test_noargs(self, simple, timer, N): - with timer: - for i in range(N): - simple.noargs() - - def test_onearg_None(self, simple, timer, N): - with timer: - for i in range(N): - simple.onearg(None) - - def test_onearg_int(self, simple, timer, N): - with timer: - for i in range(N): - simple.onearg(i) - - def test_varargs(self, simple, timer, N): - with timer: - for i in range(N): - simple.varargs(None, None) - - def test_call_with_tuple(self, simple, timer, N): - def f(a, b): - return a + b - - with timer: - for i in range(N): - simple.call_with_tuple(f, (1, 2)) - - def test_call_with_tuple_and_dict(self, simple, timer, N): - def f(a, b): - return a + b - - with timer: - for i in range(N): - simple.call_with_tuple_and_dict(f, (1,), {"b": 2}) - - def test_allocate_int(self, simple, timer, N): - with timer: - for i in range(N): - simple.allocate_int() - - def test_allocate_tuple(self, api, simple, timer, N): - with timer: - for i in range(N): - simple.allocate_tuple() - - -class TestType: - """ Compares the performance of operations on types. - - The kinds of type used are: - - * cpy: a static type - * hpy: a heap type (HPy only has heap types) - - The type is named `simple.Foo` in both cases. - """ - - def test_allocate_obj(self, simple, timer, N): - import gc - Foo = simple.Foo - objs = [None] * N - gc.collect() - with timer: - for i in range(N): - objs[i] = Foo() - del objs - gc.collect() - - def test_method_lookup(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - # note: here we are NOT calling it, we want to measure just - # the lookup - obj.noargs - - def test_noargs(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - obj.noargs() - - def test_onearg_None(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - obj.onearg(None) - - def test_onearg_int(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - obj.onearg(i) - - def test_varargs(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - obj.varargs(None, None) - - def test_len(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - len(obj) - - def test_getitem(self, simple, timer, N): - obj = simple.Foo() - with timer: - for i in range(N): - obj[0] - - -class TestHeapType: - """ Compares the performance of operations on heap types. - - The type is named `simple.HTFoo` and is a heap type in all cases. - """ - - def test_allocate_obj_and_survive(self, simple, timer, N): - import gc - HTFoo = simple.HTFoo - objs = [None] * N - gc.collect() - with timer: - for i in range(N): - objs[i] = HTFoo() - del objs - gc.collect() - - def test_allocate_obj_and_die(self, simple, timer, N): - import gc - HTFoo = simple.HTFoo - gc.collect() - with timer: - for i in range(N): - obj = HTFoo() - obj.onearg(None) - gc.collect() - - def test_method_lookup(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - # note: here we are NOT calling it, we want to measure just - # the lookup - obj.noargs - - def test_noargs(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - obj.noargs() - - def test_onearg_None(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - obj.onearg(None) - - def test_onearg_int(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - obj.onearg(i) - - def test_varargs(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - obj.varargs(None, None) - - def test_len(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - len(obj) - - def test_getitem(self, simple, timer, N): - obj = simple.HTFoo() - with timer: - for i in range(N): - obj[0] diff --git a/graalpython/hpy/proof-of-concept/pof.c b/graalpython/hpy/proof-of-concept/pof.c deleted file mode 100644 index 672a9a0199..0000000000 --- a/graalpython/hpy/proof-of-concept/pof.c +++ /dev/null @@ -1,109 +0,0 @@ -#include "hpy.h" -#include - -HPyDef_METH(do_nothing, "do_nothing", HPyFunc_NOARGS) -static HPy do_nothing_impl(HPyContext *ctx, HPy self) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_METH(double_obj, "double", HPyFunc_O) -static HPy double_obj_impl(HPyContext *ctx, HPy self, HPy obj) -{ - return HPy_Add(ctx, obj, obj); -} - -HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) -static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} - -HPyDef_METH(add_ints_kw, "add_ints_kw", HPyFunc_KEYWORDS) -static HPy add_ints_kw_impl(HPyContext *ctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames) -{ - long a, b; - const char* kwlist[] = {"a", "b", NULL}; - if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", - kwlist, &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} - -typedef struct { - double x; - double y; -} PointObject; - -HPyType_HELPERS(PointObject) - -HPyDef_SLOT(Point_new, HPy_tp_new) -static HPy Point_new_impl (HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kwnames) -{ - double x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "dd", &x, &y)) - return HPy_NULL; - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = x; - point->y = y; - return h_point; -} - -HPyDef_SLOT(Point_repr, HPy_tp_repr) -static HPy Point_repr_impl(HPyContext *ctx, HPy self) -{ - PointObject *point = PointObject_AsStruct(ctx, self); - char msg[256]; - snprintf(msg, 256, "Point(%g, %g)", point->x, point->y); - return HPyUnicode_FromString(ctx, msg); - //return HPyUnicode_FromFormat("Point(%g, %g)", point->x, point->y); -} - - -static HPyDef *point_type_defines[] = { - &Point_new, - &Point_repr, - NULL -}; -static HPyType_Spec point_type_spec = { - .name = "pof.Point", - .basicsize = sizeof(PointObject), - .flags = HPy_TPFLAGS_DEFAULT, - .defines = point_type_defines -}; - -HPyDef_SLOT(mod_exec, HPy_mod_exec) -static int mod_exec_impl(HPyContext *ctx, HPy m) -{ - HPy h_point_type = HPyType_FromSpec(ctx, &point_type_spec, NULL); - if (HPy_IsNull(h_point_type)) - return -1; - HPy_SetAttr_s(ctx, m, "Point", h_point_type); - HPy_Close(ctx, h_point_type); - return 0; -} - -static HPyDef *module_defines[] = { - &do_nothing, - &double_obj, - &add_ints, - &add_ints_kw, - &mod_exec, - NULL -}; - -static HPyModuleDef moduledef = { - .doc = "HPy Proof of Concept", - .size = 0, - .defines = module_defines -}; - -HPy_MODINIT(pof, moduledef) diff --git a/graalpython/hpy/proof-of-concept/pofcpp.cpp b/graalpython/hpy/proof-of-concept/pofcpp.cpp deleted file mode 100644 index 6214c5f87c..0000000000 --- a/graalpython/hpy/proof-of-concept/pofcpp.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "hpy.h" -#include - -HPyDef_METH(do_nothing, "do_nothing", HPyFunc_NOARGS) -static HPy do_nothing_impl(HPyContext *ctx, HPy self) -{ - return HPy_Dup(ctx, ctx->h_None); -} - -HPyDef_METH(double_obj, "double", HPyFunc_O) -static HPy double_obj_impl(HPyContext *ctx, HPy self, HPy obj) -{ - return HPy_Add(ctx, obj, obj); -} - -HPyDef_METH(add_ints, "add_ints", HPyFunc_VARARGS) -static HPy add_ints_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) -{ - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} - -HPyDef_METH(add_ints_kw, "add_ints_kw", HPyFunc_KEYWORDS) -static HPy add_ints_kw_impl(HPyContext *ctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames) -{ - long a, b; - const char* kwlist[] = {"a", "b", NULL}; - if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", - kwlist, &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a+b); -} - -typedef struct { - double x; - double y; -} PointObject; - -HPyType_HELPERS(PointObject) - -HPyDef_SLOT(Point_new, HPy_tp_new) -static HPy Point_new_impl (HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kwnames) -{ - double x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "dd", &x, &y)) - return HPy_NULL; - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = x; - point->y = y; - return h_point; -} - -HPyDef_SLOT(Point_repr, HPy_tp_repr) -static HPy Point_repr_impl(HPyContext *ctx, HPy self) -{ - PointObject *point = PointObject_AsStruct(ctx, self); - char msg[256]; - snprintf(msg, 256, "Point(%g, %g)", point->x, point->y); - return HPyUnicode_FromString(ctx, msg); - //return HPyUnicode_FromFormat("Point(%g, %g)", point->x, point->y); -} - - -static HPyDef *point_type_defines[] = { - &Point_new, - &Point_repr, - NULL -}; - -static HPyType_Spec point_type_spec = { - .name = "pofcpp.Point", - .basicsize = sizeof(PointObject), - .flags = HPy_TPFLAGS_DEFAULT, - .defines = point_type_defines -}; - -HPyDef_SLOT(mod_exec, HPy_mod_exec) -static int mod_exec_impl(HPyContext *ctx, HPy m) -{ - HPy h_point_type = HPyType_FromSpec(ctx, &point_type_spec, NULL); - if (HPy_IsNull(h_point_type)) - return -1; - HPy_SetAttr_s(ctx, m, "Point", h_point_type); - HPy_Close(ctx, h_point_type); - return 0; -} - -static HPyDef *module_defines[] = { - &do_nothing, - &double_obj, - &add_ints, - &add_ints_kw, - &mod_exec, - NULL -}; -static HPyModuleDef moduledef = { - .doc = "HPy c++ Proof of Concept", - .size = 0, - .defines = module_defines -}; - -#ifdef __cplusplus -extern "C" { -#endif - -HPy_MODINIT(pofcpp, moduledef) - -#ifdef __cplusplus -} -#endif diff --git a/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp b/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp deleted file mode 100644 index 01726d2d6f..0000000000 --- a/graalpython/hpy/proof-of-concept/pofpackage/bar.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "hpy.h" - -class Bar -{ - int foo; - public: - Bar(int f) - { - foo = f; - } - - int boo(HPyContext *ctx, HPy obj) - { - return foo + HPyLong_AsLong(ctx, obj); - } -}; - -HPyDef_METH(hello, "hello", HPyFunc_O) -static HPy hello_impl(HPyContext *ctx, HPy self, HPy obj) -{ - Bar b(21); - return HPyLong_FromLong(ctx, b.boo(ctx, obj)); -} - - -static HPyDef *module_defines[] = { - &hello, - NULL -}; -static HPyModuleDef moduledef = { - .doc = "HPy C++ Proof of Concept", - .size = 0, - .defines = module_defines -}; - -#ifdef __cplusplus -extern "C" { -#endif - - -HPy_MODINIT(bar, moduledef) - -#ifdef __cplusplus -} -#endif diff --git a/graalpython/hpy/proof-of-concept/pofpackage/foo.c b/graalpython/hpy/proof-of-concept/pofpackage/foo.c deleted file mode 100644 index 3a265efa25..0000000000 --- a/graalpython/hpy/proof-of-concept/pofpackage/foo.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "hpy.h" - -HPyDef_METH(hello, "hello", HPyFunc_NOARGS) -static HPy hello_impl(HPyContext *ctx, HPy self) -{ - return HPyUnicode_FromString(ctx, "hello from pofpackage.foo"); -} - - -static HPyDef *module_defines[] = { - &hello, - NULL -}; -static HPyModuleDef moduledef = { - .doc = "HPy Proof of Concept", - .size = 0, - .defines = module_defines -}; - -HPy_MODINIT(foo, moduledef) diff --git a/graalpython/hpy/proof-of-concept/requirements.txt b/graalpython/hpy/proof-of-concept/requirements.txt deleted file mode 100644 index 2009c86f18..0000000000 --- a/graalpython/hpy/proof-of-concept/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -hpy diff --git a/graalpython/hpy/proof-of-concept/setup.py b/graalpython/hpy/proof-of-concept/setup.py deleted file mode 100644 index 8132e1f2dc..0000000000 --- a/graalpython/hpy/proof-of-concept/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -from setuptools import setup, Extension -import platform - -cpp_compile_extra_args = [] - -if platform.system() == "Windows": - compile_extra_args = ['/WX'] - cpp_compile_extra_args = [ - "/std:c++latest", # MSVC C7555 - ] -else: - compile_extra_args = ['-Werror'] - - -setup( - name="hpy-pof", - packages = ['pofpackage'], - zip_safe=False, - hpy_ext_modules=[ - Extension('pof', - sources=['pof.c'], - extra_compile_args=compile_extra_args), - Extension('pofpackage.foo', - sources=['pofpackage/foo.c'], - extra_compile_args=compile_extra_args), - Extension('pofcpp', - sources=['pofcpp.cpp'], - language='C++', - extra_compile_args=compile_extra_args + cpp_compile_extra_args), - Extension('pofpackage.bar', - sources=['pofpackage/bar.cpp'], - language='C++', - extra_compile_args=compile_extra_args + cpp_compile_extra_args), - ], - setup_requires=['hpy'], -) diff --git a/graalpython/hpy/proof-of-concept/test_pof.py b/graalpython/hpy/proof-of-concept/test_pof.py deleted file mode 100644 index 54c6851c3f..0000000000 --- a/graalpython/hpy/proof-of-concept/test_pof.py +++ /dev/null @@ -1,44 +0,0 @@ -import pof -import pofpackage.foo -import pofcpp -import pofpackage.bar - -def test_do_nothing(): - assert pof.do_nothing() is None - -def test_double(): - assert pof.double(21) == 42 - -def test_add_ints(): - assert pof.add_ints(30, 12) == 42 - -def test_add_ints_kw(): - assert pof.add_ints_kw(b=30, a=12) == 42 - -def test_point(): - p = pof.Point(1, 2) - assert repr(p) == 'Point(1, 2)' # fixme when we have HPyFloat_FromDouble - -def test_pofpackage(): - assert pofpackage.foo.__name__ == "pofpackage.foo" - assert pofpackage.foo.hello() == 'hello from pofpackage.foo' - -def test_cpp_do_nothing(): - assert pofcpp.do_nothing() is None - -def test_cpp_double(): - assert pofcpp.double(21) == 42 - -def test_cpp_add_ints(): - assert pofcpp.add_ints(30, 12) == 42 - -def test_cpp_add_ints_kw(): - assert pofcpp.add_ints_kw(b=30, a=12) == 42 - -def test_cpp_point(): - p = pofcpp.Point(1, 2) - assert repr(p) == 'Point(1, 2)' # fixme when we have HPyFloat_FromDouble - -def test_cpp_pofpackage(): - assert pofpackage.bar.__name__ == "pofpackage.bar" - assert pofpackage.bar.hello(21) == 42 diff --git a/graalpython/hpy/proof-of-concept/test_pof.sh b/graalpython/hpy/proof-of-concept/test_pof.sh deleted file mode 100755 index 1ac800769c..0000000000 --- a/graalpython/hpy/proof-of-concept/test_pof.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash -set -e -ROOT=`pwd` # we expect this script to be run from the repo root - -# Allow the caller to override the Python runtime used -PYTHON=${PYTHON:-python3} - -_install_hpy() { - echo "Installing hpy" - # at the moment this install hpy.devel and hpy.universal. Eventually, we - # will want to split those into two separate packages - local PYTHON="$1" - pushd ${ROOT} - ${PYTHON} -m pip install -U pip - ${PYTHON} -m pip install wheel - ${PYTHON} -m pip install . - popd -} - -_test_pof() { - echo "==== testing pof ====" - # this assumes that pof is already installed, e.g. after calling - # wheel or setup_py_install - ${PYTHON} -m pip install pytest pytest-azurepipelines - cd proof-of-concept - ${PYTHON} -m pytest -} - -_build_wheel() { - HPY_ABI="$1" - local VENV="venv/wheel_builder_$HPY_ABI" - # we use this venv just to build the wheel, and then we install the wheel - # in the currently active virtualenv - echo "Create venv: $VENV" - ${PYTHON} -m venv "$VENV" - local PY_BUILDER="`pwd`/$VENV/bin/python3" - if [ -x "`pwd`/$VENV/Scripts/python.exe" ] - then - # Set the correct python executable for Windows - PY_BUILDER="`pwd`/$VENV/Scripts/python.exe" - fi - echo - echo "Installing hpy and requirements" - _install_hpy ${PY_BUILDER} - pushd proof-of-concept - ${PY_BUILDER} -m pip install -r requirements.txt - echo - echo "Building wheel" - ${PY_BUILDER} setup.py --hpy-abi="$HPY_ABI" bdist_wheel - popd -} - -_myrm() { - for path in "$@" - do - if [ -d "$path" -o -f "$path" ] - then - echo "rm $path" - rm -rf "$path" - else - echo "skipping $path" - fi - done -} - -clean() { - echo "=== cleaning up old stuff ===" - _myrm ${ROOT}/venv/wheel_builder_{cpython,universal} - _myrm ${ROOT}/venv/wheel_runner_{cpython,universal} - _myrm ${ROOT}/venv/setup_py_install_{cpython,universal} - _myrm ${ROOT}/venv/setup_py_build_ext_inplace_{cpython,universal} - _myrm ${ROOT}/build - _myrm ${ROOT}/proof-of-concept/build - _myrm ${ROOT}/proof-of-concept/dist - # remove files written by build_ext --inplace - _myrm ${ROOT}/proof-of-concept/pof*{.so,.py} - _myrm ${ROOT}/proof-of-concept/pofpackage/foo*{.so,.py} - _myrm ${ROOT}/proof-of-concept/pofcpp*{.so,.py} - _myrm ${ROOT}/proof-of-concept/pofpackage/bar*{.so,.py} - echo -} - -wheel() { - # build a wheel, install and test - HPY_ABI="$1" - local VENV="venv/wheel_runner_$HPY_ABI" - clean - echo "=== testing setup.py bdist_wheel" $HPY_ABI "===" - _build_wheel "$HPY_ABI" - WHEEL=`ls proof-of-concept/dist/*.whl` - echo "Wheel created: ${WHEEL}" - echo - echo "Create venv: $VENV" - ${PYTHON} -m venv "$VENV" - if [ -e "$VENV/bin/activate" ] ; then - source "$VENV/bin/activate" - else - source "$VENV/Scripts/activate" - fi - _install_hpy ${PYTHON} - echo "Installing wheel" - ${PYTHON} -m pip install $WHEEL - echo - _test_pof -} - -setup_py_install() { - # install proof-of-concept using setup.py install and run tests - HPY_ABI="$1" - VENV="venv/setup_py_install_$HPY_ABI" - clean - echo "=== testing setup.py --hpy-abi=$HPY_ABI install ===" - echo "Create venv: $VENV" - ${PYTHON} -m venv "$VENV" - if [ -e "$VENV/bin/activate" ] ; then - source "$VENV/bin/activate" - else - source "$VENV/Scripts/activate" - fi - _install_hpy ${PYTHON} - echo - echo "Running setup.py" - pushd proof-of-concept - ${PYTHON} setup.py --hpy-abi="$HPY_ABI" install - popd - echo - _test_pof -} - -setup_py_build_ext_inplace() { - # install proof-of-concept using setup.py install and run tests - HPY_ABI="$1" - VENV="venv/setup_py_build_ext_inplace_$HPY_ABI" - clean - echo "=== testing setup.py --hpy-abi=$HPY_ABI build_ext --inplace ===" - echo "Create venv: $VENV" - ${PYTHON} -m venv "$VENV" - if [ -e "$VENV/bin/activate" ] ; then - source "$VENV/bin/activate" - else - source "$VENV/Scripts/activate" - fi - _install_hpy ${PYTHON} - echo - echo "Running setup.py" - pushd proof-of-concept - echo python is $(which ${PYTHON}) - ${PYTHON} setup.py --hpy-abi="$HPY_ABI" build_ext --inplace - popd - echo - _test_pof -} - -# ======== main code ======= - -# validate arguments -if [[ "$#" -lt 1 || ( "$#" -lt 2 && "$1" != "clean") ]]; then - echo "Usage: $0 COMMAND [TARGET_ABI]" >&2 - echo "Commands:" >&2 - echo " wheel TARGET_ABI: build a wheel, install and test" - echo " setup_py_install TARGET_ABI: install poc using 'setup.py install' & run tests" >&2 - echo " clean: clean build artifacts" >&2 - echo "Target ABIs:" >&2 - echo " universal: Binary intended for any Python implementation" >&2 - echo " cpython : Binary optimized for CPython" >&2 - exit 1 -fi - -if [ ! -d "proof-of-concept" ] ; then - echo "Script must be run in the repo root" >&2 - exit 1 -fi - -# call the function mentioned as the first arg -COMMAND="$1" -shift -$COMMAND "$@" diff --git a/graalpython/hpy/pyproject.toml b/graalpython/hpy/pyproject.toml deleted file mode 100644 index a9b7082776..0000000000 --- a/graalpython/hpy/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build-system] -requires = [ "setuptools==80.9.0", "setuptools-scm[toml]==8.3.1", "wheel==0.45.1",] -build-backend = "setuptools.build_meta" diff --git a/graalpython/hpy/requirements-autogen.txt b/graalpython/hpy/requirements-autogen.txt deleted file mode 100644 index 320fc259c8..0000000000 --- a/graalpython/hpy/requirements-autogen.txt +++ /dev/null @@ -1,3 +0,0 @@ -pycparser==2.21 -packaging==25.0 -attrs==23.2.0 diff --git a/graalpython/hpy/setup.py b/graalpython/hpy/setup.py deleted file mode 100644 index 09dda3c4ec..0000000000 --- a/graalpython/hpy/setup.py +++ /dev/null @@ -1,269 +0,0 @@ -import sys -import os.path -from setuptools import setup, Extension -from setuptools.command.build_clib import build_clib -import platform - -# this package is supposed to be installed ONLY on CPython and GraalPy. Try to -# bail out with a meaningful error message in other cases. -if sys.implementation.name not in ('cpython', 'graalpy'): - msg = 'ERROR: Cannot install and/or update hpy on this python implementation:\n' - msg += f' sys.implementation.name == {sys.implementation.name!r}\n\n' - if '_hpy_universal' in sys.builtin_module_names: - # this is a python which comes with its own hpy implementation - import _hpy_universal - if hasattr(_hpy_universal, 'get_version'): - hpy_version, git_rev = _hpy_universal.get_version() - msg += f'This python implementation comes with its own version of hpy=={hpy_version}\n' - msg += '\n' - msg += 'If you are trying to install hpy through pip, consider to put the\n' - msg += 'following in your requirements.txt, to make sure that pip will NOT\n' - msg += 'try to re-install it:\n' - msg += f' hpy=={hpy_version}' - else: - msg += 'This python implementation comes with its own version of hpy,\n' - msg += 'but the exact version could not be determined.\n' - # - else: - # this seems to be a python which does not support hpy - msg += 'This python implementation does not seem to support hpy:\n' - msg += '(built-in module _hpy_universal not found).\n' - msg += 'Please contact your vendor for more information.' - sys.exit(msg) - - -this_directory = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f: - LONG_DESCRIPTION = f.read() - -if 'HPY_DEBUG_BUILD' in os.environ: - # -fkeep-inline-functions is needed to make sure that the stubs for HPy_* - # functions are available to call inside GDB - EXTRA_COMPILE_ARGS = [ - '-g', '-O0', '-UNDEBUG', - '-fkeep-inline-functions', - # - ## these flags are useful but don't work on all - ## platforms/compilers. Uncomment temporarily if you need them. - #'-Wfatal-errors', # stop after one error (unrelated to warnings) - #'-Werror', # turn warnings into errors - ] -else: - EXTRA_COMPILE_ARGS = [] - -if '_HPY_DEBUG_FORCE_DEFAULT_MEM_PROTECT' not in os.environ: - EXTRA_COMPILE_ARGS += ['-D_HPY_DEBUG_MEM_PROTECT_USEMMAP'] - -if platform.system() == "Windows": - EXTRA_COMPILE_ARGS += ['/WX'] -else: - EXTRA_COMPILE_ARGS += ['-Werror'] - - -def get_scm_config(): - """ - We use this function as a hook to generate version.h before building. - """ - import textwrap - import subprocess - import pathlib - import setuptools_scm - - version = setuptools_scm.get_version() - try: - gitrev = subprocess.check_output('git rev-parse --short HEAD'.split(), - encoding='utf-8') - gitrev = gitrev.strip() - except subprocess.CalledProcessError: - gitrev = "__UNKNOWN__" - - version_h = pathlib.Path('.').joinpath('hpy', 'devel', 'include', 'hpy', 'version.h') - version_h.write_text(textwrap.dedent(f""" - // automatically generated by setup.py:get_scm_config() - #define HPY_VERSION "{version}" - #define HPY_GIT_REVISION "{gitrev}" - """)) - - version_py = pathlib.Path('.').joinpath('hpy', 'devel', 'version.py') - version_py.write_text(textwrap.dedent(f""" - # automatically generated by setup.py:get_scm_config() - __version__ = "{version}" - __git_revision__ = "{gitrev}" - """)) - - return {} # use the default config - -HPY_EXTRA_SOURCES = [ - 'hpy/devel/src/runtime/argparse.c', - 'hpy/devel/src/runtime/buildvalue.c', - 'hpy/devel/src/runtime/format.c', - 'hpy/devel/src/runtime/helpers.c', - 'hpy/devel/src/runtime/structseq.c', -] - -HPY_CTX_SOURCES = [ - 'hpy/devel/src/runtime/ctx_bytes.c', - 'hpy/devel/src/runtime/ctx_call.c', - 'hpy/devel/src/runtime/ctx_capsule.c', - 'hpy/devel/src/runtime/ctx_err.c', - 'hpy/devel/src/runtime/ctx_eval.c', - 'hpy/devel/src/runtime/ctx_long.c', - 'hpy/devel/src/runtime/ctx_module.c', - 'hpy/devel/src/runtime/ctx_object.c', - 'hpy/devel/src/runtime/ctx_type.c', - 'hpy/devel/src/runtime/ctx_tracker.c', - 'hpy/devel/src/runtime/ctx_listbuilder.c', - 'hpy/devel/src/runtime/ctx_tuple.c', - 'hpy/devel/src/runtime/ctx_tuplebuilder.c', - 'hpy/devel/src/runtime/ctx_contextvar.c', -] - -HPY_INCLUDE_DIRS = [ - 'hpy/devel/include', - 'hpy/universal/src', - 'hpy/debug/src/include', - 'hpy/trace/src/include', -] - -HPY_EXTRA_UNIVERSAL_LIB_NAME = "hpy-extra-universal" -HPY_EXTRA_HYBRID_LIB_NAME = "hpy-extra-hybrid" -HPY_CTX_LIB_NAME = "hpy-ctx-cpython" - -HPY_BUILD_CLIB_ABI_ATTR = "hpy_abi" - -class build_clib_hpy(build_clib): - """ Special build_clib command for building HPy's static libraries defined - by 'STATIC_LIBS' below. The behavior differs in following points: - (1) Option 'force' is set such that static libs will always be renewed. - (2) Method 'get_library_names' always returns 'None'. This is because - we only use this command to build static libraries for testing. - That means, we only use them in-place. We don't need them for - linking here. - (3) This command consumes a custom build info key - HPY_BUILD_CLIB_ABI_ATTR that is used to create separate build - temp directories for each ABI. This is necessary to avoid - incorrect sharing of (temporary) build artifacts. - (4) This command will use the include directories from command - 'build_ext'. - """ - def finalize_options(self): - super().finalize_options() - # we overwrite the include dirs and use the ones from 'build_ext' - build_ext_includes = self.get_finalized_command('build_ext').include_dirs or [] - self.include_dirs = HPY_INCLUDE_DIRS + build_ext_includes - self.force = 1 - - def get_library_names(self): - # We only build static libraries for testing. We just use them - # in-place. We don't want that our extensions (i.e. 'hpy.universal' - # etc) link to these libs. - return None - - def build_libraries(self, libraries): - # we just inherit the 'inplace' option from 'build_ext' - build_ext = self.get_finalized_command('build_ext') - inplace = build_ext.inplace - if inplace: - # the inplace option requires to find the package directory - # using the build_py command for that - build_py = self.get_finalized_command('build_py') - lib_dir = os.path.abspath(build_py.get_package_dir('hpy.devel')) - else: - lib_dir = os.path.join(build_ext.build_lib, 'hpy', 'devel') - - import pathlib - for lib in libraries: - lib_name, build_info = lib - abi = build_info.get(HPY_BUILD_CLIB_ABI_ATTR) - # Call super's build_libraries with just one library in the list - # such that we can temporarily change the 'build_temp'. - orig_build_temp = self.build_temp - orig_build_clib = self.build_clib - self.build_temp = os.path.join(orig_build_temp, 'lib', abi) - self.build_clib = os.path.join(lib_dir, 'lib', abi) - # ensure that 'build_clib' directory exists - pathlib.Path(self.build_clib).mkdir(parents=True, exist_ok=True) - try: - super().build_libraries([lib]) - finally: - self.build_temp = orig_build_temp - self.build_clib = orig_build_clib - - -STATIC_LIBS = [(HPY_EXTRA_UNIVERSAL_LIB_NAME, - {'sources': HPY_EXTRA_SOURCES, - HPY_BUILD_CLIB_ABI_ATTR: 'universal', - 'macros': [('HPY_ABI_UNIVERSAL', None)]}), - (HPY_EXTRA_HYBRID_LIB_NAME, - {'sources': HPY_EXTRA_SOURCES, - HPY_BUILD_CLIB_ABI_ATTR: 'hybrid', - 'macros': [('HPY_ABI_HYBRID', None)]}), - (HPY_CTX_LIB_NAME, - {'sources': HPY_EXTRA_SOURCES + HPY_CTX_SOURCES, - HPY_BUILD_CLIB_ABI_ATTR: 'cpython', - 'macros': [('HPY_ABI_CPYTHON', None)]})] - -EXT_MODULES = [ - Extension('hpy.universal', - ['hpy/universal/src/hpymodule.c', - 'hpy/universal/src/ctx.c', - 'hpy/universal/src/ctx_meth.c', - 'hpy/universal/src/ctx_misc.c', - 'hpy/debug/src/debug_ctx.c', - 'hpy/debug/src/debug_ctx_cpython.c', - 'hpy/debug/src/debug_handles.c', - 'hpy/debug/src/dhqueue.c', - 'hpy/debug/src/memprotect.c', - 'hpy/debug/src/stacktrace.c', - 'hpy/debug/src/_debugmod.c', - 'hpy/debug/src/autogen_debug_wrappers.c', - 'hpy/trace/src/trace_ctx.c', - 'hpy/trace/src/_tracemod.c', - 'hpy/trace/src/autogen_trace_wrappers.c', - 'hpy/trace/src/autogen_trace_func_table.c'] - + HPY_EXTRA_SOURCES - + HPY_CTX_SOURCES, - include_dirs=HPY_INCLUDE_DIRS, - extra_compile_args=[ - # so we need to enable the HYBRID ABI in order to implement - # the legacy features - '-DHPY_ABI_HYBRID', - '-DHPY_DEBUG_ENABLE_UHPY_SANITY_CHECK', - '-DHPY_EMBEDDED_MODULES', - ] + EXTRA_COMPILE_ARGS - ) - ] - -DEV_REQUIREMENTS = [ - "pytest", - "pytest-xdist", - "filelock", -] - -setup( - name="hpy", - author='The HPy team', - author_email='hpy-dev@python.org', - url='https://hpyproject.org', - license='MIT', - description='A better C API for Python', - long_description=LONG_DESCRIPTION, - long_description_content_type='text/markdown', - packages=['hpy.devel', 'hpy.debug', 'hpy.trace'], - include_package_data=True, - extras_require={ - "dev": DEV_REQUIREMENTS, - }, - libraries=STATIC_LIBS, - ext_modules=EXT_MODULES, - entry_points={ - "distutils.setup_keywords": [ - "hpy_ext_modules = hpy.devel:handle_hpy_ext_modules", - ], - }, - cmdclass={"build_clib": build_clib_hpy}, - use_scm_version=get_scm_config, - setup_requires=['setuptools_scm'], - install_requires=['setuptools==80.10.2'], - python_requires='>=3.8', -) diff --git a/graalpython/hpy/test/__init__.py b/graalpython/hpy/test/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/graalpython/hpy/test/check_py27_compat.py b/graalpython/hpy/test/check_py27_compat.py deleted file mode 100644 index 1b85bc372a..0000000000 --- a/graalpython/hpy/test/check_py27_compat.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -Some of the files in this repo are used also by PyPy tests, which run on -python2.7. - -This script tries to import all of them: it does not check any behavior, just -that they are importable and thus are not using any py3-specific syntax. - -This script assumes that pathlib and pytest are installed (because the modules -try to import them). -""" - -from __future__ import print_function -import sys -import traceback -import py - -ROOT = py.path.local(__file__).join('..', '..') -TEST_DIRS = [ROOT / 'test', ROOT / 'test' / 'debug'] - -# PyPy does NOT import these files using py2 -PY3_ONLY = ['test_support.py', - 'test_handles_invalid.py', - 'test_handles_leak.py', - 'test_builder_invalid.py'] - -def try_import(name): - try: - if isinstance(name, py.path.local): - print('Trying to import %s... ' % ROOT.bestrelpath(name), end='') - name.pyimport() - else: - print('Trying to import %s... ' % name, end='') - __import__(name) - except: - print('ERROR!') - print() - traceback.print_exc(file=sys.stdout) - print() - return False - else: - print('OK') - return True - -def try_import_hpy_devel(): - """ - To import hpy.devel we need to create an empty hpy/__init__.py, because - python2.7 does not support namespace packages. - - Return the number of failed imports. - """ - failed = 0 - init_py = ROOT.join('hpy', '__init__.py') - assert init_py.check(exists=False) - try: - init_py.write('') # create an empty __init__.py - if not try_import('hpy.devel'): - failed += 1 - finally: - init_py.remove() - return failed - -def try_import_tests(dirs): - failed = 0 - for d in dirs: - for t in d.listdir('test_*.py'): - if t.basename in PY3_ONLY: - continue - if not try_import(t): - failed += 1 - return failed - - -def main(): - if sys.version_info[:2] != (2, 7): - print('ERROR: this script should be run on top of python 2.7') - sys.exit(1) - - sys.path.insert(0, str(ROOT)) - failed = 0 - failed += try_import_hpy_devel() - failed += try_import_tests(TEST_DIRS) - print() - if failed == 0: - print('Everything ok!') - else: - print('%d failed imports :(' % failed) - sys.exit(1) - -if __name__ == '__main__': - main() diff --git a/graalpython/hpy/test/conftest.py b/graalpython/hpy/test/conftest.py deleted file mode 100644 index 01c5a61103..0000000000 --- a/graalpython/hpy/test/conftest.py +++ /dev/null @@ -1,112 +0,0 @@ -import pytest -import sys -from .support import ExtensionCompiler, DefaultExtensionTemplate,\ - PythonSubprocessRunner, HPyDebugCapture, make_hpy_abi_fixture -from pathlib import Path - -IS_VALGRIND_RUN = False - -def pytest_addoption(parser): - parser.addoption( - "--compiler-v", action="store_true", - help="Print to stdout the commands used to invoke the compiler") - parser.addoption( - "--subprocess-v", action="store_true", - help="Print to stdout the stdout and stderr of Python subprocesses " - "executed via run_python_subprocess") - parser.addoption( - "--dump-dir", - help="Enables dump mode and specifies where to write generated test " - "sources. This will then only generate the sources and skip " - "evaluation of the tests.") - parser.addoption( - '--reuse-venv', action="store_true", - help="Development only: reuse the venv for test_distutils.py instead of " - "creating a new one for every test") - - -@pytest.hookimpl(trylast=True) -def pytest_configure(config): - global IS_VALGRIND_RUN - IS_VALGRIND_RUN = config.pluginmanager.hasplugin('valgrind_checker') - config.addinivalue_line( - "markers", "syncgc: Mark tests that rely on a synchronous GC." - ) - - -def pytest_runtest_setup(item): - if any(item.iter_markers(name="syncgc")): - if sys.implementation.name in ("pypy", "graalpy"): - pytest.skip("requires synchronous garbage collector") - - -# this is the default set of hpy_abi for all the tests. Individual files and -# classes can override it. -hpy_abi = make_hpy_abi_fixture('default') - - -@pytest.fixture(scope='session') -def hpy_devel(request): - from hpy.devel import HPyDevel - return HPyDevel() - -@pytest.fixture -def leakdetector(hpy_abi): - """ - Automatically detect leaks when the hpy_abi == 'debug' - """ - from hpy.debug.leakdetector import LeakDetector - if 'debug' in hpy_abi: - with LeakDetector() as ld: - yield ld - else: - yield None - -@pytest.fixture -def ExtensionTemplate(): - return DefaultExtensionTemplate - -@pytest.fixture -def compiler(request, tmpdir, hpy_devel, hpy_abi, ExtensionTemplate): - compiler_verbose = request.config.getoption('--compiler-v') - dump_dir = request.config.getoption('--dump-dir') - if dump_dir: - # Test-specific dump dir in format: dump_dir/[mod_][cls_]func - qname_parts = [] - if request.module: - qname_parts.append(request.module.__name__) - if request.cls: - qname_parts.append(request.cls.__name__) - qname_parts.append(request.function.__name__) - test_dump_dir = "_".join(qname_parts).replace(".", "_") - dump_dir = Path(dump_dir).joinpath(test_dump_dir) - dump_dir.mkdir(parents=True, exist_ok=True) - return ExtensionCompiler(tmpdir, hpy_devel, hpy_abi, - compiler_verbose=compiler_verbose, - dump_dir=dump_dir, - ExtensionTemplate=ExtensionTemplate) - - -@pytest.fixture(scope="session") -def fatal_exit_code(request): - import sys - return { - "linux": -6, # SIGABRT - # See https://bugs.python.org/issue36116#msg336782 -- the - # return code from abort on Windows 8+ is a stack buffer overrun. - # :| - "win32": 0xC0000409, # STATUS_STACK_BUFFER_OVERRUN - }.get(sys.platform, -6) - - -@pytest.fixture -def python_subprocess(request, hpy_abi): - verbose = request.config.getoption('--subprocess-v') - yield PythonSubprocessRunner(verbose, hpy_abi) - - -@pytest.fixture() -def hpy_debug_capture(request, hpy_abi): - assert hpy_abi == 'debug' - with HPyDebugCapture() as reporter: - yield reporter diff --git a/graalpython/hpy/test/debug/__init__.py b/graalpython/hpy/test/debug/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/graalpython/hpy/test/debug/test_builder_invalid.py b/graalpython/hpy/test/debug/test_builder_invalid.py deleted file mode 100644 index ebe708c0e0..0000000000 --- a/graalpython/hpy/test/debug/test_builder_invalid.py +++ /dev/null @@ -1,148 +0,0 @@ -import pytest -from hpy.debug.leakdetector import LeakDetector - -@pytest.fixture -def hpy_abi(): - with LeakDetector(): - yield "debug" - - -def test_correct_usage(compiler, hpy_debug_capture): - # Basic sanity check that valid code does not trigger any error reports - mod = compiler.make_module(""" - HPyDef_METH(build, "build", HPyFunc_VARARGS) - static HPy build_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyTupleBuilder tbuilder = HPyTupleBuilder_New(ctx, nargs); - HPyListBuilder lbuilder = HPyListBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) { - HPyTupleBuilder_Set(ctx, tbuilder, i, args[i]); - HPyListBuilder_Set(ctx, lbuilder, i, args[i]); - } - HPy t = HPyTupleBuilder_Build(ctx, tbuilder); - HPy l = HPyListBuilder_Build(ctx, lbuilder); - HPy h_result = HPyTuple_Pack(ctx, 2, t, l); - HPy_Close(ctx, t); - HPy_Close(ctx, l); - return h_result; - } - - HPyDef_METH(cancel, "cancel", HPyFunc_VARARGS) - static HPy cancel_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyTupleBuilder tbuilder = HPyTupleBuilder_New(ctx, nargs); - HPyListBuilder lbuilder = HPyListBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) { - HPyTupleBuilder_Set(ctx, tbuilder, i, args[i]); - HPyListBuilder_Set(ctx, lbuilder, i, args[i]); - } - HPyTupleBuilder_Cancel(ctx, tbuilder); - HPyListBuilder_Cancel(ctx, lbuilder); - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(build) - @EXPORT(cancel) - @INIT - """) - assert mod.build('hello', 42, None) == (('hello', 42, None), ['hello', 42, None]) - assert mod.cancel('hello', 42, None) is None - assert hpy_debug_capture.invalid_builders_count == 0 - - -def test_build_twice(compiler, hpy_debug_capture): - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyTupleBuilder builder = HPyTupleBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyTupleBuilder_Set(ctx, builder, i, args[i]); - HPy h_result = HPyTupleBuilder_Build(ctx, builder); - HPy_Close(ctx, h_result); - return HPyTupleBuilder_Build(ctx, builder); - } - HPyDef_METH(g, "g", HPyFunc_VARARGS) - static HPy g_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyListBuilder builder = HPyListBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyListBuilder_Set(ctx, builder, i, args[i]); - HPy h_result = HPyListBuilder_Build(ctx, builder); - HPy_Close(ctx, h_result); - return HPyListBuilder_Build(ctx, builder); - } - @EXPORT(f) - @EXPORT(g) - @INIT - """) - with pytest.raises(MemoryError): - mod.f('hello', 42, None) - assert hpy_debug_capture.invalid_builders_count == 1 - with pytest.raises(MemoryError): - mod.g('hello', 42, None) - assert hpy_debug_capture.invalid_builders_count == 2 - - -def test_build_after_cancel(compiler, hpy_debug_capture): - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyTupleBuilder builder = HPyTupleBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyTupleBuilder_Set(ctx, builder, i, args[i]); - HPyTupleBuilder_Cancel(ctx, builder); - return HPyTupleBuilder_Build(ctx, builder); - } - HPyDef_METH(g, "g", HPyFunc_VARARGS) - static HPy g_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyListBuilder builder = HPyListBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyListBuilder_Set(ctx, builder, i, args[i]); - HPyListBuilder_Cancel(ctx, builder); - return HPyListBuilder_Build(ctx, builder); - } - @EXPORT(f) - @EXPORT(g) - @INIT - """) - with pytest.raises(MemoryError): - mod.f('hello', 42, None) - assert hpy_debug_capture.invalid_builders_count == 1 - with pytest.raises(MemoryError): - mod.g('hello', 42, None) - assert hpy_debug_capture.invalid_builders_count == 2 - - -def test_build_cancel_after_build(compiler, hpy_debug_capture): - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyTupleBuilder builder = HPyTupleBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyTupleBuilder_Set(ctx, builder, i, args[i]); - HPy h_result = HPyTupleBuilder_Build(ctx, builder); - HPyTupleBuilder_Cancel(ctx, builder); - HPy_Close(ctx, h_result); - return HPy_Dup(ctx, ctx->h_None); - } - HPyDef_METH(g, "g", HPyFunc_VARARGS) - static HPy g_impl(HPyContext *ctx, HPy h_self, const HPy *args, size_t nargs) - { - HPyListBuilder builder = HPyListBuilder_New(ctx, nargs); - for (size_t i=0; i < nargs; i++) - HPyListBuilder_Set(ctx, builder, i, args[i]); - HPy h_result = HPyListBuilder_Build(ctx, builder); - HPyListBuilder_Cancel(ctx, builder); - HPy_Close(ctx, h_result); - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @EXPORT(g) - @INIT - """) - mod.f('hello', 42, None) - mod.g('hello', 42, None) - assert hpy_debug_capture.invalid_builders_count == 2 diff --git a/graalpython/hpy/test/debug/test_charptr.py b/graalpython/hpy/test/debug/test_charptr.py deleted file mode 100644 index cc1fb9406f..0000000000 --- a/graalpython/hpy/test/debug/test_charptr.py +++ /dev/null @@ -1,300 +0,0 @@ -import os -import pytest -import sys -from ..support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, IS_GRAALPY - -# Tests detection of usage of char pointers associated with invalid already -# closed handles. For now, the debug mode does not provide any hook for this -# error, so we have to run the tests from subprocess and check the return code. - -@pytest.fixture -def hpy_abi(): - from hpy.debug import LeakDetector - with LeakDetector(): - yield "debug" - - -@pytest.mark.skipif(IS_GRAALPY, reason="fails on GraalPy") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_charptr_use_after_implicit_arg_handle_close(compiler, python_subprocess): - mod = compiler.compile_module(""" - const char *keep; - - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t n) - { - if (n != 2) { - HPyErr_SetString(ctx, ctx->h_ValueError, "expected exactly two arguments"); - return HPy_NULL; - } - long mode = HPyLong_AsLong(ctx, args[1]); - if (mode == -1) - return HPy_NULL; - - HPy_ssize_t size; - if (mode == 0) { - keep = HPyUnicode_AsUTF8AndSize(ctx, args[0], &size); - } else if (mode == 1) { - keep = HPyBytes_AsString(ctx, args[0]); - } else if (mode == 2) { - keep = HPyBytes_AS_STRING(ctx, args[0]); - } else { - HPyErr_SetString(ctx, ctx->h_ValueError, "invalid mode"); - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(g, "g", HPyFunc_NOARGS) - static HPy g_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, keep); - } - - @EXPORT(f) - @EXPORT(g) - @INIT - """) - content = "'use after close me!'" - bcontent = 'b' + content - for mode, msg in enumerate((content, bcontent, bcontent)): - if SUPPORTS_MEM_PROTECTION and False: - code = "mod.f({}, {}); mod.g()".format(msg, mode) - else: - code = "mod.f({0}, {1}); assert mod.g() == str({0})".format(msg, mode) - result = python_subprocess.run(mod, code) - assert result.returncode != 0 - assert result.stdout == b"" - if SUPPORTS_MEM_PROTECTION: - assert result.stderr == b"" - else: - # The garbage we override the data with will cause this error - assert b"UnicodeDecodeError" in result.stderr - - -@pytest.mark.skipif(IS_GRAALPY, reason="fails on GraalPy") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_charptr_use_after_handle_close(compiler, python_subprocess): - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t n) - { - if (n != 2) { - HPyErr_SetString(ctx, ctx->h_ValueError, "expected exactly two arguments"); - return HPy_NULL; - } - long mode = HPyLong_AsLong(ctx, args[1]); - if (mode == -1) - return HPy_NULL; - - HPy arg_dup = HPy_Dup(ctx, args[0]); - HPy_ssize_t size; - const char *keep; - if (mode == 0) { - keep = HPyUnicode_AsUTF8AndSize(ctx, arg_dup, &size); - } else if (mode == 1) { - keep = HPyBytes_AsString(ctx, arg_dup); - } else if (mode == 2) { - keep = HPyBytes_AS_STRING(ctx, arg_dup); - } else { - HPyErr_SetString(ctx, ctx->h_ValueError, "invalid mode"); - return HPy_NULL; - } - HPy_Close(ctx, arg_dup); - return HPyUnicode_FromString(ctx, keep); - } - - @EXPORT(f) - @INIT - """) - content = "'use after close me!'" - bcontent = "b" + content - for mode, msg in enumerate((content, bcontent, bcontent)): - if SUPPORTS_MEM_PROTECTION: - code = "mod.f({}, {})".format(msg, mode) - else: - code = "assert mod.f({0}, {1}) == str({0})".format(msg, mode) - result = python_subprocess.run(mod, code) - assert result.returncode != 0 - assert result.stdout == b"" - if SUPPORTS_MEM_PROTECTION: - assert result.stderr == b"" - else: - # The garbage we override the data with will cause this error - assert b"UnicodeDecodeError" in result.stderr - - -@pytest.mark.skipif(IS_GRAALPY, reason="transiently fails on GraalPy") -@pytest.mark.skipif(not SUPPORTS_MEM_PROTECTION, reason= - "Could be implemented by checking the contents on close.") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_charptr_write_ptr(compiler, python_subprocess): - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t n) - { - if (n != 2) { - HPyErr_SetString(ctx, ctx->h_ValueError, "expected exactly two arguments"); - return HPy_NULL; - } - long mode = HPyLong_AsLong(ctx, args[1]); - if (mode == -1) - return HPy_NULL; - - HPy_ssize_t size; - char *data; - if (mode == 0) { - data = (char *)HPyUnicode_AsUTF8AndSize(ctx, args[0], &size); - } else if (mode == 1) { - data = (char *)HPyBytes_AsString(ctx, args[0]); - } else if (mode == 2) { - data = (char *)HPyBytes_AS_STRING(ctx, args[0]); - } else { - HPyErr_SetString(ctx, ctx->h_ValueError, "invalid mode"); - return HPy_NULL; - } - // write to read-only memory - data[0] = 'a'; - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @INIT - """) - content = "'try writing me!'" - bcontent = "b" + content - for mode, msg in enumerate((content, bcontent, bcontent)): - result = python_subprocess.run(mod, "mod.f({}, {});".format(msg, mode)) - assert result.returncode != 0 - assert result.stdout == b"" - assert result.stderr == b"" - - -def test_charptr_correct_usage(compiler): - mod = compiler.make_module(""" - #include - #include - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy arg_dup = HPy_Dup(ctx, arg); - HPy_ssize_t size; - const char *keep = HPyUnicode_AsUTF8AndSize(ctx, arg_dup, &size); - char *copy = (char*) malloc(size + 1); - memcpy(copy, keep, size + 1); - HPy_Close(ctx, arg_dup); - HPy result = HPyUnicode_FromString(ctx, copy); - free(copy); - return result; - } - - @EXPORT(f) - @INIT - """) - assert mod.f('I wont be leaked!') == 'I wont be leaked!'; - - -def test_charptr_limit_stress_test(compiler): - from hpy.universal import _debug - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t size; - HPyUnicode_AsUTF8AndSize(ctx, arg, &size); - if (size == 0) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - // Dummy function just to force handle creation, but should not create - // any raw data attached to those handles - HPyDef_METH(g, "g", HPyFunc_O) - static HPy g_impl(HPyContext *ctx, HPy self, HPy arg) - { - int len = HPyLong_AsLong(ctx, arg); - for (int i = 0; i < len; ++i) { - HPy h = HPyLong_FromLong(ctx, i); - HPy_Close(ctx, h); - } - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @EXPORT(g) - @INIT - """) - - def get_raw_data_sizes(handles): - return list(map(lambda h: h.raw_data_size, handles)) - - def clear_raw_data_in_closed_handles(): - closed_size = len(_debug.get_closed_handles()) - old_limit = _debug.get_closed_handles_queue_max_size() - try: - # make sure that the closed_handles queue is considered full: this - # will force the reuse of existing closed handles. - _debug.set_closed_handles_queue_max_size(closed_size) - # Dummy call to force the reuse of the existing closed handles - # -2 because 'self' and the 'arg' should already reuse 2 handles - mod.g(closed_size - 2) - finally: - _debug.set_closed_handles_queue_max_size(old_limit) - return closed_size - - old_raw_data_max_size = _debug.get_protected_raw_data_max_size() - old_closed_handles_max_size = _debug.get_closed_handles_queue_max_size() - _debug.set_protected_raw_data_max_size(100) - try: - # Reset the state as much as possible: - closed_size = clear_raw_data_in_closed_handles() - # Make enough room for the handles created by this test - _debug.set_closed_handles_queue_max_size(closed_size + 100) - # Sanity check: no raw data is now held by closed handles - initial = get_raw_data_sizes(_debug.get_closed_handles()) - assert all(map(lambda x: x == -1, initial)) - - # Large string that shouldn't be retained at all - gen = _debug.new_generation() - mod.f('abc' * 50) - closed1 = get_raw_data_sizes(_debug.get_closed_handles(gen)) - assert closed1 == [-1, -1, -1] # -1 for 'self' and the return value - - # Two small strings, should be kept, one large that should not fit in - gen = _debug.new_generation() - mod.f('a' * 31) - mod.f('b' * 32) - mod.f('c' * 50) - closed2 = get_raw_data_sizes(_debug.get_closed_handles(gen)) - # -1 for 'self'/return value for each call, and the long string - # note: C strings' size is +1 for the terminating '\0' - assert sorted(closed2) == [-1] * 7 + [32, 33] - - # Another small string should still fit - gen = _debug.new_generation() - mod.f('a' * 13) - closed3 = get_raw_data_sizes(_debug.get_closed_handles(gen)) - # 'self'/return, and the expected small string - assert sorted(closed3) == [-1, -1, 14] - - # But another small-ish string not anymore - gen = _debug.new_generation() - mod.f('a' * 27) - closed4 = get_raw_data_sizes(_debug.get_closed_handles(gen)) - # 'self'/return, and the string whose raw data didn't fit in - assert sorted(closed4) == [-1, -1, -1] - - # Check that raw data of closed handles is freed when the handle - # is reused - closed_size = clear_raw_data_in_closed_handles() - - # None of the closed handles should now have any raw data attached - all_closed = _debug.get_closed_handles() - assert len(all_closed) == closed_size # Sanity check - for h in all_closed: - assert h.raw_data_size == -1 - finally: - _debug.set_protected_raw_data_max_size(old_raw_data_max_size) - _debug.set_closed_handles_queue_max_size(old_closed_handles_max_size) diff --git a/graalpython/hpy/test/debug/test_context_reuse.py b/graalpython/hpy/test/debug/test_context_reuse.py deleted file mode 100644 index 164505cf31..0000000000 --- a/graalpython/hpy/test/debug/test_context_reuse.py +++ /dev/null @@ -1,107 +0,0 @@ -import pytest -import sys - -from ..support import IS_GRAALPY - - -@pytest.fixture -def hpy_abi(): - return "debug" - - -@pytest.mark.skipif(IS_GRAALPY, reason="Hangs on GraalPy") -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" diff --git a/graalpython/hpy/test/debug/test_handles_invalid.py b/graalpython/hpy/test/debug/test_handles_invalid.py deleted file mode 100644 index 355470c088..0000000000 --- a/graalpython/hpy/test/debug/test_handles_invalid.py +++ /dev/null @@ -1,216 +0,0 @@ -import pytest -import sys -from hpy.debug.leakdetector import LeakDetector -from ..support import SUPPORTS_SYS_EXECUTABLE, IS_PYTHON_DEBUG_BUILD, IS_GRAALPY -from ..conftest import IS_VALGRIND_RUN - -@pytest.fixture -def hpy_abi(): - with LeakDetector(): - yield "debug" - - -@pytest.mark.skipif(sys.implementation.name == 'pypy', - reason="Cannot recover from use-after-close on pypy") -@pytest.mark.skipif(IS_GRAALPY, - reason="This corrupts process memory on GraalPy and crashes later") -def test_no_invalid_handle(compiler, hpy_debug_capture): - # Basic sanity check that valid code does not trigger any error reports - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy x = HPyLong_FromLong(ctx, 42); - HPy y = HPyLong_FromLong(ctx, 2); - HPy arg_dup = HPy_Dup(ctx, arg); - HPy_Close(ctx, y); - HPy b = HPy_Dup(ctx, x); - HPy_Close(ctx, x); - HPy_Close(ctx, arg_dup); - return b; - } - - @EXPORT(f) - @INIT - """) - assert mod.f("hello") == 42 - assert mod.f("world") == 42 - assert hpy_debug_capture.invalid_handles_count == 0 - - -@pytest.mark.skipif(sys.implementation.name == 'pypy', - reason="Cannot recover from use-after-close on pypy") -@pytest.mark.skipif(IS_GRAALPY, - reason="This corrupts process memory on GraalPy and crashes later") -def test_cant_use_closed_handle(compiler, hpy_debug_capture): - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O, .doc="double close") - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h = HPy_Dup(ctx, arg); - HPy_Close(ctx, h); - HPy_Close(ctx, h); // double close - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(g, "g", HPyFunc_O, .doc="use after close") - static HPy g_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h = HPy_Dup(ctx, arg); - HPy_Close(ctx, h); - return HPy_Repr(ctx, h); - } - - HPyDef_METH(h, "h", HPyFunc_O, .doc="closing argument") - static HPy h_impl(HPyContext *ctx, HPy self, HPy arg) - { - // Argument is implicitly closed by the caller - HPy_Close(ctx, arg); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(f_noargs, "f_noargs", HPyFunc_NOARGS, .doc="returns arg w/o dupping it") - static HPy f_noargs_impl(HPyContext *ctx, HPy self) - { - // should be: return HPy_Dup(ctx, self); - return self; - } - - HPyDef_METH(f0, "f0", HPyFunc_O, .doc="returns arg w/o dupping it") - static HPy f0_impl(HPyContext *ctx, HPy self, HPy arg) - { - // should be: return HPy_Dup(ctx, arg); - return arg; - } - - HPyDef_METH(f_varargs, "f_varargs", HPyFunc_VARARGS, .doc="returns arg w/o dupping it") - static HPy f_varargs_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - // should be: return HPy_Dup(ctx, args[0]); - return args[0]; - } - - @EXPORT(f) - @EXPORT(g) - @EXPORT(f0) - @EXPORT(f_noargs) - @EXPORT(f_varargs) - @EXPORT(h) - @INIT - """) - mod.f('foo') # double close - assert hpy_debug_capture.invalid_handles_count == 1 - mod.g('bar') # use-after-close - assert hpy_debug_capture.invalid_handles_count == 2 - if not IS_PYTHON_DEBUG_BUILD and not IS_VALGRIND_RUN: - # CPython debug build can also catch these errors, so we cannot trigger - # them when running on debug builds - mod.f0('foo') - assert hpy_debug_capture.invalid_handles_count == 3 - mod.f_noargs() - assert hpy_debug_capture.invalid_handles_count == 4 - mod.f_varargs('foo', 'bar') - assert hpy_debug_capture.invalid_handles_count == 5 - mod.h('baz') - assert hpy_debug_capture.invalid_handles_count == 6 - - -@pytest.mark.skipif(sys.implementation.name == 'pypy', - reason="Cannot recover from use-after-close on pypy") -@pytest.mark.skipif(IS_GRAALPY, - reason="This corrupts process memory on GraalPy and crashes later") -def test_keeping_and_reusing_argument_handle(compiler, hpy_debug_capture): - mod = compiler.make_module(""" - HPy keep; - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - keep = arg; - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(g, "g", HPyFunc_NOARGS) - static HPy g_impl(HPyContext *ctx, HPy self) - { - HPy_ssize_t len = HPy_Length(ctx, keep); - return HPyLong_FromSsize_t(ctx, len); - } - - @EXPORT(f) - @EXPORT(g) - @INIT - """) - s = "hello leaks!" - mod.f(s) - assert hpy_debug_capture.invalid_handles_count == 0 - assert mod.g() == len(s) - assert hpy_debug_capture.invalid_handles_count == 1 - - -@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") -def test_return_ctx_constant_without_dup(compiler, python_subprocess, fatal_exit_code): - # Since this puts the context->h_None into an inconsistent state, we run - # this test in a subprocess and check fatal error instead - if not SUPPORTS_SYS_EXECUTABLE: - pytest.skip("no sys.executable") - - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return ctx->h_None; - } - - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f();") - assert result.returncode == fatal_exit_code - assert b"Invalid usage of already closed handle" in result.stderr - - -@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") -def test_close_ctx_constant(compiler, python_subprocess, fatal_exit_code): - # Since this puts the context->h_True into an inconsistent state, we run - # this test in a subprocess and check fatal error instead - if not SUPPORTS_SYS_EXECUTABLE: - pytest.skip("no sys.executable") - - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPy_Close(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f();") - assert result.returncode == fatal_exit_code - assert b"Invalid usage of already closed handle" in result.stderr - - -@pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") -def test_invalid_handle_crashes_python_if_no_hook(compiler, python_subprocess, fatal_exit_code): - if not SUPPORTS_SYS_EXECUTABLE: - pytest.skip("no sys.executable") - - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_O, .doc="double close") - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h = HPy_Dup(ctx, arg); - HPy_Close(ctx, h); - HPy_Close(ctx, h); // double close - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f(42);") - assert result.returncode == fatal_exit_code - assert b"Invalid usage of already closed handle" in result.stderr diff --git a/graalpython/hpy/test/debug/test_handles_leak.py b/graalpython/hpy/test/debug/test_handles_leak.py deleted file mode 100644 index b0cca5f27a..0000000000 --- a/graalpython/hpy/test/debug/test_handles_leak.py +++ /dev/null @@ -1,280 +0,0 @@ -import pytest -from hpy.debug import set_handle_stack_trace_limit, disable_handle_stack_traces - -@pytest.fixture -def hpy_abi(): - return "debug" - - -class AllocationTraceEnabler: - def __enter__(self): - set_handle_stack_trace_limit(32) - - def __exit__(self, exc_type, exc_val, exc_tb): - disable_handle_stack_traces() - - -@pytest.fixture(params=["with stacktrace", "no stacktrace"]) -def with_alloc_trace(request): - if request.param == "with stacktrace": - with AllocationTraceEnabler(): - yield - else: - yield - - -def make_leak_module(compiler): - # for convenience - return compiler.make_module(""" - HPyDef_METH(leak, "leak", HPyFunc_O) - static HPy leak_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_Dup(ctx, arg); // leak! - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(leak) - @INIT - """) - - -def test_debug_ctx_name(compiler): - # this is very similar to the one in test_00_basic, but: - # 1. by doing the same here, we ensure that we are actually using - # the debug ctx in these tests - # 2. in pypy we run HPyTest with only hpy_abi==universal, so this - # tests something which is NOT tested by test_00_basic - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, ctx->name); - } - - @EXPORT(f) - @INIT - """) - ctx_name = mod.f() - assert ctx_name.startswith('HPy Debug Mode ABI') - -def test_get_open_handles(compiler): - from hpy.universal import _debug - mod = make_leak_module(compiler) - gen1 = _debug.new_generation() - mod.leak('hello') - mod.leak('world') - gen2 = _debug.new_generation() - mod.leak('a younger leak') - leaks1 = _debug.get_open_handles(gen1) - leaks2 = _debug.get_open_handles(gen2) - leaks1 = [dh.obj for dh in leaks1] - leaks2 = [dh.obj for dh in leaks2] - assert leaks1 == ['hello', 'world', 'a younger leak'] - assert leaks2 == ['a younger leak'] - -def test_leak_from_method(compiler): - from hpy.universal import _debug - mod = compiler.make_module(""" - HPyDef_METH(Dummy_leak, "leak", HPyFunc_O) - static HPy Dummy_leak_impl(HPyContext *ctx, HPy self, HPy arg) { - HPy_Dup(ctx, arg); // leak! - return HPy_Dup(ctx, ctx->h_None); - } - static HPyDef *Dummy_defines[] = { - &Dummy_leak, - NULL - }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .defines = Dummy_defines, - }; - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - gen = _debug.new_generation() - obj = mod.Dummy() - obj.leak("a") - leaks = [dh.obj for dh in _debug.get_open_handles(gen)] - assert leaks == ["a"] - -def test_DebugHandle_id(compiler, with_alloc_trace): - from hpy.universal import _debug - mod = make_leak_module(compiler) - gen = _debug.new_generation() - mod.leak('a') - mod.leak('b') - a1, b1 = _debug.get_open_handles(gen) - a2, b2 = _debug.get_open_handles(gen) - assert a1.obj == a2.obj == 'a' - assert b1.obj == b2.obj == 'b' - # - assert a1 is not a2 - assert b1 is not b2 - # - assert a1.id == a2.id - assert b1.id == b2.id - assert a1.id != b1.id - -def test_DebugHandle_compare(compiler): - import pytest - from hpy.universal import _debug - mod = make_leak_module(compiler) - gen = _debug.new_generation() - mod.leak('a') - mod.leak('a') - a2, a1 = _debug.get_open_handles(gen) - assert a1 != a2 # same underlying object, but different DebugHandle - # - a2_new, a1_new = _debug.get_open_handles(gen) - assert a1 is not a1_new # different objects... - assert a2 is not a2_new - assert a1 == a1_new # ...but same DebugHandle - assert a2 == a2_new - # - with pytest.raises(TypeError): - a1 < a2 - with pytest.raises(TypeError): - a1 <= a2 - with pytest.raises(TypeError): - a1 > a2 - with pytest.raises(TypeError): - a1 >= a2 - - assert not a1 == 'hello' - assert a1 != 'hello' - with pytest.raises(TypeError): - a1 < 'hello' - -def test_DebugHandle_repr(compiler, with_alloc_trace): - from hpy.universal import _debug - mod = make_leak_module(compiler) - gen = _debug.new_generation() - mod.leak('hello') - h_hello, = _debug.get_open_handles(gen) - assert repr(h_hello).startswith("" % h_hello.id) - -def test_LeakDetector(compiler): - import pytest - from hpy.debug import LeakDetector, HPyLeakError - mod = make_leak_module(compiler) - ld = LeakDetector() - ld.start() - mod.leak('hello') - with pytest.raises(HPyLeakError) as exc: - ld.stop() - assert str(exc.value).startswith('1 unclosed handle:') - # - with pytest.raises(HPyLeakError) as exc: - with LeakDetector(): - mod.leak('foo') - mod.leak('bar') - mod.leak('baz') - msg = str(exc.value) - assert msg.startswith('3 unclosed handles:') - assert 'foo' in msg - assert 'bar' in msg - assert 'baz' in msg - assert 'hello' not in msg - assert 'world' not in msg - -def test_closed_handles(compiler, with_alloc_trace): - from hpy.universal import _debug - mod = make_leak_module(compiler) - gen = _debug.new_generation() - mod.leak('hello') - h_hello, = _debug.get_open_handles(gen) - assert not h_hello.is_closed - h_hello._force_close() - assert h_hello.is_closed - assert _debug.get_open_handles(gen) == [] - assert h_hello in _debug.get_closed_handles() - assert repr(h_hello).startswith("" % h_hello.id) - -def test_closed_handles_queue_max_size(compiler): - from hpy.universal import _debug - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - old_size = _debug.get_closed_handles_queue_max_size() - try: - # by calling "f" we open and close 3 handles: 1 for self, 1 for arg - # and 1 for the result. So, every call to f() increases the size of - # closed_handles() by 3 - n1 = len(_debug.get_closed_handles()) - _debug.set_closed_handles_queue_max_size(n1+7) - assert _debug.get_closed_handles_queue_max_size() == n1+7 - # - mod.f('aaa') - n2 = len(_debug.get_closed_handles()) - assert n2 == n1+3 - # - mod.f('bbb') - n3 = len(_debug.get_closed_handles()) - assert n3 == n2+3 - # with the next call we reach the maximum size of the queue - mod.f('ccc') - n4 = len(_debug.get_closed_handles()) - assert n4 == n1+7 - # - # same as before - mod.f('ddd') - n5 = len(_debug.get_closed_handles()) - assert n5 == n1+7 - finally: - _debug.set_closed_handles_queue_max_size(old_size) - -def test_reuse_closed_handles(compiler): - from hpy.universal import _debug - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Dup(ctx, ctx->h_None); - } - HPyDef_METH(leak, "leak", HPyFunc_O) - static HPy leak_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_Dup(ctx, arg); // leak! - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @EXPORT(leak) - @INIT - """) - - old_size = _debug.get_closed_handles_queue_max_size() - try: - gen = _debug.new_generation() - # call f twice to open/closes a bunch of handles - mod.f('hello') - mod.f('world') - # - # make sure that the closed_handles queue is considered full: this - # will force the reuse of existing closed handles - _debug.set_closed_handles_queue_max_size(1) - # during the call to leak, we create handles for: - # 1. self - # 2. arg - # 3. HPy_Dup(arg) (leaking) - # 4. result - # So the leaked handle will be 3rd in the old closed_handles queue - closed_handles = _debug.get_closed_handles() - mod.leak('foo') - assert not closed_handles[2].is_closed - assert closed_handles[2].obj == 'foo' - - closed_handles = _debug.get_closed_handles() - mod.leak('bar') - assert not closed_handles[2].is_closed - assert closed_handles[2].obj == 'bar' - - leaks = _debug.get_open_handles(gen) - for h in leaks: - h._force_close() - finally: - _debug.set_closed_handles_queue_max_size(old_size) diff --git a/graalpython/hpy/test/debug/test_misc.py b/graalpython/hpy/test/debug/test_misc.py deleted file mode 100644 index 3640459798..0000000000 --- a/graalpython/hpy/test/debug/test_misc.py +++ /dev/null @@ -1,179 +0,0 @@ -import pytest -import sys -from ..support import SUPPORTS_SYS_EXECUTABLE, SUPPORTS_MEM_PROTECTION, IS_GRAALPY - -@pytest.fixture -def hpy_abi(): - return "debug" - - -@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_use_invalid_as_struct(compiler, python_subprocess): - mod = compiler.compile_module(""" - typedef struct { - int value; - } DummyObject; - HPyType_HELPERS(DummyObject, HPyType_BuiltinShape_Object) - - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .basicsize = sizeof(DummyObject), - .builtin_shape = HPyType_BuiltinShape_Type - }; - - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - DummyObject *data = DummyObject_AsStruct(ctx, arg); - return HPyLong_FromLong(ctx, data->value); - } - - @EXPORT_TYPE("Dummy", Dummy_spec) - @EXPORT(f) - @INIT - """) - code = "assert mod.f(mod.Dummy()) == 0" - result = python_subprocess.run(mod, code) - assert result.returncode != 0 - assert "Invalid usage of _HPy_AsStruct_Object" in result.stderr.decode("utf-8") - - -@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") -@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, const HPy *args, size_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") - - -@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") -@pytest.mark.skipif(not SUPPORTS_MEM_PROTECTION, reason= - "Could be implemented by checking the contents on close.") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_type_getname(compiler, python_subprocess): - mod = compiler.compile_module(""" - #define MODE_READ_ONLY 0 - #define MODE_USE_AFTER_FREE 1 - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy type; - int mode; - const char *name; - char *buffer; - - // parse arguments - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 2 arguments"); - return HPy_NULL; - } - mode = HPyLong_AsLong(ctx, args[0]); - if (mode < 0) { - HPyErr_Clear(ctx); - HPyErr_SetString(ctx, ctx->h_ValueError, "invalid test mode"); - return HPy_NULL; - } - type = mode == 1 ? HPy_Dup(ctx, args[1]) : args[1]; - - name = HPyType_GetName(ctx, type); - if (name == NULL) - return HPy_NULL; - - switch (mode) { - case MODE_READ_ONLY: - // write to read-only memory - buffer = (char *)name; - buffer[0] = 'h'; - break; - case MODE_USE_AFTER_FREE: - // will cause use after handle was closed - HPy_Close(ctx, type); - break; - } - return HPyUnicode_FromString(ctx, name); - } - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f(0, 'hello')") - assert result.returncode != 0 - assert "HPyType_GetName arg must be a type" in result.stderr.decode("utf-8") - - result = python_subprocess.run(mod, "mod.f(0, str)") - assert result.returncode != 0 - - result = python_subprocess.run(mod, "mod.f(1, str)") - assert result.returncode != 0 - - -@pytest.mark.skipif(IS_GRAALPY, reason="hangs on GraalPy") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_type_issubtype(compiler, python_subprocess): - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 2 arguments"); - return HPy_NULL; - } - return HPyLong_FromLong(ctx, HPyType_IsSubtype(ctx, args[0], args[1])); - } - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f(bool, 'hello')") - assert result.returncode != 0 - assert "HPyType_IsSubtype arg 2 must be a type" in result.stderr.decode("utf-8") - - result = python_subprocess.run(mod, "mod.f('hello', str)") - assert result.returncode != 0 - assert "HPyType_IsSubtype arg 1 must be a type" in result.stderr.decode("utf-8") - - -@pytest.mark.skipif(IS_GRAALPY, reason="transiently fails on GraalPy") -@pytest.mark.skipif(not SUPPORTS_SYS_EXECUTABLE, reason="needs subprocess") -def test_unicode_substring(compiler, python_subprocess): - mod = compiler.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy_ssize_t start, end; - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 3 arguments"); - return HPy_NULL; - } - - start = HPyLong_AsSsize_t(ctx, args[1]); - if (start == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - - end = HPyLong_AsSsize_t(ctx, args[2]); - if (end == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - - return HPyUnicode_Substring(ctx, args[0], start, end); - } - @EXPORT(f) - @INIT - """) - result = python_subprocess.run(mod, "mod.f(b'hello', 2, 3)") - assert result.returncode != 0 - assert "HPyUnicode_Substring arg 1 must be a Unicode object" in result.stderr.decode("utf-8") diff --git a/graalpython/hpy/test/hpy_devel/__init__.py b/graalpython/hpy/test/hpy_devel/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/graalpython/hpy/test/hpy_devel/test_abitag.py b/graalpython/hpy/test/hpy_devel/test_abitag.py deleted file mode 100644 index 819763891b..0000000000 --- a/graalpython/hpy/test/hpy_devel/test_abitag.py +++ /dev/null @@ -1,25 +0,0 @@ -from hpy.devel.abitag import parse_ext_suffix, get_hpy_ext_suffix, HPY_ABI_TAG - -def test_parse_ext_suffix_ext(): - _, ext = parse_ext_suffix('.cpython-310-x86_64-linux-gnu.so') - assert ext == 'so' - -def test_parse_ext_suffix_abi_tag(): - def abi_tag(suffix): - tag, ext = parse_ext_suffix(suffix) - return tag - - assert abi_tag('.cpython-38-x86_64-linux-gnu.so') == 'cp38' - assert abi_tag('.cpython-38d-x86_64-linux-gnu.so') == 'cp38d' - assert abi_tag('.cpython-310-x86_64-linux-gnu.so') == 'cp310' - assert abi_tag('.cpython-310d-x86_64-linux-gnu.so') == 'cp310d' - assert abi_tag('.cpython-310-darwin.so') == 'cp310' - assert abi_tag('.cp310-win_amd64.pyd') == 'cp310' - assert abi_tag('.pypy38-pp73-x86_64-linux-gnu.so') == 'pypy38-pp73' - assert abi_tag('.graalpy-38-native-x86_64-darwin.dylib') == 'graalpy-38-native' - -def test_get_hpy_ext_suffix(): - get = get_hpy_ext_suffix - hpy0 = HPY_ABI_TAG - assert get('universal', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}.so' - assert get('hybrid', '.cpython-38-x86_64-linux-gnu.so') == f'.{hpy0}-cp38.so' diff --git a/graalpython/hpy/test/hpy_devel/test_distutils.py b/graalpython/hpy/test/hpy_devel/test_distutils.py deleted file mode 100644 index 62904f0957..0000000000 --- a/graalpython/hpy/test/hpy_devel/test_distutils.py +++ /dev/null @@ -1,364 +0,0 @@ -""" -Test the hpy+distutils integration. Most of the relevant code is in -hpy/devel/__init__.py. - -Note that this is a different kind of test than the majority of the other -files in this directory, which all inherit from HPyTest and test the API -itself. -""" - -import sys -import os -import textwrap -import subprocess -import shutil -import venv -import py -import pytest - -from ..support import atomic_run, HPY_ROOT, IS_GRAALPY - -# ====== IMPORTANT DEVELOPMENT TIP ===== -# You can use py.test --reuse-venv to speed up local testing. -# -# The env is created once in /tmp/venv-for-hpytest and reused among tests and -# sessions. If you want to recreate it, simply rm -r /tmp/venv-for-hpytest - -def print_CalledProcessError(p): - """ - Print all information about a CalledProcessError - """ - print('========== subprocess failed ==========') - print('command:', ' '.join(p.cmd)) - print('argv: ', p.cmd) - print('return code:', p.returncode) - print() - print('---------- ----------') - print(p.stdout.decode('latin-1')) - print('---------- ---------') - print() - print('---------- ----------') - print(p.stderr.decode('latin-1')) - print('---------- ---------') - -@pytest.fixture(scope='session') -def venv_template(request, tmpdir_factory): - if getattr(request.config.option, "reuse_venv", False): - d = py.path.local('/tmp/venv-for-hpytest') - if d.check(dir=True): - # if it exists, we assume it's correct. If you want to recreate, - # just manually delete /tmp/venv-for-hpytest - return d - else: - d = tmpdir_factory.mktemp('venv') - - venv.create(d, with_pip=True) - - # remove the scripts: they contains a shebang and it will fail subtly - # after we clone the template. Yes, we could try to fix the shebangs, but - # it's just easier to use e.g. python -m pip - attach_python_to_venv(d) - for script in d.bin.listdir(): - if script.basename.startswith(('python', 'graalpy')): - continue - script.remove() - # - try: - atomic_run( - [str(d.python), '-m', 'pip', 'install', '-U', 'pip', 'wheel', 'setuptools'], - check=True, - capture_output=True, - ) - atomic_run( - [str(d.python), '-m', 'pip', 'install', str(HPY_ROOT)], - check=True, - capture_output=True, - ) - except subprocess.CalledProcessError as cpe: - print_CalledProcessError(cpe) - raise - return d - -def attach_python_to_venv(d): - if os.name == 'nt': - d.bin = d.join('Scripts') - else: - d.bin = d.join('bin') - d.python = d.bin.join('python') - - -@pytest.mark.usefixtures('initargs') -class TestDistutils: - - @pytest.fixture() - def initargs(self, pytestconfig, tmpdir, venv_template): - self.tmpdir = tmpdir - # create a fresh venv by copying the template - self.venv = tmpdir.join('venv') - shutil.copytree(venv_template, self.venv, symlinks=True) - attach_python_to_venv(self.venv) - # create the files for our test project - self.hpy_test_project = tmpdir.join('hpy_test_project').ensure(dir=True) - self.gen_project() - self.hpy_test_project.chdir() - - @pytest.fixture(params=['cpython', 'hybrid', 'universal']) - def hpy_abi(self, request): - return request.param - - def python(self, *args, capture=False): - """ - Run python inside the venv; if capture==True, return stdout - """ - cmd = [str(self.venv.python)] + list(args) - print('[RUN]', ' '.join(cmd)) - if capture: - proc = atomic_run(cmd, capture_output=True) - out = proc.stdout.decode('latin-1').strip() - else: - proc = atomic_run(cmd) - out = None - proc.check_returncode() - return out - - - def writefile(self, fname, content): - """ - Write a file inside hpy_test_project - """ - f = self.hpy_test_project.join(fname) - content = textwrap.dedent(content) - f.write(content) - - def gen_project(self): - """ - Generate the files needed to build the project, except setup.py - """ - self.writefile('cpymod.c', """ - // the simplest possible Python/C module - #include - static PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "cpymod", - "cpymod docstring" - }; - - PyMODINIT_FUNC - PyInit_cpymod(void) - { - return PyModule_Create(&moduledef); - } - """) - - self.writefile('hpymod.c', """ - // the simplest possible HPy module - #include - static HPyModuleDef moduledef = { - .doc = "hpymod with HPy ABI: " HPY_ABI, - }; - - HPy_MODINIT(hpymod, moduledef) - """) - - self.writefile('hpymod_legacy.c', """ - // the simplest possible HPy+legacy module - #include - #include - - static PyObject *f(PyObject *self, PyObject *args) - { - return PyLong_FromLong(1234); - } - static PyMethodDef my_legacy_methods[] = { - {"f", (PyCFunction)f, METH_NOARGS}, - {NULL} - }; - - static HPyModuleDef moduledef = { - .doc = "hpymod_legacy with HPy ABI: " HPY_ABI, - .legacy_methods = my_legacy_methods, - }; - - HPy_MODINIT(hpymod_legacy, moduledef) - """) - - def gen_setup_py(self, src): - preamble = textwrap.dedent(""" - from setuptools import setup, Extension - cpymod = Extension("cpymod", ["cpymod.c"]) - hpymod = Extension("hpymod", ["hpymod.c"]) - hpymod_legacy = Extension("hpymod_legacy", ["hpymod_legacy.c"]) - """) - src = preamble + textwrap.dedent(src) - f = self.hpy_test_project.join('setup.py') - f.write(src) - - def get_docstring(self, modname): - cmd = f'import {modname}; print({modname}.__doc__)' - return self.python('-c', cmd, capture=True) - - def test_cpymod_setup_install(self): - # CPython-only project, no hpy at all. This is a baseline to check - # that everything works even without hpy. - self.gen_setup_py(""" - setup(name = "hpy_test_project", - ext_modules = [cpymod], - ) - """) - self.python('setup.py', 'install') - doc = self.get_docstring('cpymod') - assert doc == 'cpymod docstring' - - def test_cpymod_with_empty_hpy_ext_modules_setup_install(self): - # if we have hpy_ext_modules=[] we trigger the hpy.devel monkey - # patch. This checks that we don't ext_modules still works after that. - self.gen_setup_py(""" - setup(name = "hpy_test_project", - ext_modules = [cpymod], - hpy_ext_modules = [] - ) - """) - self.python('setup.py', 'install') - doc = self.get_docstring('cpymod') - assert doc == 'cpymod docstring' - - def test_hpymod_py_stub(self): - # check that that we generated the .py stub for universal - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - ) - """) - self.python('setup.py', '--hpy-abi=universal', 'build') - build = self.hpy_test_project.join('build') - lib = build.listdir('lib*')[0] - hpymod_py = lib.join('hpymod.py') - assert hpymod_py.check(exists=True) - assert 'This file is automatically generated by hpy' in hpymod_py.read() - - def test_hpymod_build_platlib(self): - # check that if we have only hpy_ext_modules, the distribution is - # detected as "platform-specific" and not "platform-neutral". In - # particular, we want the end result to be in - # e.g. build/lib.linux-x86_64-3.8 and NOT in build/lib. - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - ) - """) - self.python('setup.py', 'build') - build = self.hpy_test_project.join('build') - libs = build.listdir('lib*') - assert len(libs) == 1 - libdir = libs[0] - # this is something like lib.linux-x86_64-cpython-38 - assert libdir.basename != 'lib' - - def test_hpymod_build_ext_inplace(self, hpy_abi): - # check that we can install hpy modules with setup.py build_ext -i - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - ) - """) - self.python('setup.py', f'--hpy-abi={hpy_abi}', 'build_ext', '--inplace') - doc = self.get_docstring('hpymod') - assert doc == f'hpymod with HPy ABI: {hpy_abi}' - - def test_hpymod_setup_install(self, hpy_abi): - # check that we can install hpy modules with setup.py install - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - ) - """) - self.python('setup.py', f'--hpy-abi={hpy_abi}', 'install') - doc = self.get_docstring('hpymod') - assert doc == f'hpymod with HPy ABI: {hpy_abi}' - - def test_hpymod_wheel(self, hpy_abi): - # check that we can build and install wheels - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - ) - """) - self.python('setup.py', f'--hpy-abi={hpy_abi}', 'bdist_wheel') - dist = self.hpy_test_project.join('dist') - whl = dist.listdir('*.whl')[0] - self.python('-m', 'pip', 'install', str(whl)) - doc = self.get_docstring('hpymod') - assert doc == f'hpymod with HPy ABI: {hpy_abi}' - - @pytest.mark.skipif(IS_GRAALPY, reason='not supported on GraalPy') - def test_dont_mix_cpython_and_universal_abis(self): - """ - See issue #322 - """ - # make sure that the build dirs for cpython and universal ABIs are - # distinct - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod], - install_requires = [], - ) - """) - self.python('setup.py', 'install') - # in the build/ dir, we should have 2 directories: temp and lib - build = self.hpy_test_project.join('build') - temps = build.listdir('temp*') - libs = build.listdir('lib*') - assert len(temps) == 1 - assert len(libs) == 1 - # - doc = self.get_docstring('hpymod') - assert doc == 'hpymod with HPy ABI: cpython' - - # now recompile with universal *without* cleaning the build - self.python('setup.py', '--hpy-abi=universal', 'install') - # in the build/ dir, we should have 4 directories: 2 temp*, and 2 lib* - build = self.hpy_test_project.join('build') - temps = build.listdir('temp*') - libs = build.listdir('lib*') - assert len(temps) == 2 - assert len(libs) == 2 - # - doc = self.get_docstring('hpymod') - assert doc == 'hpymod with HPy ABI: universal' - - def test_hpymod_legacy(self, hpy_abi): - if hpy_abi == 'universal': - pytest.skip('only for cpython and hybrid ABIs') - if IS_GRAALPY: - pytest.skip('not supported on GraalPy') - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod_legacy], - install_requires = [], - ) - """) - self.python('setup.py', 'install') - src = 'import hpymod_legacy; print(hpymod_legacy.f())' - out = self.python('-c', src, capture=True) - assert out == '1234' - - def test_hpymod_legacy_fails_with_universal(self): - self.gen_setup_py(""" - setup(name = "hpy_test_project", - hpy_ext_modules = [hpymod_legacy], - install_requires = [], - ) - """) - with pytest.raises(subprocess.CalledProcessError) as exc: - self.python('setup.py', '--hpy-abi=universal', 'install', capture=True) - expected_msg = ("It is forbidden to #include when " - "targeting the HPy Universal ABI") - - # gcc/clang prints the #error on stderr, MSVC prints it on - # stdout. Here we check that the error is printed "somewhere", we - # don't care exactly where. - out = exc.value.stdout + b'\n' + exc.value.stderr - out = out.decode('latin-1') - if expected_msg not in out: - print_CalledProcessError(exc.value) - assert expected_msg in out diff --git a/graalpython/hpy/test/support.py b/graalpython/hpy/test/support.py deleted file mode 100644 index d102e398e7..0000000000 --- a/graalpython/hpy/test/support.py +++ /dev/null @@ -1,601 +0,0 @@ -import os, sys -from filelock import FileLock -import pytest -from pathlib import Path -import re -import subprocess -import textwrap -import distutils - -PY2 = sys.version_info[0] == 2 - -HPY_ROOT = Path(__file__).parent.parent -LOCK = FileLock(HPY_ROOT / ".hpy.lock") - -# True if `sys.executable` is set to a value that allows a Python equivalent to -# the current Python to be launched via, e.g., `python_subprocess.run(...)`. -# By default is `True` if sys.executable is set to a true value. -SUPPORTS_SYS_EXECUTABLE = bool(getattr(sys, "executable", None)) -# True if we are running on the CPython debug build -IS_PYTHON_DEBUG_BUILD = hasattr(sys, 'gettotalrefcount') - -IS_GRAALPY = getattr(getattr(sys, "implementation", None), "name", None) == 'graalpy' - -# pytest marker to run tests only on linux -ONLY_LINUX = pytest.mark.skipif(sys.platform!='linux', reason='linux only') - -SUPPORTS_MEM_PROTECTION = '_HPY_DEBUG_FORCE_DEFAULT_MEM_PROTECT' not in os.environ - -def reindent(s, indent): - s = textwrap.dedent(s) - return ''.join(' '*indent + line if line.strip() else line - for line in s.splitlines(True)) - -def atomic_run(*args, **kwargs): - with LOCK: - return subprocess.run(*args, **kwargs) - - -def make_hpy_abi_fixture(ABIs, class_fixture=False): - """ - Make an hpy_abi fixture. - - conftest.py defines a default hpy_abi for all tests, but individual files - and classes can override the set of ABIs they want to use. The indented - usage is the following: - - # at the top of a file - hpy_abi = make_hpy_abi_fixture(['universal', 'debug']) - - # in a class - class TestFoo(HPyTest): - hpy_abi = make_hpy_abi_fixture('with hybrid', class_fixture=True) - """ - is_cpython = not hasattr(sys, "implementation") or sys.implementation.name == 'cpython' - if isinstance(ABIs, list): - pass - else: - if ABIs == 'default': - ABIs = ['universal', 'debug'] - elif ABIs == 'with hybrid': - ABIs = ['hybrid', 'hybrid+debug'] - else: - raise ValueError("ABIs must be 'default', 'with hybrid' " - "or a list of strings. Got: %s" % ABIs) - if is_cpython: - ABIs.append('cpython') - if class_fixture: - @pytest.fixture(params=ABIs) - def hpy_abi(self, request): - abi = request.param - yield abi - else: - @pytest.fixture(params=ABIs) - def hpy_abi(request): - abi = request.param - yield abi - - return hpy_abi - - -class DefaultExtensionTemplate(object): - - INIT_TEMPLATE = textwrap.dedent( - """ - static HPyDef *moduledefs[] = { - %(defines)s - NULL - }; - %(globals_defs)s - static HPyModuleDef moduledef = { - .doc = "some test for hpy", - .size = 0, - .legacy_methods = %(legacy_methods)s, - .defines = moduledefs, - %(globals_field)s - }; - - HPy_MODINIT(%(name)s, moduledef) - """) - - INIT_TEMPLATE_WITH_TYPES_INIT = textwrap.dedent( - """ - HPyDef_SLOT(generated_init, HPy_mod_exec) - static int generated_init_impl(HPyContext *ctx, HPy m) - { - // Shouldn't really happen, but jut to silence the unused label warning - if (HPy_IsNull(m)) - goto MODINIT_ERROR; - - %(init_types)s - return 0; - - MODINIT_ERROR: - return -1; - } - """ + INIT_TEMPLATE) - - r_marker = re.compile(r"^\s*@([A-Za-z_]+)(\(.*\))?$") - - def __init__(self, src, name): - self.src = textwrap.dedent(src) - self.name = name - self.defines_table = None - self.legacy_methods = 'NULL' - self.type_table = None - self.globals_table = None - - def expand(self): - self.defines_table = [] - self.globals_table = [] - self.type_table = [] - self.output = ['#include '] - for line in self.src.split('\n'): - match = self.r_marker.match(line) - if match: - name, args = self.parse_marker(match) - meth = getattr(self, name) - out = meth(*args) - if out is not None: - out = textwrap.dedent(out) - self.output.append(out) - else: - self.output.append(line) - return '\n'.join(self.output) - - def parse_marker(self, match): - name = match.group(1) - args = match.group(2) - if args is None: - args = () - else: - assert args[0] == '(' - assert args[-1] == ')' - args = args[1:-1].split(',') - args = [x.strip() for x in args] - return name, args - - def INIT(self): - NL_INDENT = '\n ' - if self.type_table: - init_types = '\n'.join(self.type_table) - else: - init_types = '' - - globals_defs = '' - globals_field = '' - if self.globals_table: - globals_defs = \ - textwrap.dedent(''' - static HPyGlobal *module_globals[] = { - %s - NULL - };''') % NL_INDENT.join(self.globals_table) - globals_field = '.globals = module_globals' - - template = self.INIT_TEMPLATE - if init_types: - template = self.INIT_TEMPLATE_WITH_TYPES_INIT - self.EXPORT('generated_init') - exp = template % { - 'legacy_methods': self.legacy_methods, - 'defines': NL_INDENT.join(self.defines_table), - 'init_types': init_types, - 'name': self.name, - 'globals_defs': globals_defs, - 'globals_field': globals_field} - self.output.append(exp) - # make sure that we don't fill the tables any more - self.defines_table = None - self.type_table = None - - def EXPORT(self, meth): - self.defines_table.append('&%s,' % meth) - - def EXPORT_GLOBAL(self, var): - self.globals_table.append('&%s,' % var) - - def EXPORT_LEGACY(self, pymethoddef): - self.legacy_methods = pymethoddef - - def EXPORT_TYPE(self, name, spec): - src = """ - if (!HPyHelpers_AddType(ctx, m, {name}, &{spec}, NULL)) {{ - goto MODINIT_ERROR; - }} - """ - src = reindent(src, 4) - self.type_table.append(src.format( - name=name, - spec=spec)) - - def EXTRA_INIT_FUNC(self, func): - src = """ - {func}(ctx, m); - if (HPyErr_Occurred(ctx)) - goto MODINIT_ERROR; - """ - src = reindent(src, 4) - self.type_table.append(src.format(func=func)) - - def HPy_MODINIT(self, mod): - return "HPy_MODINIT({}, {})".format(self.name, mod) - - -class Spec(object): - def __init__(self, name, origin): - self.name = name - self.origin = origin - - -class HPyModule(object): - def __init__(self, name, so_file): - self.name = name - self.so_filename = so_file - - -class ExtensionCompiler: - def __init__(self, tmpdir, hpy_devel, hpy_abi, compiler_verbose=False, - dump_dir=None, - ExtensionTemplate=DefaultExtensionTemplate, - extra_include_dirs=None): - """ - hpy_devel is an instance of HPyDevel which specifies where to find - include/, runtime/src, etc. Usually it will point to hpy/devel/, but - alternate implementations can point to their own place (e.g. pypy puts - it into pypy/module/_hpy_universal/_vendored) - - extra_include_dirs is a list of include dirs which is put BEFORE all - others. By default it is empty, but it is used e.g. by PyPy to make - sure that #include picks its own version, instead of the - system-wide one. - """ - self.tmpdir = tmpdir - self.dump_dir = dump_dir - self.hpy_devel = hpy_devel - self.hpy_abi = hpy_abi - self.compiler_verbose = compiler_verbose - self.ExtensionTemplate = ExtensionTemplate - self.extra_include_dirs = extra_include_dirs - - def _expand(self, ExtensionTemplate, name, template): - source = ExtensionTemplate(template, name).expand() - filename = self.tmpdir.join(name + '.c') - dump_file = self.dump_dir.joinpath(name + '.c') if self.dump_dir else None - if PY2: - # this code is used also by pypy tests, which run on python2. In - # this case, we need to write as binary, because source is - # "bytes". If we don't and source contains a non-ascii char, we - # get an UnicodeDecodeError - if dump_file: - dump_file.write_text(source) - filename.write(source, mode='wb') - else: - if dump_file: - dump_file.write_text(source) - filename.write(source) - return name + '.c' - - def _fixup_template(self, ExtensionTemplate): - return self.ExtensionTemplate if ExtensionTemplate is None else ExtensionTemplate - - def compile_module(self, main_src, ExtensionTemplate=None, name='mytest', extra_sources=()): - """ - Create and compile a HPy module from the template - """ - ExtensionTemplate = self._fixup_template(ExtensionTemplate) - from distutils.core import Extension - filename = self._expand(ExtensionTemplate, name, main_src) - sources = [str(filename)] - for i, src in enumerate(extra_sources): - extra_filename = self._expand(ExtensionTemplate, 'extmod_%d' % i, src) - sources.append(extra_filename) - # - if self.dump_dir: - pytest.skip("dumping test sources only") - if sys.platform == 'win32': - # not strictly true, could be mingw - compile_args = [ - '/Od', - '/WX', # turn warnings into errors (all, for now) - # '/Wall', # this is too aggressive, makes windows itself fail - '/Zi', - '-D_CRT_SECURE_NO_WARNINGS', # something about _snprintf and _snprintf_s - '/FS', # Since the tests run in parallel - ] - link_args = [ - '/DEBUG', - '/LTCG', - ] - else: - compile_args = [ - '-g', '-O0', - '-Wfatal-errors', # stop after one error (unrelated to warnings) - '-Werror', # turn warnings into errors (all, for now) - ] - link_args = [ - '-g', - ] - # - ext = Extension( - name, - sources=sources, - include_dirs=self.extra_include_dirs, - extra_compile_args=compile_args, - extra_link_args=link_args) - - hpy_abi = self.hpy_abi - if hpy_abi == 'debug' or hpy_abi == 'trace': - # there is no compile-time difference between universal and debug - # extensions. The only difference happens at load time - hpy_abi = 'universal' - elif hpy_abi in ('hybrid+debug', 'hybrid+trace'): - hpy_abi = 'hybrid' - so_filename = c_compile(str(self.tmpdir), ext, - hpy_devel=self.hpy_devel, - hpy_abi=hpy_abi, - compiler_verbose=self.compiler_verbose) - return HPyModule(name, so_filename) - - def make_module(self, main_src, ExtensionTemplate=None, name='mytest', - extra_sources=()): - """ - Compile & load a module. This is NOT a proper import: e.g. - the module is not put into sys.modules. - - We don't want to unnecessarily modify the global state inside tests: - if you are writing a test which needs a proper import, you should not - use make_module but explicitly use compile_module and import it - manually as required by your test. - """ - ExtensionTemplate = self._fixup_template(ExtensionTemplate) - module = self.compile_module( - main_src, ExtensionTemplate, name, extra_sources) - so_filename = module.so_filename - from hpy.universal import MODE_UNIVERSAL, MODE_DEBUG, MODE_TRACE - if self.hpy_abi in ('universal', 'hybrid'): - return self.load_universal_module(name, so_filename, mode=MODE_UNIVERSAL) - elif self.hpy_abi in ('debug', 'hybrid+debug'): - return self.load_universal_module(name, so_filename, mode=MODE_DEBUG) - elif self.hpy_abi in ('trace', 'hybrid+trace'): - return self.load_universal_module(name, so_filename, mode=MODE_TRACE) - elif self.hpy_abi == 'cpython': - return self.load_cpython_module(name, so_filename) - else: - assert False - - def load_universal_module(self, name, so_filename, mode): - assert self.hpy_abi in ('universal', 'hybrid', 'debug', 'hybrid+debug', - 'trace', 'hybrid+trace') - import sys - import hpy.universal - import importlib.util - assert name not in sys.modules - spec = importlib.util.spec_from_file_location(name, so_filename) - mod = hpy.universal.load(name, so_filename, spec, mode=mode) - mod.__file__ = so_filename - mod.__spec__ = spec - return mod - - def load_cpython_module(self, name, so_filename): - assert self.hpy_abi == 'cpython' - # we've got a normal CPython module compiled with the CPython API/ABI, - # let's load it normally. It is important to do the imports only here, - # because this file will be imported also by PyPy tests which runs on - # Python2 - import importlib.util - import sys - assert name not in sys.modules - spec = importlib.util.spec_from_file_location(name, so_filename) - try: - # module_from_spec adds the module to sys.modules - module = importlib.util.module_from_spec(spec) - finally: - if name in sys.modules: - del sys.modules[name] - spec.loader.exec_module(module) - return module - - -class PythonSubprocessRunner: - def __init__(self, verbose, hpy_abi): - self.verbose = verbose - self.hpy_abi = hpy_abi - - def run(self, mod, code): - """ Starts new subprocess that loads given module as 'mod' using the - correct ABI mode and then executes given code snippet. Use - "--subprocess-v" to enable logging from this. - """ - env = os.environ.copy() - pythonpath = [os.path.dirname(mod.so_filename)] - if 'PYTHONPATH' in env: - pythonpath.append(env['PYTHONPATH']) - env["PYTHONPATH"] = os.pathsep.join(pythonpath) - if self.hpy_abi in ['universal', 'debug']: - # HPy module - load_module = "import sys;" + \ - "import hpy.universal;" + \ - "import importlib.util;" + \ - "spec = importlib.util.spec_from_file_location('{name}', '{so_filename}');" + \ - "mod = hpy.universal.load('{name}', '{so_filename}', spec, debug={debug});" - escaped_filename = mod.so_filename.replace("\\", "\\\\") # Needed for Windows paths - load_module = load_module.format(name=mod.name, so_filename=escaped_filename, - debug=self.hpy_abi == 'debug') - else: - # CPython module - assert self.hpy_abi == 'cpython' - load_module = "import {} as mod;".format(mod.name) - if self.verbose: - print("\n---\nExecuting in subprocess: {}".format(load_module + code)) - result = atomic_run([sys.executable, "-c", load_module + code], env=env, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if self.verbose: - print("stdout/stderr:") - try: - out = result.stdout.decode('latin-1') - err = result.stderr.decode('latin-1') - print("----\n{out}--\n{err}-----".format(out=out, err=err)) - except UnicodeDecodeError: - print("Warning: stdout or stderr could not be decoded with 'latin-1' encoding") - return result - - -@pytest.mark.usefixtures('initargs') -class HPyTest: - is_graalpy = IS_GRAALPY # Exposed here for tests running as PyPy apptests - ExtensionTemplate = DefaultExtensionTemplate - - @pytest.fixture() - def initargs(self, compiler, leakdetector, capfd): - self.compiler = compiler - self.leakdetector = leakdetector - self.capfd = capfd - - def make_module(self, main_src, name='mytest', extra_sources=()): - ExtensionTemplate = self.ExtensionTemplate - return self.compiler.make_module(main_src, ExtensionTemplate, name, - extra_sources) - - def compile_module(self, main_src, name='mytest', extra_sources=()): - ExtensionTemplate = self.ExtensionTemplate - return self.compiler.compile_module(main_src, ExtensionTemplate, name, - extra_sources) - - def expect_make_error(self, main_src, error): - with pytest.raises(distutils.errors.CompileError): - self.make_module(main_src) - # - # capfd.readouterr() "eats" the output, but we want to still see it in - # case of failure. Just print it again - cap = self.capfd.readouterr() - sys.stdout.write(cap.out) - sys.stderr.write(cap.err) - # - # gcc prints compiler errors to stderr, but MSVC seems to print them - # to stdout. Let's just check both - if error in cap.out or error in cap.err: - # the error was found, we are good - return - raise Exception("The following error message was not found in the compiler " - "output:\n " + error) - - - def supports_refcounts(self): - """ Returns True if the underlying Python implementation supports - reference counts. - - By default, returns True on CPython and False on other - implementations. - """ - return sys.implementation.name == "cpython" - - def supports_ordinary_make_module_imports(self): - """ Returns True if `.make_module(...)` loads modules using a - standard Python import mechanism (e.g. `importlib.import_module`). - - By default, returns True because the base implementation of - `.make_module(...)` uses an ordinary import. Sub-classes that - override `.make_module(...)` may also want to override this - method. - """ - return True - - -class HPyDebugCapture: - """ - Context manager that sets HPy debug invalid handle hook and remembers the - number of invalid handles reported. Once closed, sets the invalid handle - hook back to None. - """ - def __init__(self): - self.invalid_handles_count = 0 - self.invalid_builders_count = 0 - - def _capture_report(self): - self.invalid_handles_count += 1 - - def _capture_builder_report(self): - self.invalid_builders_count += 1 - - def __enter__(self): - from hpy.universal import _debug - _debug.set_on_invalid_handle(self._capture_report) - _debug.set_on_invalid_builder_handle(self._capture_builder_report) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - from hpy.universal import _debug - _debug.set_on_invalid_handle(None) - _debug.set_on_invalid_builder_handle(None) - - -# the few functions below are copied and adapted from cffi/ffiplatform.py - -def c_compile(tmpdir, ext, hpy_devel, hpy_abi, compiler_verbose=0, debug=None): - """Compile a C extension module using distutils.""" - saved_environ = os.environ.copy() - try: - outputfilename = _build(tmpdir, ext, hpy_devel, hpy_abi, compiler_verbose, debug) - outputfilename = os.path.abspath(outputfilename) - finally: - # workaround for a distutils bugs where some env vars can - # become longer and longer every time it is used - for key, value in saved_environ.items(): - if os.environ.get(key) != value: - os.environ[key] = value - return outputfilename - - -def _build(tmpdir, ext, hpy_devel, hpy_abi, compiler_verbose=0, debug=None): - # XXX compact but horrible :-( - from distutils.core import Distribution - import distutils.errors - import distutils.log - # - dist = Distribution() - dist.parse_config_files() - if debug is None: - debug = sys.flags.debug - options_build_ext = dist.get_option_dict('build_ext') - options_build_ext['debug'] = ('ffiplatform', debug) - options_build_ext['force'] = ('ffiplatform', True) - options_build_ext['build_lib'] = ('ffiplatform', tmpdir) - options_build_ext['build_temp'] = ('ffiplatform', tmpdir) - options_build_py = dist.get_option_dict('build_py') - options_build_py['build_lib'] = ('ffiplatform', tmpdir) - - # this is the equivalent of passing --hpy-abi from setup.py's command line - dist.hpy_abi = hpy_abi - # For testing, we want to use static libs to avoid repeated compilation - # of the same sources which slows down testing. - dist.hpy_use_static_libs = True - dist.hpy_ext_modules = [ext] - # We need to explicitly specify which Python modules we expect because some - # test cases create several distributions in the same temp directory. - dist.py_modules = [ext.name] - hpy_devel.fix_distribution(dist) - - old_level = distutils.log.set_threshold(0) or 0 - old_dir = os.getcwd() - try: - os.chdir(tmpdir) - distutils.log.set_verbosity(compiler_verbose) - dist.run_command('build_ext') - cmd_obj = dist.get_command_obj('build_ext') - outputs = cmd_obj.get_outputs() - sonames = [x for x in outputs if - not x.endswith(".py") and not x.endswith(".pyc")] - assert len(sonames) == 1, 'build_ext is not supposed to return multiple DLLs' - soname = sonames[0] - finally: - os.chdir(old_dir) - distutils.log.set_threshold(old_level) - - return soname - - -# For situations when one wants to have "support.py" on the call stack. -# For example, for asserting that it is in a stack trace. -def trampoline(fun, *args, **kwargs): - fun(*args, **kwargs) diff --git a/graalpython/hpy/test/test_00_basic.py b/graalpython/hpy/test/test_00_basic.py deleted file mode 100644 index 7fc483407e..0000000000 --- a/graalpython/hpy/test/test_00_basic.py +++ /dev/null @@ -1,580 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest -from hpy.devel.abitag import HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR - - -class TestBasic(HPyTest): - - def test_get_version(self): - if self.compiler.hpy_abi != 'universal': - return - import hpy.universal - version, gitrev = hpy.universal.get_version() - # it's a bit hard to test the CONTENT of these values. Let's just - # check that they are strings... - assert isinstance(version, str) - assert isinstance(gitrev, str) - - def test_empty_module(self): - import sys - mod = self.make_module(""" - @INIT - """) - assert type(mod) is type(sys) - - def test_abi_version_check(self): - if self.compiler.hpy_abi != 'universal': - return - try: - self.make_module(""" - // hack: we redefine the version - #undef HPY_ABI_VERSION - #define HPY_ABI_VERSION 999 - @INIT - """) - except RuntimeError as ex: - assert str(ex) == "HPy extension module 'mytest' requires unsupported " \ - "version of the HPy runtime. Requested version: 999.0. " \ - "Current HPy version: {}.{}.".format(HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR) - else: - assert False, "Expected exception" - - def test_abi_tag_check(self): - import shutil - if self.compiler.hpy_abi != 'universal': - return - - from hpy.universal import MODE_UNIVERSAL - def assert_load_raises(filename, message): - try: - self.compiler.load_universal_module('mytest', filename, mode=MODE_UNIVERSAL) - except RuntimeError as ex: - assert str(ex) == message - else: - assert False, "Expected exception" - - module = self.compile_module("@INIT") - filename = module.so_filename - hpy_tag = ".hpy{}".format(HPY_ABI_VERSION) - - filename_wrong_tag = filename.replace(hpy_tag, ".hpy999") - shutil.move(filename, filename_wrong_tag) - assert_load_raises(filename_wrong_tag, - "HPy extension module 'mytest' at path '{}': mismatch " - "between the HPy ABI tag encoded in the filename and " - "the major version requested by the HPy extension itself. " - "Major version tag parsed from filename: 999. " - "Requested version: {}.{}.".format(filename_wrong_tag, HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR)) - - filename_no_tag = filename.replace(hpy_tag, "") - shutil.move(filename_wrong_tag, filename_no_tag) - assert_load_raises(filename_no_tag, - "HPy extension module 'mytest' at path '{}': " - "could not find HPy ABI tag encoded in the filename. " - "The extension claims to be compiled with HPy ABI version: " - "{}.{}.".format(filename_no_tag, HPY_ABI_VERSION, HPY_ABI_VERSION_MINOR)) - - def test_different_name(self): - mod = self.make_module(""" - @INIT - """, name="foo") - assert mod.__name__ == "foo" - - def test_noop_function(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS, .doc="hello world") - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @INIT - """) - assert mod.f() is None - assert mod.f.__doc__ == 'hello world' - - def test_self_is_module(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPy_Dup(ctx, self); - } - @EXPORT(f) - @INIT - """) - assert mod.f() is mod - - def test_identity_function(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Dup(ctx, arg); - } - @EXPORT(f) - @INIT - """) - x = object() - assert mod.f(x) is x - - def test_float_asdouble(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - double a = HPyFloat_AsDouble(ctx, arg); - return HPyFloat_FromDouble(ctx, a * 2.); - } - @EXPORT(f) - @INIT - """) - assert mod.f(1.) == 2. - - def test_wrong_number_of_arguments(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f_noargs, "f_noargs", HPyFunc_NOARGS) - static HPy f_noargs_impl(HPyContext *ctx, HPy self) - { - return HPy_Dup(ctx, ctx->h_None); - } - HPyDef_METH(f_o, "f_o", HPyFunc_O) - static HPy f_o_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f_noargs) - @EXPORT(f_o) - @INIT - """) - with pytest.raises(TypeError): - mod.f_noargs(1) - with pytest.raises(TypeError): - mod.f_o() - with pytest.raises(TypeError): - mod.f_o(1, 2) - - def test_close(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy one = HPyLong_FromLong(ctx, 1); - if (HPy_IsNull(one)) - return HPy_NULL; - HPy res = HPy_Add(ctx, arg, one); - HPy_Close(ctx, one); - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f(41.5) == 42.5 - - def test_bool(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int cond = HPyLong_AsLong(ctx, arg) > 5; - return HPy_Dup(ctx, cond ? ctx->h_True : ctx->h_False); - } - @EXPORT(f) - @INIT - """) - assert mod.f(4) is False - assert mod.f(6) is True - - def test_exception(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - long x = HPyLong_AsLong(ctx, arg); - if (x < 5) { - return HPyLong_FromLong(ctx, -x); - } - else { - HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); - return HPy_NULL; - } - } - @EXPORT(f) - @INIT - """) - assert mod.f(-10) == 10 - with pytest.raises(ValueError) as exc: - mod.f(20) - assert str(exc.value) == 'hello world' - - def test_varargs(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, 10*a + b); - } - @EXPORT(f) - @INIT - """) - assert mod.f(4, 5) == 45 - - def test_builtin_handles(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - long i = HPyLong_AsLong(ctx, arg); - HPy h; - switch(i) { - case 1: h = ctx->h_None; break; - case 2: h = ctx->h_False; break; - case 3: h = ctx->h_True; break; - case 4: h = ctx->h_ValueError; break; - case 5: h = ctx->h_TypeError; break; - case 6: h = ctx->h_IndexError; break; - case 7: h = ctx->h_SystemError; break; - case 8: h = ctx->h_BaseObjectType; break; - case 9: h = ctx->h_TypeType; break; - case 10: h = ctx->h_BoolType; break; - case 11: h = ctx->h_LongType; break; - case 12: h = ctx->h_FloatType; break; - case 13: h = ctx->h_UnicodeType; break; - case 14: h = ctx->h_TupleType; break; - case 15: h = ctx->h_ListType; break; - case 16: h = ctx->h_NotImplemented; break; - case 17: h = ctx->h_Ellipsis; break; - case 18: h = ctx->h_ComplexType; break; - case 19: h = ctx->h_BytesType; break; - case 20: h = ctx->h_MemoryViewType; break; - case 21: h = ctx->h_SliceType; break; - case 22: h = ctx->h_Builtins; break; - case 23: h = ctx->h_DictType; break; - case 2048: h = ctx->h_CapsuleType; break; - default: - HPyErr_SetString(ctx, ctx->h_ValueError, "invalid choice"); - return HPy_NULL; - } - return HPy_Dup(ctx, h); - } - @EXPORT(f) - @INIT - """) - import builtins - - builtin_objs = ( - '', None, False, True, ValueError, TypeError, IndexError, - SystemError, object, type, bool, int, float, str, tuple, list, - NotImplemented, Ellipsis, complex, bytes, memoryview, slice, - builtins.__dict__, dict - ) - for i, obj in enumerate(builtin_objs): - if i == 0: - continue - assert mod.f(i) is obj - - # we cannot be sure if 'datetime_CAPI' is available - import datetime - if hasattr(datetime, "datetime_CAPI"): - assert mod.f(2048) is type(datetime.datetime_CAPI) - - def test_extern_def(self): - import pytest - main = """ - extern HPyDef f; - extern HPyDef g; - extern HPyDef h; - extern HPyDef i; - - @EXPORT(f) - @EXPORT(g) - @EXPORT(h) - @EXPORT(i) - @INIT - """ - extra = """ - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 12345); - } - HPyDef_METH(g, "g", HPyFunc_O) - static HPy g_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Dup(ctx, arg); - } - HPyDef_METH(h, "h", HPyFunc_VARARGS) - static HPy h_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - long a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, 10*a + b); - } - HPyDef_METH(i, "i", HPyFunc_KEYWORDS) - static HPy i_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs, - HPy kwnames) - { - long a, b; - static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, "ll", kwlist, &a, &b)) - return HPy_NULL; - return HPyLong_FromLong(ctx, 10*a + b); - } - """ - mod = self.make_module(main, extra_sources=[extra]) - assert mod.f() == 12345 - assert mod.g(42) == 42 - assert mod.h(5, 6) == 56 - assert mod.i(4, 3) == 43 - assert mod.i(a=2, b=5) == 25 - with pytest.raises(TypeError): - mod.h("not an integer", "not an integer either") - - def test_Float_FromDouble(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyFloat_FromDouble(ctx, 123.45); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 123.45 - - def test_unsupported_signature(self): - import pytest - with pytest.raises(ValueError) as exc: - self.make_module(""" - HPyDef f = { - .kind = HPyDef_Kind_Meth, - .meth = { - .name = "f", - .signature = (HPyFunc_Signature)1234, - } - }; - @EXPORT(f) - @INIT - """) - assert str(exc.value) == 'Unsupported HPyMeth signature' - - def test_repr_str_ascii_bytes(self): - mod = self.make_module(""" - HPyDef_METH(f1, "f1", HPyFunc_O) - static HPy f1_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Repr(ctx, arg); - } - HPyDef_METH(f2, "f2", HPyFunc_O) - static HPy f2_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Str(ctx, arg); - } - HPyDef_METH(f3, "f3", HPyFunc_O) - static HPy f3_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_ASCII(ctx, arg); - } - HPyDef_METH(f4, "f4", HPyFunc_O) - static HPy f4_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Bytes(ctx, arg); - } - @EXPORT(f1) - @EXPORT(f2) - @EXPORT(f3) - @EXPORT(f4) - @INIT - """) - assert mod.f1("\u1234") == "'\u1234'" - assert mod.f2(42) == "42" - assert mod.f3("\u1234") == "'\\u1234'" - assert mod.f4(bytearray(b"foo")) == b"foo" - - def test_is_true(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int cond = HPy_IsTrue(ctx, arg); - return HPy_Dup(ctx, cond ? ctx->h_True : ctx->h_False); - } - @EXPORT(f) - @INIT - """) - assert mod.f("1234") is True - assert mod.f("") is False - - def test_richcompare(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy arg2 = HPyLong_FromLong(ctx, 100); - HPy result = HPy_RichCompare(ctx, arg, arg2, HPy_GT); - HPy_Close(ctx, arg2); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f(100) is False - assert mod.f(150) is True - - def test_richcomparebool(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy arg2 = HPyLong_FromLong(ctx, 100); - int result = HPy_RichCompareBool(ctx, arg, arg2, HPy_GE); - HPy_Close(ctx, arg2); - return HPyLong_FromLong(ctx, -result); - } - @EXPORT(f) - @INIT - """) - assert mod.f(50) == 0 - assert mod.f(100) == -1 - - def test_hash(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_hash_t hash = HPy_Hash(ctx, arg); - return HPyLong_FromSsize_t(ctx, hash); - } - @EXPORT(f) - @INIT - """) - x = object() - assert mod.f(x) == hash(x) - - def test_ctx_name(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, ctx->name); - } - - @EXPORT(f) - @INIT - """) - ctx_name = mod.f() - hpy_abi = self.compiler.hpy_abi - if hpy_abi == 'cpython': - assert ctx_name == 'HPy CPython ABI' - elif hpy_abi == 'universal': - # this can be "HPy Universal ABI (CPython backend)" or - # "... (PyPy backend)", etc. - assert ctx_name.startswith('HPy Universal ABI') - elif hpy_abi == 'debug': - assert ctx_name.startswith('HPy Debug Mode ABI') - elif hpy_abi == 'trace': - assert ctx_name.startswith('HPy Trace Mode ABI') - else: - assert False, 'unexpected hpy_abi: %s' % hpy_abi - - def test_abi_version(self): - """ - Check that all the various ABI version info that we have around match. - """ - from hpy.devel import abitag - mod = self.make_module( - """ - HPyDef_METH(get_ABI_VERSION, "get_ABI_VERSION", HPyFunc_NOARGS) - static HPy get_ABI_VERSION_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, HPY_ABI_VERSION); - } - - HPyDef_METH(get_ABI_TAG, "get_ABI_TAG", HPyFunc_NOARGS) - static HPy get_ABI_TAG_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, HPY_ABI_TAG); - } - - HPyDef_METH(get_ctx_version, "get_ctx_version", HPyFunc_NOARGS) - static HPy get_ctx_version_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, ctx->abi_version); - } - - @EXPORT(get_ABI_VERSION) - @EXPORT(get_ABI_TAG) - @EXPORT(get_ctx_version) - @INIT - """) - c_HPY_ABI_VERSION = mod.get_ABI_VERSION() - c_HPY_ABI_TAG = mod.get_ABI_TAG() - ctx_version = mod.get_ctx_version() - assert c_HPY_ABI_VERSION == ctx_version == abitag.HPY_ABI_VERSION - assert c_HPY_ABI_TAG == abitag.HPY_ABI_TAG - - def test_FromVoidP_AsVoidP(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - void *p = HPy_AsVoidP(arg); - HPy h = HPy_FromVoidP(p); - return HPy_Dup(ctx, h); - } - @EXPORT(f) - @INIT - """) - assert mod.f(42) == 42 - - def test_leave_python(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t data_len; - const char* data = HPyUnicode_AsUTF8AndSize(ctx, arg, &data_len); - HPy_ssize_t acount = 0; - HPy_BEGIN_LEAVE_PYTHON(ctx); - for (HPy_ssize_t i = 0; i < data_len; ++i) { - if (data[i] == 'a') - acount++; - } - HPy_END_LEAVE_PYTHON(ctx); - return HPyLong_FromSize_t(ctx, acount); - } - @EXPORT(f) - @INIT - """) - assert mod.f("abraka") == 3 - - def test_dup_null(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPy h = HPy_Dup(ctx, HPy_NULL); - if (HPy_IsNull(h)) { - return HPyLong_FromSize_t(ctx, 0); - } - HPy_Close(ctx, h); - return HPyLong_FromSize_t(ctx, -1); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 0 diff --git a/graalpython/hpy/test/test_argparse.py b/graalpython/hpy/test/test_argparse.py deleted file mode 100644 index 55bdd31c6d..0000000000 --- a/graalpython/hpy/test/test_argparse.py +++ /dev/null @@ -1,678 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestParseItem(HPyTest): - - def unsigned_long_bits(self): - """ Return the number of bits in an unsigned long. """ - # XXX: Copied from test_hpylong.py - import struct - unsigned_long_bytes = len(struct.pack('l', 0)) - return 8 * unsigned_long_bytes - - - def make_parse_item(self, fmt, type, hpy_converter): - mod = self.make_module(""" - #ifndef _MSC_VER - __attribute__((unused)) - #endif - static inline - HPy char_to_hpybytes(HPyContext *ctx, char a) {{ - return HPyBytes_FromStringAndSize(ctx, &a, 1); - }} - - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - {{ - {type} a; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "{fmt}", &a)) - return HPy_NULL; - return {hpy_converter}(ctx, a); - }} - @EXPORT(f) - @INIT - """.format(fmt=fmt, type=type, hpy_converter=hpy_converter)) - return mod - - def test_b(self): - import pytest - mod = self.make_parse_item("b", "char", "char_to_hpybytes") - assert mod.f(0) == b"\x00" - assert mod.f(1) == b"\x01" - assert mod.f(255) == b"\xff" - with pytest.raises(OverflowError) as err: - mod.f(256) - assert str(err.value) == ( - "function unsigned byte integer is greater than maximum" - ) - with pytest.raises(OverflowError) as err: - mod.f(-1) - assert str(err.value) == ( - "function unsigned byte integer is less than minimum" - ) - - def test_s(self): - import pytest - mod = self.make_parse_item("s", "const char*", "HPyUnicode_FromString") - assert mod.f("hello HPy") == "hello HPy" - with pytest.raises(ValueError) as err: - mod.f(b"hello\0HPy".decode('utf-8')) - assert str(err.value) == ( - "function embedded null character" - ) - with pytest.raises(TypeError) as err: - mod.f(b"hello HPy") - assert str(err.value) == ( - "function a str is required" - ) - - def test_upper_b(self): - mod = self.make_parse_item("B", "char", "char_to_hpybytes") - assert mod.f(0) == b"\x00" - assert mod.f(1) == b"\x01" - assert mod.f(2**8 - 1) == b"\xff" - assert mod.f(2**8) == b"\x00" - assert mod.f(-1) == b"\xff" - - def test_h(self): - import pytest - mod = self.make_parse_item("h", "short", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**15 - 1) == 2**15 - 1 - assert mod.f(-2**15) == -2**15 - with pytest.raises(OverflowError) as err: - mod.f(2**15) - assert str(err.value) == ( - "function signed short integer is greater than maximum" - ) - with pytest.raises(OverflowError) as err: - mod.f(-2**15 - 1) - assert str(err.value) == ( - "function signed short integer is less than minimum" - ) - - def test_upper_h_short(self): - mod = self.make_parse_item("H", "short", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**15 - 1) == 2**15 - 1 - assert mod.f(-2**15) == -2**15 - assert mod.f(2**16 - 1) == -1 - assert mod.f(-2**16 + 1) == 1 - assert mod.f(2**16) == 0 - assert mod.f(-2**16) == 0 - - def test_upper_h_unsigned_short(self): - mod = self.make_parse_item( - "H", "unsigned short", "HPyLong_FromUnsignedLong" - ) - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == 2**16 - 1 - assert mod.f(2**16 - 1) == 2**16 - 1 - assert mod.f(-2**16 + 1) == 1 - assert mod.f(2**16) == 0 - assert mod.f(-2**16) == 0 - - def test_i(self): - import pytest - mod = self.make_parse_item("i", "int", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**31 - 1) == 2**31 - 1 - assert mod.f(-2**31) == -2**31 - with pytest.raises(OverflowError) as err: - mod.f(2**31) - assert str(err.value) in ( - "function signed integer is greater than maximum", - "Python int too large to convert to C long", # where sizeof(long) == 4 - ) - with pytest.raises(OverflowError) as err: - mod.f(-2**31 - 1) - assert str(err.value) in ( - "function signed integer is less than minimum", - "Python int too large to convert to C long", # where sizeof(long) == 4 - ) - - def test_upper_i_signed(self): - mod = self.make_parse_item("I", "int", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**31 - 1) == 2**31 - 1 - assert mod.f(-2**31) == -2**31 - assert mod.f(2**32 - 1) == -1 - assert mod.f(-2**32 + 1) == 1 - assert mod.f(2**32) == 0 - assert mod.f(-2**32) == 0 - - def test_upper_i_unsigned(self): - mod = self.make_parse_item( - "I", "unsigned int", "HPyLong_FromUnsignedLong" - ) - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == 2**32 - 1 - assert mod.f(2**32 - 1) == 2**32 - 1 - assert mod.f(-2**32 + 1) == 1 - assert mod.f(2**32) == 0 - assert mod.f(-2**32) == 0 - - def test_l(self): - import pytest - LONG_BITS = self.unsigned_long_bits() - 1 - mod = self.make_parse_item("l", "long", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**LONG_BITS - 1) == 2**LONG_BITS - 1 - assert mod.f(-2**LONG_BITS) == -2**LONG_BITS - with pytest.raises(OverflowError): - mod.f(2**LONG_BITS) - with pytest.raises(OverflowError): - mod.f(-2**LONG_BITS - 1) - - def test_k_signed(self): - LONG_BITS = self.unsigned_long_bits() - 1 - mod = self.make_parse_item("k", "long", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**LONG_BITS - 1) == 2**LONG_BITS - 1 - assert mod.f(-2**LONG_BITS) == -2**LONG_BITS - assert mod.f(2**(LONG_BITS + 1) - 1) == -1 - assert mod.f(-2**(LONG_BITS + 1) + 1) == 1 - assert mod.f(2**(LONG_BITS + 1)) == 0 - assert mod.f(-2**(LONG_BITS + 1)) == 0 - - def test_k_unsigned(self): - ULONG_BITS = self.unsigned_long_bits() - mod = self.make_parse_item( - "k", "unsigned long", "HPyLong_FromUnsignedLong" - ) - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == 2**ULONG_BITS - 1 - assert mod.f(2**ULONG_BITS - 1) == 2**ULONG_BITS - 1 - assert mod.f(-2**ULONG_BITS + 1) == 1 - assert mod.f(2**ULONG_BITS) == 0 - assert mod.f(-2**ULONG_BITS) == 0 - - def test_upper_l(self): - import pytest - mod = self.make_parse_item("L", "long long", "HPyLong_FromLongLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**63 - 1) == 2**63 - 1 - assert mod.f(-2**63) == -2**63 - with pytest.raises(OverflowError): - mod.f(2**63) - with pytest.raises(OverflowError): - mod.f(-2**63 - 1) - - def test_upper_k_signed(self): - mod = self.make_parse_item("K", "long long", "HPyLong_FromLongLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**63 - 1) == 2**63 - 1 - assert mod.f(-2**63) == -2**63 - assert mod.f(2**64 - 1) == -1 - assert mod.f(-2**64 + 1) == 1 - assert mod.f(2**64) == 0 - assert mod.f(-2**64) == 0 - - def test_upper_k_unsigned(self): - mod = self.make_parse_item( - "K", "unsigned long long", "HPyLong_FromUnsignedLongLong" - ) - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == 2**64 - 1 - assert mod.f(2**64 - 1) == 2**64 - 1 - assert mod.f(-2**64 + 1) == 1 - assert mod.f(2**64) == 0 - assert mod.f(-2**64) == 0 - - def test_n(self): - import pytest - mod = self.make_parse_item("n", "HPy_ssize_t", "HPyLong_FromSsize_t") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == -1 - assert mod.f(2**63 - 1) == 2**63 - 1 - assert mod.f(-2**63) == -2**63 - with pytest.raises(OverflowError): - mod.f(2**63) - with pytest.raises(OverflowError): - mod.f(-2**63 - 1) - - def test_f(self): - import pytest - mod = self.make_parse_item("f", "float", "HPyFloat_FromDouble") - assert mod.f(1.) == 1. - assert mod.f(-2) == -2. - with pytest.raises(TypeError): - mod.f("x") - - def test_d(self): - import pytest - mod = self.make_parse_item("d", "double", "HPyFloat_FromDouble") - assert mod.f(1.) == 1. - assert mod.f(-2) == -2. - with pytest.raises(TypeError): - mod.f("x") - - def test_upper_o(self): - mod = self.make_parse_item("O", "HPy", "HPy_Dup") - assert mod.f("a") == "a" - assert mod.f(5) == 5 - - def test_p(self): - mod = self.make_parse_item("p", "int", "HPyLong_FromLong") - assert mod.f(0) == 0 - assert mod.f(1) == 1 - assert mod.f(-1) == 1 - assert mod.f(False) == 0 - assert mod.f(True) == 1 - assert mod.f([]) == 0 - assert mod.f([0]) == 1 - assert mod.f("") == 0 - assert mod.f("0") == 1 - - -class TestArgParse(HPyTest): - def make_two_arg_add(self, fmt="OO"): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - {{ - HPy a; - HPy b = HPy_NULL; - HPy res; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "{fmt}", &a, &b)) - return HPy_NULL; - if (HPy_IsNull(b)) {{ - b = HPyLong_FromLong(ctx, 5); - }} else {{ - b = HPy_Dup(ctx, b); - }} - res = HPy_Add(ctx, a, b); - HPy_Close(ctx, b); - return res; - }} - @EXPORT(f) - @INIT - """.format(fmt=fmt)) - return mod - - def test_many_int_arguments(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - long a, b, c, d, e; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "lllll", - &a, &b, &c, &d, &e)) - return HPy_NULL; - return HPyLong_FromLong(ctx, - 10000*a + 1000*b + 100*c + 10*d + e); - } - @EXPORT(f) - @INIT - """) - assert mod.f(4, 5, 6, 7, 8) == 45678 - - def test_many_handle_arguments(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_Add(ctx, a, b); - } - @EXPORT(f) - @INIT - """) - assert mod.f("a", "b") == "ab" - - def test_supplying_hpy_tracker(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b, result; - HPyTracker ht; - if (!HPyArg_Parse(ctx, &ht, args, nargs, "OO", &a, &b)) - return HPy_NULL; - result = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f("a", "b") == "ab" - - def test_unsupported_fmt(self): - import pytest - mod = self.make_two_arg_add(fmt="ZZ:two_add") - with pytest.raises(SystemError) as exc: - mod.f("a") - assert str(exc.value) == "two_add() unknown arg format code" - - def test_too_few_args(self): - import pytest - mod = self.make_two_arg_add("OO:two_add") - with pytest.raises(TypeError) as exc: - mod.f() - assert str(exc.value) == "two_add() required positional argument missing" - - def test_too_many_args(self): - import pytest - mod = self.make_two_arg_add("OO:two_add") - with pytest.raises(TypeError) as exc: - mod.f(1, 2, 3) - assert str(exc.value) == "two_add() mismatched args (too many arguments for fmt)" - - def test_optional_args(self): - mod = self.make_two_arg_add(fmt="O|O") - assert mod.f(1) == 6 - assert mod.f(3, 4) == 7 - - def test_keyword_only_args_fails(self): - import pytest - mod = self.make_two_arg_add(fmt="O$O:two_add") - with pytest.raises(SystemError) as exc: - mod.f(1, 2) - assert str(exc.value) == "two_add() unknown arg format code" - - def test_error_default_message(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "function required positional argument missing" - - def test_error_with_function_name(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO:my_func") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "my_func() required positional argument missing" - - def test_error_with_overridden_message(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO;my-error-message") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "my-error-message" - - -class TestArgParseKeywords(HPyTest): - def make_two_arg_add(self, fmt="O+O+"): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - {{ - HPy a, b, result; - HPyTracker ht; - static const char *kwlist[] = {{ "a", "b", NULL }}; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, - "{fmt}", kwlist, &a, &b)) {{ - return HPy_NULL; - }} - result = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return result; - }} - @EXPORT(f) - @INIT - """.format(fmt=fmt)) - return mod - - def test_handle_two_arguments(self): - mod = self.make_two_arg_add("OO") - assert mod.f("x", b="y") == "xy" - - def test_handle_reordered_arguments(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy a, b, result; - HPyTracker ht; - static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "OO", - kwlist, &a, &b)) { - return HPy_NULL; - } - result = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f(b="y", a="x") == "xy" - - def test_handle_optional_arguments(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy a; - HPy b = HPy_NULL; - HPyTracker ht; - HPy res; - static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "O|O", - kwlist, &a, &b)) { - return HPy_NULL; - } - if (HPy_IsNull(b)) { - b = HPyLong_FromLong(ctx, 5); - HPyTracker_Add(ctx, ht, b); - } - res = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f(a=3, b=2) == 5 - assert mod.f(3, 2) == 5 - assert mod.f(a=3) == 8 - assert mod.f(3) == 8 - - def test_unsupported_fmt(self): - import pytest - mod = self.make_two_arg_add(fmt="ZZ:two_add") - with pytest.raises(SystemError) as exc: - mod.f("a") - assert str(exc.value) == "two_add() unknown arg format code" - - def test_missing_required_argument(self): - import pytest - mod = self.make_two_arg_add(fmt="OO:add_two") - with pytest.raises(TypeError) as exc: - mod.f(1) - assert str(exc.value) == "add_two() no value for required argument" - - def test_mismatched_args_too_few_keywords(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO:add_two") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "add_two() mismatched args (too few keywords for fmt)" - - def test_mismatched_args_too_many_keywords(self): - import pytest - mod = self.make_two_arg_add(fmt="O:add_two") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "add_two() mismatched args (too many keywords for fmt)" - - def test_blank_keyword_argument_exception(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - long a, b, c; - static const char *kwlist[] = { "", "b", "", NULL }; - if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kwnames, - "lll", kwlist, &a, &b, &c)) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - with pytest.raises(SystemError) as exc: - mod.f() - assert str(exc.value) == "function empty keyword parameter name" - - def test_positional_only_argument(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy a; - HPy b = HPy_NULL; - HPyTracker ht; - HPy res; - static const char *kwlist[] = { "", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, - "O|O", kwlist, &a, &b)) { - return HPy_NULL; - } - if (HPy_IsNull(b)) { - b = HPyLong_FromLong(ctx, 5); - HPyTracker_Add(ctx, ht, b); - } - res = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f(1, b=2) == 3 - assert mod.f(1, 2) == 3 - assert mod.f(1) == 6 - with pytest.raises(TypeError) as exc: - mod.f(a=1, b=2) - assert str(exc.value) == "function no value for required argument" - - def test_keyword_only_argument(self): - import pytest - mod = self.make_two_arg_add(fmt="O$O") - assert mod.f(1, b=2) == 3 - assert mod.f(a=1, b=2) == 3 - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == ( - "function keyword only argument passed as positional argument") - - def test_error_default_message(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "function mismatched args (too few keywords for fmt)" - - def test_error_with_function_name(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO:my_func") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "my_func() mismatched args (too few keywords for fmt)" - - def test_error_with_overridden_message(self): - import pytest - mod = self.make_two_arg_add(fmt="OOO;my-error-message") - with pytest.raises(TypeError) as exc: - mod.f(1, 2) - assert str(exc.value) == "my-error-message" - - def test_keywords_dict(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_KEYWORDS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy args_tuple, kwdict; - HPy a, b = HPy_NULL, res; - HPyTracker ht; - HPy_ssize_t n_args_tuple, i; - HPy *args_arr; - int status; - static const char *kwlist[] = { "a", "b", NULL }; - - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_SystemError, - "expected exactly two args"); - return HPy_NULL; - } - args_tuple = args[0]; - kwdict = args[1]; - n_args_tuple = HPy_Length(ctx, args_tuple); - args_arr = (HPy *)malloc(n_args_tuple * sizeof(HPy)); - for (i=0; i < n_args_tuple; i++) - args_arr[i] = HPy_GetItem_i(ctx, args_tuple, i); - - status = HPyArg_ParseKeywordsDict(ctx, &ht, args_arr, - n_args_tuple, kwdict, "O|O", kwlist, &a, &b); - - for (i=0; i < n_args_tuple; i++) - HPy_Close(ctx, args_arr[i]); - free(args_arr); - if (!status) { - return HPy_NULL; - } - if (HPy_IsNull(b)) { - b = HPyLong_FromLong(ctx, 5); - HPyTracker_Add(ctx, ht, b); - } - res = HPy_Add(ctx, a, b); - HPyTracker_Close(ctx, ht); - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f(tuple(), dict(a=3, b=2)) == 5 - assert mod.f((3, 2), {}) == 5 - assert mod.f(tuple(), dict(a=3)) == 8 - assert mod.f((3,), {}) == 8 - with pytest.raises(TypeError): - mod.f(tuple(), {}) diff --git a/graalpython/hpy/test/test_call.py b/graalpython/hpy/test/test_call.py deleted file mode 100644 index 3702063946..0000000000 --- a/graalpython/hpy/test/test_call.py +++ /dev/null @@ -1,329 +0,0 @@ -from .support import HPyTest - - -class TestCall(HPyTest): - def argument_combinations(self, **items): - """ Returns all possible ways of expressing the given items as - arguments to a function. - """ - items = list(items.items()) - for i in range(len(items) + 1): - args = tuple(item[1] for item in items[:i]) - kw = dict(items[i:]) - yield {"args": args, "kw": kw} - if not args: - yield {"kw": kw} - if not kw: - yield {"args": args} - if not args and not kw: - yield {} - - def argument_combinations_tuple(self, **items): - """ Same as 'argument_combinations' but returns a tuple where - the first element is the argument tuple and the second is - a dict that may contain the keywords dict. - """ - items = list(items.items()) - for i in range(len(items) + 1): - args = tuple(item[1] for item in items[:i]) - kw = dict(items[i:]) - yield args, kw - if not args: - yield tuple(), kw - if not kw: - yield args, {} - if not args and not kw: - yield tuple(), {} - - def test_hpy_calltupledict(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(call, "call", HPyFunc_KEYWORDS) - static HPy call_impl(HPyContext *ctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames) - { - - HPy f, result; - HPy f_args = HPy_NULL; - HPy f_kw = HPy_NULL; - HPyTracker ht; - static const char *kwlist[] = { "f", "args", "kw", NULL }; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, - "O|OO", kwlist, &f, &f_args, &f_kw)) { - return HPy_NULL; - } - result = HPy_CallTupleDict(ctx, f, f_args, f_kw); - HPyTracker_Close(ctx, ht); - return result; - } - @EXPORT(call) - @INIT - """) - - def f(a, b): - return a + b - - def g(): - return "this is g" - - # test passing arguments with handles of the correct type -- - # i.e. args is a tuple or a null handle, kw is a dict or a null handle. - for d in self.argument_combinations(a=1, b=2): - assert mod.call(f, **d) == 3 - for d in self.argument_combinations(a=1): - with pytest.raises(TypeError): - mod.call(f, **d) - for d in self.argument_combinations(): - with pytest.raises(TypeError): - mod.call(f, **d) - for d in self.argument_combinations(): - assert mod.call(g, **d) == "this is g" - for d in self.argument_combinations(object=2): - assert mod.call(str, **d) == "2" - for d in self.argument_combinations(): - with pytest.raises(TypeError): - mod.call("not callable", **d) - for d in self.argument_combinations(unknown=2): - with pytest.raises(TypeError): - mod.call("not callable", **d) - - # test passing handles of the incorrect type as arguments - with pytest.raises(TypeError): - mod.call(f, args=[1, 2]) - with pytest.raises(TypeError): - mod.call(f, args="string") - with pytest.raises(TypeError): - mod.call(f, args=1) - with pytest.raises(TypeError): - mod.call(f, args=None) - with pytest.raises(TypeError): - mod.call(f, kw=[1, 2]) - with pytest.raises(TypeError): - mod.call(f, kw="string") - with pytest.raises(TypeError): - mod.call(f, kw=1) - with pytest.raises(TypeError): - mod.call(f, kw=None) - - def test_hpy_callmethodtupledict(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(call, "call", HPyFunc_KEYWORDS) - static HPy call_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy result, result_0, result_1; - HPy receiver = HPy_NULL; - HPy h_name = HPy_NULL; - HPy m_args = HPy_NULL; - const char *s_name = ""; - HPyTracker ht; - static const char *kwlist[] = { "receiver", "name", "args", NULL }; - if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kwnames, "OO|O", - kwlist, &receiver, &h_name, &m_args)) { - return HPy_NULL; - } - s_name = HPyUnicode_AsUTF8AndSize(ctx, h_name, NULL); - if (s_name == NULL) { - HPyTracker_Close(ctx, ht); - return HPy_NULL; - } - - result_0 = HPy_CallMethodTupleDict(ctx, h_name, receiver, m_args, HPy_NULL); - if (HPy_IsNull(result_0)) { - HPyTracker_Close(ctx, ht); - return HPy_NULL; - } - - result_1 = HPy_CallMethodTupleDict_s(ctx, s_name, receiver, m_args, HPy_NULL); - if (HPy_IsNull(result_1)) { - HPyTracker_Close(ctx, ht); - HPy_Close(ctx, result_0); - return HPy_NULL; - } - - HPyTracker_Close(ctx, ht); - result = HPyTuple_Pack(ctx, 2, result_0, result_1); - HPy_Close(ctx, result_0); - HPy_Close(ctx, result_1); - return result; - } - @EXPORT(call) - @INIT - """) - - test_args = ( - # (receiver, method, args_tuple) - dict(receiver={"hello": 1, "world": 2}, name="keys", args=tuple()), - dict(receiver="Hello, World", name="find", args=("Wo", )), - ) - - for kw in test_args: - res = getattr(kw["receiver"], kw["name"])(*kw["args"]) - assert mod.call(**kw) == (res, res) - - with pytest.raises(AttributeError): - mod.call(receiver=dict(), name="asdf", args=tuple()) - - with pytest.raises(TypeError): - mod.call(receiver="Hello, World", name="find") - - with pytest.raises(TypeError): - mod.call(receiver="Hello, World", name="find", args=("1", ) * 100) - - def test_hpy_call(self): - import pytest - mod = self.make_module(""" - #define SELF 1 - - HPyDef_METH(call, "call", HPyFunc_KEYWORDS) - static HPy call_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - if (nargs < SELF) { - HPyErr_SetString(ctx, ctx->h_TypeError, "HPy_Call requires a receiver"); - return HPy_NULL; - } - return HPy_Call(ctx, args[0], args + SELF, nargs - SELF, kwnames); - } - @EXPORT(call) - @INIT - """) - - def foo(): - raise ValueError - - def listify(*args): - return args - - def f(a, b): - return a + b - - def g(): - return "this is g" - - class KwDict(dict): - def __getitem__(self, key): - return "key=" + str(key); - - test_args = ( - # (receiver, args_tuple, kwd) - (dict, (dict(a=0, b=1), ), {}), - (dict, tuple(), dict(a=0, b=1)), - ) - for receiver, args_tuple, kwd in test_args: - assert mod.call(receiver, *args_tuple, **kwd) == receiver(*args_tuple, **kwd) - - # NULL dict for keywords - mod.call(dict) - - # dict subclass for keywords - kwdict = KwDict(x=11, y=12, z=13) - assert mod.call(dict, **kwdict) == dict(kwdict) - - with pytest.raises(ValueError): - mod.call(foo) - with pytest.raises(TypeError): - mod.call() - - # large amount of args - r = range(1000) - assert mod.call(listify, *r) == listify(*r) - - # test passing arguments with handles of the correct type -- - # i.e. args is a tuple or a null handle, kw is a dict or a null handle. - for args, kwd in self.argument_combinations_tuple(a=1, b=2): - assert mod.call(f, *args, **kwd) == 3 - for args, kwd in self.argument_combinations_tuple(a=1): - with pytest.raises(TypeError): - mod.call(f, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(): - with pytest.raises(TypeError): - mod.call(f, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(): - assert mod.call(g, *args, **kwd) == "this is g" - for args, kwd in self.argument_combinations_tuple(object=2): - assert mod.call(str, *args, **kwd) == "2" - for args, kwd in self.argument_combinations_tuple(): - with pytest.raises(TypeError): - mod.call("not callable", *args, **kwd) - for args, kwd in self.argument_combinations_tuple(unknown=2): - with pytest.raises(TypeError): - mod.call("not callable", *args, **kwd) - - def test_hpy_callmethod(self): - import pytest - mod = self.make_module(""" - #define NAME 1 - - HPyDef_METH(call, "call", HPyFunc_KEYWORDS) - static HPy call_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs, HPy kwnames) - { - if (nargs < NAME) { - HPyErr_SetString(ctx, ctx->h_TypeError, "HPy_CallMethod requires a receiver and a method name"); - return HPy_NULL; - } - // 'args[0]' is the name - return HPy_CallMethod(ctx, args[0], args + NAME, nargs - NAME, kwnames); - } - @EXPORT(call) - @INIT - """) - - class Dummy: - not_callable = 123 - - def f(self, a, b): - return a + b - - def g(self): - return 'this is g' - - test_obj = Dummy() - - # test passing arguments with handles of the correct type -- - # i.e. args is a tuple or a null handle, kw is a dict or a null handle. - for args, kwd in self.argument_combinations_tuple(a=1, b=2): - assert mod.call('f', test_obj, *args, **kwd) == 3 - for args, kwd in self.argument_combinations_tuple(a=1): - with pytest.raises(TypeError): - mod.call('f', test_obj, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(a=1, b=2, c=3): - with pytest.raises(TypeError): - mod.call('f', test_obj, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(): - with pytest.raises(TypeError): - mod.call('f', test_obj, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(): - assert mod.call('g', test_obj, *args, **kwd) == 'this is g' - for args, kwd in self.argument_combinations_tuple(): - with pytest.raises(TypeError): - mod.call('not_callable', test_obj, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(unknown=2): - with pytest.raises(TypeError): - mod.call('not_callable', test_obj, *args, **kwd) - for args, kwd in self.argument_combinations_tuple(): - with pytest.raises(AttributeError): - mod.call('embedded null byte', test_obj, *args, **kwd) - - def test_hpycallable_check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyCallable_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - - def f(): - return "this is f" - - assert mod.f(f) is True - assert mod.f(str) is True - assert mod.f("a") is False - assert mod.f(3) is False diff --git a/graalpython/hpy/test/test_capsule.py b/graalpython/hpy/test/test_capsule.py deleted file mode 100644 index 546b264f01..0000000000 --- a/graalpython/hpy/test/test_capsule.py +++ /dev/null @@ -1,471 +0,0 @@ -""" -NOTE: these tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -import pytest -from .support import HPyTest, DefaultExtensionTemplate - -class CapsuleTemplate(DefaultExtensionTemplate): - - def DEFINE_strdup(self): - return """ - #include - - static char *strdup0(const char *s) - { - size_t n = strlen(s) + 1; - char *copy = (char *) malloc(n * sizeof(char)); - if (copy == NULL) { - return NULL; - } - strncpy(copy, s, n); - return copy; - } - """ - - def DEFINE_SomeObject(self): - return """ - #include - - typedef struct { - int value; - char message[]; - } SomeObject; - - static SomeObject *create_payload(int value, char *message) - { - size_t n_message = strlen(message) + 1; - SomeObject *pointer = (SomeObject *) - malloc(sizeof(SomeObject) + n_message * sizeof(char)); - if (pointer == NULL) { - return NULL; - } - pointer->value = value; - strncpy(pointer->message, message, n_message); - return pointer; - } - """ - - def DEFINE_Capsule_New(self, destructor="NULL"): - return """ - #include - - static const char *_capsule_name = "some_capsule"; - - #define CAPSULE_NAME _capsule_name - - HPyDef_METH(Capsule_New, "capsule_new", HPyFunc_VARARGS) - static HPy Capsule_New_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy res; - int value; - char *message; - void *ptr; - - if (nargs > 0) - { - if (!HPyArg_Parse(ctx, NULL, args, nargs, "is", &value, &message)) { - return HPy_NULL; - } - ptr = (void *) create_payload(value, message); - if (ptr == NULL) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "out of memory"); - return HPy_NULL; - } - res = HPyCapsule_New(ctx, ptr, CAPSULE_NAME, %s); - if (HPy_IsNull(res)) { - free(ptr); - } - return res; - } - /* just for error case testing */ - return HPyCapsule_New(ctx, NULL, CAPSULE_NAME, NULL); - } - """ % destructor - - def DEFINE_Payload_Free(self): - return """ - #include - - HPyDef_METH(Payload_Free, "payload_free", HPyFunc_O) - static HPy Payload_Free_impl(HPyContext *ctx, HPy self, HPy arg) - { - const char *name = HPyCapsule_GetName(ctx, arg); - if (name == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - - void *pointer = HPyCapsule_GetPointer(ctx, arg, name); - if (pointer == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - free(pointer); - - void *context = HPyCapsule_GetContext(ctx, arg); - if (context == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - free(context); - - return HPy_Dup(ctx, ctx->h_None); - } - """ - - def DEFINE_Capsule_GetName(self): - return """ - HPyDef_METH(Capsule_GetName, "capsule_getname", HPyFunc_O) - static HPy Capsule_GetName_impl(HPyContext *ctx, HPy self, HPy arg) - { - const char *name = HPyCapsule_GetName(ctx, arg); - if (name == NULL) { - return HPy_NULL; - } - return HPyUnicode_FromString(ctx, name); - } - """ - - def DEFINE_Capsule_GetPointer(self): - return """ - static HPy payload_as_tuple(HPyContext *ctx, SomeObject *pointer) - { - HPy value = HPyLong_FromLong(ctx, pointer->value); - HPy message = HPyUnicode_FromString(ctx, pointer->message); - HPy result = HPyTuple_Pack(ctx, 2, value, message); - HPy_Close(ctx, value); - HPy_Close(ctx, message); - return result; - } - - HPyDef_METH(Capsule_GetPointer, "capsule_getpointer", HPyFunc_O) - static HPy Capsule_GetPointer_impl(HPyContext *ctx, HPy self, HPy arg) - { - SomeObject *pointer = (SomeObject *) HPyCapsule_GetPointer(ctx, arg, CAPSULE_NAME); - if (pointer == NULL) { - return HPy_NULL; - } - return payload_as_tuple(ctx, pointer); - } - """ - -class TestHPyCapsule(HPyTest): - - ExtensionTemplate = CapsuleTemplate - - def test_capsule_new(self): - import pytest - mod = self.make_module(""" - @DEFINE_SomeObject - @DEFINE_Capsule_New - @DEFINE_Capsule_GetName - @DEFINE_Payload_Free - - @EXPORT(Capsule_New) - @EXPORT(Capsule_GetName) - @EXPORT(Payload_Free) - - @INIT - """) - p = mod.capsule_new(789, "Hello, World!") - try: - assert mod.capsule_getname(p) == "some_capsule" - finally: - # manually free the payload to avoid a memleak - mod.payload_free(p) - with pytest.raises(ValueError): - mod.capsule_new() - - def test_capsule_getter_and_setter(self): - import pytest - mod = self.make_module(""" - #include - - @DEFINE_strdup - @DEFINE_SomeObject - @DEFINE_Capsule_New - @DEFINE_Capsule_GetPointer - @DEFINE_Capsule_GetName - @DEFINE_Payload_Free - - HPyDef_METH(Capsule_SetPointer, "capsule_setpointer", HPyFunc_VARARGS) - static HPy Capsule_SetPointer_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy capsule; - int value; - char *message; - int non_null_pointer; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Oisi", - &capsule, &value, &message, &non_null_pointer)) { - return HPy_NULL; - } - - /* avoid memleak; get and later free previous pointer */ - void *old_ptr= HPyCapsule_GetPointer(ctx, capsule, CAPSULE_NAME); - if (old_ptr == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - - SomeObject *pointer = NULL; - if (non_null_pointer) { - pointer = create_payload(value, message); - if (pointer == NULL) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "out of memory"); - return HPy_NULL; - } - } - - if (HPyCapsule_SetPointer(ctx, capsule, (void *) pointer) < 0) { - if (non_null_pointer) { - free(pointer); - } - return HPy_NULL; - } - free(old_ptr); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(Capsule_GetContext, "capsule_getcontext", HPyFunc_O) - static HPy Capsule_GetContext_impl(HPyContext *ctx, HPy self, HPy arg) - { - SomeObject *context = (SomeObject *) HPyCapsule_GetContext(ctx, arg); - if (context == NULL) { - return HPyErr_Occurred(ctx) ? HPy_NULL : HPy_Dup(ctx, ctx->h_None); - } - return payload_as_tuple(ctx, context); - } - - HPyDef_METH(Capsule_SetContext, "capsule_setcontext", HPyFunc_VARARGS) - static HPy Capsule_SetContext_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy capsule; - int value; - char *message; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Ois", &capsule, &value, &message)) { - return HPy_NULL; - } - - /* avoid memleak; get and free previous context */ - void *old_context = HPyCapsule_GetContext(ctx, capsule); - if (old_context == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - free(old_context); - - SomeObject *context = create_payload(value, message); - if (context == NULL) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "out of memory"); - return HPy_NULL; - } - if (HPyCapsule_SetContext(ctx, capsule, (void *) context) < 0) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(Capsule_SetName, "capsule_setname", HPyFunc_VARARGS) - static HPy Capsule_SetName_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy capsule; - const char *name; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Os", &capsule, &name)) { - return HPy_NULL; - } - - /* avoid memleak; get and free previous context */ - const char *old_name = HPyCapsule_GetName(ctx, capsule); - if (old_name == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - if (old_name != CAPSULE_NAME) { - free((void *) old_name); - } - - char *name_copy = strdup0(name); - if (name_copy == NULL) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "out of memory"); - return HPy_NULL; - } - - if (HPyCapsule_SetName(ctx, capsule, (const char *) name_copy) < 0) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - static HPyCapsule_Destructor invalid_dtor = { NULL, NULL }; - - HPyDef_METH(Capsule_SetDestructor, "capsule_set_destructor", HPyFunc_VARARGS) - static HPy Capsule_SetDestructor_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy capsule; - HPy null_dtor; - HPyCapsule_Destructor *dtor; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &capsule, &null_dtor)) { - return HPy_NULL; - } - - if (HPy_IsTrue(ctx, null_dtor)) { - dtor = NULL; - } else { - dtor = &invalid_dtor; - } - - if (HPyCapsule_SetDestructor(ctx, capsule, dtor) < 0) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(Capsule_free_name, "capsule_freename", HPyFunc_O) - static HPy Capsule_free_name_impl(HPyContext *ctx, HPy self, HPy arg) - { - /* avoid memleak; get and free previous context */ - const char *old_name = HPyCapsule_GetName(ctx, arg); - if (old_name == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - if (old_name != CAPSULE_NAME) { - free((void *) old_name); - } - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(Capsule_New) - @EXPORT(Capsule_GetPointer) - @EXPORT(Capsule_SetPointer) - @EXPORT(Capsule_GetContext) - @EXPORT(Capsule_SetContext) - @EXPORT(Capsule_GetName) - @EXPORT(Capsule_SetName) - @EXPORT(Capsule_SetDestructor) - @EXPORT(Capsule_free_name) - @EXPORT(Payload_Free) - - @INIT - """) - p = mod.capsule_new(789, "Hello, World!") - try: - assert mod.capsule_getpointer(p) == (789, "Hello, World!") - assert mod.capsule_setpointer(p, 456, "lorem ipsum", True) is None - assert mod.capsule_getpointer(p) == (456, "lorem ipsum") - - assert mod.capsule_getcontext(p) == None - assert mod.capsule_setcontext(p, 123, "hello") is None - assert mod.capsule_getcontext(p) == (123, "hello") - - assert mod.capsule_getname(p) == "some_capsule" - assert mod.capsule_setname(p, "foo") is None - assert mod.capsule_getname(p) == "foo" - - assert mod.capsule_set_destructor(p, True) is None - - not_a_capsule = "hello" - with pytest.raises(ValueError): - mod.capsule_getpointer(not_a_capsule) - with pytest.raises(ValueError): - mod.capsule_setpointer(not_a_capsule, 0, "", True) - with pytest.raises(ValueError): - mod.capsule_setpointer(p, 456, "lorem ipsum", False) - with pytest.raises(ValueError): - mod.capsule_getcontext(not_a_capsule) - with pytest.raises(ValueError): - mod.capsule_setcontext(not_a_capsule, 0, "") - with pytest.raises(ValueError): - mod.capsule_getname(not_a_capsule) - with pytest.raises(ValueError): - mod.capsule_setname(not_a_capsule, "") - with pytest.raises(ValueError): - mod.capsule_set_destructor(not_a_capsule, True) - with pytest.raises(ValueError): - mod.capsule_set_destructor(p, False) - finally: - # manually free the payload to avoid a memleak - mod.payload_free(p) - mod.capsule_freename(p) - - def test_capsule_isvalid(self): - import pytest - mod = self.make_module(""" - @DEFINE_SomeObject - @DEFINE_Capsule_New - @DEFINE_Capsule_GetName - @DEFINE_Payload_Free - - HPyDef_METH(Capsule_isvalid, "capsule_isvalid", HPyFunc_VARARGS) - static HPy Capsule_isvalid_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy capsule; - const char *name; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Os", &capsule, &name)) { - return HPy_NULL; - } - return HPyBool_FromLong(ctx, HPyCapsule_IsValid(ctx, capsule, name)); - } - - @EXPORT(Capsule_New) - @EXPORT(Capsule_GetName) - @EXPORT(Capsule_isvalid) - @EXPORT(Payload_Free) - - @INIT - """) - p = mod.capsule_new(789, "Hello, World!") - name = mod.capsule_getname(p) - try: - assert mod.capsule_isvalid(p, name) - assert not mod.capsule_isvalid(p, "asdf") - assert not mod.capsule_isvalid("asdf", name) - finally: - # manually free the payload to avoid a memleak since the - # capsule doesn't have a destructor - mod.payload_free(p) - - @pytest.mark.syncgc - def test_capsule_new_with_destructor(self): - mod = self.make_module(""" - static int pointer_freed = 0; - - HPyCapsule_DESTRUCTOR(mydtor) - static void mydtor_impl(const char *name, void *pointer, void *context) - { - free(pointer); - pointer_freed = 1; - } - - @DEFINE_SomeObject - @DEFINE_Capsule_New(&mydtor) - @DEFINE_Capsule_GetName - @DEFINE_Payload_Free - - HPyDef_METH(Pointer_freed, "pointer_freed", HPyFunc_NOARGS) - static HPy Pointer_freed_impl(HPyContext *ctx, HPy self) - { - return HPyBool_FromLong(ctx, pointer_freed); - } - - @EXPORT(Capsule_New) - @EXPORT(Capsule_GetName) - @EXPORT(Pointer_freed) - - @INIT - """) - p = mod.capsule_new(789, "Hello, World!") - assert mod.capsule_getname(p) == "some_capsule" - del p - assert mod.pointer_freed() - - def test_capsule_new_with_invalid_destructor(self): - import pytest - mod = self.make_module(""" - static HPyCapsule_Destructor mydtor = { NULL, NULL }; - - @DEFINE_SomeObject - @DEFINE_Capsule_New(&mydtor) - @EXPORT(Capsule_New) - @INIT - """) - with pytest.raises(ValueError): - mod.capsule_new(789, "Hello, World!") diff --git a/graalpython/hpy/test/test_capsule_legacy.py b/graalpython/hpy/test/test_capsule_legacy.py deleted file mode 100644 index ed4a0ba936..0000000000 --- a/graalpython/hpy/test/test_capsule_legacy.py +++ /dev/null @@ -1,86 +0,0 @@ -import pytest -from .support import HPyTest, make_hpy_abi_fixture -from .test_capsule import CapsuleTemplate - -hpy_abi = make_hpy_abi_fixture('with hybrid') - -class TestHPyCapsuleLegacy(HPyTest): - - ExtensionTemplate = CapsuleTemplate - - def test_legacy_capsule_compat(self): - import pytest - mod = self.make_module(""" - @DEFINE_strdup - - #include - #include - - static int dummy = 123; - - static void legacy_destructor(PyObject *capsule) - { - /* We need to use C lib 'free' because the string was - created with 'strdup0'. */ - free((void *) PyCapsule_GetName(capsule)); - } - - HPyDef_METH(Create_pycapsule, "create_pycapsule", HPyFunc_O) - static HPy Create_pycapsule_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t n; - const char *name = HPyUnicode_AsUTF8AndSize(ctx, arg, &n); - char *name_copy = strdup0(name); - if (name_copy == NULL) { - HPyErr_SetString(ctx, ctx->h_MemoryError, "out of memory"); - return HPy_NULL; - } - PyObject *legacy_caps = PyCapsule_New(&dummy, (const char *) name_copy, - legacy_destructor); - HPy res = HPy_FromPyObject(ctx, legacy_caps); - Py_DECREF(legacy_caps); - return res; - } - - HPyDef_METH(Capsule_get, "get", HPyFunc_O) - static HPy Capsule_get_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy res = HPy_NULL; - HPy h_value = HPy_NULL; - int *ptr = NULL; - - const char *name = HPyCapsule_GetName(ctx, arg); - if (name == NULL && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - HPy h_name = HPyUnicode_FromString(ctx, name); - if (HPy_IsNull(h_name)) { - goto finish; - } - - ptr = (int *) HPyCapsule_GetPointer(ctx, arg, name); - if (ptr == NULL && HPyErr_Occurred(ctx)) { - goto finish; - } - - h_value = HPyLong_FromLong(ctx, *ptr); - if (HPy_IsNull(h_value)) { - goto finish; - } - - res = HPyTuple_Pack(ctx, 2, h_name, h_value); - - finish: - HPy_Close(ctx, h_name); - HPy_Close(ctx, h_value); - return res; - } - - @EXPORT(Create_pycapsule) - @EXPORT(Capsule_get) - - @INIT - """) - name = "legacy_capsule" - p = mod.create_pycapsule(name) - assert mod.get(p) == (name, 123) diff --git a/graalpython/hpy/test/test_contextvar.py b/graalpython/hpy/test/test_contextvar.py deleted file mode 100644 index dec376a256..0000000000 --- a/graalpython/hpy/test/test_contextvar.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyContextVar(HPyTest): - - def test_basics(self): - mod = self.make_module(""" - HPyDef_METH(new_ctxv, "new_ctxv", HPyFunc_NOARGS) - static HPy new_ctxv_impl(HPyContext *ctx, HPy self) - { - return HPyContextVar_New(ctx, "test_contextvar", HPy_NULL); - } - - HPyDef_METH(set_ctxv, "set_ctxv", HPyFunc_VARARGS) - static HPy set_ctxv_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy obj, val; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &obj, &val)) - return HPy_NULL; - return HPyContextVar_Set(ctx, obj, val); - } - HPyDef_METH(get_ctxv, "get_ctxv", HPyFunc_VARARGS) - static HPy get_ctxv_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy obj, def=HPy_NULL, val; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "O|O", &obj, &def)) - return HPy_NULL; - if (HPyContextVar_Get(ctx, obj, def, &val) < 0) { - return HPy_NULL; - } - return val; - } - - - @EXPORT(new_ctxv) - @EXPORT(get_ctxv) - @EXPORT(set_ctxv) - @INIT - """) - var = mod.new_ctxv() - tok = mod.set_ctxv(var, 4) - assert tok.var is var - four = mod.get_ctxv(var) - assert four == 4 diff --git a/graalpython/hpy/test/test_cpy_compat.py b/graalpython/hpy/test/test_cpy_compat.py deleted file mode 100644 index 8151be0dd9..0000000000 --- a/graalpython/hpy/test/test_cpy_compat.py +++ /dev/null @@ -1,221 +0,0 @@ -import pytest -from .support import HPyTest, make_hpy_abi_fixture, IS_GRAALPY - -class TestCPythonCompatibility(HPyTest): - - hpy_abi = make_hpy_abi_fixture('with hybrid', class_fixture=True) - - # One note about the supports_refcounts() in the tests below: on - # CPython, handles are actually implemented as INCREF/DECREF, so we can - # check e.g. after an HPy_Dup the refcnt is += 1. However, on PyPy they - # are implemented in a completely different way which is unrelated to the - # refcnt (this is the whole point of HPy, after all :)). So in many of the - # following tests, checking the actual result of the function doesn't - # really make sens on PyPy. We still run the functions to ensure they do - # not crash, though. - - def test_abi(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, HPY_ABI); - } - @EXPORT(f) - @INIT - """) - hpy_abi = mod.f() - expected = self.compiler.hpy_abi - if expected in ('hybrid+debug', 'hybrid+trace'): - expected = 'hybrid' - assert hpy_abi == expected - - @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") - def test_frompyobject(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - PyObject *o = PyList_New(0); - Py_ssize_t initial_refcount = o->ob_refcnt; - HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t final_refcount = o->ob_refcnt; - - PyList_Append(o, PyLong_FromLong(1234)); - PyList_Append(o, PyLong_FromSsize_t(final_refcount - - initial_refcount)); - Py_DECREF(o); - return h; - } - @EXPORT(f) - @INIT - """) - x = mod.f() - assert x[0] == 1234 - assert len(x) == 2 - if self.supports_refcounts(): - assert x == [1234, +1] - - def test_frompyobject_null(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPy h = HPy_FromPyObject(ctx, NULL); - if (HPy_IsNull(h)) { - return HPy_Dup(ctx, ctx->h_True); - } - else { - return HPy_Dup(ctx, ctx->h_False); - } - } - @EXPORT(f) - @INIT - """) - assert mod.f() - - def test_aspyobject(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - PyObject *o = HPy_AsPyObject(ctx, arg); - long val = PyLong_AsLong(o); - Py_DecRef(o); - return HPyLong_FromLong(ctx, val*2); - } - @EXPORT(f) - @INIT - """) - assert mod.f(21) == 42 - - def test_aspyobject_null(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - PyObject *o = HPy_AsPyObject(ctx, HPy_NULL); - if (o == NULL) { - return HPy_Dup(ctx, ctx->h_True); - } - else { - return HPy_Dup(ctx, ctx->h_False); - } - } - @EXPORT(f) - @INIT - """) - assert mod.f() - - def test_aspyobject_custom_class(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - PyObject *o = HPy_AsPyObject(ctx, arg); - PyObject *o_res = PyObject_CallMethod(o, "foo", ""); - HPy h_res = HPy_FromPyObject(ctx, o_res); - Py_DecRef(o); - Py_DecRef(o_res); - return h_res; - } - @EXPORT(f) - @INIT - """) - class MyClass: - def foo(self): - return 1234 - obj = MyClass() - assert mod.f(obj) == 1234 - - @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") - def test_hpy_close(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - PyObject *o = PyList_New(0); - - HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t initial_refcount = o->ob_refcnt; - HPy_Close(ctx, h); - Py_ssize_t final_refcount = o->ob_refcnt; - - Py_DECREF(o); - return HPyLong_FromLong(ctx, (long)(final_refcount - - initial_refcount)); - } - @EXPORT(f) - @INIT - """) - x = mod.f() - if self.supports_refcounts(): - assert x == -1 - - @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") - def test_hpy_dup(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - PyObject *o = PyList_New(0); - - HPy h = HPy_FromPyObject(ctx, o); - Py_ssize_t initial_refcount = o->ob_refcnt; - HPy h2 = HPy_Dup(ctx, h); - Py_ssize_t final_refcount = o->ob_refcnt; - - HPy_Close(ctx, h); - HPy_Close(ctx, h2); - Py_DECREF(o); - return HPyLong_FromLong(ctx, (long)(final_refcount - - initial_refcount)); - } - @EXPORT(f) - @INIT - """) - x = mod.f() - if self.supports_refcounts(): - assert x == +1 - - @pytest.mark.skipif(IS_GRAALPY, reason="Crashes on GraalPy") - def test_many_handles(self): - mod = self.make_module(""" - #include - #define NUM_HANDLES 10000 - - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - PyObject *o = PyList_New(0); - Py_ssize_t final_refcount; - - Py_ssize_t result = -42; - HPy handles[NUM_HANDLES]; - int i; - Py_ssize_t initial_refcount = o->ob_refcnt; - for (i = 0; i < NUM_HANDLES; i++) - handles[i] = HPy_FromPyObject(ctx, o); - for (i = 0; i < NUM_HANDLES; i++) - if (HPy_IsNull(handles[i])) - goto error; - for (i = 0; i < NUM_HANDLES; i++) - HPy_Close(ctx, handles[i]); - final_refcount = o->ob_refcnt; - result = final_refcount - initial_refcount; - - error: - return HPyLong_FromLong(ctx, (long)result); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 0 diff --git a/graalpython/hpy/test/test_eval.py b/graalpython/hpy/test/test_eval.py deleted file mode 100644 index 441c0ab838..0000000000 --- a/graalpython/hpy/test/test_eval.py +++ /dev/null @@ -1,87 +0,0 @@ -from .support import HPyTest - -class TestEval(HPyTest): - def test_compile(self): - import pytest - from textwrap import dedent - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - const char *source, *filename; - HPy_SourceKind src_kind; - int src_kind_i; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ssi", &source, &filename, &src_kind_i)) - return HPy_NULL; - - switch (src_kind_i) - { - case 0: src_kind = HPy_SourceKind_Expr; break; - case 1: src_kind = HPy_SourceKind_File; break; - case 2: src_kind = HPy_SourceKind_Single; break; - default: - // just pass through for testing - src_kind = (HPy_SourceKind) src_kind_i; - } - return HPy_Compile_s(ctx, source, filename, src_kind); - } - @EXPORT(f) - @INIT - """) - c0 = mod.f("1 + 2", "hello0.py", 0) - assert c0 - assert c0.co_filename == "hello0.py" - assert eval(c0) == 3 - - c1 = mod.f(dedent(""" - a = 1 - b = 2 - def add(x, y): - return x + y - res = add(a, b) - """), "hello1.py", 1) - globals1 = dict() - locals1 = dict() - assert eval(c1, globals1, locals1) is None - assert "add" in locals1, "was: %r" % locals1 - assert locals1["a"] == 1 - assert locals1["b"] == 2 - assert locals1["res"] == 3 - - c2 = mod.f("x = 1 + 2", "hello2.py", 2) - locals2 = dict() - assert eval(c2, dict(), locals2) is None - assert locals2["x"] == 3 - - with pytest.raises(SyntaxError): - mod.f("1 +.", "hello1.c", 0) - - with pytest.raises(SystemError): - mod.f("1+2", "hello.c", 777) - - def test_eval_code(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 3 args"); - return HPy_NULL; - } - return HPy_EvalCode(ctx, args[0], args[1], args[2]); - } - @EXPORT(f) - @INIT - """) - c0 = compile("a + b", "hello.py", "eval") - assert mod.f(c0, dict(), dict(a=2, b=3)) == 5 - - locals1 = dict(a=10, b=20) - c1 = compile("x = a + b", "hello.py", "exec") - assert mod.f(c1, dict(), locals1) is None - assert locals1['x'] == 30 - - c0 = compile("raise ValueError", "hello.py", "exec") - with pytest.raises(ValueError): - mod.f(c0, dict(__builtins__=__builtins__), dict()) diff --git a/graalpython/hpy/test/test_helpers.py b/graalpython/hpy/test/test_helpers.py deleted file mode 100644 index d16e4632eb..0000000000 --- a/graalpython/hpy/test/test_helpers.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyModuleAddType(HPyTest): - def test_with_spec_only(self): - mod = self.make_module(""" - static HPyType_Spec dummy_spec = { - .name = "mytest.Dummy", - }; - - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - if (!HPyHelpers_AddType(ctx, self, "Dummy", &dummy_spec, NULL)) - { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @INIT - """) - assert not hasattr(mod, "Dummy") - mod.f() - assert isinstance(mod.Dummy, type) - assert mod.Dummy.__name__ == "Dummy" - assert isinstance(mod.Dummy(), mod.Dummy) - - def test_with_spec_and_params(self): - mod = self.make_module(""" - static HPyType_Spec dummy_spec = { - .name = "mytest.Dummy", - }; - - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Base, ctx->h_LongType }, - { (HPyType_SpecParam_Kind)0 } - }; - if (!HPyHelpers_AddType(ctx, self, "Dummy", &dummy_spec, param)) - { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(f) - @INIT - """) - assert not hasattr(mod, "Dummy") - mod.f() - assert isinstance(mod.Dummy, type) - assert mod.Dummy.__name__ == "Dummy" - assert isinstance(mod.Dummy(), mod.Dummy) - assert isinstance(mod.Dummy(), int) - assert mod.Dummy() == 0 - assert mod.Dummy(3) == 3 - - def test_pack_args_and_keywords(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(pack, "pack", HPyFunc_KEYWORDS) - static HPy pack_impl(HPyContext *ctx, HPy self, const HPy *args, - size_t nargs, HPy kwnames) - { - HPy out[] = { HPy_NULL, HPy_NULL }; - HPy result; - if (!HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, kwnames, - &out[0], &out[1])) { - return HPy_NULL; - } - for (int i=0; i < 2; i++) { - if (HPy_IsNull(out[i])) { - out[i] = HPy_Dup(ctx, ctx->h_None); - } - } - result = HPyTuple_FromArray(ctx, out, 2); - for (int i=0; i < 2; i++) { - HPy_Close(ctx, out[i]); - } - return result; - } - - HPyDef_METH(pack_error, "pack_error", HPyFunc_O) - static HPy pack_error_impl(HPyContext *ctx, HPy self, HPy arg) - { - int success; - HPy t = HPy_NULL; - HPy d = HPy_NULL; - const HPy args[] = { ctx->h_None, ctx->h_True, ctx->h_False }; - size_t nargs = sizeof(args); - uint64_t mode = HPyLong_AsUInt64_t(ctx, arg); - switch (mode) { - case 0: - success = HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, - HPy_NULL, NULL, &d); - break; - case 1: - success = HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, - HPy_NULL, &t, NULL); - break; - case 2: - success = HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, - HPy_NULL, NULL, NULL); - break; - case 3: - success = HPyHelpers_PackArgsAndKeywords(ctx, args, nargs, - ctx->h_None, &t, &d); - break; - default: - success = 0; - HPyErr_SetString(ctx, ctx->h_ValueError, - "unknown test mode"); - break; - } - if (success) - return HPy_Dup(ctx, ctx->h_None); - return HPy_NULL; - } - - @EXPORT(pack) - @EXPORT(pack_error) - @INIT - """) - assert mod.pack() == (None, None) - assert mod.pack(1, '2', b'3') == ((1, '2', b'3'), None) - assert mod.pack(1, '2', b'3', a='b', c='d') == ((1, '2', b'3'), dict(a='b', c='d')) - assert mod.pack(a='b', c='d') == (None, dict(a='b', c='d')) - for mode in range(3): - with pytest.raises(SystemError): - mod.pack_error(mode) - with pytest.raises(TypeError): - mod.pack_error(3) diff --git a/graalpython/hpy/test/test_hpybuildvalue.py b/graalpython/hpy/test/test_hpybuildvalue.py deleted file mode 100644 index 059a39ed1c..0000000000 --- a/graalpython/hpy/test/test_hpybuildvalue.py +++ /dev/null @@ -1,218 +0,0 @@ -from .support import HPyTest - - -class TestBuildValue(HPyTest): - - def make_tests_module(self, test_cases): - # Creates a module with function "f", that takes index of a test case - # to execute. Argument test_cases should be a tuple with first item - # being C code of the test case. - # Generates, e.g.: case 0: return HPy_BuildValue(...); - test_cases_c_code = ["case {}: {}; break;".format(i, case[0]) for i, case in enumerate(test_cases)] - return self.make_module(""" - #include - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - {{ - switch (HPyLong_AsLong(ctx, arg)) {{ - {test_cases} - default: - HPyErr_SetString(ctx, ctx->h_ValueError, "Wrong test case number"); - return HPy_NULL; - }} - }} - - @EXPORT(f) - @INIT - """.format(test_cases='\n'.join(test_cases_c_code))) - - def test_formats(self): - test_cases = [ - ('return HPy_BuildValue(ctx, "");', None), - ('return HPy_BuildValue(ctx, "i", 42);', 42), - ('return HPy_BuildValue(ctx, "i", 0);', 0), - ('return HPy_BuildValue(ctx, "i", -1);', -1), - ('return HPy_BuildValue(ctx, "I", 33);', 33), - ('return HPy_BuildValue(ctx, "k", 1);', 1), - ('return HPy_BuildValue(ctx, "K", 6543);', 6543), - ('return HPy_BuildValue(ctx, "n", 9876);', 9876), - ('return HPy_BuildValue(ctx, "l", 345L);', 345), - ('return HPy_BuildValue(ctx, "l", -876L);', -876), - ('return HPy_BuildValue(ctx, "L", 545LL);', 545), - ('return HPy_BuildValue(ctx, "L", -344LL);', -344), - ('return HPy_BuildValue(ctx, "f", 0.25f);', 0.25), - ('return HPy_BuildValue(ctx, "d", 0.25);', 0.25), - ('return HPy_BuildValue(ctx, "ii", -1, 1);', (-1, 1)), - ('return HPy_BuildValue(ctx, "(i)", -1);', (-1,)), - ('return HPy_BuildValue(ctx, "(i,i)", -1, 1);', (-1, 1)), - ('return HPy_BuildValue(ctx, "(ii)", -1, 1);', (-1, 1)), - ('return HPy_BuildValue(ctx, "s", "test string");', 'test string'), - ('return HPy_BuildValue(ctx, "[ii]", 4, 2);', [4, 2]), - ('return HPy_BuildValue(ctx, "[i,i]", 4, 2);', [4, 2]), - ('return HPy_BuildValue(ctx, "[is]", 4, "2");', [4, '2']), - ('return HPy_BuildValue(ctx, "[]");', []), - ('return HPy_BuildValue(ctx, "[(is)((f)[kk])i]", 4, "str", 0.25, 4, 2, 14267);', - [(4, 'str'), ((0.25,), [4, 2]), 14267]), - ('return HPy_BuildValue(ctx, "{s:i, s:f}", "A", 4, "B", 0.25);', - {'A':4, "B":0.25}), - ('return HPy_BuildValue(ctx, "{s:(i,i), s:f}", "A", 4, 4, "B", 0.25);', - {'A':(4, 4), "B":0.25}), - ('return HPy_BuildValue(ctx, "[{s:(i,i), s:f},i]", "A", 4, 4, "B", 0.25, 42);', - [{'A':(4, 4), "B":0.25}, 42]), - ('return HPy_BuildValue(ctx, "({s:(i,i), s:f},[i])", "A", 4, 4, "B", 0.25, 42);', - ({'A':(4, 4), "B":0.25}, [42])), - ] - mod = self.make_tests_module(test_cases) - for i, (code, expected) in enumerate(test_cases): - actual = mod.f(i) - assert actual == expected, code - - def test_bad_formats(self): - test_cases = [ - ('return HPy_BuildValue(ctx, "(q)", 42);', - "bad format char 'q' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "(i", 42);', - "unmatched '(' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "[i", 42);', - "unmatched '[' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "([(i)k", 42);', - "unmatched '(' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "(i]", 42);', - "unmatched '(' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "[i)", 42);', - "unmatched '[' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "N", 42);', - "HPy_BuildValue does not support the 'N' formatting unit."), - ('return HPy_BuildValue(ctx, "{i:i", "foo", 42);', - "unmatched '{' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "{i:i,,}", "foo", 42);', - "unexpected ',' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "{i:ii,}", "foo", 42, 42);', - "missing ',' in the format string passed to HPy_BuildValue"), - ('return HPy_BuildValue(ctx, "{i}", 42);', - "missing ':' in the format string passed to HPy_BuildValue"), - ] - import pytest - mod = self.make_tests_module(test_cases) - for i, (code, expected_error) in enumerate(test_cases): - with pytest.raises(SystemError) as e: - mod.f(i) - assert expected_error in str(e), code - - def test_O_and_aliases(self): - mod = self.make_module(""" - HPyDef_METH(fo, "fo", HPyFunc_O) - static HPy fo_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_BuildValue(ctx, "O", arg); - } - - HPyDef_METH(fs, "fs", HPyFunc_O) - static HPy fs_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_BuildValue(ctx, "S", arg); - } - - @EXPORT(fo) - @EXPORT(fs) - @INIT - """) - - class Dummy: - pass - obj = Dummy() - assert mod.fo(obj) == obj - assert mod.fs(obj) == obj - - def test_O_with_new_object(self): - # HPy_BuildValue does not steal the reference to the object passed as 'O', - # the caller still needs to close it, otherwise -> handle leak - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy o = HPyLong_FromLong(ctx, 42); - HPy result; - if (HPyLong_AsLong(ctx, arg)) { - result = HPy_BuildValue(ctx, "O", o); - } else { - result = HPy_BuildValue(ctx, "(dO)", 0.25, o); - } - HPy_Close(ctx, o); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f(0) == (0.25, 42) - assert mod.f(1) == 42 - - def test_O_with_null(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(no_msg, "no_msg", HPyFunc_O) - static HPy no_msg_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyLong_AsLong(ctx, arg)) { - return HPy_BuildValue(ctx, "O", HPy_NULL); - } else { - return HPy_BuildValue(ctx, "(iO)", 42, HPy_NULL); - } - } - - HPyDef_METH(with_msg, "with_msg", HPyFunc_O) - static HPy with_msg_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyErr_SetString(ctx, ctx->h_ValueError, "Some err msg that will be asserted"); - return no_msg_impl(ctx, self, arg); - } - - @EXPORT(with_msg) - @EXPORT(no_msg) - @INIT - """) - for i in [0, 1]: - with pytest.raises(ValueError) as e: - mod.with_msg(i) - assert "Some err msg that will be asserted" in str(e) - for i in [0, 1]: - with pytest.raises(SystemError) as e: - mod.no_msg(i) - assert 'HPy_NULL object passed to HPy_BuildValue' in str(e) - - - def test_OO_pars_with_new_objects(self): - mod = self.make_module(""" - #include - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy o1 = HPyLong_FromLong(ctx, 1); - HPy o2 = HPyLong_FromLong(ctx, 2); - HPy result = HPy_BuildValue(ctx, "(OO)", o1, o2); - HPy_Close(ctx, o1); - HPy_Close(ctx, o2); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f(None) == (1, 2) - - def test_num_limits(self): - test_cases = [ - ('return HPy_BuildValue(ctx, "(ii)", INT_MIN, INT_MAX);',), - ('return HPy_BuildValue(ctx, "(ll)", LONG_MIN, LONG_MAX);',), - ('return HPy_BuildValue(ctx, "(LL)", LLONG_MIN, LLONG_MAX);',), - ('return HPy_BuildValue(ctx, "(iI)", -1, UINT_MAX);',), - ('return HPy_BuildValue(ctx, "(ik)", -1, ULONG_MAX);',), - ('return HPy_BuildValue(ctx, "(iK)", -1, ULLONG_MAX);',), - ('return HPy_BuildValue(ctx, "(nn)", HPY_SSIZE_T_MIN, HPY_SSIZE_T_MAX);',), - ] - mod = self.make_tests_module(test_cases) - for i, (test,) in enumerate(test_cases): - result = mod.f(i) - assert result[0] < 0, test - assert result[1] > 0, test diff --git a/graalpython/hpy/test/test_hpybytes.py b/graalpython/hpy/test/test_hpybytes.py deleted file mode 100644 index c713bcb97a..0000000000 --- a/graalpython/hpy/test/test_hpybytes.py +++ /dev/null @@ -1,131 +0,0 @@ -from .support import HPyTest - -class TestBytes(HPyTest): - - def test_Check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyBytes_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - class MyBytes(bytes): - pass - - assert mod.f(b'hello') is True - assert mod.f('hello') is False - assert mod.f(MyBytes(b'hello')) is True - - def test_Size(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t a = HPyBytes_Size(ctx, arg); - HPy_ssize_t b = HPyBytes_GET_SIZE(ctx, arg); - return HPyLong_FromLongLong(ctx, 10 * a + b); - } - @EXPORT(f) - @INIT - """) - assert mod.f(b'hello') == 55 - - def test_AsString(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - long res = 0; - HPy_ssize_t n = HPyBytes_Size(ctx, arg); - const char *buf = HPyBytes_AsString(ctx, arg); - for(int i=0; ih_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - class MyDict(dict): - pass - - assert mod.f({}) is True - assert mod.f([]) is False - assert mod.f(MyDict()) is True - - def test_New(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyDict_New(ctx); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == {} - - def test_set_item(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy dict = HPyDict_New(ctx); - if (HPy_IsNull(dict)) - return HPy_NULL; - HPy val = HPyLong_FromLong(ctx, 1234); - if (HPy_SetItem(ctx, dict, arg, val) == -1) - return HPy_NULL; - HPy_Close(ctx, val); - return dict; - } - @EXPORT(f) - @INIT - """) - assert mod.f('hello') == {'hello': 1234} - - def test_get_item(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy key = HPyUnicode_FromString(ctx, "hello"); - if (HPy_IsNull(key)) - return HPy_NULL; - HPy val = HPy_GetItem(ctx, arg, key); - HPy_Close(ctx, key); - if (HPy_IsNull(val)) { - HPyErr_Clear(ctx); - return HPy_Dup(ctx, ctx->h_None); - } - return val; - } - @EXPORT(f) - @INIT - """) - assert mod.f({'hello': 1}) == 1 - assert mod.f({}) is None - - def test_keys(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h_dict = HPy_Is(ctx, arg, ctx->h_None) ? HPy_NULL : arg; - return HPyDict_Keys(ctx, h_dict); - } - @EXPORT(f) - @INIT - """) - - class SubDict(dict): - def keys(self): - return [1, 2, 3] - assert mod.f({}) == [] - assert mod.f({'hello': 1}) == ['hello'] - assert mod.f(SubDict(hello=1)) == ['hello'] - with pytest.raises(SystemError): - mod.f(None) - with pytest.raises(SystemError): - mod.f(42) - - def test_copy(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h_dict = HPy_Is(ctx, arg, ctx->h_None) ? HPy_NULL : arg; - return HPyDict_Copy(ctx, h_dict); - } - @EXPORT(f) - @INIT - """) - dicts = ({}, {'hello': 1}) - for d in dicts: - d_copy = mod.f(d) - assert d_copy == d - assert d_copy is not d - with pytest.raises(SystemError): - mod.f(None) - with pytest.raises(SystemError): - mod.f(42) diff --git a/graalpython/hpy/test/test_hpyerr.py b/graalpython/hpy/test/test_hpyerr.py deleted file mode 100644 index 20426aaa31..0000000000 --- a/graalpython/hpy/test/test_hpyerr.py +++ /dev/null @@ -1,711 +0,0 @@ -import pytest -from .support import HPyTest, SUPPORTS_SYS_EXECUTABLE, trampoline, IS_GRAALPY - - -class TestErr(HPyTest): - - def test_NoMemory(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyErr_NoMemory(ctx); - } - @EXPORT(f) - @INIT - """) - with pytest.raises(MemoryError): - mod.f() - - @pytest.mark.skipif(IS_GRAALPY, reason="Fails transiently on GraalPy especially with xdist") - def test_FatalError(self, python_subprocess, fatal_exit_code): - mod = self.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPy_FatalError(ctx, "boom!"); - // note: no 'return' statement. This also tests that - // the call above is known to never return---otherwise, - // we get a warning from the missing 'return' and it is - // turned into an error. - } - @EXPORT(f) - @INIT - """) - if not SUPPORTS_SYS_EXECUTABLE: - # if sys.executable is not available (e.g. inside pypy app-level) - # tests, then skip the rest of this test - return - # subprocess is not importable in pypy app-level tests - result = python_subprocess.run(mod, "mod.f()") - assert result.returncode == fatal_exit_code - assert result.stdout == b"" - # In Python 3.9, the Py_FatalError() function was replaced with a macro - # which automatically prepends the name of the current function, so - # we have to allow for that difference here: - stderr_msg = result.stderr.splitlines()[0] - assert stderr_msg.startswith(b"Fatal Python error: ") - assert stderr_msg.endswith(b": boom!") - - def test_HPyErr_Occurred(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyLong_AsLong(ctx, arg); - if (HPyErr_Occurred(ctx)) { - return HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); - } - return HPyLong_FromLong(ctx, -1002); - } - @EXPORT(f) - @INIT - """) - assert mod.f(-10) == -1002 - with pytest.raises(ValueError) as exc: - mod.f("not an integer") - assert str(exc.value) == 'hello world' - - def test_HPyErr_Cleared(self): - import sys - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); - HPyErr_Clear(ctx); - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - assert mod.f() is None - assert sys.exc_info() == (None, None, None) - - def test_HPyErr_SetString(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyErr_SetString(ctx, ctx->h_ValueError, "error message"); - } - - HPyDef_METH(g, "g", HPyFunc_NOARGS) - static HPy g_impl(HPyContext *ctx, HPy self) - { - HPyErr_SetString(ctx, ctx->h_ValueError, "error message"); - return HPy_NULL; - } - - @EXPORT(g) - @EXPORT(f) - @INIT - """) - with pytest.raises(ValueError) as err: - mod.f() - assert str(err.value) == "error message" - - with pytest.raises(ValueError) as err: - mod.g() - assert str(err.value) == "error message" - - def test_HPyErr_SetObject(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyErr_SetObject(ctx, ctx->h_ValueError, arg); - } - @EXPORT(f) - @INIT - """) - with pytest.raises(ValueError) as err: - mod.f(ValueError("error message")) - assert str(err.value) == "error message" - - def test_HPyErr_SetFromErrno(self): - import pytest - import errno - mod = self.make_module(""" - #include - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy type) - {{ - errno = {errno}; - return HPyErr_SetFromErrno(ctx, type); - }} - @EXPORT(f) - @INIT - """.format(errno = errno.EINVAL)) - for type in [OSError, TimeoutError]: - with pytest.raises(type) as err: - mod.f(type) - - assert err.value.errno == errno.EINVAL - - def test_HPyErr_SetFromErrnoWithFilenameObjects(self): - import pytest - import errno - mod = self.make_module(""" - #include - - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - {{ - HPy type, file1, file2; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &type, &file1, &file2)) - return HPy_NULL; - - errno = {errno}; - if (HPy_Is(ctx, file2, ctx->h_None)) {{ - return HPyErr_SetFromErrnoWithFilenameObject(ctx, type, file1); - }} else {{ - return HPyErr_SetFromErrnoWithFilenameObjects(ctx, type, file1, file2); - }} - }} - @EXPORT(f) - @INIT - """.format(errno = errno.EINVAL)) - file1 = "some/file/name/to/be/asserted" - with pytest.raises(OSError) as err: - mod.f(OSError, file1, None) - assert err.value.errno == errno.EINVAL - assert err.value.filename == file1 - - file2 = "some/different/file/name/to/be/asserted" - with pytest.raises(OSError) as err: - mod.f(OSError, file1, file2) - assert err.value.errno == errno.EINVAL - assert err.value.filename == file1 - assert err.value.filename2 == file2 - - def test_HPyErr_SetFromErrnoWithFilename(self): - import pytest - import errno - mod = self.make_module(""" - #include - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy type) - {{ - errno = {errno}; - return HPyErr_SetFromErrnoWithFilename(ctx, type, "Some message that will be asserted"); - }} - @EXPORT(f) - @INIT - """.format(errno = errno.EINVAL)) - with pytest.raises(OSError) as err: - mod.f(OSError) - - assert err.value.errno == errno.EINVAL - assert "Some message that will be asserted" in str(err.value) - - def test_h_exceptions(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h_dict, h_err; - h_dict = HPyDict_New(ctx); - HPy_SetItem_s(ctx, h_dict, "BaseException", ctx->h_BaseException); - HPy_SetItem_s(ctx, h_dict, "Exception", ctx->h_Exception); - HPy_SetItem_s(ctx, h_dict, "StopAsyncIteration", ctx->h_StopAsyncIteration); - HPy_SetItem_s(ctx, h_dict, "StopIteration", ctx->h_StopIteration); - HPy_SetItem_s(ctx, h_dict, "GeneratorExit", ctx->h_GeneratorExit); - HPy_SetItem_s(ctx, h_dict, "ArithmeticError", ctx->h_ArithmeticError); - HPy_SetItem_s(ctx, h_dict, "LookupError", ctx->h_LookupError); - HPy_SetItem_s(ctx, h_dict, "AssertionError", ctx->h_AssertionError); - HPy_SetItem_s(ctx, h_dict, "AttributeError", ctx->h_AttributeError); - HPy_SetItem_s(ctx, h_dict, "BufferError", ctx->h_BufferError); - HPy_SetItem_s(ctx, h_dict, "EOFError", ctx->h_EOFError); - HPy_SetItem_s(ctx, h_dict, "FloatingPointError", ctx->h_FloatingPointError); - HPy_SetItem_s(ctx, h_dict, "OSError", ctx->h_OSError); - HPy_SetItem_s(ctx, h_dict, "ImportError", ctx->h_ImportError); - HPy_SetItem_s(ctx, h_dict, "ModuleNotFoundError", ctx->h_ModuleNotFoundError); - HPy_SetItem_s(ctx, h_dict, "IndexError", ctx->h_IndexError); - HPy_SetItem_s(ctx, h_dict, "KeyError", ctx->h_KeyError); - HPy_SetItem_s(ctx, h_dict, "KeyboardInterrupt", ctx->h_KeyboardInterrupt); - HPy_SetItem_s(ctx, h_dict, "MemoryError", ctx->h_MemoryError); - HPy_SetItem_s(ctx, h_dict, "NameError", ctx->h_NameError); - HPy_SetItem_s(ctx, h_dict, "OverflowError", ctx->h_OverflowError); - HPy_SetItem_s(ctx, h_dict, "RuntimeError", ctx->h_RuntimeError); - HPy_SetItem_s(ctx, h_dict, "RecursionError", ctx->h_RecursionError); - HPy_SetItem_s(ctx, h_dict, "NotImplementedError", ctx->h_NotImplementedError); - HPy_SetItem_s(ctx, h_dict, "SyntaxError", ctx->h_SyntaxError); - HPy_SetItem_s(ctx, h_dict, "IndentationError", ctx->h_IndentationError); - HPy_SetItem_s(ctx, h_dict, "TabError", ctx->h_TabError); - HPy_SetItem_s(ctx, h_dict, "ReferenceError", ctx->h_ReferenceError); - HPy_SetItem_s(ctx, h_dict, "SystemError", ctx->h_SystemError); - HPy_SetItem_s(ctx, h_dict, "SystemExit", ctx->h_SystemExit); - HPy_SetItem_s(ctx, h_dict, "TypeError", ctx->h_TypeError); - HPy_SetItem_s(ctx, h_dict, "UnboundLocalError", ctx->h_UnboundLocalError); - HPy_SetItem_s(ctx, h_dict, "ValueError", ctx->h_ValueError); - HPy_SetItem_s(ctx, h_dict, "ZeroDivisionError", ctx->h_ZeroDivisionError); - HPy_SetItem_s(ctx, h_dict, "BlockingIOError", ctx->h_BlockingIOError); - HPy_SetItem_s(ctx, h_dict, "BrokenPipeError", ctx->h_BrokenPipeError); - HPy_SetItem_s(ctx, h_dict, "ChildProcessError", ctx->h_ChildProcessError); - HPy_SetItem_s(ctx, h_dict, "ConnectionError", ctx->h_ConnectionError); - HPy_SetItem_s(ctx, h_dict, "ConnectionAbortedError", ctx->h_ConnectionAbortedError); - HPy_SetItem_s(ctx, h_dict, "ConnectionRefusedError", ctx->h_ConnectionRefusedError); - HPy_SetItem_s(ctx, h_dict, "ConnectionResetError", ctx->h_ConnectionResetError); - HPy_SetItem_s(ctx, h_dict, "FileExistsError", ctx->h_FileExistsError); - HPy_SetItem_s(ctx, h_dict, "FileNotFoundError", ctx->h_FileNotFoundError); - HPy_SetItem_s(ctx, h_dict, "InterruptedError", ctx->h_InterruptedError); - HPy_SetItem_s(ctx, h_dict, "IsADirectoryError", ctx->h_IsADirectoryError); - HPy_SetItem_s(ctx, h_dict, "NotADirectoryError", ctx->h_NotADirectoryError); - HPy_SetItem_s(ctx, h_dict, "PermissionError", ctx->h_PermissionError); - HPy_SetItem_s(ctx, h_dict, "ProcessLookupError", ctx->h_ProcessLookupError); - HPy_SetItem_s(ctx, h_dict, "TimeoutError", ctx->h_TimeoutError); - h_err = HPy_GetItem(ctx, h_dict, arg); - if (HPy_IsNull(h_err)) { - HPy_FatalError(ctx, "missing exception type"); - } - HPyErr_SetString(ctx, h_err, "error message"); - HPy_Close(ctx, h_dict); - HPy_Close(ctx, h_err); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - - def check_exception(cls): - with pytest.raises(cls): - mod.f(cls.__name__) - - check_exception(BaseException) - check_exception(Exception) - check_exception(StopAsyncIteration) - check_exception(StopIteration) - check_exception(GeneratorExit) - check_exception(ArithmeticError) - check_exception(LookupError) - check_exception(AssertionError) - check_exception(AttributeError) - check_exception(BufferError) - check_exception(EOFError) - check_exception(FloatingPointError) - check_exception(OSError) - check_exception(ImportError) - check_exception(ModuleNotFoundError) - check_exception(IndexError) - check_exception(KeyError) - check_exception(KeyboardInterrupt) - check_exception(MemoryError) - check_exception(NameError) - check_exception(OverflowError) - check_exception(RuntimeError) - check_exception(RecursionError) - check_exception(NotImplementedError) - check_exception(SyntaxError) - check_exception(IndentationError) - check_exception(TabError) - check_exception(ReferenceError) - check_exception(SystemError) - check_exception(SystemExit) - check_exception(TypeError) - check_exception(UnboundLocalError) - check_exception(ValueError) - check_exception(ZeroDivisionError) - check_exception(BlockingIOError) - check_exception(BrokenPipeError) - check_exception(ChildProcessError) - check_exception(ConnectionError) - check_exception(ConnectionAbortedError) - check_exception(ConnectionRefusedError) - check_exception(ConnectionResetError) - check_exception(FileExistsError) - check_exception(FileNotFoundError) - check_exception(InterruptedError) - check_exception(IsADirectoryError) - check_exception(NotADirectoryError) - check_exception(PermissionError) - check_exception(ProcessLookupError) - check_exception(TimeoutError) - # EnvironmentError and IOError are not explicitly defined by HPy - # but they work because they are actually OSError. - check_exception(EnvironmentError) - check_exception(IOError) - - def test_h_unicode_exceptions(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy h_key, h_args, h_kw; - HPy h_dict, h_err, h_err_value; - - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &h_key, &h_args, &h_kw)) - return HPy_NULL; - - h_dict = HPyDict_New(ctx); - if (HPy_IsNull(h_dict)) { - return HPy_NULL; - } - HPy_SetItem_s(ctx, h_dict, "UnicodeError", ctx->h_UnicodeError); - HPy_SetItem_s(ctx, h_dict, "UnicodeEncodeError", ctx->h_UnicodeEncodeError); - HPy_SetItem_s(ctx, h_dict, "UnicodeDecodeError", ctx->h_UnicodeDecodeError); - HPy_SetItem_s(ctx, h_dict, "UnicodeTranslateError", ctx->h_UnicodeTranslateError); - - h_err = HPy_GetItem(ctx, h_dict, h_key); - if (HPy_IsNull(h_err)) { - HPy_Close(ctx, h_dict); - return HPy_NULL; - } - h_err_value = HPy_CallTupleDict(ctx, h_err, h_args, h_kw); - if (HPy_IsNull(h_err_value)) { - HPy_Close(ctx, h_dict); - HPy_Close(ctx, h_err); - return HPy_NULL; - } - - HPyErr_SetObject(ctx, h_err, h_err_value); - HPy_Close(ctx, h_dict); - HPy_Close(ctx, h_err); - HPy_Close(ctx, h_err_value); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - - def check_exception(cls, *args, **kw): - with pytest.raises(cls): - mod.f(cls.__name__, args, kw) - - check_exception(UnicodeError) - check_exception( - UnicodeEncodeError, "utf-8", "object", 0, 2, "reason" - ) - check_exception( - UnicodeDecodeError, "utf-8", b"object", 0, 2, "reason" - ) - check_exception(UnicodeTranslateError, "object", 0, 2, "reason") - - def test_h_warnings(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy h_dict, h_err; - h_dict = HPyDict_New(ctx); - HPy_SetItem_s(ctx, h_dict, "Warning", ctx->h_Warning); - HPy_SetItem_s(ctx, h_dict, "UserWarning", ctx->h_UserWarning); - HPy_SetItem_s(ctx, h_dict, "DeprecationWarning", ctx->h_DeprecationWarning); - HPy_SetItem_s(ctx, h_dict, "PendingDeprecationWarning", ctx->h_PendingDeprecationWarning); - HPy_SetItem_s(ctx, h_dict, "SyntaxWarning", ctx->h_SyntaxWarning); - HPy_SetItem_s(ctx, h_dict, "RuntimeWarning", ctx->h_RuntimeWarning); - HPy_SetItem_s(ctx, h_dict, "FutureWarning", ctx->h_FutureWarning); - HPy_SetItem_s(ctx, h_dict, "ImportWarning", ctx->h_ImportWarning); - HPy_SetItem_s(ctx, h_dict, "UnicodeWarning", ctx->h_UnicodeWarning); - HPy_SetItem_s(ctx, h_dict, "BytesWarning", ctx->h_BytesWarning); - HPy_SetItem_s(ctx, h_dict, "ResourceWarning", ctx->h_ResourceWarning); - h_err = HPy_GetItem(ctx, h_dict, arg); - if (HPy_IsNull(h_err)) { - HPy_FatalError(ctx, "missing exception type"); - } - HPyErr_SetString(ctx, h_err, "error message"); - HPy_Close(ctx, h_dict); - HPy_Close(ctx, h_err); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - - def check_warning(cls): - with pytest.raises(cls): - mod.f(cls.__name__) - - check_warning(Warning) - check_warning(UserWarning) - check_warning(DeprecationWarning) - check_warning(PendingDeprecationWarning) - check_warning(SyntaxWarning) - check_warning(RuntimeWarning) - check_warning(FutureWarning) - check_warning(ImportWarning) - check_warning(UnicodeWarning) - check_warning(BytesWarning) - check_warning(ResourceWarning) - - def test_HPyErr_WarnEx(self): - import warnings - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - switch (HPyLong_AsLong(ctx, arg)) { - case 0: - HPyErr_WarnEx(ctx, ctx->h_RuntimeWarning, "warn qzp", 1); - break; - case 1: - HPyErr_WarnEx(ctx, ctx->h_FutureWarning, "warn rtq", 2); - break; - case 2: - HPyErr_WarnEx(ctx, HPy_NULL, "warn null", 1); - break; - } - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - - # NOTE: trampoline is defined in support.py - def check_warning(arg, category, message, file): - with warnings.catch_warnings(record=True) as warnings_list: - trampoline(mod.f, arg) - assert len(warnings_list) == 1, str(category) - w = warnings_list[-1] - assert issubclass(w.category, category), str(category) - assert str(w.message) == message, str(category) - assert w.filename.endswith(file), str(category) - - check_warning(0, RuntimeWarning, "warn qzp", "support.py") - check_warning(1, FutureWarning, "warn rtq", "test_hpyerr.py") - check_warning(2, Warning, "warn null", "support.py") - - - def test_errorval_returned_by_api_functions_hpy(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy a = HPy_NULL; - HPy b = HPy_NULL; - HPy res; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - res = HPy_TrueDivide(ctx, a, b); - - // the point of the test is to check that in case of error - // HPy_Div returns HPy_NULL - if (HPy_IsNull(res)) { - HPyErr_Clear(ctx); - return HPyLong_FromLong(ctx, -42); - } - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f(21, 3) == 7 - assert mod.f(21, 0) == -42 - - def test_errorval_returned_by_api_functions_int(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t length = HPy_Length(ctx, arg); - if (length == -1) { - HPyErr_Clear(ctx); - return HPyLong_FromLong(ctx, -42); - } - return HPyLong_FromLong(ctx, (long) length); - } - @EXPORT(f) - @INIT - """) - assert mod.f([100, 200, 300]) == 3 - assert mod.f(None) == -42 - - def test_HPyErr_NewException(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - // MSVC doesn't allow "static HPy h_FooErr = HPy_NULL" - // so we do an initialization dance instead. - static int foo_error_initialized = 0; - static HPy h_FooError; - HPy arg; - HPy h_base = HPy_NULL; - HPy h_dict = HPy_NULL; - HPy h_doc = HPy_NULL; - - if (!foo_error_initialized) { - foo_error_initialized = 1; - h_FooError = HPy_NULL; - } - - if (!HPyArg_Parse(ctx, NULL, args, nargs, "O|OOO", &arg, &h_base, &h_dict, &h_doc)) { - return HPy_NULL; - } - - if (!HPy_IsTrue(ctx, arg)) { - // cleanup and close the FooError which we created earlier - if (!HPy_IsNull(h_FooError)) - HPy_Close(ctx, h_FooError); - return HPy_Dup(ctx, ctx->h_None); - } - - if(HPy_Is(ctx, h_base, ctx->h_None)) { - h_base = HPy_NULL; - } - - if(HPy_Is(ctx, h_dict, ctx->h_None)) { - h_dict = HPy_NULL; - } - - if(HPy_Is(ctx, h_doc, ctx->h_None)) { - h_FooError = HPyErr_NewException(ctx, "mytest.FooError", h_base, h_dict); - } else { - // we use bytes because ATM we don't have HPyUnicode_AsUTF8 or similar - h_FooError = HPyErr_NewExceptionWithDoc(ctx, "mytest.FooError", - HPyBytes_AsString(ctx, h_doc), h_base, h_dict); - } - - if (HPy_IsNull(h_FooError)) - return HPy_NULL; - HPyErr_SetString(ctx, h_FooError, "hello"); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - - def check(base, dict_, doc): - with pytest.raises(Exception) as exc: - mod.f(True, base, dict_, doc) - assert issubclass(exc.type, RuntimeError if base else Exception) - assert exc.type.__name__ == 'FooError', exc.value - assert exc.type.__module__ == 'mytest' - if doc is None: - assert exc.type.__doc__ is None - else: - assert exc.type.__doc__ == doc.decode("utf-8") - - if dict_: - assert exc.type.__dict__["test"] == "pass" - mod.f(False, None, None, None) # cleanup - - check(base=None, dict_=None, doc=None) - check(base=None, dict_=None, doc=b'mytest') - check(base=None, dict_={"test": "pass"}, doc=None) - check(base=None, dict_={"test": "pass"}, doc=b'mytest') - check(base=RuntimeError, dict_=None, doc=None) - check(base=RuntimeError, dict_=None, doc=b'mytest') - check(base=RuntimeError, dict_={"test": "pass"}, doc=None) - check(base=RuntimeError, dict_={"test": "pass"}, doc=b'mytest') - - def test_exception_matches(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPyTracker ht; - HPy fun, fun_args; - HPy expected_exc_type; - HPy tmp; - HPy result; - - if (!HPyArg_Parse(ctx, &ht, args, nargs, "OOO", &fun, &fun_args, &expected_exc_type)) { - return HPy_NULL; - } - - tmp = HPy_CallTupleDict(ctx, fun, fun_args, HPy_NULL); - if (HPy_IsNull(tmp)) { - if (HPyErr_ExceptionMatches(ctx, expected_exc_type)) { - HPyErr_Clear(ctx); - result = HPy_Dup(ctx, ctx->h_True); - } else { - // propagate the unexpected exception to the caller - result = HPy_NULL; - } - } else { - HPy_Close(ctx, tmp); - result = HPy_Dup(ctx, ctx->h_False); - } - - HPyTracker_Close(ctx, ht); - return result; - } - @EXPORT(f) - @INIT - """) - - class DummyException(Exception): - pass - - def raise_exception(e): - raise e - - def do_not_raise_exception(*args): - return None - - exc_types = (StopAsyncIteration, StopIteration, GeneratorExit, ArithmeticError, LookupError, AssertionError, - AttributeError, BufferError, EOFError, FloatingPointError, OSError, ImportError, ModuleNotFoundError, IndexError, - KeyError, KeyboardInterrupt, MemoryError, NameError, OverflowError, RuntimeError, RecursionError, NotImplementedError, - SyntaxError, IndentationError, TabError, ReferenceError, SystemError, SystemExit, TypeError, UnboundLocalError, - ValueError, ZeroDivisionError, BlockingIOError, BrokenPipeError, ChildProcessError, ConnectionError, ConnectionAbortedError, - ConnectionRefusedError, ConnectionResetError, FileExistsError, FileNotFoundError, InterruptedError, IsADirectoryError, - NotADirectoryError, PermissionError, ProcessLookupError, TimeoutError) - - # just a sanity check of the extension function - assert not mod.f(do_not_raise_exception, tuple(), DummyException) - - # test with "leaf" exception - assert mod.f(raise_exception, (DummyException, ), DummyException) - with pytest.raises(DummyException): - mod.f(raise_exception, (DummyException, ), StopIteration) - - # test exception subclass - for exc_type in exc_types: - assert mod.f(raise_exception, (exc_type, ), BaseException) - assert mod.f(raise_exception, (DummyException, ), BaseException) - - # match whole tuple - for exc_type in exc_types: - res = mod.f(raise_exception, (exc_type, ), exc_types) - with pytest.raises(DummyException): - mod.f(raise_exception, (DummyException, ), exc_types) - - @pytest.mark.skipif(IS_GRAALPY, reason="Fails transiently on GraalPy especially with xdist") - def test_HPyErr_WriteUnraisable(self, python_subprocess): - mod = self.compile_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPyErr_SetString(ctx, ctx->h_ValueError, "error message"); - HPyErr_WriteUnraisable(ctx, HPy_NULL); - return HPyBool_FromLong(ctx, HPyErr_Occurred(ctx)); - } - @EXPORT(f) - @INIT - """) - if not SUPPORTS_SYS_EXECUTABLE: - # if sys.executable is not available (e.g. inside pypy app-level) - # tests, then skip the rest of this test - return - # subprocess is not importable in pypy app-level tests - result = python_subprocess.run(mod, "mod.f()") - assert result.returncode == 0 - - - def test_HPyErr_Format(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyErr_Format(ctx, ctx->h_ValueError, "Formatted '%S' and %d", arg, 42); - } - @EXPORT(f) - @INIT - """) - with pytest.raises(ValueError, match="Formatted 'error message' and 42"): - mod.f("error message") diff --git a/graalpython/hpy/test/test_hpyfield.py b/graalpython/hpy/test/test_hpyfield.py deleted file mode 100644 index 5e67515a13..0000000000 --- a/graalpython/hpy/test/test_hpyfield.py +++ /dev/null @@ -1,429 +0,0 @@ -""" -NOTE: these tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -import pytest -from .support import HPyTest, DefaultExtensionTemplate - -class PairTemplate(DefaultExtensionTemplate): - - def DEFINE_PairObject(self): - return """ - typedef struct { - HPyField a; - HPyField b; - } PairObject; - - HPyType_HELPERS(PairObject); - """ - - def DEFINE_Pair_new(self): - return """ - HPyDef_SLOT(Pair_new, HPy_tp_new) - static HPy Pair_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - HPy a; - HPy b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - PairObject *pair; - HPy h_obj = HPy_New(ctx, cls, &pair); - HPyField_Store(ctx, h_obj, &pair->a, a); - HPyField_Store(ctx, h_obj, &pair->b, b); - return h_obj; - } - """ - - def DEFINE_Pair_traverse(self): - return """ - HPyDef_SLOT(Pair_traverse, HPy_tp_traverse) - static int Pair_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) - { - PairObject *p = (PairObject *)self; - HPy_VISIT(&p->a); - HPy_VISIT(&p->b); - return 0; - } - """ - - def DEFINE_Pair_set_a(self): - return """ - HPyDef_METH(Pair_set_a, "set_a", HPyFunc_O) - static HPy Pair_set_a_impl(HPyContext *ctx, HPy self, HPy arg) - { - PairObject *pair = PairObject_AsStruct(ctx, self); - HPyField_Store(ctx, self, &pair->a, arg); - return HPy_Dup(ctx, ctx->h_None); - } - """ - - def DEFINE_Pair_get_ab(self): - return """ - HPyDef_METH(Pair_get_a, "get_a", HPyFunc_NOARGS) - static HPy Pair_get_a_impl(HPyContext *ctx, HPy self) - { - PairObject *pair = PairObject_AsStruct(ctx, self); - if (HPy_IsNull(pair->a)) - return HPyUnicode_FromString(ctx, ""); - return HPyField_Load(ctx, self, pair->a); - } - - HPyDef_METH(Pair_get_b, "get_b", HPyFunc_NOARGS) - static HPy Pair_get_b_impl(HPyContext *ctx, HPy self) - { - PairObject *pair = PairObject_AsStruct(ctx, self); - if (HPy_IsNull(pair->b)) - return HPyUnicode_FromString(ctx, ""); - return HPyField_Load(ctx, self, pair->b); - } - """ - - pair_type_flags = 'HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_HAVE_GC' - def PAIR_TYPE_FLAGS(self, flags): - self.pair_type_flags = flags - - def EXPORT_PAIR_TYPE(self, *defines): - defines += ('NULL',) - defines = ', '.join(defines) - self.EXPORT_TYPE('"Pair"', "Pair_spec") - return """ - static HPyDef *Pair_defines[] = { %s }; - static HPyType_Spec Pair_spec = { - .name = "mytest.Pair", - .basicsize = sizeof(PairObject), - .flags = %s, - .defines = Pair_defines - }; - """ % (defines, self.pair_type_flags) - -class TestHPyField(HPyTest): - - ExtensionTemplate = PairTemplate - - def test_gc_track(self): - if not self.supports_refcounts(): - import pytest - pytest.skip("CPython only") - import sys - # Test that we correctly call PyObject_GC_Track on CPython. The - # easiest way is to check whether the object is in - # gc.get_objects(). - import gc - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse) - @INIT - """) - p = mod.Pair("hello", "world") - assert gc.is_tracked(p) - - def test_gc_track_no_gc_flag(self): - if not self.supports_refcounts(): - import pytest - pytest.skip("CPython only") - # Same code as test_gc_track, but without HPy_TPFLAGS_HAVE_GC. On - # CPython, the object is NOT tracked. - import gc - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - - @PAIR_TYPE_FLAGS(HPy_TPFLAGS_DEFAULT) - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse) - @INIT - """) - p = mod.Pair("hello", "world") - assert not gc.is_tracked(p) - - def test_tp_traverse(self): - if self.is_graalpy: - import pytest - pytest.skip("Crashes on GraalPy") - import gc - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse) - @INIT - """) - p = mod.Pair("hello", "world") - referents = gc.get_referents(p) - referents.sort() - assert referents == ['hello', 'world'] - - def test_tp_traverse_sanity_check(self): - import pytest - with pytest.raises(ValueError): - self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - - // here we are defining a type with HPy_TPFLAGS_HAVE_GC but - // without providing a tp_traverse - @EXPORT_PAIR_TYPE(&Pair_new) - @INIT - """) - - def test_store_load(self): - import sys - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_get_ab - @DEFINE_Pair_traverse - - @PAIR_TYPE_FLAGS(HPy_TPFLAGS_DEFAULT) - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse, &Pair_get_a, &Pair_get_b) - @INIT - """) - p = mod.Pair("hello", "world") - assert p.get_a() == 'hello' - assert p.get_b() == 'world' - # - # check the refcnt - if self.supports_refcounts(): - a = object() - a_refcnt = sys.getrefcount(a) - p2 = mod.Pair(a, None) - assert sys.getrefcount(a) == a_refcnt + 1 - assert p2.get_a() is a - assert sys.getrefcount(a) == a_refcnt + 1 - - def test_store_overwrite(self): - import sys - mod = self.make_module(""" - #include - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_get_ab - @DEFINE_Pair_traverse - @DEFINE_Pair_set_a - - HPyDef_METH(Pair_clear_a, "clear_a", HPyFunc_NOARGS) - static HPy Pair_clear_a_impl(HPyContext *ctx, HPy self) - { - PairObject *pair = PairObject_AsStruct(ctx, self); - HPyField_Store(ctx, self, &pair->a, HPy_NULL); - return HPy_Dup(ctx, ctx->h_None); - } - - @PAIR_TYPE_FLAGS(HPy_TPFLAGS_DEFAULT) - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse, &Pair_get_a, &Pair_get_b, &Pair_set_a, &Pair_clear_a) - @INIT - """) - p = mod.Pair("hello", "world") - assert p.get_a() == 'hello' - assert p.get_b() == 'world' - p.set_a('foo') - assert p.get_a() == 'foo' - p.clear_a() - assert p.get_a() == '' - p.set_a('bar') - assert p.get_a() == 'bar' - # - # check the refcnt - if self.supports_refcounts(): - a = object() - a_refcnt = sys.getrefcount(a) - p2 = mod.Pair(a, None) - assert sys.getrefcount(a) == a_refcnt + 1 - assert p2.get_a() is a - p2.set_a('foo') - assert sys.getrefcount(a) == a_refcnt - p2.set_a(a) - assert sys.getrefcount(a) == a_refcnt + 1 - p2.clear_a() - assert sys.getrefcount(a) == a_refcnt - p2.clear_a() - assert sys.getrefcount(a) == a_refcnt - - def test_automatic_tp_dealloc(self): - import sys - if not self.supports_refcounts(): - import pytest - pytest.skip("CPython only") - - import sys - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse) - @INIT - """) - a = object() - b = object() - p = mod.Pair(a, b) - a_cnt = sys.getrefcount(a) - b_cnt = sys.getrefcount(b) - del p - assert sys.getrefcount(a) == a_cnt - 1 - assert sys.getrefcount(b) == b_cnt - 1 - - @pytest.mark.syncgc - def test_automatic_tp_clear(self): - if not self.supports_refcounts(): - import pytest - pytest.skip("CPython only") - import sys - - import gc - mod = self.make_module(""" - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - @DEFINE_Pair_set_a - - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse, &Pair_set_a) - @INIT - """) - def count_pairs(): - return len([obj for obj in gc.get_objects() if type(obj) is mod.Pair]) - assert count_pairs() == 0 - p1 = mod.Pair(None, 'hello') - p2 = mod.Pair(None, 'world') - p1.set_a(p2) - p2.set_a(p1) - assert count_pairs() == 2 - # - try: - gc.disable() - del p1 - del p2 - assert count_pairs() == 2 - finally: - gc.enable() - # - gc.collect() - assert count_pairs() == 0 - - def test_tp_finalize(self): - if self.is_graalpy: - import pytest - pytest.skip("Crashes on GraalPy") - # Tests the contract of tp_finalize: what it should see - # if called from within HPyField_Store - mod = self.make_module(""" - #include - - @DEFINE_PairObject - @DEFINE_Pair_new - @DEFINE_Pair_traverse - @DEFINE_Pair_set_a - - static bool saw_expected_finalize_call; - static bool unexpected_finalize_call; - static bool test_finished; - - // During the test we check our assumptions with an assert to play - // nicely with pytest, but if the finalizer gets called after the - // test has finished, we have no choice but to abort to signal - // the error - static void on_unexpected_finalize_call(void); - static void on_unexpected_finalize_call() { - if (test_finished) - abort(); - else - unexpected_finalize_call = true; - } - - HPyDef_SLOT(Pair_finalize, HPy_tp_finalize) - static void Pair_finalize_impl(HPyContext *ctx, HPy to_be_finalized) - { - PairObject *pair = PairObject_AsStruct(ctx, to_be_finalized); - - // Check that we were called on the right object: 'to_be_finalized' - HPy to_be_finalized_b = HPyField_Load(ctx, to_be_finalized, pair->b); - if (!HPy_Is(ctx, to_be_finalized_b, ctx->h_True)) { - HPy_Close(ctx, to_be_finalized_b); - // This is OK to happen after the test was finished - unexpected_finalize_call = true; - return; - } - HPy_Close(ctx, to_be_finalized_b); - - // Check that we were not called twice - if (saw_expected_finalize_call) { - printf("tp_finalize called twice for 'to_be_finalized'\\\n"); - on_unexpected_finalize_call(); - return; - } - - HPy owner = HPy_NULL, owner_a = HPy_NULL, owner_b = HPy_NULL; - owner = HPyField_Load(ctx, to_be_finalized, pair->a); - PairObject *owner_pair = PairObject_AsStruct(ctx, owner); - - // Check that 'to_be_finalized'->a really points to 'owner' - owner_b = HPyField_Load(ctx, owner, owner_pair->b); - if (!HPy_Is(ctx, owner_b, ctx->h_False)) { - printf("to_be_finalized'->a != 'owner'\\\n"); - on_unexpected_finalize_call(); - goto owner_cleanup; - } - - // Whatever we see in owner->a must not be 'to_be_finalized' - // For CPython it should be NULL, because Pair_finalize should - // be called immediately when the field is swapped to new value - if (HPyField_IsNull(owner_pair->a)) { - saw_expected_finalize_call = true; - goto owner_cleanup; - } - - // For GC based implementations, it can be already the 42 if - // Pair_finalize gets called later - owner_a = HPyField_Load(ctx, owner, owner_pair->a); - if (HPyLong_AsLong(ctx, owner_a) == 42) { - saw_expected_finalize_call = true; - goto owner_cleanup; - } - - HPyErr_Clear(ctx); // if the field was not a long at all - printf("unexpected value of the field: %p\\\n", (void*) owner_a._i); - on_unexpected_finalize_call(); - owner_cleanup: - HPy_Close(ctx, owner); - HPy_Close(ctx, owner_a); - HPy_Close(ctx, owner_b); - } - - HPyDef_METH(check_finalize_calls, "check_finalize_calls", HPyFunc_NOARGS) - static HPy check_finalize_calls_impl(HPyContext *ctx, HPy self) - { - test_finished = true; - if (!unexpected_finalize_call && saw_expected_finalize_call) - return HPy_Dup(ctx, ctx->h_True); - else - return HPy_Dup(ctx, ctx->h_False); - } - - @EXPORT(check_finalize_calls) - @EXPORT_PAIR_TYPE(&Pair_new, &Pair_traverse, &Pair_finalize, &Pair_set_a) - @INIT - """) - to_be_finalized = mod.Pair(None, True) - owner = mod.Pair(to_be_finalized, False) - to_be_finalized.set_a(owner) - del to_be_finalized - # Now 'to_be_finalized' is referenced only by 'owner'. - # By setting the field to the new value, the object originally pointed - # by 'to_be_finalized' becomes garbage. In CPython, this should - # immediately trigger tp_finalize, in other impls it may also - # trigger tp_finalize at that point or any later point. - # In any case, tp_finalize should not see the original value of the - # field anymore. - owner.set_a(42) - from gc import collect - collect() - assert mod.check_finalize_calls() diff --git a/graalpython/hpy/test/test_hpyglobal.py b/graalpython/hpy/test/test_hpyglobal.py deleted file mode 100644 index 238e6aa7fc..0000000000 --- a/graalpython/hpy/test/test_hpyglobal.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyGlobal(HPyTest): - - def test_basics(self): - mod = self.make_module(""" - HPyGlobal myglobal; - - HPyDef_METH(setg, "setg", HPyFunc_O) - static HPy setg_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPyGlobal_Store(ctx, &myglobal, arg); - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(getg, "getg", HPyFunc_NOARGS) - static HPy getg_impl(HPyContext *ctx, HPy self) - { - return HPyGlobal_Load(ctx, myglobal); - } - - @EXPORT(setg) - @EXPORT(getg) - @EXPORT_GLOBAL(myglobal) - @INIT - """) - obj = {'hello': 'world'} - assert mod.setg(obj) is None - assert mod.getg() is obj diff --git a/graalpython/hpy/test/test_hpyimport.py b/graalpython/hpy/test/test_hpyimport.py deleted file mode 100644 index 7bb922c807..0000000000 --- a/graalpython/hpy/test/test_hpyimport.py +++ /dev/null @@ -1,24 +0,0 @@ -from .support import HPyTest - -class TestImport(HPyTest): - - def test_ImportModule(self): - import pytest - import sys - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy h_name) - { - // we use bytes because ATM we don't have HPyUnicode_AsUTF8 or similar - const char *name = HPyBytes_AsString(ctx, h_name); - if (name == NULL) - return HPy_NULL; - return HPyImport_ImportModule(ctx, name); - } - @EXPORT(f) - @INIT - """) - sys2 = mod.f(b'sys') - assert sys is sys2 - with pytest.raises(ImportError): - mod.f(b'This is the name of a module which does not exist, hopefully') diff --git a/graalpython/hpy/test/test_hpyiter.py b/graalpython/hpy/test/test_hpyiter.py deleted file mode 100644 index 58387253f9..0000000000 --- a/graalpython/hpy/test/test_hpyiter.py +++ /dev/null @@ -1,90 +0,0 @@ -from .support import HPyTest - -class TestIter(HPyTest): - - def test_Check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyIter_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - - class CustomIterable: - def __init__(self): - self._iter = iter([1, 2, 3]) - - def __iter__(self): - return self._iter - - class CustomIterator: - def __init__(self): - self._iter = iter([1, 2, 3]) - - def __iter__(self): - return self._iter - - def __next__(self): - return next(self._iter) - - assert mod.f(object()) is False - assert mod.f(10) is False - - assert mod.f((1, 2)) is False - assert mod.f(iter((1, 2))) is True - - assert mod.f([]) is False - assert mod.f(iter([])) is True - - assert mod.f('hello') is False - assert mod.f(iter('hello')) is True - - assert mod.f(map(int, ("1", "2"))) is True - assert mod.f(range(1, 10)) is False - - assert mod.f(CustomIterable()) is False - assert mod.f(iter(CustomIterable())) is True - assert mod.f(CustomIterator()) is True - - def test_Next(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy result = HPyIter_Next(ctx, arg); - int is_null = HPy_IsNull(result); - - if (is_null && HPyErr_Occurred(ctx)) - return HPy_NULL; - if (is_null) - return HPyErr_SetObject(ctx, ctx->h_StopIteration, ctx->h_None); - return result; - } - @EXPORT(f) - @INIT - """) - - class CustomIterator: - def __init__(self): - self._iter = iter(["a", "b", "c"]) - - def __iter__(self): - return self._iter - - def __next__(self): - return next(self._iter) - - assert mod.f(iter([3, 2, 1])) == 3 - assert mod.f((i for i in range(1, 10))) == 1 - assert mod.f(CustomIterator()) == "a" - - import pytest - with pytest.raises(StopIteration): - assert mod.f(iter([])) - - diff --git a/graalpython/hpy/test/test_hpylist.py b/graalpython/hpy/test/test_hpylist.py deleted file mode 100644 index 42270cdc6d..0000000000 --- a/graalpython/hpy/test/test_hpylist.py +++ /dev/null @@ -1,112 +0,0 @@ -from .support import HPyTest - -class TestList(HPyTest): - - def test_Check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyList_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - class MyList(list): - pass - - assert mod.f([]) is True - assert mod.f('hello') is False - assert mod.f(MyList()) is True - - def test_New(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyList_New(ctx, 0); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == [] - - def test_Append(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy list = HPyList_New(ctx, 0); - if (HPy_IsNull(list)) - return HPy_NULL; - if (HPyList_Append(ctx, list, arg) == -1) - return HPy_NULL; - if (HPyList_Append(ctx, list, arg) == -1) - return HPy_NULL; - return list; - } - @EXPORT(f) - @INIT - """) - assert mod.f(42) == [42, 42] - - def test_ListBuilder(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy h_self, HPy h_arg) - { - HPyListBuilder builder = HPyListBuilder_New(ctx, 3); - HPyListBuilder_Set(ctx, builder, 0, h_arg); - HPyListBuilder_Set(ctx, builder, 1, ctx->h_True); - HPy h_num = HPyLong_FromLong(ctx, -42); - if (HPy_IsNull(h_num)) - { - HPyListBuilder_Cancel(ctx, builder); - return HPy_NULL; - } - HPyListBuilder_Set(ctx, builder, 2, h_num); - HPy_Close(ctx, h_num); - HPy h_list = HPyListBuilder_Build(ctx, builder); - return h_list; - } - @EXPORT(f) - @INIT - """) - assert mod.f("xy") == ["xy", True, -42] - - def test_Insert(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy_ssize_t index; - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_ValueError, "expected exactly three arguments"); - return HPy_NULL; - } - index = HPyLong_AsSsize_t(ctx, args[1]); - if (index == -1 && HPyErr_Occurred(ctx)) { - return HPy_NULL; - } - if (HPyList_Insert(ctx, args[0], index, args[2]) == -1) - return HPy_NULL; - return HPy_Dup(ctx, args[0]); - } - @EXPORT(f) - @INIT - """) - l = [] - assert mod.f(l, 0, 0) == [0] - l = [] - assert mod.f(l, -1, 0) == [0] - l = [1, 2, 4] - assert mod.f(l, 0, 0) == [0, 1, 2, 4] - assert mod.f(l, -1, 3) == [0, 1, 2, 3, 4] - assert mod.f(l, -3, 1.5) == [0, 1, 1.5, 2, 3, 4] - assert mod.f(l, 1000, 5) == [0, 1, 1.5, 2, 3, 4, 5] - assert mod.f(l, -1000, -1) == [-1, 0, 1, 1.5, 2, 3, 4, 5] - with pytest.raises(SystemError): - mod.f(None, 0, 0) diff --git a/graalpython/hpy/test/test_hpylong.py b/graalpython/hpy/test/test_hpylong.py deleted file mode 100644 index 5900ab2843..0000000000 --- a/graalpython/hpy/test/test_hpylong.py +++ /dev/null @@ -1,440 +0,0 @@ -from .support import HPyTest, DefaultExtensionTemplate - -class HPyLongTemplate(DefaultExtensionTemplate): - def DEFINE_Long_From(self, type, api_suffix, val): - self.EXPORT("from_{type}_{val}".format(type=type, val=val)) - return """ - HPyDef_METH(from_{type}_{val}, "from_{type}_{val}", HPyFunc_NOARGS) - static HPy from_{type}_{val}_impl(HPyContext *ctx, HPy self) - {{ - {type} a = {val}; - return HPyLong_From{api_suffix}(ctx, a); - }} - """.format(type=type, val=val, api_suffix=api_suffix) - - def DEFINE_Long_As(self, type, api_suffix, from_suffix=None): - self.EXPORT("as_{api_suffix}".format(api_suffix=api_suffix)) - if not from_suffix: - from_suffix = api_suffix - return """ - HPyDef_METH(as_{api_suffix}, "as_{api_suffix}", HPyFunc_O) - static HPy as_{api_suffix}_impl(HPyContext *ctx, HPy self, HPy arg) - {{ - {type} a = HPyLong_As{api_suffix}(ctx, arg); - if (a == (({type})-1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_From{from_suffix}(ctx, a * 2); - }} - """.format(type=type, api_suffix=api_suffix, from_suffix=from_suffix) - -class TestLong(HPyTest): - - ExtensionTemplate = HPyLongTemplate - - def unsigned_long_bits(self): - """ Return the number of bits in an unsigned long. """ - import struct - unsigned_long_bytes = len(struct.pack('l', 0)) - return 8 * unsigned_long_bytes - - def magic_int(self, v): - """ Return an instance of a class that implements __int__ - and returns value v. - """ - class MagicInt(object): - def __int__(self): - return v - return MagicInt() - - def magic_index(self, v): - """ Return an instance of a class that implements __index__ - and returns value v. - """ - class MagicIndex(object): - def __index__(self): - return v - return MagicIndex() - - def python_supports_magic_index(self): - """ Return True if the Python version is 3.8 or later and thus - should support calling __index__ in the various HPyLong_As... - methods. - """ - import sys - vi = sys.version_info - return (vi.major > 3 or (vi.major == 3 and vi.minor >= 8)) - - def python_supports_magic_int(self): - """ Return True if the Python version is 3.9 or earlier and thus - should support calling __int__ on non-int based types in some - HPyLong_As... methods. - """ - import sys - vi = sys.version_info - assert vi.major >= 3 - return (vi.major == 3 and vi.minor <= 9) - - def test_Long_FromFixedWidth(self): - mod = self.make_module(""" - @DEFINE_Long_From(int32_t, Int32_t, INT32_MAX) - @DEFINE_Long_From(int32_t, Int32_t, INT32_MIN) - @DEFINE_Long_From(uint32_t, UInt32_t, UINT32_MAX) - @DEFINE_Long_From(int64_t, Int64_t, INT64_MAX) - @DEFINE_Long_From(int64_t, Int64_t, INT64_MIN) - @DEFINE_Long_From(uint64_t, UInt64_t, UINT64_MAX) - @INIT - """) - assert mod.from_int32_t_INT32_MAX() == 2147483647 - assert mod.from_int32_t_INT32_MIN() == -2147483648 - assert mod.from_uint32_t_UINT32_MAX() == 4294967295 - assert mod.from_int64_t_INT64_MAX() == 9223372036854775807 - assert mod.from_int64_t_INT64_MIN() == -9223372036854775808 - assert mod.from_uint64_t_UINT64_MAX() == 18446744073709551615 - - def test_Long_FromLong(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - long a = 500; - return HPyLong_FromLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 500 - - def test_Long_AsFixedWidth(self): - import pytest - mod = self.make_module(""" - @DEFINE_Long_As(int32_t, Int32_t) - @DEFINE_Long_As(uint32_t, UInt32_t) - @DEFINE_Long_As(uint32_t, UInt32_tMask, UInt32_t) - @DEFINE_Long_As(int64_t, Int64_t) - @DEFINE_Long_As(uint64_t, UInt64_t) - @DEFINE_Long_As(uint64_t, UInt64_tMask, UInt64_t) - @INIT - """) - - assert mod.as_Int32_t(45) == 90 - assert mod.as_Int32_t(-45) == -90 - # doubling INT32_MAX is like a left-shift and will result in a negative value - assert mod.as_Int32_t(2147483647) < 0 - with pytest.raises(TypeError): - mod.as_Int32_t("this is not a number") - if self.python_supports_magic_int(): - assert mod.as_Int32_t(self.magic_int(2)) == 4 - if self.python_supports_magic_index(): - assert mod.as_Int32_t(self.magic_index(2)) == 4 - - assert mod.as_UInt32_t(45) == 90 - with pytest.raises(OverflowError): - mod.as_UInt32_t(-45) - assert mod.as_UInt32_t(2147483647) == 4294967294 - - assert mod.as_UInt32_tMask(0xffffffffffffffff) == 0xfffffffe - - assert mod.as_Int64_t(45) == 90 - assert mod.as_Int64_t(-45) == -90 - # doubling INT32_MAX is like a left-shift and will result in a negative value - assert mod.as_Int64_t(2147483647) == 4294967294 - assert mod.as_Int64_t(9223372036854775807) < 0 - with pytest.raises(TypeError): - mod.as_Int64_t("this is not a number") - - assert mod.as_UInt64_t(45) == 90 - with pytest.raises(OverflowError): - mod.as_UInt64_t(-45) - assert mod.as_UInt64_t(9223372036854775807) == 18446744073709551614 - - assert mod.as_UInt64_tMask(0xffffffffffffffffff) == 0xfffffffffffffffe - - def test_Long_AsLong(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - long a = HPyLong_AsLong(ctx, arg); - if (a == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromLong(ctx, a * 2); - } - @EXPORT(f) - @INIT - """) - assert mod.f(45) == 90 - with pytest.raises(TypeError): - mod.f("this is not a number") - if self.python_supports_magic_int(): - assert mod.f(self.magic_int(2)) == 4 - if self.python_supports_magic_index(): - assert mod.f(self.magic_index(2)) == 4 - - def test_Long_FromUnsignedLong(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - unsigned long a = 500; - return HPyLong_FromUnsignedLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 500 - - def test_Long_AsUnsignedLong(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - unsigned long a = HPyLong_AsUnsignedLong(ctx, arg); - if ((a == (unsigned long) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromUnsignedLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(45) == 45 - with pytest.raises(OverflowError): - mod.f(-91) - with pytest.raises(TypeError): - mod.f("this is not a number") - with pytest.raises(TypeError): - mod.f(self.magic_int(2)) - with pytest.raises(TypeError): - mod.f(self.magic_index(2)) - - def test_Long_AsUnsignedLongMask(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - unsigned long a = HPyLong_AsUnsignedLongMask(ctx, arg); - if ((a == (unsigned long) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromUnsignedLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(45) == 45 - assert mod.f(-1) == 2**self.unsigned_long_bits() - 1 - with pytest.raises(TypeError): - mod.f("this is not a number") - if self.python_supports_magic_int(): - assert mod.f(self.magic_int(2)) == 2 - if self.python_supports_magic_index(): - assert mod.f(self.magic_index(2)) == 2 - - def test_Long_FromLongLong(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - // take a value which doesn't fit in 32 bit - long long val = 2147483648; - return HPyLong_FromLongLong(ctx, val); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 2147483648 - - def test_Long_AsLongLong(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - long long a = HPyLong_AsLongLong(ctx, arg); - if ((a == (long long) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromLongLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(2147483648) == 2147483648 - assert mod.f(-2147483648) == -2147483648 - with pytest.raises(TypeError): - mod.f("this is not a number") - if self.python_supports_magic_int(): - assert mod.f(self.magic_int(2)) == 2 - if self.python_supports_magic_index(): - assert mod.f(self.magic_index(2)) == 2 - - def test_Long_FromUnsignedLongLong(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - // take a value which doesn't fit in unsigned 32 bit - unsigned long long val = 4294967296; - return HPyLong_FromUnsignedLongLong(ctx, val); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 4294967296 - - def test_Long_AsUnsignedLongLong(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - unsigned long long a = HPyLong_AsUnsignedLongLong(ctx, arg); - if ((a == (unsigned long long) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromUnsignedLongLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(4294967296) == 4294967296 - with pytest.raises(OverflowError): - mod.f(-4294967296) - with pytest.raises(TypeError): - mod.f("this is not a number") - with pytest.raises(TypeError): - mod.f(self.magic_int(2)) - with pytest.raises(TypeError): - mod.f(self.magic_index(2)) - - def test_Long_AsUnsignedLongLongMask(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - unsigned long long a = HPyLong_AsUnsignedLongLongMask(ctx, arg); - if ((a == (unsigned long long) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromUnsignedLongLong(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(45) == 45 - assert mod.f(-1) == 2**64 - 1 - with pytest.raises(TypeError): - mod.f("this is not a number") - if self.python_supports_magic_int(): - assert mod.f(self.magic_int(2)) == 2 - if self.python_supports_magic_index(): - assert mod.f(self.magic_index(2)) == 2 - - def test_Long_FromSize_t(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - // take a value which doesn't fit in 32 bit - size_t a = 2147483648; - return HPyLong_FromSize_t(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == 2147483648 - - def test_Long_AsSize_t(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - size_t a = HPyLong_AsSize_t(ctx, arg); - if ((a == (size_t) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromSize_t(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(2147483648) == 2147483648 - with pytest.raises(OverflowError): - mod.f(-2147483648) - with pytest.raises(TypeError): - mod.f("this is not a number") - with pytest.raises(TypeError): - mod.f(self.magic_int(2)) - with pytest.raises(TypeError): - mod.f(self.magic_index(2)) - - def test_Long_FromSsize_t(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - HPy_ssize_t a = -42; - return HPyLong_FromSsize_t(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == -42 - - def test_Long_AsSsize_t(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t a = HPyLong_AsSsize_t(ctx, arg); - if ((a == (HPy_ssize_t) -1) && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyLong_FromSsize_t(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(41) == 41 - assert mod.f(-41) == -41 - with pytest.raises(TypeError): - mod.f("this is not a number") - with pytest.raises(TypeError): - mod.f(self.magic_int(2)) - with pytest.raises(TypeError): - mod.f(self.magic_index(2)) - - def test_Long_AsVoidPtr(self): - mod = self.make_module(""" - HPyDef_METH(f, "is_null", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy val) - { - void* ptr = HPyLong_AsVoidPtr(ctx, val); - if (!ptr) { - return HPy_Dup(ctx, ctx->h_True); - } else { - return HPy_Dup(ctx, ctx->h_False); - } - } - @EXPORT(f) - @INIT - """) - assert mod.is_null(0) == True - assert mod.is_null(10) == False - - def test_Long_AsDouble(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - double a = HPyLong_AsDouble(ctx, arg); - if (a == -1.0 && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyFloat_FromDouble(ctx, a); - } - @EXPORT(f) - @INIT - """) - assert mod.f(45) == 45.0 - with pytest.raises(TypeError): - mod.f("this is not a number") diff --git a/graalpython/hpy/test/test_hpymodule.py b/graalpython/hpy/test/test_hpymodule.py deleted file mode 100644 index 5b675c98df..0000000000 --- a/graalpython/hpy/test/test_hpymodule.py +++ /dev/null @@ -1,287 +0,0 @@ -from .support import HPyTest - -class TestModule(HPyTest): - def test_HPyModule_simple(self): - """ - The simplest fully declarative module creation. - """ - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 42); - } - - static HPyDef *moduledefs[] = { &f, NULL }; - static HPyModuleDef moduledef = { - .doc = "Some doc", - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - assert mod.__name__ == mod.__spec__.name - assert mod.__doc__ == "Some doc" - assert mod.f() == 42 - - def test_HPyModule_custom_exec(self): - """ - Module that defines several exec slots. HPy specifies that the slots - will be executed in declaration order. Exec slots can add new types, - and other objects into the module. They can also initialize other - objects. The exec slots will be called on every new instance of the - module, for example, when it is imported in several subinterpreters. - """ - mod = self.make_module(""" - HPyDef_SLOT(exec1, HPy_mod_exec) - static int exec1_impl(HPyContext *ctx, HPy mod) - { - HPy list = HPyList_New(ctx, 0); - if (HPy_IsNull(list)) - return -1; - HPy_SetAttr_s(ctx, mod, "data", list); - HPy_Close(ctx, list); - return 0; - } - - HPyDef_SLOT(exec2, HPy_mod_exec) - static int exec2_impl(HPyContext *ctx, HPy mod) - { - HPy list = HPy_GetAttr_s(ctx, mod, "data"); - if (HPy_IsNull(list)) - return -1; - if (HPy_Length(ctx, list) != 0) { - HPyErr_SetString(ctx, ctx->h_RuntimeError, "Unexpected: len(list) != 0"); - return -1; - } - HPy item = HPyLong_FromLong(ctx, 42); - HPyList_Append(ctx, list, item); - HPy_Close(ctx, item); - HPy_Close(ctx, list); - return 0; - } - - static HPyDef *moduledefs[] = { - &exec1, - &exec2, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = "Some doc", - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - assert mod.data == [42] - - def test_HPyModule_custom_create_returns_non_module(self): - """ - Module that defines create slot that returns non module object. This - is, for the time being, the only supported way to implement the module - 'create' slot. HPy intentionally does not expose direct API to create - a module object. Module objects are created for the extension by the - runtime and the extension can only populate that module object in the - init slots. - """ - import types - mod = self.make_module(""" - HPyDef_SLOT(create, HPy_mod_create) - static HPy create_impl(HPyContext *ctx, HPy spec) - { - HPy result = HPy_NULL, dict = HPy_NULL, ns_type = HPy_NULL; - - HPy types = HPyImport_ImportModule(ctx, "types"); - if (HPy_IsNull(types)) - return HPy_NULL; - - ns_type = HPy_GetAttr_s(ctx, types, "SimpleNamespace"); - if (HPy_IsNull(ns_type)) - goto cleanup; - dict = HPyDict_New(ctx); - HPy_SetItem_s(ctx, dict, "spec", spec); - result = HPy_CallTupleDict(ctx, ns_type, HPy_NULL, dict); - if (HPy_IsNull(result)) - goto cleanup; - - cleanup: - HPy_Close(ctx, dict); - HPy_Close(ctx, types); - HPy_Close(ctx, ns_type); - return result; - } - - static HPyDef *moduledefs[] = { - &create, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = NULL, - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - assert isinstance(mod, types.SimpleNamespace) - assert mod.spec is mod.__spec__ - - def test_HPyModule_error_when_create_returns_module(self): - """ - The HPy_mod_create slot cannot return a builtin module object. - HPy does not expose any API to create builtin module objects and, until - there are any actual use-cases, the purpose of the 'create' slot is to - create non-builtin-module objects. - """ - import pytest - expected_message = "HPy_mod_create slot returned a builtin module " \ - "object. This is currently not supported." - with pytest.raises(SystemError, match=expected_message): - self.make_module(""" - HPyDef_SLOT(create, HPy_mod_create) - static HPy create_impl(HPyContext *ctx, HPy spec) - { - return HPyImport_ImportModule(ctx, "types"); - } - - static HPyDef *moduledefs[] = { - &create, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = NULL, - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - - def test_HPyModule_create_raises(self): - import pytest - with pytest.raises(RuntimeError, match="Test error"): - self.make_module(""" - HPyDef_SLOT(create, HPy_mod_create) - static HPy create_impl(HPyContext *ctx, HPy spec) - { - HPyErr_SetString(ctx, ctx->h_RuntimeError, "Test error"); - return HPy_NULL; - } - - static HPyDef *moduledefs[] = { - &create, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = NULL, - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - - def test_HPyModule_create_and_nondefault_values(self): - import pytest - expected_message = r'^HPyModuleDef defines a HPy_mod_create slot.*' - with pytest.raises(SystemError, match=expected_message): - self.make_module(""" - HPyDef_SLOT(create, HPy_mod_create) - static HPy create_impl(HPyContext *ctx, HPy spec) - { - HPyErr_SetString(ctx, ctx->h_RuntimeError, "Test error"); - return HPy_NULL; - } - - static HPyDef *moduledefs[] = { - &create, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = "Some doc - this is non-default", - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - - def test_HPyModule_create_and_exec_slots(self): - import pytest - expected_message = r'^HPyModuleDef defines a HPy_mod_create slot.*' - with pytest.raises(SystemError, match=expected_message): - self.make_module(""" - HPyDef_SLOT(create, HPy_mod_create) - static HPy create_impl(HPyContext *ctx, HPy spec) - { - HPyErr_SetString(ctx, ctx->h_RuntimeError, "Test error"); - return HPy_NULL; - } - - HPyDef_SLOT(exec, HPy_mod_exec) - static int exec_impl(HPyContext *ctx, HPy mod) - { - return 0; - } - - static HPyDef *moduledefs[] = { - &create, - &exec, - NULL - }; - - static HPyModuleDef moduledef = { - .doc = NULL, - .size = 0, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) - - def test_HPyModule_negative_size(self): - """ - The simplest fully declarative module creation. - """ - import pytest - expected_message = "HPy does not permit HPyModuleDef.size < 0" - with pytest.raises(SystemError, match=expected_message): - self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 42); - } - - static HPyDef *moduledefs[] = { &f, NULL }; - static HPyModuleDef moduledef = { - .doc = "Some doc", - .size = -1, - .legacy_methods = NULL, - .defines = moduledefs, - .globals = NULL, - }; - - @HPy_MODINIT(moduledef) - """) diff --git a/graalpython/hpy/test/test_hpyslice.py b/graalpython/hpy/test/test_hpyslice.py deleted file mode 100644 index 97f45b77b7..0000000000 --- a/graalpython/hpy/test/test_hpyslice.py +++ /dev/null @@ -1,138 +0,0 @@ -from .support import HPyTest - -class TestSlice(HPyTest): - - def test_unpack(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(sizeof_ssize_t, "sizeof_ssize_t", HPyFunc_NOARGS) - static HPy sizeof_ssize_t_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, sizeof(HPy_ssize_t)); - } - - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t start, stop, step; - HPy h_start, h_stop, h_step; - if (HPySlice_Unpack(ctx, arg, &start, &stop, &step)) - return HPy_NULL; - - h_start = HPyLong_FromSsize_t(ctx, start); - h_stop = HPyLong_FromSsize_t(ctx, stop); - h_step = HPyLong_FromSsize_t(ctx, step); - HPy result = HPyTuple_Pack(ctx, 3, h_start, h_stop, h_step); - HPy_Close(ctx, h_start); - HPy_Close(ctx, h_stop); - HPy_Close(ctx, h_step); - return result; - } - @EXPORT(f) - @EXPORT(sizeof_ssize_t) - @INIT - """) - - ssize_t_max = (1 << (mod.sizeof_ssize_t() * 8 - 1)) - 1 - ssize_t_min = -(1 << (mod.sizeof_ssize_t() * 8 - 1)) - assert mod.f(slice(2, 20, 2)) == (2, 20, 2) - assert mod.f(slice(4, 20)) == (4, 20, 1) - assert mod.f(slice(5, (1 << 129))) == (5, ssize_t_max, 1) - assert mod.f(slice(13, -27, -1)) == (13, -27, -1) - assert mod.f(slice(ssize_t_min - 1000, ssize_t_max + 1000, 1)) == (ssize_t_min, ssize_t_max, 1) - assert mod.f(slice(ssize_t_max, 0, -ssize_t_max-1000)) == (ssize_t_max, 0, -ssize_t_max) - assert mod.f(slice(None, 10, 1)) == (0, 10, 1) - assert mod.f(slice(None, 10, -1)) == (ssize_t_max, 10, -1) - assert mod.f(slice(None, None, -1)) == (ssize_t_max, ssize_t_min, -1) - assert mod.f(slice(None, None, None)) == (0, ssize_t_max, 1) - assert mod.f(slice(13, None, None)) == (13, ssize_t_max, 1) - assert mod.f(slice(13, None, -1)) == (13, ssize_t_min, -1) - with pytest.raises(ValueError): - mod.f(slice(1, 10, 0)) - with pytest.raises(TypeError): - mod.f(slice(1, 10, "1")) - with pytest.raises(TypeError): - mod.f(slice(1, "10", 1)) - with pytest.raises(TypeError): - mod.f(slice("0", 10, 1)) - - def test_adjust_indices(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy_ssize_t length, start, stop, step; - - if (nargs != 4) { - HPyErr_SetString(ctx, ctx->h_TypeError, - "expected exactly 4 arguments"); - return HPy_NULL; - } - - if (HPyArg_Parse(ctx, NULL, args, nargs, "nnnn", - &length, &start, &stop, &step) < 0) { - return HPy_NULL; - } - length = HPySlice_AdjustIndices(ctx, length, &start, &stop, step); - return HPy_BuildValue(ctx, "nnnn", length, start, stop, step); - } - @EXPORT(f) - @INIT - """) - - # For the following tests, assume we work on a list: - # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - assert mod.f(10, 0, 10, 1) == (10, 0, 10, 1) - assert mod.f(10, 0, -1, 1) == (9, 0, 9, 1) - assert mod.f(10, -10, -1, 1) == (9, 0, 9, 1) - assert mod.f(10, 15, 20, 1) == (0, 10, 10, 1) - # start at index 9 and to go index 1 (inclusive; since 0 is exclusive) - assert mod.f(10, 9, 0, -1) == (9, 9, 0, -1) - assert mod.f(10, -1, -10, -1) == (9, 9, 0, -1) - assert mod.f(10, 5, 5, -1) == (0, 5, 5, -1) - - # same as above but with step 2 - assert mod.f(10, 0, 10, 2) == (5, 0, 10, 2) - assert mod.f(10, 0, -1, 2) == (5, 0, 9, 2) - assert mod.f(10, -10, -1, 2) == (5, 0, 9, 2) - assert mod.f(10, 15, 20, 2) == (0, 10, 10, 2) - assert mod.f(10, 9, 0, -2) == (5, 9, 0, -2) - assert mod.f(10, -1, -10, -2) == (5, 9, 0, -2) - assert mod.f(10, 5, 5, -2) == (0, 5, 5, -2) - - # same as above but with step 3 - assert mod.f(10, 0, 10, 3) == (4, 0, 10, 3) - assert mod.f(10, 0, -1, 3) == (3, 0, 9, 3) - assert mod.f(10, -10, -1, 3) == (3, 0, 9, 3) - assert mod.f(10, 15, 20, 3) == (0, 10, 10, 3) - assert mod.f(10, 9, 0, -3) == (3, 9, 0, -3) - assert mod.f(10, -1, -10, -3) == (3, 9, 0, -3) - assert mod.f(10, 5, 5, -3) == (0, 5, 5, -3) - - def test_new(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy start, stop, step; - - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, - "expected exactly 3 arguments"); - return HPy_NULL; - } - - if (HPyArg_Parse(ctx, NULL, args, nargs, "OOO", - &start, &stop, &step) < 0) { - return HPy_NULL; - } - return HPySlice_New(ctx, start, stop, step); - } - @EXPORT(f) - @INIT - """) - - assert mod.f(0, 10, 1) == slice(0, 10, 1) - assert mod.f(None, 10, 1) == slice(None, 10, 1) - assert mod.f(1, None, 1) == slice(1, None, 1) - assert mod.f(0, 10, None) == slice(0, 10, None) \ No newline at end of file diff --git a/graalpython/hpy/test/test_hpystructseq.py b/graalpython/hpy/test/test_hpystructseq.py deleted file mode 100644 index aee7578ae2..0000000000 --- a/graalpython/hpy/test/test_hpystructseq.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyStructSequence(HPyTest): - def test_structseq(self): - import pytest - mod = self.make_module(""" - static HPyStructSequence_Field structseq_fields[] = { - { "field0", "doc0" }, - { "field1", NULL }, - { NULL, NULL }, - { NULL, NULL }, - }; - - static HPyStructSequence_Field structseq_empty_fields[] = { - { NULL, NULL }, - }; - - static HPyStructSequence_Desc withfields_desc = { - .name = "mytest.WithFields", - .doc = "some doc", - .fields = structseq_fields - }; - - static HPyStructSequence_Desc nofields_desc = { - .name = "mytest.NoFields", - .fields = structseq_empty_fields - }; - - #define N 3 - - HPyDef_METH(build, "build", HPyFunc_O) - static HPy build_impl(HPyContext *ctx, HPy self, HPy type) - { - int i; - HPy elements[N]; - elements[0] = HPyLong_FromLong(ctx, 1); - elements[1] = HPyFloat_FromDouble(ctx, 2.0); - elements[2] = HPyUnicode_FromString(ctx, "3"); - HPy structseq = HPyStructSequence_New(ctx, type, N, elements); - for (i = 0; i < N; i++) - HPy_Close(ctx, elements[i]); - if (HPy_IsNull(structseq)) - return HPy_NULL; - return structseq; - } - - static void make_types(HPyContext *ctx, HPy module) - { - // cannot be done in the static initializer - structseq_fields[2].name = HPyStructSequence_UnnamedField; - - HPy h_withfields_type = HPyStructSequence_NewType(ctx, &withfields_desc); - if (HPy_IsNull(h_withfields_type)) - return; - HPy_SetAttr_s(ctx, module, "WithFields", h_withfields_type); - HPy_Close(ctx, h_withfields_type); - - HPy h_nofields_type = HPyStructSequence_NewType(ctx, &nofields_desc); - if (HPy_IsNull(h_nofields_type)) { - return; - } - HPy_SetAttr_s(ctx, module, "NoFields", h_nofields_type); - HPy_Close(ctx, h_nofields_type); - } - - @EXPORT(build) - @EXTRA_INIT_FUNC(make_types) - @INIT - """) - assert mod.WithFields.__name__ == "WithFields" - assert mod.WithFields.__doc__ == "some doc" - assert mod.WithFields.__module__ == "mytest" - assert mod.NoFields.__name__ == "NoFields" - # In Python 3.8 or earlier, we cannot pass a NULL pointer as docstring, - # so we pass the empty string. Therefore, we are testing for None or - # empty docstring. - assert not mod.NoFields.__doc__ - assert mod.NoFields.__module__ == "mytest" - - assert mod.WithFields.n_fields == 3 - assert mod.NoFields.n_fields == 0 - - s0 = mod.build(mod.WithFields) - assert s0.field0 == 1, s0.field0 - assert s0.field1 == 2.0, s0.field1 - assert s0[2] == "3", s0[2] - - with pytest.raises(TypeError): - mod.build(mod.NoFields) - - with pytest.raises(TypeError): - mod.build(str) - - - def test_invalid_descriptor(self): - import pytest - mod = self.make_module(""" - static HPyStructSequence_Field sentinel = { NULL, NULL }; - - static HPyStructSequence_Desc nofields_desc = { - .fields = &sentinel - }; - - HPyDef_METH(build, "build", HPyFunc_NOARGS) - static HPy build_impl(HPyContext *ctx, HPy self) - { - return HPyStructSequence_NewType(ctx, &nofields_desc); - } - - @EXPORT(build) - @INIT - """) - with pytest.raises(SystemError): - mod.build() diff --git a/graalpython/hpy/test/test_hpytuple.py b/graalpython/hpy/test/test_hpytuple.py deleted file mode 100644 index 1a44cba6bc..0000000000 --- a/graalpython/hpy/test/test_hpytuple.py +++ /dev/null @@ -1,81 +0,0 @@ -from .support import HPyTest - -class TestTuple(HPyTest): - - def test_Check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyTuple_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - class MyTuple(tuple): - pass - - assert mod.f(()) is True - assert mod.f([]) is False - assert mod.f(MyTuple()) is True - - def test_FromArray(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy x = HPyLong_FromLong(ctx, 42); - if (HPy_IsNull(x)) - return HPy_NULL; - HPy items[] = {self, arg, x}; - HPy res = HPyTuple_FromArray(ctx, items, 3); - HPy_Close(ctx, x); - return res; - } - @EXPORT(f) - @INIT - """) - assert mod.f('hello') == (mod, 'hello', 42) - - def test_Pack(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy x = HPyLong_FromLong(ctx, 42); - if (HPy_IsNull(x)) - return HPy_NULL; - HPy result = HPyTuple_Pack(ctx, 3, self, arg, x); - HPy_Close(ctx, x); - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f('hello') == (mod, 'hello', 42) - - def test_TupleBuilder(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy h_self, HPy h_arg) - { - HPyTupleBuilder builder = HPyTupleBuilder_New(ctx, 3); - HPyTupleBuilder_Set(ctx, builder, 0, h_arg); - HPyTupleBuilder_Set(ctx, builder, 1, ctx->h_True); - HPy h_num = HPyLong_FromLong(ctx, -42); - if (HPy_IsNull(h_num)) - { - HPyTupleBuilder_Cancel(ctx, builder); - return HPy_NULL; - } - HPyTupleBuilder_Set(ctx, builder, 2, h_num); - HPy_Close(ctx, h_num); - HPy h_tuple = HPyTupleBuilder_Build(ctx, builder); - return h_tuple; - } - @EXPORT(f) - @INIT - """) - assert mod.f("xy") == ("xy", True, -42) diff --git a/graalpython/hpy/test/test_hpytype.py b/graalpython/hpy/test/test_hpytype.py deleted file mode 100644 index 4d39fbcd0a..0000000000 --- a/graalpython/hpy/test/test_hpytype.py +++ /dev/null @@ -1,1685 +0,0 @@ -""" -NOTE: these tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest, DefaultExtensionTemplate - - -class PointTemplate(DefaultExtensionTemplate): - """ - ExtensionTemplate with extra markers which helps to define again and again - a simple Point type. Note that every test can use a different combination - of markers, to test different features. - """ - - _CURRENT_STRUCT = None - - _STRUCT_BEGIN_FORMAT = """ - typedef struct {{ - """ - - _STRUCT_END_FORMAT = """ - }} {struct_name}; - {type_helpers} - """ - - _METACLASS_STRUCT_BEGIN_FORMAT = """ - typedef struct {{ - """ - - _METACLASS_STRUCT_END_FORMAT = """ - }} {struct_name}; - HPyType_HELPERS({struct_name}, HPyType_BuiltinShape_Type) - """ - - def TYPE_STRUCT_BEGIN(self, struct_name): - assert self._CURRENT_STRUCT is None - self._CURRENT_STRUCT = struct_name - return self._STRUCT_BEGIN_FORMAT.format(struct_name=struct_name) - - def TYPE_STRUCT_END(self, builtin_shape=None): - assert self._CURRENT_STRUCT is not None - struct_name = self._CURRENT_STRUCT - self._CURRENT_STRUCT = None - if builtin_shape: - type_helpers = "HPyType_HELPERS({struct_name}, {builtin_shape})"\ - .format(struct_name=struct_name, builtin_shape=builtin_shape) - else: - type_helpers = "HPyType_HELPERS({struct_name})"\ - .format(struct_name=struct_name) - return self._STRUCT_END_FORMAT.format(struct_name=struct_name, - type_helpers=type_helpers) - - def DEFAULT_SHAPE(self): - return "/* default object shape */" - - def DEFINE_PointObject(self, builtin_shape=None): - type_begin = self.TYPE_STRUCT_BEGIN("PointObject") - type_end = self.TYPE_STRUCT_END(builtin_shape=builtin_shape) - return """ - {type_begin} - long x; - long y; - {type_end} - """.format(type_begin=type_begin, type_end=type_end) - - def DEFINE_Point_new(self): - return """ - HPyDef_SLOT(Point_new, HPy_tp_new) - static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - long x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) - return HPy_NULL; - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = x; - point->y = y; - return h_point; - } - """ - - def DEFINE_Point_xy(self): - return """ - HPyDef_MEMBER(Point_x, "x", HPyMember_LONG, offsetof(PointObject, x)) - HPyDef_MEMBER(Point_y, "y", HPyMember_LONG, offsetof(PointObject, y)) - """ - - def DEFINE_Point_call(self): - return """ - HPyDef_SLOT(Point_call, HPy_tp_call) - static HPy - Point_call_impl(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) - { - long x, sum = 0; - for (size_t i = 0; i < nargs; i++) { - x = HPyLong_AsLong(ctx, args[i]); - if (x == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - sum += x; - } - if (!HPy_IsNull(kwnames)) { - x = 1; - HPy_ssize_t n = HPy_Length(ctx, kwnames); - HPy h_factor_str = HPyUnicode_FromString(ctx, "factor"); - HPy kwname; - for (HPy_ssize_t i=0; i < n; i++) { - kwname = HPy_GetItem_i(ctx, kwnames, i); - if (HPy_IsNull(kwname)) { - HPy_Close(ctx, h_factor_str); - return HPy_NULL; - } - if (HPy_RichCompareBool(ctx, h_factor_str, kwname, HPy_EQ)) { - x = HPyLong_AsLong(ctx, args[nargs + i]); - if (x == -1 && HPyErr_Occurred(ctx)) { - HPy_Close(ctx, kwname); - HPy_Close(ctx, h_factor_str); - return HPy_NULL; - } - HPy_Close(ctx, kwname); - break; - } - HPy_Close(ctx, kwname); - } - HPy_Close(ctx, h_factor_str); - } - PointObject *data = PointObject_AsStruct(ctx, callable); - sum += data->x + data->y; - return HPyLong_FromLong(ctx, sum * x); - } - """ - - def EXPORT_POINT_TYPE(self, *defines): - defines += ('NULL',) - defines = ', '.join(defines) - self.EXPORT_TYPE('"Point"', "Point_spec") - return """ - static HPyDef *Point_defines[] = { %s }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .defines = Point_defines - }; - """ % defines - - - def METACLASS_STRUCT_BEGIN(self, struct_name): - assert self._CURRENT_STRUCT is None - self._CURRENT_STRUCT = struct_name - return self._METACLASS_STRUCT_BEGIN_FORMAT.format(struct_name=struct_name) - - def METACLASS_STRUCT_END(self): - assert self._CURRENT_STRUCT is not None - struct_name = self._CURRENT_STRUCT - self._CURRENT_STRUCT = None - return self._METACLASS_STRUCT_END_FORMAT.format(struct_name=struct_name) - - def DEFINE_DummyMeta_struct(self): - type_begin = self.METACLASS_STRUCT_BEGIN("DummyMeta") - type_end = self.METACLASS_STRUCT_END() - return """ - {type_begin} - int meta_magic; - int meta_member; - char some_more[64]; - {type_end} - """.format(type_begin=type_begin, type_end=type_end) - - def DEFINE_DummyMeta(self): - struct = self.DEFINE_DummyMeta_struct() - return """ - {struct} - - static HPyType_Spec DummyMeta_spec = {{ - .name = "mytest.DummyMeta", - .basicsize = sizeof(DummyMeta), - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - .builtin_shape = SHAPE(DummyMeta), - }}; - - static HPy make_DummyMeta(HPyContext *ctx) - {{ - HPyType_SpecParam param[] = {{ - {{ HPyType_SpecParam_Base, ctx->h_TypeType }}, - {{ (HPyType_SpecParam_Kind)0 }} - }}; - return HPyType_FromSpec(ctx, &DummyMeta_spec, param); - }} - """.format(struct=struct) - - def EXPORT_DummyMeta(self): - self.EXTRA_INIT_FUNC("register_DummyMeta") - return """ - static void register_DummyMeta(HPyContext *ctx, HPy module) - { - HPy h_DummyMeta = make_DummyMeta(ctx); - if (HPy_IsNull(h_DummyMeta)) - return; - HPy_SetAttr_s(ctx, module, "DummyMeta", h_DummyMeta); - HPy_Close(ctx, h_DummyMeta); - } - """ - - def DEFINE_Dummy_struct(self): - type_begin = self.TYPE_STRUCT_BEGIN("Dummy") - type_end = self.TYPE_STRUCT_END() - return """ - {type_begin} - int member; - {type_end} - """.format(type_begin=type_begin, type_end=type_end) - - def DEFINE_Dummy(self): - struct = self.DEFINE_Dummy_struct() - return """ - {struct} - - HPyDef_MEMBER(member, "member", HPyMember_INT, offsetof(Dummy, member)) - - static HPyDef *Dummy_defines[] = {{ - &member, - NULL - }}; - - static HPyType_Spec Dummy_spec = {{ - .name = "mytest.Dummy", - .basicsize = sizeof(Dummy), - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - .builtin_shape = SHAPE(Dummy), - .defines = Dummy_defines, - }}; - """.format(struct=struct) - - def DEFINE_meta_data_accessors(self): - return """ - HPyDef_METH(set_meta_data, "set_meta_data", HPyFunc_O) - static HPy set_meta_data_impl(HPyContext *ctx, HPy self, HPy arg) - { - DummyMeta *data = DummyMeta_AsStruct(ctx, arg); - data->meta_magic = 42; - data->meta_member = 11; - for (size_t i = 0; i < 64; ++i) - data->some_more[i] = (char) i; - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(get_meta_data, "get_meta_data", HPyFunc_O) - static HPy get_meta_data_impl(HPyContext *ctx, HPy self, HPy arg) - { - DummyMeta *data = DummyMeta_AsStruct(ctx, arg); - for (size_t i = 0; i < 64; ++i) { - if (data->some_more[i] != (char) i) { - HPyErr_SetString(ctx, ctx->h_RuntimeError, "some_more got mangled"); - return HPy_NULL; - } - } - return HPyLong_FromLong(ctx, data->meta_magic + data->meta_member); - } - - HPyDef_METH(set_member, "set_member", HPyFunc_O) - static HPy set_member_impl(HPyContext *ctx, HPy self, HPy arg) - { - Dummy *data = Dummy_AsStruct(ctx, arg); - data->member = 123614; - return HPy_Dup(ctx, ctx->h_None); - } - """ - - -class TestType(HPyTest): - - ExtensionTemplate = PointTemplate - - def test_simple_type(self): - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - assert isinstance(mod.Dummy, type) - assert mod.Dummy.__name__ == 'Dummy' - assert mod.Dummy.__module__ == 'mytest' - assert isinstance(mod.Dummy(), mod.Dummy) - - class Sub(mod.Dummy): - pass - assert isinstance(Sub(), mod.Dummy) - - def test_doc_string(self): - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - .doc = "A succinct description.", - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - assert mod.Dummy.__doc__ == "A succinct description." - - def test_HPyDef_SLOT_IMPL(self): - mod = self.make_module(""" - HPyDef_SLOT_IMPL(Dummy_repr, Dummy_repr_impl, HPy_tp_repr); - static HPy Dummy_repr_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, ""); - } - - HPyDef_SLOT_IMPL(Dummy_abs, Dummy_abs_impl, HPy_nb_absolute); - static HPy Dummy_abs_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - static HPyDef *Dummy_defines[] = { - &Dummy_repr, - &Dummy_abs, - NULL - }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - @DEFAULT_SHAPE - .defines = Dummy_defines, - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - d = mod.Dummy() - assert repr(d) == '' - assert abs(d) == 1234 - - def test_HPyDef_SLOT(self): - mod = self.make_module(""" - HPyDef_SLOT(Dummy_repr, HPy_tp_repr); - static HPy Dummy_repr_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, ""); - } - - HPyDef_SLOT(Dummy_abs, HPy_nb_absolute); - static HPy Dummy_abs_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - static HPyDef *Dummy_defines[] = { - &Dummy_repr, - &Dummy_abs, - NULL - }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .defines = Dummy_defines, - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - d = mod.Dummy() - assert repr(d) == '' - assert abs(d) == 1234 - - def test_HPyDef_METH_IMPL(self): - import pytest - mod = self.make_module(""" - HPyDef_METH_IMPL(Dummy_foo, "foo", Dummy_foo_impl, HPyFunc_O, .doc="hello") - static HPy Dummy_foo_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Add(ctx, arg, arg); - } - - HPyDef_METH_IMPL(Dummy_bar, "bar", Dummy_bar_impl, HPyFunc_NOARGS) - static HPy Dummy_bar_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - HPyDef_METH_IMPL(Dummy_identity, "identity", Dummy_identity_impl, HPyFunc_NOARGS) - static HPy Dummy_identity_impl(HPyContext *ctx, HPy self) - { - return HPy_Dup(ctx, self); - } - - static HPyDef *dummy_type_defines[] = { - &Dummy_foo, - &Dummy_bar, - &Dummy_identity, - NULL - }; - - static HPyType_Spec dummy_type_spec = { - .name = "mytest.Dummy", - .defines = dummy_type_defines, - }; - - @EXPORT_TYPE("Dummy", dummy_type_spec) - @INIT - """) - d = mod.Dummy() - assert d.foo.__doc__ == 'hello' - assert d.bar.__doc__ is None - assert d.foo(21) == 42 - assert d.bar() == 1234 - assert d.identity() is d - with pytest.raises(TypeError): - mod.Dummy.identity() - class A: pass - with pytest.raises(TypeError): - mod.Dummy.identity(A()) - - def test_HPyDef_METH(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(Dummy_foo, "foo", HPyFunc_O, .doc="hello") - static HPy Dummy_foo_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Add(ctx, arg, arg); - } - - HPyDef_METH(Dummy_bar, "bar", HPyFunc_NOARGS) - static HPy Dummy_bar_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - HPyDef_METH(Dummy_identity, "identity", HPyFunc_NOARGS) - static HPy Dummy_identity_impl(HPyContext *ctx, HPy self) - { - return HPy_Dup(ctx, self); - } - - static HPyDef *dummy_type_defines[] = { - &Dummy_foo, - &Dummy_bar, - &Dummy_identity, - NULL - }; - - static HPyType_Spec dummy_type_spec = { - .name = "mytest.Dummy", - @DEFAULT_SHAPE - .defines = dummy_type_defines, - }; - - @EXPORT_TYPE("Dummy", dummy_type_spec) - @INIT - """) - d = mod.Dummy() - assert d.foo.__doc__ == 'hello' - assert d.bar.__doc__ is None - assert d.foo(21) == 42 - assert d.bar() == 1234 - assert d.identity() is d - with pytest.raises(TypeError): - mod.Dummy.identity() - class A: pass - with pytest.raises(TypeError): - mod.Dummy.identity(A()) - - def test_HPy_New(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_METH(Point_foo, "foo", HPyFunc_NOARGS) - static HPy Point_foo_impl(HPyContext *ctx, HPy self) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_foo) - @INIT - """) - p1 = mod.Point(7, 3) - assert p1.foo() == 73 - p2 = mod.Point(4, 2) - assert p2.foo() == 42 - - def test_HPy_New_initialize_to_zero(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_xy - - HPyDef_METH(newPoint, "newPoint", HPyFunc_NOARGS) - static HPy newPoint_impl(HPyContext *ctx, HPy self) - { - HPy h_pointClass = HPy_GetAttr_s(ctx, self, "Point"); - if (HPy_IsNull(h_pointClass)) - return HPy_NULL; - - PointObject *point; - HPy h_point = HPy_New(ctx, h_pointClass, &point); - HPy_Close(ctx, h_pointClass); - return h_point; - } - - @EXPORT(newPoint) - @EXPORT_POINT_TYPE(&Point_x, &Point_y) - @INIT - """) - # this is suboptimal: if we don't initialized the memory after - # allocation, it might be 0 anyway. Try to allocate several Points to - # increase the chances that the test don't pass by chance - for i in range(10): - p = mod.newPoint() - assert p.x == 0 - assert p.y == 0 - - def test_refcount(self): - import pytest - import sys - if not self.supports_refcounts(): - pytest.skip() - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @EXPORT_POINT_TYPE(&Point_new) - @INIT - """) - tp = mod.Point - init_refcount = sys.getrefcount(tp) - p = tp(1, 2) - assert sys.getrefcount(tp) == init_refcount + 1 - p = None - assert sys.getrefcount(tp) == init_refcount - - def test_HPyDef_Member_basic(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_xy - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y) - @INIT - """) - p = mod.Point(7, 3) - assert p.x == 7 - assert p.y == 3 - p.x = 123 - p.y = 456 - assert p.x == 123 - assert p.y == 456 - - def test_HPyDef_Member_integers(self): - import pytest - BIGNUM = 2**200 - for kind, c_type in [ - ('SHORT', 'short'), - ('INT', 'int'), - ('LONG', 'long'), - ('USHORT', 'unsigned short'), - ('UINT', 'unsigned int'), - ('ULONG', 'unsigned long'), - ('BYTE', 'char'), - ('UBYTE', 'unsigned char'), - ('LONGLONG', 'long long'), - ('ULONGLONG', 'unsigned long long'), - ('HPYSSIZET', 'HPy_ssize_t'), - ]: - mod = self.make_module(""" - @TYPE_STRUCT_BEGIN(FooObject) - %(c_type)s member; - @TYPE_STRUCT_END - - HPyDef_SLOT(Foo_new, HPy_tp_new) - static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - FooObject *foo; - HPy h_obj = HPy_New(ctx, cls, &foo); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - foo->member = 42; - return h_obj; - } - - HPyDef_MEMBER(Foo_member, "member", HPyMember_%(kind)s, offsetof(FooObject, member)) - - static HPyDef *Foo_defines[] = { - &Foo_new, - &Foo_member, - NULL - }; - - static HPyType_Spec Foo_spec = { - .name = "test_%(kind)s.Foo", - .basicsize = sizeof(FooObject), - .builtin_shape = SHAPE(FooObject), - .defines = Foo_defines - }; - - @EXPORT_TYPE("Foo", Foo_spec) - @INIT - """ % {'c_type': c_type, 'kind': kind}, name='test_%s' % (kind,)) - foo = mod.Foo() - assert foo.member == 42 - foo.member = 43 - assert foo.member == 43 - with pytest.raises(OverflowError): - foo.member = BIGNUM - with pytest.raises(TypeError): - foo.member = None - with pytest.raises(TypeError): - del foo.member - - def test_HPyDef_Member_readonly_integers(self): - import pytest - for kind, c_type in [ - ('SHORT', 'short'), - ('INT', 'int'), - ('LONG', 'long'), - ('USHORT', 'unsigned short'), - ('UINT', 'unsigned int'), - ('ULONG', 'unsigned long'), - ('BYTE', 'char'), - ('UBYTE', 'unsigned char'), - ('LONGLONG', 'long long'), - ('ULONGLONG', 'unsigned long long'), - ('HPYSSIZET', 'HPy_ssize_t'), - ]: - mod = self.make_module(""" - @TYPE_STRUCT_BEGIN(FooObject) - %(c_type)s member; - @TYPE_STRUCT_END - - HPyDef_SLOT(Foo_new, HPy_tp_new) - static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - FooObject *foo; - HPy h_obj = HPy_New(ctx, cls, &foo); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - foo->member = 42; - return h_obj; - } - - HPyDef_MEMBER(Foo_member, "member", HPyMember_%(kind)s, offsetof(FooObject, member), .readonly=1) - - static HPyDef *Foo_defines[] = { - &Foo_new, - &Foo_member, - NULL - }; - - static HPyType_Spec Foo_spec = { - .name = "test_%(kind)s.Foo", - .basicsize = sizeof(FooObject), - .builtin_shape = SHAPE(FooObject), - .defines = Foo_defines - }; - - @EXPORT_TYPE("Foo", Foo_spec) - @INIT - """ % {'c_type': c_type, 'kind': kind}, name='test_%s' % (kind,)) - foo = mod.Foo() - assert foo.member == 42 - with pytest.raises(AttributeError): - foo.member = 43 - assert foo.member == 42 - with pytest.raises(AttributeError): - del foo.member - assert foo.member == 42 - - def test_HPyDef_Member_others(self): - import pytest - mod = self.make_module(""" - #include - @TYPE_STRUCT_BEGIN(FooObject) - float FLOAT_member; - double DOUBLE_member; - const char* STRING_member; - const char *STRING_null_member; - char CHAR_member; - char ISTRING_member[6]; - char BOOL_member; - HPyField OBJECT_member; - HPyField OBJECT_NULL_member; - HPyField OBJECT_EX_member; - @TYPE_STRUCT_END - - HPyDef_SLOT(Foo_new, HPy_tp_new) - static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - FooObject *foo; - HPy h_obj = HPy_New(ctx, cls, &foo); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - foo->FLOAT_member = 1.; - foo->DOUBLE_member = 1.; - const char * s = "Hello"; - foo->STRING_member = s; - foo->STRING_null_member = NULL; - foo->CHAR_member = 'A'; - strncpy(foo->ISTRING_member, "Hello", 6); - foo->BOOL_member = 0; - HPyField_Store(ctx, h_obj, &foo->OBJECT_member, ctx->h_NotImplemented); - foo->OBJECT_NULL_member = HPyField_NULL; - foo->OBJECT_EX_member = HPyField_NULL; - return h_obj; - } - - HPyDef_MEMBER(Foo_FLOAT_member, "FLOAT_member", HPyMember_FLOAT, offsetof(FooObject, FLOAT_member)) - HPyDef_MEMBER(Foo_DOUBLE_member, "DOUBLE_member", HPyMember_DOUBLE, offsetof(FooObject, DOUBLE_member)) - HPyDef_MEMBER(Foo_STRING_member, "STRING_member", HPyMember_STRING, offsetof(FooObject, STRING_member)) - HPyDef_MEMBER(Foo_STRING_null_member, "STRING_null_member", HPyMember_STRING, offsetof(FooObject, STRING_null_member)) - HPyDef_MEMBER(Foo_CHAR_member, "CHAR_member", HPyMember_CHAR, offsetof(FooObject, CHAR_member)) - HPyDef_MEMBER(Foo_ISTRING_member, "ISTRING_member", HPyMember_STRING_INPLACE, offsetof(FooObject, ISTRING_member)) - HPyDef_MEMBER(Foo_BOOL_member, "BOOL_member", HPyMember_BOOL, offsetof(FooObject, BOOL_member)) - HPyDef_MEMBER(Foo_OBJECT_member, "OBJECT_member", HPyMember_OBJECT, offsetof(FooObject, OBJECT_member)) - HPyDef_MEMBER(Foo_OBJECT_NULL_member, "OBJECT_NULL_member", HPyMember_OBJECT, offsetof(FooObject, OBJECT_NULL_member)) - HPyDef_MEMBER(Foo_OBJECT_EX_member, "OBJECT_EX_member", HPyMember_OBJECT_EX, offsetof(FooObject, OBJECT_EX_member)) - HPyDef_MEMBER(Foo_NONE_member, "NONE_member", HPyMember_NONE, offsetof(FooObject, FLOAT_member)) - - HPyDef_SLOT(Foo_traverse, HPy_tp_traverse) - static int Foo_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) - { - FooObject *p = (FooObject *)self; - HPy_VISIT(&p->OBJECT_member); - HPy_VISIT(&p->OBJECT_NULL_member); - HPy_VISIT(&p->OBJECT_EX_member); - return 0; - } - - static HPyDef *Foo_defines[] = { - &Foo_new, - &Foo_FLOAT_member, - &Foo_DOUBLE_member, - &Foo_STRING_member, - &Foo_STRING_null_member, - &Foo_CHAR_member, - &Foo_ISTRING_member, - &Foo_BOOL_member, - &Foo_OBJECT_member, - &Foo_OBJECT_NULL_member, - &Foo_OBJECT_EX_member, - &Foo_NONE_member, - &Foo_traverse, - NULL - }; - - static HPyType_Spec Foo_spec = { - .name = "mytest.Foo", - .basicsize = sizeof(FooObject), - .builtin_shape = SHAPE(FooObject), - .defines = Foo_defines - }; - - @EXPORT_TYPE("Foo", Foo_spec) - @INIT - """) - foo = mod.Foo() - assert foo.FLOAT_member == 1. - foo.FLOAT_member = 0.1 - assert foo.FLOAT_member != 0.1 - assert abs(foo.FLOAT_member - 0.1) < 1e-8 - with pytest.raises(TypeError): - del foo.FLOAT_member - - assert foo.DOUBLE_member == 1. - foo.DOUBLE_member = 0.1 - assert foo.DOUBLE_member == 0.1 # exactly - with pytest.raises(TypeError): - del foo.DOUBLE_member - - assert foo.STRING_member == "Hello" - assert foo.STRING_null_member is None - with pytest.raises(TypeError): - foo.STRING_member = "world" - with pytest.raises(TypeError): - del foo.STRING_member - - assert foo.CHAR_member == 'A' - foo.CHAR_member = 'B' - assert foo.CHAR_member == 'B' - with pytest.raises(TypeError): - foo.CHAR_member = 'ABC' - with pytest.raises(TypeError): - del foo.CHAR_member - - assert foo.ISTRING_member == "Hello" - with pytest.raises(TypeError): - foo.ISTRING_member = "world" - with pytest.raises(TypeError): - del foo.ISTRING_member - - assert foo.BOOL_member is False - foo.BOOL_member = True - assert foo.BOOL_member is True - with pytest.raises(TypeError): - foo.BOOL_member = 1 - with pytest.raises(TypeError): - del foo.BOOL_member - - assert foo.OBJECT_member is NotImplemented - foo.OBJECT_member = 1 - assert foo.OBJECT_member == 1 - - assert foo.OBJECT_NULL_member is None - foo.OBJECT_NULL_member = 1 - assert foo.OBJECT_NULL_member == 1 - del foo.OBJECT_NULL_member - assert foo.OBJECT_NULL_member is None - - with pytest.raises(AttributeError, match="OBJECT_EX_member"): - foo.OBJECT_EX_member - foo.OBJECT_EX_member = 1 - assert foo.OBJECT_EX_member == 1 - del foo.OBJECT_EX_member - with pytest.raises(AttributeError): - foo.OBJECT_EX_member - - assert foo.NONE_member is None - with pytest.raises((SystemError, TypeError)): # CPython quirk/bug - foo.NONE_member = None - with pytest.raises(TypeError): - del foo.NONE_member - - def test_HPyDef_Member_readonly_others(self): - import pytest - mod = self.make_module(""" - #include - @TYPE_STRUCT_BEGIN(FooObject) - float FLOAT_member; - double DOUBLE_member; - const char* STRING_member; - char CHAR_member; - char ISTRING_member[6]; - char BOOL_member; - HPyField OBJECT_member; - @TYPE_STRUCT_END - - HPyDef_SLOT(Foo_new, HPy_tp_new) - static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - FooObject *foo; - HPy h_obj = HPy_New(ctx, cls, &foo); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - foo->FLOAT_member = 1.; - foo->DOUBLE_member = 1.; - const char * s = "Hello"; - foo->STRING_member = s; - foo->CHAR_member = 'A'; - strncpy(foo->ISTRING_member, "Hello", 6); - foo->BOOL_member = 0; - foo->OBJECT_member = HPyField_NULL; - return h_obj; - } - - HPyDef_MEMBER(Foo_FLOAT_member, "FLOAT_member", HPyMember_FLOAT, offsetof(FooObject, FLOAT_member), .readonly=1) - HPyDef_MEMBER(Foo_DOUBLE_member, "DOUBLE_member", HPyMember_DOUBLE, offsetof(FooObject, DOUBLE_member), .readonly=1) - HPyDef_MEMBER(Foo_STRING_member, "STRING_member", HPyMember_STRING, offsetof(FooObject, STRING_member), .readonly=1) - HPyDef_MEMBER(Foo_CHAR_member, "CHAR_member", HPyMember_CHAR, offsetof(FooObject, CHAR_member), .readonly=1) - HPyDef_MEMBER(Foo_ISTRING_member, "ISTRING_member", HPyMember_STRING_INPLACE, offsetof(FooObject, ISTRING_member), .readonly=1) - HPyDef_MEMBER(Foo_BOOL_member, "BOOL_member", HPyMember_BOOL, offsetof(FooObject, BOOL_member), .readonly=1) - HPyDef_MEMBER(Foo_OBJECT_member, "OBJECT_member", HPyMember_OBJECT, offsetof(FooObject, OBJECT_member), .readonly=1) - HPyDef_MEMBER(Foo_NONE_member, "NONE_member", HPyMember_NONE, offsetof(FooObject, FLOAT_member), .readonly=1) - - HPyDef_SLOT(Foo_traverse, HPy_tp_traverse) - static int Foo_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) - { - FooObject *p = (FooObject *)self; - HPy_VISIT(&p->OBJECT_member); - return 0; - } - - static HPyDef *Foo_defines[] = { - &Foo_new, - &Foo_FLOAT_member, - &Foo_DOUBLE_member, - &Foo_STRING_member, - &Foo_CHAR_member, - &Foo_ISTRING_member, - &Foo_BOOL_member, - &Foo_OBJECT_member, - &Foo_NONE_member, - &Foo_traverse, - NULL - }; - - static HPyType_Spec Foo_spec = { - .name = "mytest.Foo", - .basicsize = sizeof(FooObject), - .builtin_shape = SHAPE(FooObject), - .defines = Foo_defines - }; - - @EXPORT_TYPE("Foo", Foo_spec) - @INIT - """) - foo = mod.Foo() - assert foo.FLOAT_member == 1. - with pytest.raises(AttributeError): - foo.FLOAT_member = 0.1 - assert foo.DOUBLE_member == 1. - with pytest.raises(AttributeError): - foo.DOUBLE_member = 0.1 - - assert foo.STRING_member == "Hello" - with pytest.raises(AttributeError): - foo.STRING_member = "world" - with pytest.raises(AttributeError): - del foo.STRING_member - - assert foo.CHAR_member == 'A' - with pytest.raises(AttributeError): - foo.CHAR_member = 'B' - with pytest.raises(AttributeError): - foo.CHAR_member = 'ABC' - with pytest.raises(AttributeError): - del foo.CHAR_member - - assert foo.ISTRING_member == "Hello" - with pytest.raises(AttributeError): - foo.ISTRING_member = "world" - with pytest.raises(AttributeError): - del foo.ISTRING_member - - assert foo.BOOL_member is False - with pytest.raises(AttributeError): - foo.BOOL_member = True - with pytest.raises(AttributeError): - foo.BOOL_member = 1 - with pytest.raises(AttributeError): - del foo.BOOL_member - - assert foo.OBJECT_member is None - with pytest.raises(AttributeError): - foo.OBJECT_member = 1 - with pytest.raises(AttributeError): - del foo.OBJECT_member - - assert foo.NONE_member is None - with pytest.raises(AttributeError): - foo.NONE_member = None - with pytest.raises(AttributeError): - del foo.NONE_member - - def test_call(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_call - - HPyDef_SLOT(Dummy_call, HPy_tp_call) - static HPy - Dummy_call_impl(HPyContext *ctx, HPy callable, const HPy *args, - size_t nargs, HPy kwnames) - { - return HPyUnicode_FromString(ctx, "hello"); - } - - @EXPORT_POINT_TYPE(&Point_call) - @INIT - """) - p = mod.Point() - assert p(3, 4, 5, factor=2) == 24 - - def test_call_with_tp_new(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_call - @EXPORT_POINT_TYPE(&Point_new, &Point_call) - @INIT - """) - p = mod.Point(1, 2) - assert p(3, 4, 5, factor=2) == 30 - - def test_call_set(self): - import pytest - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_call - - HPyDef_CALL_FUNCTION(Point_special_call) - static HPy - Point_special_call_impl(HPyContext *ctx, HPy callable, - const HPy *args, size_t nargs, HPy kwnames) - { - HPy tmp = Point_call_impl(ctx, callable, args, nargs, kwnames); - HPy res = HPy_Negative(ctx, tmp); - HPy_Close(ctx, tmp); - return res; - } - - HPyDef_SLOT(Point_new, HPy_tp_new) - static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - long x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) - return HPy_NULL; - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - if (x < 0 && HPy_SetCallFunction(ctx, h_point, &Point_special_call) < 0) { - HPy_Close(ctx, h_point); - return HPy_NULL; - } - point->x = x; - point->y = y; - return h_point; - } - - HPyDef_METH(call_set, "call_set", HPyFunc_O) - static HPy call_set_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPy_SetCallFunction(ctx, arg, &Point_special_call) < 0) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_call) - @EXPORT(call_set) - @INIT - """) - - # this uses 'Point_call' - p0 = mod.Point(1, 2) - assert p0(3, 4, 5, factor=2) == 30 - - # the negative 'x' will cause that 'Point_special_call' is used - p1 = mod.Point(-1, 2) - assert p1(3, 4, 5, factor=2) == -26 - - # error case: setting call function on object that does not implement - # the HPy call protocol - with pytest.raises(TypeError): - mod.call_set(object()) - - def test_call_invalid_specs(self): - import pytest - mod = self.make_module(""" - HPyDef_SLOT(Dummy_call, HPy_tp_call) - static HPy - Dummy_call_impl(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) - { - return HPyUnicode_FromString(ctx, "hello"); - } - - HPyDef_MEMBER(Dummy_vcall_offset, "__vectorcalloffset__", HPyMember_HPYSSIZET, 4*sizeof(void*), .readonly=1) - - static HPyDef *Dummy_defines[] = { &Dummy_call, NULL }; - static HPyDef *Dummy_vcall_defines[] = { &Dummy_call, &Dummy_vcall_offset, NULL }; - - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = sizeof(intptr_t), - .flags = HPy_TPFLAGS_DEFAULT, - @DEFAULT_SHAPE - .defines = Dummy_defines, - }; - - static HPyType_Spec Dummy_vcall_spec = { - .name = "mytest.DummyVCall", - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_HAVE_VECTORCALL, - @DEFAULT_SHAPE - .defines = Dummy_vcall_defines, - }; - - HPyDef_METH(create_var_type, "create_var_type", HPyFunc_NOARGS) - static HPy create_var_type_impl(HPyContext *ctx, HPy self) - { - if (!HPyHelpers_AddType(ctx, self, "Dummy", &Dummy_spec, NULL)) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - HPyDef_METH(create_vcall, "create_call_and_vectorcalloffset_type", HPyFunc_NOARGS) - static HPy create_vcall_impl(HPyContext *ctx, HPy self) - { - if (!HPyHelpers_AddType(ctx, self, "DummyVCall", &Dummy_vcall_spec, NULL)) { - return HPy_NULL; - } - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT(create_var_type) - @EXPORT(create_vcall) - @INIT - """) - with pytest.raises(TypeError) as err: - mod.create_var_type() - assert "Cannot use HPy call protocol with var" in str(err.value) - with pytest.raises(TypeError) as err: - mod.create_call_and_vectorcalloffset_type() - # assert "Cannot have HPy_tp_call and explicit member" in str(err.value) - - def test_call_explicit_offset(self): - mod = self.make_module(""" - @TYPE_STRUCT_BEGIN(FooObject) - void *a; - HPyCallFunction call_func; - void *b; - @TYPE_STRUCT_END - - HPyDef_MEMBER(Foo_vcall_offset, "__vectorcalloffset__", HPyMember_HPYSSIZET, offsetof(FooObject, call_func), .readonly=1) - - HPyDef_CALL_FUNCTION(Foo_manual_call_func) - static HPy - Foo_manual_call_func_impl(HPyContext *ctx, HPy callable, const HPy *args, size_t nargs, HPy kwnames) - { - return HPyUnicode_FromString(ctx, "hello manually initialized call function"); - } - - HPyDef_SLOT(Foo_new, HPy_tp_new) - static HPy Foo_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - FooObject *data; - HPy h_obj = HPy_New(ctx, cls, &data); - if (HPy_IsNull(h_obj)) - return HPy_NULL; - data->call_func = Foo_manual_call_func; - return h_obj; - } - - static HPyDef *Foo_defines[] = { - &Foo_vcall_offset, - &Foo_new, - NULL - }; - - static HPyType_Spec Foo_spec = { - .name = "mytest.Foo", - .basicsize = sizeof(FooObject), - .itemsize = sizeof(intptr_t), - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_HAVE_VECTORCALL, - @DEFAULT_SHAPE - .defines = Foo_defines, - }; - - @EXPORT_TYPE("Foo", Foo_spec) - @INIT - """) - foo = mod.Foo() - assert foo() == 'hello manually initialized call function' - - def test_HPyType_GenericNew(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_xy - - HPyDef_SLOT_IMPL(Point_new, HPyType_GenericNew, HPy_tp_new) - - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y) - @INIT - """) - p = mod.Point() - assert p.x == 0 - assert p.y == 0 - - def test_HPyDef_GET(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_GET(Point_z, "z") - static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.z == 73 - - def test_HPyDef_GETSET(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_GETSET(Point_z, "z", .closure=(void *)1000) - static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y + (long)(HPy_ssize_t)closure); - } - static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - long target = HPyLong_AsLong(ctx, value); // assume no exception - point->y += target - current; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.z == 1073 - p.z = 1075 - assert p.z == 1075 - - def test_HPyDef_SET(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_xy - - HPyDef_SET(Point_z, "z", .closure=(void *)1000) - static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - long target = HPyLong_AsLong(ctx, value); // assume no exception - point->y += target - current; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.y == 3 - p.z = 1075 - assert p.y == 5 - - def test_HPyDef_GET_IMPL(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_GET_IMPL(Point_z, "z", Point_z_get) - static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.z == 73 - - def test_HPyDef_GETSET_IMPL(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_GETSET_IMPL(Point_z, "z", Point_z_get, Point_z_set, .closure=(void *)1000) - static HPy Point_z_get(HPyContext *ctx, HPy self, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return HPyLong_FromLong(ctx, point->x*10 + point->y + (long)(HPy_ssize_t)closure); - } - static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - long target = HPyLong_AsLong(ctx, value); // assume no exception - point->y += target - current; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.z == 1073 - p.z = 1075 - assert p.z == 1075 - - def test_HPyDef_SET_IMPL(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_xy - - HPyDef_SET_IMPL(Point_z, "z", Point_z_set, .closure=(void *)1000) - static int Point_z_set(HPyContext *ctx, HPy self, HPy value, void *closure) - { - PointObject *point = PointObject_AsStruct(ctx, self); - long current = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - long target = HPyLong_AsLong(ctx, value); // assume no exception - point->y += target - current; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y, &Point_z) - @INIT - """) - p = mod.Point(7, 3) - assert p.y == 3 - p.z = 1075 - assert p.y == 5 - - def test_specparam_base(self): - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - }; - - static void make_Dummy(HPyContext *ctx, HPy module) - { - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Base, ctx->h_LongType }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_Dummy = HPyType_FromSpec(ctx, &Dummy_spec, param); - if (HPy_IsNull(h_Dummy)) - return; - HPy_SetAttr_s(ctx, module, "Dummy", h_Dummy); - HPy_Close(ctx, h_Dummy); - } - @EXTRA_INIT_FUNC(make_Dummy) - @INIT - """) - assert isinstance(mod.Dummy, type) - assert mod.Dummy.__name__ == 'Dummy' - assert mod.Dummy.__module__ == 'mytest' - assert issubclass(mod.Dummy, int) - assert isinstance(mod.Dummy(), mod.Dummy) - assert mod.Dummy() == 0 - assert mod.Dummy(42) == 42 - - class Sub(mod.Dummy): - pass - assert isinstance(Sub(), mod.Dummy) - - def test_specparam_basestuple(self): - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - }; - - static void make_Dummy(HPyContext *ctx, HPy module) - { - HPy h_bases = HPyTuple_Pack(ctx, 1, ctx->h_LongType); - if (HPy_IsNull(h_bases)) - return; - HPyType_SpecParam param[] = { - { HPyType_SpecParam_BasesTuple, h_bases }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_Dummy = HPyType_FromSpec(ctx, &Dummy_spec, param); - HPy_Close(ctx, h_bases); - if (HPy_IsNull(h_Dummy)) - return; - HPy_SetAttr_s(ctx, module, "Dummy", h_Dummy); - HPy_Close(ctx, h_Dummy); - } - @EXTRA_INIT_FUNC(make_Dummy) - @INIT - """) - assert isinstance(mod.Dummy, type) - assert mod.Dummy.__name__ == 'Dummy' - assert mod.Dummy.__module__ == 'mytest' - assert issubclass(mod.Dummy, int) - assert isinstance(mod.Dummy(), mod.Dummy) - assert mod.Dummy() == 0 - assert mod.Dummy(42) == 42 - - class Sub(mod.Dummy): - pass - assert isinstance(Sub(), mod.Dummy) - - def test_specparam_multiple_metaclass_fails(self): - import pytest - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - }; - - HPyDef_METH(make_dummy, "make_dummy", HPyFunc_NOARGS) - static HPy make_dummy_impl(HPyContext *ctx, HPy module) - { - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Metaclass, ctx->h_TypeType }, - { HPyType_SpecParam_Metaclass, ctx->h_LongType }, - { (HPyType_SpecParam_Kind)0 } - }; - return HPyType_FromSpec(ctx, &Dummy_spec, param); - } - @EXPORT(make_dummy) - @INIT - """) - - with pytest.raises(ValueError): - mod.make_dummy() - - def test_metaclass(self): - import pytest - mod = self.make_module(""" - #include - - @DEFINE_DummyMeta - @DEFINE_Dummy - @DEFINE_meta_data_accessors - - HPyDef_METH(create_type, "create_type", HPyFunc_VARARGS) - static HPy create_type_impl(HPyContext *ctx, HPy module, - const HPy *args, size_t nargs) - { - HPy metaclass; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "sO", - &Dummy_spec.name, &metaclass)) - return HPy_NULL; - - HPyType_SpecParam specparam[] = { - { HPyType_SpecParam_Metaclass, metaclass }, - { (HPyType_SpecParam_Kind)0 } - }; - - const char *bare_name = strrchr(Dummy_spec.name, '.'); - if (bare_name == NULL) - bare_name = Dummy_spec.name; - else - bare_name++; - - if (!HPyHelpers_AddType(ctx, module, bare_name, - &Dummy_spec, specparam)) - return HPy_NULL; - - return HPy_Dup(ctx, ctx->h_None); - } - - @EXPORT_DummyMeta - @EXPORT(set_meta_data) - @EXPORT(get_meta_data) - @EXPORT(set_member) - @EXPORT(create_type) - @INIT - """) - - assert type(mod.DummyMeta) is type - mod.create_type("mytest.Dummy", mod.DummyMeta) - assert mod.DummyMeta is type(mod.Dummy), "type(mod.Dummy) == %r" % (type(mod.Dummy), ) - assert isinstance(mod.Dummy, type) - assert mod.set_meta_data(mod.Dummy) is None - assert mod.get_meta_data(mod.Dummy) == 42 + 11 - - d = mod.Dummy() - mod.set_member(d) - assert d.member == 123614 - - # metaclasses must inherit from 'type' - with pytest.raises(TypeError): - mod.create_type("mytest.DummyFail0", "hello") - - class WithCustomNew: - def __new__(self): - print("hello") - - # types with custom 'tp_new' cannot be used as metaclass - with pytest.raises(TypeError): - mod.create_type("mytest.DummyFail1", WithCustomNew) - - # type 'int' also has a custom new - with pytest.raises(TypeError): - mod.create_type("mytest.DummyIntMeta", int) - - def test_get_name(self): - import struct - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .itemsize = 0, - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - }; - - HPyDef_METH(get_name, "get_name", HPyFunc_O) - static HPy get_name_impl(HPyContext *ctx, HPy self, HPy arg) - { - const char *name = HPyType_GetName(ctx, arg); - if (name == NULL) - return HPy_NULL; - return HPyUnicode_FromString(ctx, name); - } - - @EXPORT_TYPE("Dummy", Dummy_spec) - @EXPORT(get_name) - @INIT - """) - assert mod.Dummy.__name__ == "Dummy" - assert mod.get_name(mod.Dummy) == "Dummy" - assert mod.get_name(str) == "str" - assert mod.get_name(struct.Struct) == "Struct" - - def test_issubtype(self): - mod = self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - @DEFAULT_SHAPE - }; - - static HPyType_Spec Single_spec = { - .name = "mytest.Single", - @DEFAULT_SHAPE - }; - - static HPyType_Spec Dual_spec = { - .name = "mytest.Dual", - @DEFAULT_SHAPE - }; - - static void make_types(HPyContext *ctx, HPy module) - { - HPy h_dummy = HPyType_FromSpec(ctx, &Dummy_spec, NULL); - HPy_SetAttr_s(ctx, module, "Dummy", h_dummy); - HPyType_SpecParam single_param[] = { - { HPyType_SpecParam_Base, ctx->h_LongType }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_single = HPyType_FromSpec(ctx, &Single_spec, single_param); - if (HPy_IsNull(h_single)) - return; - HPy_SetAttr_s(ctx, module, "Single", h_single); - HPy_Close(ctx, h_single); - - HPyType_SpecParam dual_param[] = { - { HPyType_SpecParam_Base, ctx->h_LongType }, - { HPyType_SpecParam_Base, h_dummy }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_dual = HPyType_FromSpec(ctx, &Dual_spec, dual_param); - HPy_Close(ctx, h_dummy); - if (HPy_IsNull(h_dual)) - return; - HPy_SetAttr_s(ctx, module, "Dual", h_dual); - HPy_Close(ctx, h_dual); - } - - HPyDef_METH(issubtype, "issubtype", HPyFunc_VARARGS) - static HPy issubtype_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 2 arguments"); - return HPy_NULL; - } - int res = HPyType_IsSubtype(ctx, args[0], args[1]); - return HPyLong_FromLong(ctx, res); - } - - @EXPORT(issubtype) - @EXTRA_INIT_FUNC(make_types) - @INIT - """) - - class EveryMeta(type): - def __subclasscheck__(self, subclass): - return subclass is not None - Every = EveryMeta('Every', (), {}) - assert mod.issubtype(mod.Single, int) - assert mod.issubtype(mod.Dual, int) - assert mod.issubtype(mod.Dual, mod.Dummy) - assert not mod.issubtype(mod.Single, mod.Dummy) - assert not mod.issubtype(mod.Single, mod.Dual) - assert not mod.issubtype(mod.Dual, mod.Single) - assert issubclass(mod.Single, Every) - assert issubclass(mod.Dual, Every) - assert not mod.issubtype(mod.Single, Every) - assert not mod.issubtype(mod.Dual, Every) - - -class TestPureHPyType(HPyTest): - - ExtensionTemplate = PointTemplate - - def test_builtin_shape(self): - if self.is_graalpy: - import pytest - pytest.skip("Not yet implemented on GraalPy") - mod = self.make_module(""" - @DEFINE_PointObject(HPyType_BuiltinShape_Long) - @DEFINE_Point_xy - - static HPyDef *Point_defines[] = { - &Point_x, - &Point_y, - NULL - }; - - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .defines = Point_defines - }; - - static void make_Point(HPyContext *ctx, HPy module) - { - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Base, ctx->h_LongType }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_Point = HPyType_FromSpec(ctx, &Point_spec, param); - if (HPy_IsNull(h_Point)) - return; - HPy_SetAttr_s(ctx, module, "Point", h_Point); - HPy_Close(ctx, h_Point); - } - @EXTRA_INIT_FUNC(make_Point) - @INIT - """) - assert isinstance(mod.Point, type) - assert mod.Point.__name__ == 'Point' - assert mod.Point.__module__ == 'mytest' - assert issubclass(mod.Point, int) - assert isinstance(mod.Point(), mod.Point) - p0 = mod.Point() - assert p0 == 0 - assert p0.x == 0 - assert p0.y == 0 - - p42 = mod.Point(42) - p42.x = 123 - p42.y = 456 - assert p42 == 42 - assert p42.x == 123 - assert p42.y == 456 - - def test_invalid_shape(self): - import pytest - with pytest.raises(ValueError): - self.make_module(""" - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .builtin_shape = (HPyType_BuiltinShape)123 - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - - def test_call_zero_basicsize(self): - mod = self.make_module(""" - HPyDef_SLOT(Dummy_call, HPy_tp_call) - static HPy - Dummy_call_impl(HPyContext *ctx, HPy callable, const HPy *args, - size_t nargs, HPy kwnames) - { - return HPyUnicode_FromString(ctx, "hello"); - } - - static HPyDef *Dummy_defines[] = { &Dummy_call, NULL }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - @DEFAULT_SHAPE - .defines = Dummy_defines, - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - # type 'Dummy' has basicsize == 0; this test ensures that installation - # of the hidden call function field is done correctly - q = mod.Dummy() - assert q() == 'hello' diff --git a/graalpython/hpy/test/test_hpytype_legacy.py b/graalpython/hpy/test/test_hpytype_legacy.py deleted file mode 100644 index fa9710c58f..0000000000 --- a/graalpython/hpy/test/test_hpytype_legacy.py +++ /dev/null @@ -1,399 +0,0 @@ -""" HPyType tests on legacy types. """ - -import pytest -import sys -from .support import HPyTest, make_hpy_abi_fixture -from .test_hpytype import PointTemplate, TestType as _TestType - -hpy_abi = make_hpy_abi_fixture('with hybrid') - -class LegacyPointTemplate(PointTemplate): - """ - Override PointTemplate to instead define a legacy point type that - still provides access to PyObject_HEAD. - """ - - _STRUCT_BEGIN_FORMAT = """ - #include - typedef struct {{ - PyObject_HEAD - """ - - _STRUCT_END_FORMAT = """ - }} {struct_name}; - HPyType_LEGACY_HELPERS({struct_name}) - """ - - _METACLASS_STRUCT_BEGIN_FORMAT = """ - #include - typedef struct {{ - PyHeapTypeObject super; - """ - - _METACLASS_STRUCT_END_FORMAT = _STRUCT_END_FORMAT - - def DEFAULT_SHAPE(self): - return ".builtin_shape = HPyType_BuiltinShape_Legacy," - - -class TestLegacyType(_TestType): - - ExtensionTemplate = LegacyPointTemplate - - @pytest.mark.syncgc - def test_legacy_dealloc(self): - mod = self.make_module(""" - static long dealloc_counter = 0; - - HPyDef_METH(get_counter, "get_counter", HPyFunc_NOARGS) - static HPy get_counter_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, dealloc_counter); - } - - @DEFINE_PointObject - @DEFINE_Point_new - static void Point_dealloc(PyObject *self) - { - dealloc_counter++; - Py_TYPE(self)->tp_free(self); - } - - static HPyDef *Point_defines[] = {&Point_new, NULL}; - static PyType_Slot Point_slots[] = { - {Py_tp_dealloc, (void*)Point_dealloc}, - {0, NULL}, - }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_slots, - .defines = Point_defines, - }; - - @EXPORT(get_counter) - @EXPORT_TYPE("Point", Point_spec) - @INIT - """) - assert mod.get_counter() == 0 - p = mod.Point(0, 0) - del p - import gc; gc.collect() - assert mod.get_counter() == 1 - - def test_legacy_dealloc_and_HPy_tp_traverse(self): - import pytest - mod_src = """ - @DEFINE_PointObject - @DEFINE_Point_new - HPyDef_SLOT(Point_traverse, HPy_tp_traverse) - static int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) - { - return 0; - } - static void Point_dealloc(PyObject *self) - { - return; - } - - static HPyDef *Point_defines[] = {&Point_new, &Point_traverse, NULL}; - static PyType_Slot Point_slots[] = { - {Py_tp_dealloc, (void*)Point_dealloc}, - {0, NULL}, - }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_slots, - .defines = Point_defines, - }; - @EXPORT_TYPE("Point", Point_spec) - @INIT - """ - with pytest.raises(TypeError) as err: - mod = self.make_module(mod_src) - assert "legacy tp_dealloc" in str(err.value) - - def test_legacy_dealloc_and_HPy_tp_destroy(self): - import pytest - mod_src = """ - @DEFINE_PointObject - @DEFINE_Point_new - HPyDef_SLOT(Point_destroy, HPy_tp_destroy) - static void Point_destroy_impl(void *obj) - { - return; - } - static void Point_dealloc(PyObject *self) - { - return; - } - - static HPyDef *Point_defines[] = {&Point_new, &Point_destroy, NULL}; - static PyType_Slot Point_slots[] = { - {Py_tp_dealloc, (void*)Point_dealloc}, - {0, NULL}, - }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_slots, - .defines = Point_defines, - }; - @EXPORT_TYPE("Point", Point_spec) - @INIT - """ - with pytest.raises(TypeError) as err: - mod = self.make_module(mod_src) - assert "legacy tp_dealloc" in str(err.value) - - def test_metaclass_as_legacy_static_type(self): - mod = self.make_module(""" - #include - #include - - @DEFINE_DummyMeta_struct - - /* This module is compiled as a shared library and some compilers - don't allow addresses of Python objects defined in other - libraries to be used in static initializers here. The - DEFERRED_ADDRESS macro is just used for documentation and we - need to set the actual value before we call PyType_Ready. */ - #define DEFERRED_ADDRESS(x) NULL - - static PyTypeObject DummyMetaType = { - PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) - .tp_name = "mytest.DummyMeta", - .tp_basicsize = sizeof(DummyMeta), - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_base = DEFERRED_ADDRESS(&PyType_Type), - }; - - @DEFINE_Dummy_struct - - static PyMemberDef members[] = { - {"member", T_INT, offsetof(Dummy, member), 0, NULL}, - {NULL, 0, 0, 0, NULL}, - }; - - static PyType_Slot DummySlots[] = { - {Py_tp_members, members}, - {0, NULL}, - }; - - static HPyType_Spec Dummy_legacy_spec = { - .name = "mytest.Dummy", - .basicsize = sizeof(Dummy), - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - .builtin_shape = HPyType_BuiltinShape_Legacy, - .legacy_slots = DummySlots, - }; - - void setup_types(HPyContext *ctx, HPy module) { - HPy h_DummyMeta; - DummyMetaType.ob_base.ob_base.ob_type = &PyType_Type; - DummyMetaType.tp_base = &PyType_Type; - if (PyType_Ready(&DummyMetaType)) - return; - h_DummyMeta = HPy_FromPyObject(ctx, (PyObject*) &DummyMetaType); - - HPyType_SpecParam param[] = { - { HPyType_SpecParam_Metaclass, h_DummyMeta }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_Dummy = HPyType_FromSpec(ctx, &Dummy_legacy_spec, param); - if (!HPy_IsNull(h_Dummy)) { - HPy_SetAttr_s(ctx, module, "Dummy", h_Dummy); - HPy_SetAttr_s(ctx, module, "DummyMeta", h_DummyMeta); - } - - HPy_Close(ctx, h_Dummy); - HPy_Close(ctx, h_DummyMeta); - } - - @DEFINE_meta_data_accessors - - @EXPORT(set_meta_data) - @EXPORT(get_meta_data) - @EXPORT(set_member) - @EXTRA_INIT_FUNC(setup_types) - @INIT - """) - - assert isinstance(mod.Dummy, type) - assert mod.DummyMeta is type(mod.Dummy) - assert mod.set_meta_data(mod.Dummy) is None - assert mod.get_meta_data(mod.Dummy) == 42 + 11 - - d = mod.Dummy() - mod.set_member(d) - assert d.member == 123614 - - def test_call_zero_basicsize(self): - import pytest - # type 'Dummy' has basicsize == 0; we cannot use the HPy call protocol - # with legacy types that inherit their struct since we then don't know - # how to safely allocate the hidden field - with pytest.raises(TypeError): - self.make_module(""" - HPyDef_SLOT(Dummy_call, HPy_tp_call) - static HPy - Dummy_call_impl(HPyContext *ctx, HPy callable, const HPy *args, - size_t nargs, HPy kwnames) - { - return HPyUnicode_FromString(ctx, "hello"); - } - - static HPyDef *Dummy_defines[] = { &Dummy_call, NULL }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - @DEFAULT_SHAPE - .defines = Dummy_defines, - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - - @pytest.mark.skipif(sys.version_info < (3, 9), reason="not for python<3.9") - def test_legacy_class_method(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_xy - static PyObject * point_class_getitem(PyObject *cls, PyObject *args) - { - Py_ssize_t args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1; - if (args_len != 1) { - return PyErr_Format(PyExc_TypeError, - "Too %s arguments for %s", - args_len > 1 ? "many" : "few", - ((PyTypeObject *)cls)->tp_name); - } - return Py_GenericAlias(cls, args); - } - - static PyMethodDef point_methods[] = { - /* for typing; requires python >= 3.9 */ - {"__class_getitem__", - (PyCFunction)point_class_getitem, - METH_CLASS | METH_O, NULL}, - {NULL, NULL, 0, NULL} /* sentinel */ - }; - - - static PyType_Slot Point_slots[] = { - {Py_tp_methods, point_methods}, - {Py_tp_new, (void*)PyType_GenericNew}, - {0, NULL}, - }; - static HPyDef *Point_defines[] = {&Point_x, &Point_y, NULL}; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = SHAPE(PointObject), - .legacy_slots = Point_slots, - .defines = Point_defines, - }; - - @EXPORT_TYPE("Point", Point_spec) - @INIT - """) - # Calls __class_getitem__ - t = mod.Point[int] - assert str(t) == "mytest.Point[int]" - pt = mod.Point() - assert pt.x == 0 - assert pt.y == 0 - - -class TestCustomLegacyFeatures(HPyTest): - - def test_legacy_methods(self): - mod = self.make_module(""" - #include - - static PyObject *f(PyObject *self, PyObject *args) - { - return PyLong_FromLong(1234); - } - static PyObject *g(PyObject *self, PyObject *arg) - { - long x = PyLong_AsLong(arg); - return PyLong_FromLong(x * 2); - } - static PyObject *h(PyObject *self, PyObject *args) - { - long a, b, c; - if (!PyArg_ParseTuple(args, "lll", &a, &b, &c)) - return NULL; - return PyLong_FromLong(100*a + 10*b + c); - } - static PyObject *k(PyObject *self, PyObject *args, PyObject *kwargs) - { - static const char *kwlist[] = { "a", "b", "c", NULL }; - long a, b, c; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lll", (char **)kwlist, &a, &b, &c)) - return NULL; - return PyLong_FromLong(100*a + 10*b + c); - } - - static PyMethodDef my_legacy_methods[] = { - {"f", (PyCFunction)f, METH_NOARGS}, - {"g", (PyCFunction)g, METH_O}, - {"h", (PyCFunction)h, METH_VARARGS}, - {"k", (PyCFunction)k, METH_VARARGS | METH_KEYWORDS}, - {NULL} - }; - - @EXPORT_LEGACY(my_legacy_methods) - @INIT - """) - assert mod.f() == 1234 - assert mod.g(45) == 90 - assert mod.h(4, 5, 6) == 456 - assert mod.k(c=6, b=5, a=4) == 456 - - def test_legacy_inherits_from_pure_raises(self): - import pytest - mod_src = """ - static HPyType_Spec PureType_spec = { - .name = "mytest.PureType", - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE, - }; - - static HPyType_Spec LegacyType_spec = { - .name = "mytest.LegacyType", - .builtin_shape = HPyType_BuiltinShape_Legacy, - }; - - static void make_Types(HPyContext *ctx, HPy module) - { - HPy h_PureType = HPyType_FromSpec(ctx, &PureType_spec, NULL); - if (HPy_IsNull(h_PureType)) { - return; - } - - HPyType_SpecParam LegacyType_param[] = { - { HPyType_SpecParam_Base, h_PureType }, - { (HPyType_SpecParam_Kind)0 } - }; - HPy h_LegacyType = HPyType_FromSpec( - ctx, &LegacyType_spec, LegacyType_param); - if (HPy_IsNull(h_LegacyType)) { - HPy_Close(ctx, h_PureType); - return; - } - HPy_Close(ctx, h_LegacyType); - HPy_Close(ctx, h_PureType); - } - @EXTRA_INIT_FUNC(make_Types) - @INIT - """ - with pytest.raises(TypeError) as err: - self.make_module(mod_src) - assert str(err.value) == ( - "A legacy type should not inherit its memory layout from a" - " pure type") diff --git a/graalpython/hpy/test/test_hpyunicode.py b/graalpython/hpy/test/test_hpyunicode.py deleted file mode 100644 index 6f6ce29d16..0000000000 --- a/graalpython/hpy/test/test_hpyunicode.py +++ /dev/null @@ -1,977 +0,0 @@ -# -*- encoding: utf-8 -*- -import sys - -from .support import HPyTest - -class TestUnicode(HPyTest): - - def test_Check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (HPyUnicode_Check(ctx, arg)) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - class MyUnicode(str): - pass - - assert mod.f('hello') is True - assert mod.f(b'hello') is False - assert mod.f(MyUnicode('hello')) is True - - def test_FromString(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromString(ctx, "foobar"); - } - @EXPORT(f) - @INIT - """) - assert mod.f() == "foobar" - - def test_FromWideChar(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - const wchar_t buf[] = { 'h', 'e', 'l', 'l', 0xf2, ' ', - 'w', 'o', 'r', 'l', 'd', 0 }; - long n = HPyLong_AsLong(ctx, arg); - return HPyUnicode_FromWideChar(ctx, buf, n); - } - @EXPORT(f) - @INIT - """) - assert mod.f(-1) == "hellò world" - assert mod.f(11) == "hellò world" - assert mod.f(5) == "hellò" - - - def test_AsUTF8String(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_AsUTF8String(ctx, arg); - } - @EXPORT(f) - @INIT - """) - s = 'hellò' - b = mod.f(s) - assert type(b) is bytes - assert b == s.encode('utf-8') - - def test_AsASCIIString(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_AsASCIIString(ctx, arg); - } - @EXPORT(f) - @INIT - """) - s = 'world' - b = mod.f(s) - assert type(b) is bytes - assert b == s.encode('ascii') - - def test_AsLatin1String(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_AsLatin1String(ctx, arg); - } - @EXPORT(f) - @INIT - """) - s = "Müller" - b = mod.f(s) - assert type(b) is bytes - assert b == s.encode('latin1') - - def test_AsUTF8AndSize(self): - mod = self.make_module(""" - #include - - static HPy as_utf8_and_size(HPyContext *ctx, HPy arg, HPy_ssize_t *size) - { - HPy_ssize_t n; - const char* buf = HPyUnicode_AsUTF8AndSize(ctx, arg, size); - long res = 0; - - if (size) - n = *size; - else - n = strlen(buf); - - for(int i=0; i length - ("%5d", " 123", '(int)123'), - ("%5i", " 123", '(int)123'), - ("%5u", " 123", '(unsigned int)123'), - ("%5ld", " 123", '(long)123'), - ("%5li", " 123", '(long)123'), - ("%5lu", " 123", '(unsigned long)123'), - ("%5lld", " 123", '(long long)123'), - ("%5lli", " 123", '(long long)123'), - ("%5llu", " 123",'(unsigned long long)123'), - ("%5zd", " 123", '(HPy_ssize_t)123'), - ("%5zi", " 123", '(HPy_ssize_t)123'), - ("%5zu", " 123", '(size_t)123'), - ("%5x", " 7b", '(int)123'), - - ("%5d", " -123", '(int)-123'), - ("%5i", " -123", '(int)-123'), - ("%5ld", " -123", '(long)-123'), - ("%5li", " -123", '(long)-123'), - ("%5lld", " -123", '(long long)-123'), - ("%5lli", " -123", '(long long)-123'), - ("%5zd", " -123", '(HPy_ssize_t)-123'), - ("%5zi", " -123", '(HPy_ssize_t)-123'), - ("%9x", " ffffff85", '(int)-123'), - - # Integers: width > length, 0-flag - ("%05d", "00123", '(int)123'), - ("%05i", "00123", '(int)123'), - ("%05u", "00123", '(unsigned int)123'), - ("%05ld", "00123", '(long)123'), - ("%05li", "00123", '(long)123'), - ("%05lu", "00123", '(unsigned long)123'), - ("%05lld", "00123", '(long long)123'), - ("%05lli", "00123", '(long long)123'), - ("%05llu", "00123",'(unsigned long long)123'), - ("%05zd", "00123", '(HPy_ssize_t)123'), - ("%05zi", "00123", '(HPy_ssize_t)123'), - ("%05zu", "00123", '(size_t)123'), - ("%05x", "0007b", '(int)123'), - - ("%05d", "-0123", '(int)-123'), - ("%05i", "-0123", '(int)-123'), - ("%05ld", "-0123", '(long)-123'), - ("%05li", "-0123", '(long)-123'), - ("%05lld", "-0123", '(long long)-123'), - ("%05lli", "-0123", '(long long)-123'), - ("%05zd", "-0123", '(HPy_ssize_t)-123'), - ("%05zi", "-0123", '(HPy_ssize_t)-123'), - ("%09x", "0ffffff85", '(int)-123'), - - # Integers: precision < length - ("%.1d", "123", '(int)123'), - ("%.1i", "123", '(int)123'), - ("%.1u", "123", '(unsigned int)123'), - ("%.1ld", "123", '(long)123'), - ("%.1li", "123", '(long)123'), - ("%.1lu", "123", '(unsigned long)123'), - ("%.1lld", "123", '(long long)123'), - ("%.1lli", "123", '(long long)123'), - ("%.1llu", "123",'(unsigned long long)123'), - ("%.1zd", "123", '(HPy_ssize_t)123'), - ("%.1zi", "123", '(HPy_ssize_t)123'), - ("%.1zu", "123", '(size_t)123'), - ("%.1x", "7b", '(int)123'), - - ("%.1d", "-123", '(int)-123'), - ("%.1i", "-123", '(int)-123'), - ("%.1ld", "-123", '(long)-123'), - ("%.1li", "-123", '(long)-123'), - ("%.1lld", "-123", '(long long)-123'), - ("%.1lli", "-123", '(long long)-123'), - ("%.1zd", "-123", '(HPy_ssize_t)-123'), - ("%.1zi", "-123", '(HPy_ssize_t)-123'), - ("%.1x", "ffffff85", '(int)-123'), - - # Integers: precision > length - ("%.5d", "00123", '(int)123'), - ("%.5i", "00123", '(int)123'), - ("%.5u", "00123", '(unsigned int)123'), - ("%.5ld", "00123", '(long)123'), - ("%.5li", "00123", '(long)123'), - ("%.5lu", "00123", '(unsigned long)123'), - ("%.5lld", "00123", '(long long)123'), - ("%.5lli", "00123", '(long long)123'), - ("%.5llu", "00123",'(unsigned long long)123'), - ("%.5zd", "00123", '(HPy_ssize_t)123'), - ("%.5zi", "00123", '(HPy_ssize_t)123'), - ("%.5zu", "00123", '(size_t)123'), - ("%.5x", "0007b", '(int)123'), - - ("%.5d", "-00123", '(int)-123'), - ("%.5i", "-00123", '(int)-123'), - ("%.5ld", "-00123", '(long)-123'), - ("%.5li", "-00123", '(long)-123'), - ("%.5lld", "-00123", '(long long)-123'), - ("%.5lli", "-00123", '(long long)-123'), - ("%.5zd", "-00123", '(HPy_ssize_t)-123'), - ("%.5zi", "-00123", '(HPy_ssize_t)-123'), - ("%.9x", "0ffffff85", '(int)-123'), - - # Integers: width > precision > length - ("%7.5d", " 00123", '(int)123'), - ("%7.5i", " 00123", '(int)123'), - ("%7.5u", " 00123", '(unsigned int)123'), - ("%7.5ld", " 00123", '(long)123'), - ("%7.5li", " 00123", '(long)123'), - ("%7.5lu", " 00123", '(unsigned long)123'), - ("%7.5lld", " 00123", '(long long)123'), - ("%7.5lli", " 00123", '(long long)123'), - ("%7.5llu", " 00123",'(unsigned long long)123'), - ("%7.5zd", " 00123", '(HPy_ssize_t)123'), - ("%7.5zi", " 00123", '(HPy_ssize_t)123'), - ("%7.5zu", " 00123", '(size_t)123'), - ("%7.5x", " 0007b", '(int)123'), - - ("%7.5d", " -00123", '(int)-123'), - ("%7.5i", " -00123", '(int)-123'), - ("%7.5ld", " -00123", '(long)-123'), - ("%7.5li", " -00123", '(long)-123'), - ("%7.5lld", " -00123", '(long long)-123'), - ("%7.5lli", " -00123", '(long long)-123'), - ("%7.5zd", " -00123", '(HPy_ssize_t)-123'), - ("%7.5zi", " -00123", '(HPy_ssize_t)-123'), - ("%10.9x", " 0ffffff85", '(int)-123'), - - # Integers: width > precision > length, 0-flag - ("%07.5d", "0000123", '(int)123'), - ("%07.5i", "0000123", '(int)123'), - ("%07.5u", "0000123", '(unsigned int)123'), - ("%07.5ld", "0000123", '(long)123'), - ("%07.5li", "0000123", '(long)123'), - ("%07.5lu", "0000123", '(unsigned long)123'), - ("%07.5lld", "0000123", '(long long)123'), - ("%07.5lli", "0000123", '(long long)123'), - ("%07.5llu", "0000123",'(unsigned long long)123'), - ("%07.5zd", "0000123", '(HPy_ssize_t)123'), - ("%07.5zi", "0000123", '(HPy_ssize_t)123'), - ("%07.5zu", "0000123", '(size_t)123'), - ("%07.5x", "000007b", '(int)123'), - - ("%07.5d", "-000123", '(int)-123'), - ("%07.5i", "-000123", '(int)-123'), - ("%07.5ld", "-000123", '(long)-123'), - ("%07.5li", "-000123", '(long)-123'), - ("%07.5lld", "-000123", '(long long)-123'), - ("%07.5lli", "-000123", '(long long)-123'), - ("%07.5zd", "-000123", '(HPy_ssize_t)-123'), - ("%07.5zi", "-000123", '(HPy_ssize_t)-123'), - ("%010.9x","00ffffff85", '(int)-123'), - - # Integers: precision > width > length - ("%5.7d", "0000123", '(int)123'), - ("%5.7i", "0000123", '(int)123'), - ("%5.7u", "0000123", '(unsigned int)123'), - ("%5.7ld", "0000123", '(long)123'), - ("%5.7li", "0000123", '(long)123'), - ("%5.7lu", "0000123", '(unsigned long)123'), - ("%5.7lld", "0000123", '(long long)123'), - ("%5.7lli", "0000123", '(long long)123'), - ("%5.7llu", "0000123",'(unsigned long long)123'), - ("%5.7zd", "0000123", '(HPy_ssize_t)123'), - ("%5.7zi", "0000123", '(HPy_ssize_t)123'), - ("%5.7zu", "0000123", '(size_t)123'), - ("%5.7x", "000007b", '(int)123'), - - ("%5.7d", "-0000123", '(int)-123'), - ("%5.7i", "-0000123", '(int)-123'), - ("%5.7ld", "-0000123", '(long)-123'), - ("%5.7li", "-0000123", '(long)-123'), - ("%5.7lld", "-0000123", '(long long)-123'), - ("%5.7lli", "-0000123", '(long long)-123'), - ("%5.7zd", "-0000123", '(HPy_ssize_t)-123'), - ("%5.7zi", "-0000123", '(HPy_ssize_t)-123'), - ("%9.10x", "00ffffff85", '(int)-123'), - - # Integers: precision > width > length, 0-flag - ("%05.7d", "0000123", '(int)123'), - ("%05.7i", "0000123", '(int)123'), - ("%05.7u", "0000123", '(unsigned int)123'), - ("%05.7ld", "0000123", '(long)123'), - ("%05.7li", "0000123", '(long)123'), - ("%05.7lu", "0000123", '(unsigned long)123'), - ("%05.7lld", "0000123", '(long long)123'), - ("%05.7lli", "0000123", '(long long)123'), - ("%05.7llu", "0000123",'(unsigned long long)123'), - ("%05.7zd", "0000123", '(HPy_ssize_t)123'), - ("%05.7zi", "0000123", '(HPy_ssize_t)123'), - ("%05.7zu", "0000123", '(size_t)123'), - ("%05.7x", "000007b", '(int)123'), - - ("%05.7d", "-0000123", '(int)-123'), - ("%05.7i", "-0000123", '(int)-123'), - ("%05.7ld", "-0000123", '(long)-123'), - ("%05.7li", "-0000123", '(long)-123'), - ("%05.7lld", "-0000123", '(long long)-123'), - ("%05.7lli", "-0000123", '(long long)-123'), - ("%05.7zd", "-0000123", '(HPy_ssize_t)-123'), - ("%05.7zi", "-0000123", '(HPy_ssize_t)-123'), - ("%09.10x","00ffffff85", '(int)-123'), - - # Integers: precision = 0, arg = 0 (empty string in C) - ("%.0d", "0", '(int)0'), - ("%.0i", "0", '(int)0'), - ("%.0u", "0", '(unsigned int)0'), - ("%.0ld", "0", '(long)0'), - ("%.0li", "0", '(long)0'), - ("%.0lu", "0", '(unsigned long)0'), - ("%.0lld", "0", '(long long)0'), - ("%.0lli", "0", '(long long)0'), - ("%.0llu", "0", '(unsigned long long)0'), - ("%.0zd", "0", '(HPy_ssize_t)0'), - ("%.0zi", "0", '(HPy_ssize_t)0'), - ("%.0zu", "0", '(size_t)0'), - ("%.0x", "0", '(int)0'), - - # Strings - ("%s", "None", ' "None"'), - ("%U", "None", 'unicode'), - ("%A", "None", 'ctx->h_None'), - ("%S", "None", 'ctx->h_None'), - ("%R", "None", 'ctx->h_None'), - ("%V", "None", 'unicode, "ignored"'), - ("%V", "None", ' NULL, "None"'), - - # Strings: width < length - ("%1s", "None", ' "None"'), - ("%1U", "None", 'unicode'), - ("%1A", "None", 'ctx->h_None'), - ("%1S", "None", 'ctx->h_None'), - ("%1R", "None", 'ctx->h_None'), - ("%1V", "None", 'unicode, "ignored"'), - ("%1V", "None", ' NULL, "None"'), - - # Strings: width > length - ("%5s", " None", ' "None"'), - ("%5U", " None", 'unicode'), - ("%5A", " None", 'ctx->h_None'), - ("%5S", " None", 'ctx->h_None'), - ("%5R", " None", 'ctx->h_None'), - ("%5V", " None", 'unicode, "ignored"'), - ("%5V", " None", ' NULL, "None"'), - - # Strings: precision < length - ("%.1s", "N", ' "None"'), - ("%.1U", "N", 'unicode'), - ("%.1A", "N", 'ctx->h_None'), - ("%.1S", "N", 'ctx->h_None'), - ("%.1R", "N", 'ctx->h_None'), - ("%.1V", "N", 'unicode, "ignored"'), - ("%.1V", "N", ' NULL, "None"'), - - # Strings: precision > length - ("%.5s", "None", ' "None"'), - ("%.5U", "None", 'unicode'), - ("%.5A", "None", 'ctx->h_None'), - ("%.5S", "None", 'ctx->h_None'), - ("%.5R", "None", 'ctx->h_None'), - ("%.5V", "None", 'unicode, "ignored"'), - ("%.5V", "None", ' NULL, "None"'), - - # Strings: precision < length, width > length - ("%5.1s", " N", ' "None"'), - ("%5.1U", " N", 'unicode'), - ("%5.1A", " N", 'ctx->h_None'), - ("%5.1S", " N", 'ctx->h_None'), - ("%5.1R", " N", 'ctx->h_None'), - ("%5.1V", " N", 'unicode, "ignored"'), - ("%5.1V", " N", ' NULL, "None"'), - - # Strings: width < length, precision > length - ("%1.5s", "None", ' "None"'), - ("%1.5U", "None", 'unicode'), - ("%1.5A", "None", 'ctx->h_None'), - ("%1.5S", "None", 'ctx->h_None'), - ("%1.5R", "None", 'ctx->h_None'), - ("%1.5V", "None", 'unicode, "ignored"'), - ("%1.5V", "None", ' NULL, "None"'), - - # Additional HPy tests: - ("%c", (OverflowError, re.escape("character argument not in range(0x110000)")), "0x10ffff + 2"), - - ("check if %5d %s %6.3d is %5S or %6.3S", - "check if 42 == -042 is True or Fal", - '42, "==", -42, ctx->h_True, ctx->h_False') - ] - - cpython_incompatible_cases = [ - ( "%s", (SystemError, "null c string passed as value for formatting unit '%s'"), "NULL"), - - ( '%4p', (SystemError, "formatting unit '%p' does not support width nor precision"), "0"), - ( '%04p', (SystemError, "formatting unit '%p' does not support 0-padding"), "0"), - ( '%.4p', (SystemError, "formatting unit '%p' does not support width nor precision"), "0"), - ( '%8.4p', (SystemError, "formatting unit '%p' does not support width nor precision"), "0"), - ('%08.4p', (SystemError, "formatting unit '%p' does not support 0-padding"), "0"), - - ( '%4c', (SystemError, "formatting unit '%c' does not support width nor precision"), "0"), - ( '%04c', (SystemError, "formatting unit '%c' does not support 0-padding"), "0"), - ( '%.4c', (SystemError, "formatting unit '%c' does not support width nor precision"), "0"), - ( '%8.4c', (SystemError, "formatting unit '%c' does not support width nor precision"), "0"), - ('%08.4c', (SystemError, "formatting unit '%c' does not support 0-padding"), "0"), - - ("%U", (SystemError, ".*HPy_NULL passed.*"), "HPy_NULL"), - ("%S", (SystemError, ".*HPy_NULL passed.*"), "HPy_NULL"), - ("%R", (SystemError, ".*HPy_NULL passed.*"), "HPy_NULL"), - ("%A", (SystemError, ".*HPy_NULL passed.*"), "HPy_NULL"), - - ("%0s", (SystemError, "formatting unit '%s' does not support 0-padding"), "0"), - ("%0p", (SystemError, "formatting unit '%p' does not support 0-padding"), "0"), - ("%0U", (SystemError, "formatting unit '%U' does not support 0-padding"), "0"), - ("%0V", (SystemError, "formatting unit '%V' does not support 0-padding"), "0"), - ("%0S", (SystemError, "formatting unit '%S' does not support 0-padding"), "0"), - ("%0R", (SystemError, "formatting unit '%R' does not support 0-padding"), "0"), - ("%0A", (SystemError, "formatting unit '%A' does not support 0-padding"), "0"), - ] - - cases += cpython_incompatible_cases - cpython_incompatible_cases = set(cpython_incompatible_cases) - - # Generate a unique name for each test that is also valid C identifier - names = ['a' + str(i) for i in range(0, len(cases))] - cases = {name:case for (name, case) in itertools.zip_longest(names, cases)} - - # --- - # Generate the test code from the cases: - def makefun(name, fmt, arg): - cpy_arg = arg.replace("ctx->h_None", "Py_None").replace("HPy_ssize_t", "Py_ssize_t") - return """ - HPyDef_METH({name}, "{name}", HPyFunc_NOARGS) - static HPy {name}_impl(HPyContext *ctx, HPy self) - {{ - HPy unicode = HPyUnicode_FromString(ctx, "None"); - if (HPy_IsNull(unicode)) return HPy_NULL; - HPy result = HPyUnicode_FromFormat(ctx, "{fmt}", {arg}); - HPy_Close(ctx, unicode); - return result; - }} - - #ifdef CPM_WITH_CPYTHON - HPyDef_METH({name}_cpython, "{name}_cpython", HPyFunc_NOARGS) - static HPy {name}_cpython_impl(HPyContext *ctx, HPy self) - {{ - PyObject *unicode = PyUnicode_FromString("None"); - PyObject *py = PyUnicode_FromFormat("{fmt}", {cpy_arg}); - HPy hpy = HPy_NULL; - if (py != NULL) {{ - hpy = HPy_FromPyObject(ctx, py); - Py_DECREF(py); - }} - Py_DECREF(unicode); - return hpy; - }} - #endif - """.format(name=name, fmt=fmt, arg=arg, cpy_arg=cpy_arg) - - # Change False->True to also check comparison with CPython. - # Works only for 3.12 or higher, lower versions have bugs that are - # fixed in HPy - compare_with_cpython = False and \ - hpy_abi == 'cpython' and \ - sys.implementation.name == 'cpython' and \ - sys.implementation.version.major >= 3 and \ - sys.implementation.version.minor >= 12 - - # Create functions for each case using the "makefun" template, export them - lines = ['#define CPM_WITH_CPYTHON'] if compare_with_cpython else [] - lines += [makefun(name, fmt, arg) for (name, (fmt, _, arg)) in cases.items()] - lines += ["@EXPORT({})".format(name) for name in cases.keys()] - if compare_with_cpython: - lines += ["@EXPORT({}_cpython)".format(name) for name in cases.keys()] - lines += ["@INIT"] - - mod = self.make_module("\n".join(lines)) - - def check_cpython_raises_any(name): - try: - getattr(mod, name + "_cpython")() - return False - except: - return True - - for (name, case) in cases.items(): - (_, expected, _) = case - if isinstance(expected, tuple): - (expected_type, expected_message) = expected - with pytest.raises(expected_type, match=expected_message): - getattr(mod, name)() - if compare_with_cpython and case not in cpython_incompatible_cases: - check_cpython_raises_any(name) - continue - - assert getattr(mod, name)() == expected, name + ":" + repr(case) - if compare_with_cpython and case not in cpython_incompatible_cases: - assert getattr(mod, name)() == getattr(mod, name + "_cpython")(), \ - "CPython check: " + name + ":" + repr(case) - - def test_FromFormat_Ptr(self): - # '%p' is platform dependent to some extent, so we need to use regex - import re - mod = self.make_module(""" - HPyDef_METH(p, "p", HPyFunc_NOARGS) - static HPy p_impl(HPyContext *ctx, HPy self) - { - return HPyUnicode_FromFormat(ctx, "prefix-%p-suffix", (void*) 0xbeef); - } - - @EXPORT(p) - @INIT - """) - assert re.match(r'prefix-0x[0]{,60}[bB][eE][eE][fF]-suffix', mod.p()) - - def test_FromFormat_PyObjs(self): - mod = self.make_module(""" - HPyDef_METH(S, "S", HPyFunc_O) - static HPy S_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_FromFormat(ctx, "prefix-%S-suffix", arg); - } - - HPyDef_METH(R, "R", HPyFunc_O) - static HPy R_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_FromFormat(ctx, "prefix-%R-suffix", arg); - } - - HPyDef_METH(A, "A", HPyFunc_O) - static HPy A_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_FromFormat(ctx, "prefix-%A-suffix", arg); - } - - @EXPORT(S) - @EXPORT(R) - @EXPORT(A) - @INIT - """) - - class MyObj: - def __str__(self): - return "MyObj.__str__" - - def __repr__(self): - return "MyObj.__repr__ü" - - assert mod.S('ABC') == 'prefix-ABC-suffix' - assert mod.S(42) == 'prefix-42-suffix' - assert mod.S(MyObj()) == 'prefix-MyObj.__str__-suffix' - - assert mod.R('ABC') == "prefix-'ABC'-suffix" - assert mod.R(42) == 'prefix-42-suffix' - assert mod.R(MyObj()) == 'prefix-MyObj.__repr__ü-suffix' - - assert mod.A('ABC') == "prefix-'ABC'-suffix" - assert mod.A(42) == 'prefix-42-suffix' - assert mod.A(MyObj()) == 'prefix-MyObj.__repr__\\xfc-suffix' - - def test_FromFormat_NoAsciiEncodedFmt(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(no_ascii_fmt, "no_ascii_fmt", HPyFunc_O) - static HPy no_ascii_fmt_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t s; - const char *fmt = HPyUnicode_AsUTF8AndSize(ctx, arg, &s); - return HPyUnicode_FromFormat(ctx, fmt); - } - - @EXPORT(no_ascii_fmt) - @INIT - """) - - with pytest.raises(ValueError, match="expected an ASCII-encoded format string, got a non-ASCII byte: 0xc3"): - mod.no_ascii_fmt("format ü") - - def test_FromFormat_Unicode(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPyUnicode_FromFormat(ctx, "%10.5S", arg); - } - - @EXPORT(f) - @INIT - """) - assert mod.f("€urΘpe") == " €urΘp" - - def test_FromFormat_LongFormat(self): - chunk_size = 1000 - chunks_count = 5 - total_c_size = (chunk_size + 1) * chunks_count + 1 - args = ','.join([str(i) for i in range(1, chunks_count+1)]) - mod = self.make_module(""" - #include - - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - {{ - const size_t chunk_size = {chunk_size} + 1; // for the '%d' - const size_t total_size = {total_size}; - char fmt[{total_size}]; - memset(fmt, 'a', total_size); - fmt[total_size - 1] = '\\0'; - for (size_t i = 0; i < {chunks_count}; i++) {{ - fmt[i * chunk_size] = '%'; - fmt[(i * chunk_size)+1] = 'd'; - }} - return HPyUnicode_FromFormat(ctx, fmt, {args}); - }} - - @EXPORT(f) - @INIT - """.format(chunk_size=chunk_size, chunks_count=chunks_count, total_size=total_c_size, args=args)) - assert mod.f() == ''.join([str(i) + ("a" * (chunk_size - 1)) for i in range(1,chunks_count+1)]) - - def test_FromFormat_Limits(self): - import sys - import pytest - mod = self.make_module(""" - #include - - HPyDef_METH(width, "width", HPyFunc_NOARGS) - static HPy width_impl(HPyContext *ctx, HPy self) - {{ - char fmt[512]; - sprintf(fmt, "%%%llud", ((unsigned long long) HPY_SSIZE_T_MAX) + 1ull); - return HPyUnicode_FromFormat(ctx, fmt, 42); - }} - - HPyDef_METH(precision, "precision", HPyFunc_NOARGS) - static HPy precision_impl(HPyContext *ctx, HPy self) - {{ - char fmt[512]; - sprintf(fmt, "%%.%llud", ((unsigned long long) HPY_SSIZE_T_MAX) + 1ull); - return HPyUnicode_FromFormat(ctx, fmt, 42); - }} - - HPyDef_METH(memory_err_width, "memory_err_width", HPyFunc_NOARGS) - static HPy memory_err_width_impl(HPyContext *ctx, HPy self) - {{ - return HPyUnicode_FromFormat(ctx, "%{max_size}d", 42); - }} - - HPyDef_METH(memory_err_precision, "memory_err_precision", HPyFunc_NOARGS) - static HPy memory_err_precision_impl(HPyContext *ctx, HPy self) - {{ - return HPyUnicode_FromFormat(ctx, "%.{max_size}d", 42); - }} - - @EXPORT(width) - @EXPORT(precision) - @INIT - """.format(max_size = str(sys.maxsize + 1))) - with pytest.raises(ValueError) as exc: - mod.width() - assert str(exc.value) == "width too big" - with pytest.raises(ValueError) as exc: - mod.precision() - assert str(exc.value) == "precision too big" - - def test_FromEncodedObject(self): - import pytest - mod = self.make_module(""" - static const char *as_string(HPyContext *ctx, HPy h) - { - const char *res = HPyUnicode_AsUTF8AndSize(ctx, h, NULL); - if (res == NULL) - HPyErr_Clear(ctx); - return res; - } - - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy h_obj; - const char *encoding, *errors; - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 3 arguments"); - return HPy_NULL; - } - h_obj = HPy_Is(ctx, args[0], ctx->h_None) ? HPy_NULL : args[0]; - encoding = as_string(ctx, args[1]); - errors = as_string(ctx, args[2]); - return HPyUnicode_FromEncodedObject(ctx, h_obj, encoding, errors); - } - @EXPORT(f) - @INIT - """) - # "hellö" as UTF-8 encoded bytes - utf8_bytes = b"hell\xc3\xb6" - # "hellö" as UTF-16 encoded bytes - utf16_bytes = b'\xff\xfeh\x00e\x00l\x00l\x00\xf6\x00' - ascii_codepoints = bytes(range(1, 128)) - - # note: None (if passed to arguments 'encoding' or 'errors') will be - # translated to a NULL pointer - - for errors in (None, "strict", "ignore", "replace"): - assert mod.f(b"hello", "ascii", errors) == "hello" - assert mod.f(utf8_bytes, "utf8", errors) == "hellö" - assert mod.f(utf16_bytes, "utf16", errors) == "hellö" - assert len(mod.f(ascii_codepoints, "ascii", errors)) == 127 - assert len(mod.f(ascii_codepoints, "utf8", errors)) == 127 - - # None will be translated to NULL and then defaults to UTF-8 encoding - for encoding in (None, "utf8"): - assert mod.f(utf8_bytes, encoding, None) == "hellö" - - with pytest.raises(UnicodeDecodeError): - mod.f(utf16_bytes, encoding, None) - - assert mod.f(utf16_bytes, encoding, "replace") == '��h\x00e\x00l\x00l\x00�\x00' - assert mod.f(utf16_bytes, encoding, "ignore") == 'h\x00e\x00l\x00l\x00\x00' - - # test unknown encoding - with pytest.raises(LookupError): - mod.f(b"hello", "qwertyasdf13", None) - - with pytest.raises(SystemError): - mod.f(None, None, None) - with pytest.raises(TypeError): - mod.f("hello", None, None) - with pytest.raises(TypeError): - mod.f(123, None, None) - - def test_Substring(self): - import pytest - import string - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy_ssize_t start, end; - if (nargs != 3) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly 3 arguments"); - return HPy_NULL; - } - - start = HPyLong_AsSsize_t(ctx, args[1]); - if (start == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - - end = HPyLong_AsSsize_t(ctx, args[2]); - if (end == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - - return HPyUnicode_Substring(ctx, args[0], start, end); - } - @EXPORT(f) - @INIT - """) - # start == end - assert mod.f("hello", 0, 0) == "" - assert mod.f("hello", 4, 4) == "" - assert mod.f("hello", 5, 0) == "" - # start < end - assert mod.f("hello", 0, 5) == "hello" - assert mod.f("hello", 0, 100) == "hello" - assert mod.f('hello', 0, 1) == 'h' - assert mod.f("hello", 0, 2) == "he" - assert mod.f("hello", 2, 5) == "llo" - assert mod.f("hello", 2, 4) == "ll" - assert mod.f("hello", 100, 105) == "" - # start > end - assert mod.f("hello", 2000, 1000) == "" - assert mod.f("hello", 2, 1) == "" - - with pytest.raises(IndexError): - mod.f("hello", -2, 5) - with pytest.raises(IndexError): - mod.f("hello", 2, -1) - - # The following block is a variation of CPython's - # 'string_tests.py: test_extended_getslice'. This compares substrings - # with list slicing. - s = string.ascii_letters + string.digits - n = len(s) - indices = (0, 1, 3, 41, 1000, n-1, n-2, n-37) - for start in indices: - for stop in indices: - L = list(s)[start:stop] - assert mod.f(s, start, stop) == "".join(L) diff --git a/graalpython/hpy/test/test_importing.py b/graalpython/hpy/test/test_importing.py deleted file mode 100644 index a16fa74c74..0000000000 --- a/graalpython/hpy/test/test_importing.py +++ /dev/null @@ -1,55 +0,0 @@ -import pytest -from .support import HPyTest - -@pytest.fixture(params=['cpython', 'universal', 'hybrid', 'debug']) -def hpy_abi(request): - abi = request.param - yield abi - - -class TestImporting(HPyTest): - - def full_import(self, name, mod_filename): - import importlib - import sys - import os - if name in sys.modules: - raise ValueError( - "Test module {!r} already present in sys.modules".format(name)) - importlib.invalidate_caches() - mod_dir = os.path.dirname(mod_filename) - sys.path.insert(0, mod_dir) - try: - module = importlib.import_module(name) - assert sys.modules[name] is module - finally: - # assert that the module import didn't change the sys.path entry - # that was added above, then remove the entry. - assert sys.path[0] == mod_dir - del sys.path[0] - if name in sys.modules: - del sys.modules[name] - return module - - def test_importing_attributes(self, hpy_abi, tmpdir): - import pytest - if not self.supports_ordinary_make_module_imports(): - pytest.skip() - from hpy.devel.abitag import get_hpy_ext_suffix - mod = self.make_module(""" - @INIT - """, name='mytest') - mod = self.full_import(mod.__name__, mod.__file__) - assert mod.__name__ == 'mytest' - assert mod.__package__ == '' - assert mod.__doc__ == 'some test for hpy' - assert mod.__loader__.name == 'mytest' - assert mod.__spec__.loader is mod.__loader__ - assert mod.__spec__.name == 'mytest' - assert mod.__file__ - - if hpy_abi == 'debug': - hpy_abi = 'universal' - ext_suffix = get_hpy_ext_suffix(hpy_abi) - assert repr(mod) == ''.format( - repr(str(tmpdir.join('mytest' + ext_suffix)))) diff --git a/graalpython/hpy/test/test_legacy_forbidden.py b/graalpython/hpy/test/test_legacy_forbidden.py deleted file mode 100644 index 6dfe29be51..0000000000 --- a/graalpython/hpy/test/test_legacy_forbidden.py +++ /dev/null @@ -1,74 +0,0 @@ -""" -In this file we check that if we use legacy features in universal mode, we -get the expected compile time errors -""" - -from .support import HPyTest, make_hpy_abi_fixture, ONLY_LINUX - -# this is not strictly correct, we should check whether the actual compiler -# is GCC. But for the CI and most cases, it's enough to assume that if we are -# on linux we are using GCC. -# -# We need this because some of the nice compilation errors (such as the ones -# causes by _HPY_LEGACY) are triggered only by gcc. Would be nice to have them -# also for other compilers -ONLY_GCC = ONLY_LINUX - - -class TestLegacyForbidden(HPyTest): - - hpy_abi = make_hpy_abi_fixture(['universal'], class_fixture=True) - - LEGACY_ERROR = "Cannot use legacy functions when targeting the HPy Universal ABI" - - def test_expect_make_error(self): - src = """ - #error "this is a compile time error" - """ - self.expect_make_error(src, "this is a compile time error") - - def test_Python_h_forbidden(self, capfd): - src = """ - #include - @INIT - """ - self.expect_make_error(src, - "It is forbidden to #include " - "when targeting the HPy Universal ABI") - - @ONLY_GCC - def test_HPy_AsPyObject(self, capfd): - # NOTE: in this test we don't include Python.h. We want to test that - # we get a nice compile-time error by just calling HPy_AsPyObject. - # that's why we use "cpy_PyObject" (which is available because defined - # by hpy.h) - src = """ - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - cpy_PyObject *pyobj = HPy_AsPyObject(ctx, self); - (void)pyobj; // silence the warning about unused variable - return HPy_NULL; - } - @EXPORT(f) - @INIT - """ - self.expect_make_error(src, self.LEGACY_ERROR) - - @ONLY_GCC - def test_HPy_FromPyObject(self, capfd): - # NOTE: in this test we don't include Python.h. We want to test that - # we get a nice compile-time error by just calling HPy_AsPyObject. - # that's why we use "cpy_PyObject" (which is available because defined - # by hpy.h) - src = """ - HPyDef_METH(f, "f", HPyFunc_NOARGS) - static HPy f_impl(HPyContext *ctx, HPy self) - { - cpy_PyObject *pyobj = NULL; - return HPy_FromPyObject(ctx, pyobj); - } - @EXPORT(f) - @INIT - """ - self.expect_make_error(src, self.LEGACY_ERROR) diff --git a/graalpython/hpy/test/test_number.py b/graalpython/hpy/test/test_number.py deleted file mode 100644 index 2b92924fb8..0000000000 --- a/graalpython/hpy/test/test_number.py +++ /dev/null @@ -1,235 +0,0 @@ -from .support import HPyTest - - -class TestNumber(HPyTest): - - def test_bool_from_bool_and_long(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(from_bool, "from_bool", HPyFunc_O) - static HPy from_bool_impl(HPyContext *ctx, HPy self, HPy arg) - { - int32_t x = HPyLong_AsInt32_t(ctx, arg); - if (x == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - if (x != 0 && x != 1) { - HPyErr_SetString(ctx, ctx->h_ValueError, - "value must be 0 or 1"); - return HPy_NULL; - } - return HPyBool_FromBool(ctx, (x ? true : false)); - } - - HPyDef_METH(from_long, "from_long", HPyFunc_O) - static HPy from_long_impl(HPyContext *ctx, HPy self, HPy arg) - { - long x = HPyLong_AsLong(ctx, arg); - if (x == -1 && HPyErr_Occurred(ctx)) - return HPy_NULL; - return HPyBool_FromLong(ctx, x); - } - @EXPORT(from_bool) - @EXPORT(from_long) - @INIT - """) - assert mod.from_bool(0) is False - assert mod.from_bool(1) is True - with pytest.raises(ValueError): - mod.from_bool(2) - assert mod.from_long(0) is False - assert mod.from_long(42) is True - - def test_unary(self): - import pytest - import operator - for c_name, op in [ - ('Negative', operator.neg), - ('Positive', operator.pos), - ('Absolute', abs), - ('Invert', operator.invert), - ('Index', operator.index), - ('Long', int), - ('Float', float), - ]: - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_%s(ctx, arg); - } - @EXPORT(f) - @INIT - """ % (c_name,), name='number_'+c_name) - assert mod.f(-5) == op(-5) - assert mod.f(6) == op(6) - try: - res = op(4.75) - except Exception as e: - with pytest.raises(e.__class__): - mod.f(4.75) - else: - assert mod.f(4.75) == res - - def test_binary(self): - import operator - for c_name, op in [ - ('Add', operator.add), - ('Subtract', operator.sub), - ('Multiply', operator.mul), - ('FloorDivide', operator.floordiv), - ('TrueDivide', operator.truediv), - ('Remainder', operator.mod), - ('Divmod', divmod), - ('Lshift', operator.lshift), - ('Rshift', operator.rshift), - ('And', operator.and_), - ('Xor', operator.xor), - ('Or', operator.or_), - ]: - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_%s(ctx, a, b); - } - @EXPORT(f) - @INIT - """ % (c_name,), name='number_'+c_name) - assert mod.f(5, 4) == op(5, 4) - assert mod.f(6, 3) == op(6, 3) - - def test_power(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b, c; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &a, &b, &c)) - return HPy_NULL; - return HPy_Power(ctx, a, b, c); - } - @EXPORT(f) - @INIT - """) - assert mod.f(4, 5, None) == 4 ** 5 - assert mod.f(4, 5, 7) == pow(4, 5, 7) - - def test_matmul(self): - class Mat: - def __matmul__(self, other): - return ('matmul', self, other) - m1 = Mat() - m2 = Mat() - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_MatrixMultiply(ctx, a, b); - } - @EXPORT(f) - @INIT - """) - assert mod.f(m1, m2) == m1.__matmul__(m2) - - def test_inplace_binary(self): - import operator - for c_name, py_name in [ - ('Add', '__iadd__'), - ('Subtract', '__isub__'), - ('Multiply', '__imul__'), - ('FloorDivide', '__ifloordiv__'), - ('TrueDivide', '__itruediv__'), - ('Remainder', '__imod__'), - ('Lshift', '__ilshift__'), - ('Rshift', '__irshift__'), - ('And', '__iand__'), - ('Xor', '__ixor__'), - ('Or', '__ior__'), - ]: - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_InPlace%s(ctx, a, b); - } - @EXPORT(f) - @INIT - """ % (c_name,), name='number_'+c_name) - class A: - def mymethod(self, b): - return (py_name, b) - setattr(A, py_name, A.mymethod) - assert mod.f(A(), 12.34) == A().mymethod(12.34) - - def test_inplace_power(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b, c; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &a, &b, &c)) - return HPy_NULL; - return HPy_InPlacePower(ctx, a, b, c); - } - @EXPORT(f) - @INIT - """) - class A: - def __ipow__(self, b): - return ('ipow', b) - # the behavior of PyNumber_InPlacePower is weird: if __ipow__ is - # defined, the 3rd arg is always ignored, even if the doc say the - # opposite - assert mod.f(A(), 5, None) == A().__ipow__(5) - assert mod.f(A(), 7, 'hello') == A().__ipow__(7) - assert mod.f(4, 5, 7) == pow(4, 5, 7) - - def test_inplace_matmul(self): - class Mat: - def __imatmul__(self, other): - return ('imatmul', self, other) - m1 = Mat() - m2 = Mat() - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - return HPy_InPlaceMatrixMultiply(ctx, a, b); - } - @EXPORT(f) - @INIT - """) - assert mod.f(m1, m2) == m1.__imatmul__(m2) - - def test_number_check(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int cond = HPyNumber_Check(ctx, arg); - return HPyLong_FromLong(ctx, cond); - } - @EXPORT(f) - @INIT - """) - assert mod.f("foo") == 0 - assert mod.f(42) == 1 - assert mod.f(42.1) == 1 diff --git a/graalpython/hpy/test/test_object.py b/graalpython/hpy/test/test_object.py deleted file mode 100644 index 369b1500ad..0000000000 --- a/graalpython/hpy/test/test_object.py +++ /dev/null @@ -1,1040 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestObject(HPyTest): - def test_getattr(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy name, result; - name = HPyUnicode_FromString(ctx, "foo"); - if (HPy_IsNull(name)) - return HPy_NULL; - result = HPy_GetAttr(ctx, arg, name); - HPy_Close(ctx, name); - if (HPy_IsNull(result)) - return HPy_NULL; - return result; - } - @EXPORT(f) - @INIT - """) - - class Attrs: - def __init__(self, **kw): - for k, v in kw.items(): - setattr(self, k, v) - - class ClassAttr: - foo = 10 - - class PropAttr: - @property - def foo(self): - return 11 - - assert mod.f(Attrs(foo=5)) == 5 - with pytest.raises(AttributeError): - mod.f(Attrs()) - with pytest.raises(AttributeError): - mod.f(42) - assert mod.f(ClassAttr) == 10 - assert mod.f(ClassAttr()) == 10 - assert mod.f(PropAttr()) == 11 - - def test_getattr_s(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy result; - result = HPy_GetAttr_s(ctx, arg, "foo"); - if (HPy_IsNull(result)) - return HPy_NULL; - return result; - } - @EXPORT(f) - @INIT - """) - - class Attrs: - def __init__(self, **kw): - for k, v in kw.items(): - setattr(self, k, v) - - class ClassAttr: - foo = 10 - - class PropAttr: - @property - def foo(self): - return 11 - - assert mod.f(Attrs(foo=5)) == 5 - with pytest.raises(AttributeError): - mod.f(Attrs()) - with pytest.raises(AttributeError): - mod.f(42) - assert mod.f(ClassAttr) == 10 - assert mod.f(ClassAttr()) == 10 - assert mod.f(PropAttr()) == 11 - - def test_hasattr(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy name; - int result; - name = HPyUnicode_FromString(ctx, "foo"); - if (HPy_IsNull(name)) - return HPy_NULL; - result = HPy_HasAttr(ctx, arg, name); - HPy_Close(ctx, name); - if (result == -1) - return HPy_NULL; - if (result) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - - class Attrs: - def __init__(self, **kw): - for k, v in kw.items(): - setattr(self, k, v) - - class ClassAttr: - foo = 10 - - class PropAttr: - @property - def foo(self): - return 11 - - class PropAttrRaising: - @property - def foo(self): - raise RuntimeError - - - assert mod.f(Attrs(foo=5)) is True - assert mod.f(Attrs()) is False - assert mod.f(42) is False - assert mod.f(ClassAttr) is True - assert mod.f(ClassAttr()) is True - assert mod.f(PropAttr()) is True - assert mod.f(PropAttrRaising()) is False - - - def test_hasattr_s(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_HasAttr_s(ctx, arg, "foo"); - if (result == -1) - return HPy_NULL; - if (result) - return HPy_Dup(ctx, ctx->h_True); - return HPy_Dup(ctx, ctx->h_False); - } - @EXPORT(f) - @INIT - """) - - class Attrs: - def __init__(self, **kw): - for k, v in kw.items(): - setattr(self, k, v) - - class ClassAttr: - foo = 10 - - class PropAttr: - @property - def foo(self): - return 11 - - class PropAttrRaising: - @property - def foo(self): - raise RuntimeError - - assert mod.f(Attrs(foo=5)) is True - assert mod.f(Attrs()) is False - assert mod.f(42) is False - assert mod.f(ClassAttr) is True - assert mod.f(ClassAttr()) is True - assert mod.f(PropAttr()) is True - assert mod.f(PropAttrRaising()) is False - - def test_setattr(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy name; - int result; - name = HPyUnicode_FromString(ctx, "foo"); - if (HPy_IsNull(name)) - return HPy_NULL; - result = HPy_SetAttr(ctx, arg, name, ctx->h_True); - HPy_Close(ctx, name); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - - class Attrs: - pass - - class ClassAttr: - pass - - class ReadOnlyPropAttr: - @property - def foo(self): - return 11 - - class WritablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - a = Attrs() - mod.f(a) - assert a.foo is True - - mod.f(ClassAttr) - assert ClassAttr.foo is True - assert ClassAttr().foo is True - - with pytest.raises(AttributeError): - mod.f(object()) - - with pytest.raises(AttributeError): - mod.f(ReadOnlyPropAttr()) - - b = WritablePropAttr() - mod.f(b) - assert b.foo is True - - def test_setattr_s(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_SetAttr_s(ctx, arg, "foo", ctx->h_True); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - - class Attrs: - pass - - class ClassAttr: - pass - - class ReadOnlyPropAttr: - @property - def foo(self): - return 11 - - class WritablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - a = Attrs() - mod.f(a) - assert a.foo is True - - mod.f(ClassAttr) - assert ClassAttr.foo is True - assert ClassAttr().foo is True - - with pytest.raises(AttributeError): - mod.f(object()) - - with pytest.raises(AttributeError): - mod.f(ReadOnlyPropAttr()) - - b = WritablePropAttr() - mod.f(b) - assert b.foo is True - - def test_delattr(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(del_foo, "del_foo", HPyFunc_O) - static HPy del_foo_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy name; - int result; - name = HPyUnicode_FromString(ctx, "foo"); - if (HPy_IsNull(name)) - return HPy_NULL; - result = HPy_DelAttr(ctx, arg, name); - HPy_Close(ctx, name); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(del_foo) - @INIT - """) - - class Attrs: - pass - - class ClassAttr: - pass - - class WritablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - class DeletablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - @foo.deleter - def foo(self): - del self._foo - - def set_foo(obj): - obj.foo = True - - a = Attrs() - set_foo(a) - assert a.foo is True - mod.del_foo(a) - with pytest.raises(AttributeError): - a.foo - - set_foo(ClassAttr) - assert ClassAttr.foo is True - assert ClassAttr().foo is True - mod.del_foo(ClassAttr) - with pytest.raises(AttributeError): - ClassAttr.foo - with pytest.raises(AttributeError): - ClassAttr().foo - - b = WritablePropAttr() - set_foo(b) - assert b.foo is True - with pytest.raises(AttributeError): - # does not provide a delete function, so it fails - mod.del_foo(b) - - c = DeletablePropAttr() - set_foo(c) - assert c.foo is True - mod.del_foo(c) - with pytest.raises(AttributeError): - c.foo - - def test_delattr_s(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(del_foo, "del_foo", HPyFunc_O) - static HPy del_foo_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_DelAttr_s(ctx, arg, "foo"); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(del_foo) - @INIT - """) - - class Attrs: - pass - - class ClassAttr: - pass - - class WritablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - class DeletablePropAttr: - @property - def foo(self): - return self._foo - - @foo.setter - def foo(self, value): - self._foo = value - - @foo.deleter - def foo(self): - del self._foo - - def set_foo(obj): - obj.foo = True - - a = Attrs() - set_foo(a) - assert a.foo is True - mod.del_foo(a) - with pytest.raises(AttributeError): - a.foo - - set_foo(ClassAttr) - assert ClassAttr.foo is True - assert ClassAttr().foo is True - mod.del_foo(ClassAttr) - with pytest.raises(AttributeError): - ClassAttr.foo - with pytest.raises(AttributeError): - ClassAttr().foo - - b = WritablePropAttr() - set_foo(b) - assert b.foo is True - with pytest.raises(AttributeError): - # does not provide a delete function, so it fails - mod.del_foo(b) - - c = DeletablePropAttr() - set_foo(c) - assert c.foo is True - mod.del_foo(c) - with pytest.raises(AttributeError): - c.foo - - def test_getitem(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy key, result; - key = HPyLong_FromLong(ctx, 3); - if (HPy_IsNull(key)) - return HPy_NULL; - result = HPy_GetItem(ctx, arg, key); - HPy_Close(ctx, key); - if (HPy_IsNull(result)) - return HPy_NULL; - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f({3: "hello"}) == "hello" - with pytest.raises(KeyError) as exc: - mod.f({1: "bad"}) - assert exc.value.args == (3,) - - assert mod.f([0, 1, 2, "hello"]) == "hello" - with pytest.raises(IndexError): - mod.f([]) - - def test_getitem_i(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy result; - result = HPy_GetItem_i(ctx, arg, 3); - if (HPy_IsNull(result)) - return HPy_NULL; - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f({3: "hello"}) == "hello" - with pytest.raises(KeyError) as exc: - mod.f({1: "bad"}) - assert exc.value.args == (3,) - - assert mod.f([0, 1, 2, "hello"]) == "hello" - with pytest.raises(IndexError): - mod.f([]) - - def test_getitem_s(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy result; - result = HPy_GetItem_s(ctx, arg, "limes"); - if (HPy_IsNull(result)) - return HPy_NULL; - return result; - } - @EXPORT(f) - @INIT - """) - assert mod.f({"limes": "hello"}) == "hello" - with pytest.raises(KeyError) as exc: - mod.f({"oranges": "bad"}) - assert exc.value.args == ("limes",) - - with pytest.raises(TypeError): - mod.f([]) - - def test_getslice(self): - import pytest - if self.is_graalpy: - pytest.skip("Not yet implemented on GraalPy") - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy seq; - HPy_ssize_t i1, i2; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Onn", &seq, &i1, &i2)) { - return HPy_NULL; - } - if (HPy_Is(ctx, seq, ctx->h_None)) { - seq = HPy_NULL; - } - return HPy_GetSlice(ctx, seq, i1, i2); - } - @EXPORT(f) - @INIT - """) - l = [1,2,3,4,5] - assert mod.f(l, 0, 5) == l - assert mod.f(l, 2, 3) == [3] - assert mod.f(l, 1, 3) == [2, 3] - - s = "hello" - assert mod.f(s, 0, 5) == "hello" - assert mod.f(s, 1, 3) == "el" - - class Sliceable: - def __getitem__(self, key): - # assume 'key' is a slice - if key.start < 0: - raise ValueError - return key.start + key.stop - - o = Sliceable() - assert mod.f(o, 5, 13) == 18 - - # test that errors are propagated - with pytest.raises(ValueError): - mod.f(o, -1, 1) - - # 'None' will be mapped to 'HPy_NULL' by the C function - with pytest.raises(SystemError): - mod.f(None, 0, 1) - with pytest.raises(TypeError): - mod.f(123, 0, 1) - - def test_setitem(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy key; - int result; - key = HPyLong_FromLong(ctx, 3); - if (HPy_IsNull(key)) - return HPy_NULL; - result = HPy_SetItem(ctx, arg, key, ctx->h_True); - HPy_Close(ctx, key); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - @EXPORT(f) - @INIT - """) - assert mod.f({}) == {3: True} - assert mod.f({"a": 1}) == {"a": 1, 3: True} - assert mod.f({3: False}) == {3: True} - - assert mod.f([0, 1, 2, False]) == [0, 1, 2, True] - with pytest.raises(IndexError): - mod.f([]) - - def test_setitem_i(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_SetItem_i(ctx, arg, 3, ctx->h_True); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - @EXPORT(f) - @INIT - """) - assert mod.f({}) == {3: True} - assert mod.f({"a": 1}) == {"a": 1, 3: True} - assert mod.f({3: False}) == {3: True} - - assert mod.f([0, 1, 2, False]) == [0, 1, 2, True] - with pytest.raises(IndexError): - mod.f([]) - - def test_setitem_s(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_SetItem_s(ctx, arg, "limes", ctx->h_True); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - @EXPORT(f) - @INIT - """) - assert mod.f({}) == {"limes": True} - assert mod.f({"a": 1}) == {"a": 1, "limes": True} - assert mod.f({"limes": False}) == {"limes": True} - - with pytest.raises(TypeError): - mod.f([]) - - def test_setslice(self): - import pytest - if self.is_graalpy: - pytest.skip("Not yet implemented on GraalPy") - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - int res; - HPy seq, value; - HPy_ssize_t i1, i2; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OnnO", &seq, &i1, &i2, &value)) { - return HPy_NULL; - } - if (HPy_Is(ctx, seq, ctx->h_None)) { - seq = HPy_NULL; - } - res = HPy_SetSlice(ctx, seq, i1, i2, value); - if (res == 0) { - return HPy_Dup(ctx, seq); - } else if (res == -1) { - return HPy_NULL; - } - HPyErr_SetString(ctx, ctx->h_SystemError, - "HPy_SetSlice returned an invalid result code"); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - l = [1,2,3,4,5] - val = [11,22,33,44,55] - x = mod.f(l, 0, 5, val) - assert x is l - assert x is not val - assert l == val - - l = [1,2,3,4,5] - assert mod.f(l, 0, 5, []) == [] - - l = [1,2,3,4,5] - assert mod.f(l, 1, 3, [10, 11, 12]) == [1, 10, 11, 12, 4, 5] - - class Sliceable: - def __setitem__(self, key, value): - # assume 'key' is a slice - if key.start < 0: - raise ValueError - self.value = (key.start, key.stop, value) - - o = Sliceable() - assert mod.f(o, 5, 13, [7, 8, 9]).value == (5, 13, [7, 8, 9]) - - # test that errors are propagated - with pytest.raises(ValueError): - mod.f(o, -1, 1, []) - - # 'None' will be mapped to 'HPy_NULL' by the C function - with pytest.raises(SystemError): - mod.f(None, 0, 1, []) - with pytest.raises(TypeError): - mod.f(123, 0, 1, []) - - def test_delitem(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(delitem3, "delitem3", HPyFunc_O) - static HPy delitem3_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy key; - int result; - key = HPyLong_FromLong(ctx, 3); - if (HPy_IsNull(key)) - return HPy_NULL; - result = HPy_DelItem(ctx, arg, key); - HPy_Close(ctx, key); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - - HPyDef_METH(delitem_i3, "delitem_i3", HPyFunc_O) - static HPy delitem_i3_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_DelItem_i(ctx, arg, 3); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - - HPyDef_METH(delitem_s3, "delitem_s3", HPyFunc_O) - static HPy delitem_s3_impl(HPyContext *ctx, HPy self, HPy arg) - { - int result; - result = HPy_DelItem_s(ctx, arg, "3"); - if (result < 0) - return HPy_NULL; - return HPy_Dup(ctx, arg); - } - - @EXPORT(delitem3) - @EXPORT(delitem_i3) - @EXPORT(delitem_s3) - @INIT - """) - # HPy_DelItem - assert mod.delitem3({3: False, 4: True}) == {4: True} - with pytest.raises(KeyError): - mod.delitem3({}) - with pytest.raises(TypeError): - mod.delitem3((1, 2, 3, 4)) - assert mod.delitem3([0, 1, 2, False]) == [0, 1, 2] - with pytest.raises(IndexError): - mod.delitem3([]) - - # HPy_DelItem_i - assert mod.delitem_i3({3: False, 4: True}) == {4: True} - with pytest.raises(KeyError): - mod.delitem_i3({}) - with pytest.raises(TypeError): - mod.delitem_i3((1, 2, 3, 4)) - assert mod.delitem_i3([0, 1, 2, False]) == [0, 1, 2] - with pytest.raises(IndexError): - mod.delitem_i3([]) - - # HPy_DelItem_s - assert mod.delitem_s3({'3': False, '4': True}) == {'4': True} - with pytest.raises(KeyError): - mod.delitem_s3({}) - with pytest.raises(TypeError): - mod.delitem_s3((1, 2, 3, 4)) - with pytest.raises(TypeError): - mod.delitem_s3([1, 2, 3, 4]) - - def test_delslice(self): - import pytest - if self.is_graalpy: - pytest.skip("Not yet implemented on GraalPy") - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - int res; - HPy seq; - HPy_ssize_t i1, i2; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "Onn", &seq, &i1, &i2)) { - return HPy_NULL; - } - if (HPy_Is(ctx, seq, ctx->h_None)) { - seq = HPy_NULL; - } - res = HPy_DelSlice(ctx, seq, i1, i2); - if (res == 0) { - return HPy_Dup(ctx, seq); - } else if (res == -1) { - return HPy_NULL; - } - HPyErr_SetString(ctx, ctx->h_SystemError, - "HPy_DelSlice returned an invalid result code"); - return HPy_NULL; - } - @EXPORT(f) - @INIT - """) - l = [1,2,3,4,5] - x = mod.f(l, 0, 5) - assert x is l - assert l == [] - - l = [1,2,3,4,5] - assert mod.f(l, 1, 3) == [1, 4, 5] - - class Sliceable: - def __delitem__(self, key): - # assume 'key' is a slice - if key.start < 0: - raise ValueError - self.value = key.start + key.stop - - o = Sliceable() - assert mod.f(o, 5, 13).value == 18 - - # test that errors are propagated - with pytest.raises(ValueError): - mod.f(o, -1, 1) - - # 'None' will be mapped to 'HPy_NULL' by the C function - with pytest.raises(SystemError): - mod.f(None, 0, 1) - with pytest.raises(TypeError): - mod.f(123, 0, 1) - - def test_length(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy_ssize_t result; - result = HPy_Length(ctx, arg); - if (result < 0) - return HPy_NULL; - return HPyLong_FromSsize_t(ctx, result); - } - @EXPORT(f) - @INIT - """) - assert mod.f([5,6,7,8]) == 4 - assert mod.f({"a": 1}) == 1 - - def test_contains(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - int result = HPy_Contains(ctx, args[0], args[1]); - if (result == -1) { - return HPy_NULL; - } - return HPyLong_FromLong(ctx, result); - } - @EXPORT(f) - @INIT - """) - - class WithContains: - def __contains__(self, item): - return item == 42 - - class WithIter: - def __iter__(self): - return [1, 2, 3].__iter__() - - class WithGetitem: - def __getitem__(self, item): - if item > 3: - raise IndexError() - else: - return item - - class Dummy: - pass - - assert mod.f([5, 6, 42, 7, 8], 42) - assert not mod.f([5, 6, 42, 7, 8], 4) - - assert mod.f(WithContains(), 42) - assert not mod.f(WithContains(), 1) - - assert mod.f(WithIter(), 2) - assert not mod.f(WithIter(), 33) - - assert mod.f(WithGetitem(), 2) - assert not mod.f(WithGetitem(), 33) - - import pytest - with pytest.raises(TypeError): - mod.f(Dummy(), 42) - - def test_getiter(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - HPy iterator; - iterator = HPy_GetIter(ctx, arg); - if HPy_IsNull(iterator) - return HPy_NULL; - return iterator; - } - @EXPORT(f) - @INIT - """) - - def test_for_loop(iterator): - results = [] - for obj in iterator: - results.append(obj) - return results - - class WithIter: - def __iter__(self): - return (1, 2, 3).__iter__() - - class WithoutIter: - pass - - case = [1, 2, 3] - result = mod.f(case) - assert result - assert test_for_loop(result) == [1, 2, 3] - - case = iter([1, 2, 3]) - result = mod.f(case) - assert result - assert test_for_loop(result) == [1, 2, 3] - - case = zip((1, 2, 3), [4, 5, 6]) - result = mod.f(case) - assert result - assert test_for_loop(result) == [(1, 4), (2, 5), (3, 6)] - - case = range(10) - result = mod.f(case) - assert result - assert test_for_loop(result) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - - case = WithIter() - result = mod.f(case) - assert result - assert test_for_loop(result) == [1, 2, 3] - - import pytest - with pytest.raises(TypeError): - assert mod.f(WithoutIter()) - - - def test_dump(self): - # _HPy_Dump is supposed to be used e.g. inside a gdb session: it - # prints various about the given handle to stdout, and it's - # implementation-specific. As such, it's hard to write a meaningful - # test: let's just call it an check it doesn't crash. - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - _HPy_Dump(ctx, arg); - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - mod.f('hello') - - def test_type(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - return HPy_Type(ctx, arg); - } - @EXPORT(f) - @INIT - """) - assert mod.f('hello') is str - assert mod.f(42) is int - - def test_typecheck(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy a, b; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) - return HPy_NULL; - int res = HPy_TypeCheck(ctx, a, b); - return HPyBool_FromLong(ctx, res); - } - @EXPORT(f) - @INIT - """) - class MyStr(str): - pass - assert mod.f('hello', str) - assert not mod.f('hello', int) - assert mod.f(MyStr('hello'), str) - - def test_is(self): - mod = self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - HPy obj, other; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &obj, &other)) - return HPy_NULL; - int res = HPy_Is(ctx, obj, other); - return HPyBool_FromLong(ctx, res); - } - @EXPORT(f) - @INIT - """) - assert mod.f(None, None) - a = object() - assert mod.f(a, a) - assert not mod.f(a, None) diff --git a/graalpython/hpy/test/test_slots.py b/graalpython/hpy/test/test_slots.py deleted file mode 100644 index ac9cbe2fc7..0000000000 --- a/graalpython/hpy/test/test_slots.py +++ /dev/null @@ -1,833 +0,0 @@ -import pytest -from .support import HPyTest -from .test_hpytype import PointTemplate - - -class TestSlots(HPyTest): - - ExtensionTemplate = PointTemplate - - def test_tp_init(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_xy - HPyDef_SLOT_IMPL(Point_new, HPyType_GenericNew, HPy_tp_new) - - HPyDef_SLOT(Point_init, HPy_tp_init) - static int Point_init_impl(HPyContext *ctx, HPy self, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - long x, y; - if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) - return -1; - - PointObject *p = PointObject_AsStruct(ctx, self); - p->x = x; - p->y = y; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_init, &Point_x, &Point_y) - @INIT - """) - p = mod.Point(1, 2) - assert p.x == 1 - assert p.y == 2 - - @pytest.mark.syncgc - def test_tp_destroy(self): - import gc - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - static long destroyed_x; - - HPyDef_SLOT(Point_destroy, HPy_tp_destroy) - static void Point_destroy_impl(void *obj) - { - PointObject *point = (PointObject *)obj; - destroyed_x += point->x; - } - - HPyDef_METH(get_destroyed_x, "get_destroyed_x", HPyFunc_NOARGS) - static HPy get_destroyed_x_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, destroyed_x); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_destroy) - @EXPORT(get_destroyed_x) - @INIT - """) - point = mod.Point(7, 3) - assert mod.get_destroyed_x() == 0 - del point - gc.collect() - assert mod.get_destroyed_x() == 7 - gc.collect() - assert mod.get_destroyed_x() == 7 - - @pytest.mark.syncgc - def test_tp_finalize_nongc(self): - import gc - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - static long finalized_x; - - HPyDef_SLOT(Point_finalize, HPy_tp_finalize) - static void Point_finalize_impl(HPyContext *ctx, HPy obj) - { - PointObject *point = PointObject_AsStruct(ctx, obj); - finalized_x += point->x; - } - - HPyDef_METH(get_finalized_x, "get_finalized_x", HPyFunc_NOARGS) - static HPy get_finalized_x_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, finalized_x); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_finalize) - @EXPORT(get_finalized_x) - @INIT - """) - point = mod.Point(7, 3) - assert mod.get_finalized_x() == 0 - del point - gc.collect() - assert mod.get_finalized_x() == 7 - gc.collect() - assert mod.get_finalized_x() == 7 - - @pytest.mark.syncgc - def test_tp_finalize_gc(self): - import gc - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - static long finalized_x; - - HPyDef_SLOT(Point_finalize, HPy_tp_finalize) - static void Point_finalize_impl(HPyContext *ctx, HPy obj) - { - PointObject *point = PointObject_AsStruct(ctx, obj); - finalized_x += point->x; - } - - HPyDef_SLOT(Point_traverse, HPy_tp_traverse) - static int Point_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) - { - return 0; - } - - static HPyDef *Point_defines[] = { - &Point_new, &Point_finalize, &Point_traverse, NULL}; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_HAVE_GC, - .builtin_shape = SHAPE(PointObject), - .defines = Point_defines, - }; - @EXPORT_TYPE("Point", Point_spec) - - HPyDef_METH(get_finalized_x, "get_finalized_x", HPyFunc_NOARGS) - static HPy get_finalized_x_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, finalized_x); - } - - @EXPORT(get_finalized_x) - @INIT - """) - point = mod.Point(7, 3) - assert mod.get_finalized_x() == 0 - del point - gc.collect() - assert mod.get_finalized_x() == 7 - gc.collect() - assert mod.get_finalized_x() == 7 - - def test_nb_ops_binary(self): - import operator - mod = self.make_module(r""" - @DEFINE_PointObject - - #define MYSLOT(NAME) \ - HPyDef_SLOT_IMPL(p_##NAME, NAME##_impl, HPy_nb_##NAME) \ - static HPy NAME##_impl(HPyContext *ctx, HPy self, HPy other) \ - { \ - HPy s = HPyUnicode_FromString(ctx, #NAME); \ - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); \ - HPy_Close(ctx, s); \ - return res; \ - } - - MYSLOT(add) - MYSLOT(and) - MYSLOT(divmod) - MYSLOT(floor_divide) - MYSLOT(lshift) - MYSLOT(multiply) - MYSLOT(or) - MYSLOT(remainder) - MYSLOT(rshift) - MYSLOT(subtract) - MYSLOT(true_divide) - MYSLOT(xor) - MYSLOT(matrix_multiply) - - @EXPORT_POINT_TYPE(&p_add, &p_and, &p_divmod, &p_floor_divide, &p_lshift, &p_multiply, &p_or, &p_remainder, &p_rshift, &p_subtract, &p_true_divide, &p_xor, &p_matrix_multiply) - @INIT - """) - p = mod.Point() - assert p + 42 == (p, "add", 42) - assert p & 42 == (p, "and", 42) - assert divmod(p, 42) == (p, "divmod", 42) - assert p // 42 == (p, "floor_divide", 42) - assert p << 42 == (p, "lshift", 42) - assert p * 42 == (p, "multiply", 42) - assert p | 42 == (p, "or", 42) - assert p % 42 == (p, "remainder", 42) - assert p >> 42 == (p, "rshift", 42) - assert p - 42 == (p, "subtract", 42) - assert p / 42 == (p, "true_divide", 42) - assert p ^ 42 == (p, "xor", 42) - # we can't use '@' because we want to be importable on py27 - assert operator.matmul(p, 42) == (p, "matrix_multiply", 42) - - def test_nb_ops_inplace(self): - import operator - mod = self.make_module(r""" - @DEFINE_PointObject - - #define MYSLOT(NAME) \ - HPyDef_SLOT_IMPL(p_##NAME, NAME##_impl, HPy_nb_##NAME); \ - static HPy NAME##_impl(HPyContext *ctx, HPy self, HPy other) \ - { \ - HPy s = HPyUnicode_FromString(ctx, #NAME); \ - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); \ - HPy_Close(ctx, s); \ - return res; \ - } - - MYSLOT(inplace_add) - MYSLOT(inplace_and) - MYSLOT(inplace_floor_divide) - MYSLOT(inplace_lshift) - MYSLOT(inplace_multiply) - MYSLOT(inplace_or) - MYSLOT(inplace_remainder) - MYSLOT(inplace_rshift) - MYSLOT(inplace_subtract) - MYSLOT(inplace_true_divide) - MYSLOT(inplace_xor) - MYSLOT(inplace_matrix_multiply) - - @EXPORT_POINT_TYPE(&p_inplace_add, &p_inplace_and, &p_inplace_floor_divide, &p_inplace_lshift, &p_inplace_multiply, &p_inplace_or, &p_inplace_remainder, &p_inplace_rshift, &p_inplace_subtract, &p_inplace_true_divide, &p_inplace_xor, &p_inplace_matrix_multiply) - @INIT - """) - p = mod.Point() - tmp = p; tmp += 42; assert tmp == (p, "inplace_add", 42) - tmp = p; tmp &= 42; assert tmp == (p, "inplace_and", 42) - tmp = p; tmp //= 42; assert tmp == (p, "inplace_floor_divide", 42) - tmp = p; tmp <<= 42; assert tmp == (p, "inplace_lshift", 42) - tmp = p; tmp *= 42; assert tmp == (p, "inplace_multiply", 42) - tmp = p; tmp |= 42; assert tmp == (p, "inplace_or", 42) - tmp = p; tmp %= 42; assert tmp == (p, "inplace_remainder", 42) - tmp = p; tmp >>= 42; assert tmp == (p, "inplace_rshift", 42) - tmp = p; tmp -= 42; assert tmp == (p, "inplace_subtract", 42) - tmp = p; tmp /= 42; assert tmp == (p, "inplace_true_divide", 42) - tmp = p; tmp ^= 42; assert tmp == (p, "inplace_xor", 42) - # - # we can't use '@=' because we want to be importable on py27 - tmp = p - tmp = operator.imatmul(p, 42) - assert tmp == (p, "inplace_matrix_multiply", 42) - - def test_nb_ops_unary(self): - mod = self.make_module(r""" - @DEFINE_PointObject - - #define MYSLOT(NAME) \ - HPyDef_SLOT_IMPL(p_##NAME, NAME##_impl, HPy_nb_##NAME); \ - static HPy NAME##_impl(HPyContext *ctx, HPy self) \ - { \ - HPy s = HPyUnicode_FromString(ctx, #NAME); \ - HPy res = HPyTuple_Pack(ctx, 2, s, self); \ - HPy_Close(ctx, s); \ - return res; \ - } - - MYSLOT(negative) - MYSLOT(positive) - MYSLOT(absolute) - MYSLOT(invert) - - @EXPORT_POINT_TYPE(&p_negative, &p_positive, &p_absolute, &p_invert) - @INIT - """) - p = mod.Point() - assert +p == ('positive', p) - assert -p == ('negative', p) - assert abs(p) == ('absolute', p) - assert ~p == ('invert', p) - - def test_nb_ops_type_conversion(self): - import operator - mod = self.make_module(r""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_SLOT(p_int, HPy_nb_int); - static HPy p_int_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 42); - } - - HPyDef_SLOT(p_float, HPy_nb_float); - static HPy p_float_impl(HPyContext *ctx, HPy self) - { - return HPyFloat_FromDouble(ctx, 123.4); - } - - HPyDef_SLOT(p_index, HPy_nb_index); - static HPy p_index_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, -456); - } - - HPyDef_SLOT(p_bool, HPy_nb_bool); - static int p_bool_impl(HPyContext *ctx, HPy self) - { - PointObject *point = PointObject_AsStruct(ctx, self); - return (point->x != 0); - } - - @EXPORT_POINT_TYPE(&Point_new, &p_int, &p_float, &p_index, &p_bool) - @INIT - """) - p = mod.Point(0, 0) - assert int(p) == 42 - assert float(p) == 123.4 - assert operator.index(p) == -456 - # - assert bool(mod.Point(0, 0)) is False - assert bool(mod.Point(1, 0)) is True - - def test_nb_ops_power(self): - mod = self.make_module(r""" - @DEFINE_PointObject - - HPyDef_SLOT(p_power, HPy_nb_power); - static HPy p_power_impl(HPyContext *ctx, HPy self, HPy x, HPy y) - { - HPy s = HPyUnicode_FromString(ctx, "power"); - HPy res = HPyTuple_Pack(ctx, 4, self, s, x, y); - HPy_Close(ctx, s); - return res; - } - - HPyDef_SLOT(p_inplace_power, HPy_nb_inplace_power); - static HPy p_inplace_power_impl(HPyContext *ctx, HPy self, HPy x, HPy y) - { - HPy s = HPyUnicode_FromString(ctx, "inplace_power"); - HPy res = HPyTuple_Pack(ctx, 4, self, s, x, y); - HPy_Close(ctx, s); - return res; - } - - @EXPORT_POINT_TYPE(&p_power, &p_inplace_power) - @INIT - """) - p = mod.Point() - assert p**42 == (p, 'power', 42, None) - assert pow(p, 42, 123) == (p, 'power', 42, 123) - tmp = p - tmp **= 42 - assert tmp == (p, 'inplace_power', 42, None) - - def test_buffer(self): - import pytest - import sys - mod = self.make_module(""" - @TYPE_STRUCT_BEGIN(FakeArrayObject) - int exports; - @TYPE_STRUCT_END - - static char static_mem[12] = {0,1,2,3,4,5,6,7,8,9,10,11}; - static HPy_ssize_t _shape[1] = {12}; - static HPy_ssize_t _strides[1] = {1}; - - HPyDef_SLOT_IMPL(FakeArray_getbuffer, _getbuffer_impl, HPy_bf_getbuffer) - static int _getbuffer_impl(HPyContext *ctx, HPy self, HPy_buffer* buf, int flags) { - FakeArrayObject *arr = FakeArrayObject_AsStruct(ctx, self); - if (arr->exports > 0) { - buf->obj = HPy_NULL; - HPyErr_SetString(ctx, ctx->h_BufferError, - "only one buffer allowed"); - return -1; - } - arr->exports++; - buf->buf = static_mem; - buf->len = 12; - buf->itemsize = 1; - buf->readonly = 1; - buf->ndim = 1; - buf->format = (char*)"B"; - buf->shape = _shape; - buf->strides = _strides; - buf->suboffsets = NULL; - buf->internal = NULL; - buf->obj = HPy_Dup(ctx, self); - return 0; - } - - HPyDef_SLOT_IMPL(FakeArray_releasebuffer, _relbuffer_impl, HPy_bf_releasebuffer) - static void _relbuffer_impl(HPyContext *ctx, HPy h_obj, HPy_buffer* buf) { - FakeArrayObject *arr = FakeArrayObject_AsStruct(ctx, h_obj); - arr->exports--; - } - - static HPyDef *FakeArray_defines[] = { - &FakeArray_getbuffer, - &FakeArray_releasebuffer, - NULL - }; - - static HPyType_Spec FakeArray_Spec = { - .name = "mytest.FakeArray", - .basicsize = sizeof(FakeArrayObject), - .builtin_shape = SHAPE(FakeArrayObject), - .defines = FakeArray_defines, - }; - - @EXPORT_TYPE("FakeArray", FakeArray_Spec) - @INIT - """) - arr = mod.FakeArray() - if self.supports_refcounts(): - init_refcount = sys.getrefcount(arr) - with memoryview(arr) as mv: - with pytest.raises(BufferError): - mv2 = memoryview(arr) - if self.supports_refcounts(): - assert sys.getrefcount(arr) == init_refcount + 1 - for i in range(12): - assert mv[i] == i - if self.supports_refcounts(): - assert sys.getrefcount(arr) == init_refcount - mv2 = memoryview(arr) # doesn't raise - - def test_tp_repr_and_tp_str(self): - mod = self.make_module(""" - #include - - #define BUF_SIZE 128 - - @DEFINE_PointObject - @DEFINE_Point_new - - static HPy - point_str_repr(HPyContext *ctx, HPy h, int str) - { - char buf[BUF_SIZE]; - PointObject *p = PointObject_AsStruct(ctx, h); - snprintf(buf, BUF_SIZE, "%s(Point(%ld, %ld))", - (str ? "str" : "repr"), p->x, p->y); - return HPyUnicode_FromString(ctx, buf); - } - - HPyDef_SLOT(Point_repr, HPy_tp_repr) - static HPy Point_repr_impl(HPyContext *ctx, HPy self) - { - return point_str_repr(ctx, self, 0); - } - - HPyDef_SLOT(Point_str, HPy_tp_str) - static HPy Point_str_impl(HPyContext *ctx, HPy self) - { - return point_str_repr(ctx, self, 1); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_str, &Point_repr) - @INIT - """) - p = mod.Point(1, 2) - assert str(p) == 'str(Point(1, 2))' - assert repr(p) == 'repr(Point(1, 2))' - - def test_tp_hash(self): - import pytest - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_SLOT(Point_hash, HPy_tp_hash) - static HPy_ssize_t Point_hash_impl(HPyContext *ctx, HPy self) - { - PointObject *p = PointObject_AsStruct(ctx, self); - if (p->x < 0) { - HPyErr_SetString(ctx, ctx->h_ValueError, "cannot hash Point object with negative x"); - return -1; - } - return p->x + p->y; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_hash) - @INIT - """) - p = mod.Point(1, 10) - assert p.__hash__() == 11 - assert hash(p) == 11 - # We expect that the slot wrapper accepts hash code -1 without - # complaining. This is not the case for built-in function 'hash'. - assert mod.Point(0, -1).__hash__() == -1 - with pytest.raises(ValueError): - hash(mod.Point(-1, 10)) - - -class TestSqSlots(HPyTest): - - ExtensionTemplate = PointTemplate - - def test_mp_subscript_and_mp_length(self): - mod = self.make_module(""" - @DEFINE_PointObject - - HPyDef_SLOT(Point_getitem, HPy_mp_subscript); - static HPy Point_getitem_impl(HPyContext *ctx, HPy self, HPy key) - { - HPy prefix = HPyUnicode_FromString(ctx, "key was: "); - HPy key_repr = HPy_Repr(ctx, key); - HPy res = HPy_Add(ctx, prefix, key_repr); - HPy_Close(ctx, key_repr); - HPy_Close(ctx, prefix); - return res; - } - - HPyDef_SLOT(Point_length, HPy_mp_length); - static HPy_ssize_t Point_length_impl(HPyContext *ctx, HPy self) - { - return 1234; - } - - @EXPORT_POINT_TYPE(&Point_getitem, &Point_length) - @INIT - """) - p = mod.Point() - class Dummy: - def __repr__(self): - return "Hello, World" - assert len(p) == 1234 - assert p[4] == "key was: 4" - assert p["hello"] == "key was: 'hello'" - assert p[Dummy()] == "key was: Hello, World" - - def test_mp_ass_subscript(self): - import pytest - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_xy - - HPyDef_SLOT(Point_len, HPy_mp_length); - static HPy_ssize_t Point_len_impl(HPyContext *ctx, HPy self) - { - return 2; - } - - HPyDef_SLOT(Point_setitem, HPy_mp_ass_subscript); - static int Point_setitem_impl(HPyContext *ctx, HPy self, HPy key, - HPy h_value) - { - long value; - if (HPy_IsNull(h_value)) { - value = -123; // this is the del p[] case - } else { - value = HPyLong_AsLong(ctx, h_value); - if (HPyErr_Occurred(ctx)) - return -1; - } - PointObject *point = PointObject_AsStruct(ctx, self); - const char *s_key = HPyUnicode_AsUTF8AndSize(ctx, key, NULL); - if (s_key == NULL) { - return -1; - } - if (s_key[0] == 'x') { - point->x = value; - } else if (s_key[0] == 'y') { - point->y = value; - } else { - HPyErr_SetString(ctx, ctx->h_KeyError, "invalid key"); - return -1; - } - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y, &Point_len, &Point_setitem) - @INIT - """) - p = mod.Point(1, 2) - # check __setitem__ - p['x'] = 100 - assert p.x == 100 - p['y'] = 200 - assert p.y == 200 - with pytest.raises(KeyError): - p['z'] = 300 - with pytest.raises(TypeError): - p[0] = 300 - # check __delitem__ - del p['x'] - assert p.x == -123 - del p['y'] - assert p.y == -123 - - def test_sq_item_and_sq_length(self): - mod = self.make_module(""" - @DEFINE_PointObject - - HPyDef_SLOT(Point_getitem, HPy_sq_item); - static HPy Point_getitem_impl(HPyContext *ctx, HPy self, HPy_ssize_t idx) - { - return HPyLong_FromLong(ctx, (long)idx*2); - } - - HPyDef_SLOT(Point_length, HPy_sq_length); - static HPy_ssize_t Point_length_impl(HPyContext *ctx, HPy self) - { - return 1234; - } - - @EXPORT_POINT_TYPE(&Point_getitem, &Point_length) - @INIT - """) - p = mod.Point() - assert len(p) == 1234 - assert p[4] == 8 - assert p[21] == 42 - assert p[-1] == 1233 * 2 - - def test_sq_ass_item(self): - import pytest - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - @DEFINE_Point_xy - - HPyDef_SLOT(Point_len, HPy_sq_length); - static HPy_ssize_t Point_len_impl(HPyContext *ctx, HPy self) - { - return 2; - } - - HPyDef_SLOT(Point_setitem, HPy_sq_ass_item); - static int Point_setitem_impl(HPyContext *ctx, HPy self, HPy_ssize_t idx, - HPy h_value) - { - long value; - if (HPy_IsNull(h_value)) - value = -123; // this is the del p[] case - else { - value = HPyLong_AsLong(ctx, h_value); - if (HPyErr_Occurred(ctx)) - return -1; - } - PointObject *point = PointObject_AsStruct(ctx, self); - if (idx == 0) - point->x = value; - else if (idx == 1) - point->y = value; - else { - HPyErr_SetString(ctx, ctx->h_IndexError, "invalid index"); - return -1; - } - return 0; - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_x, &Point_y, &Point_len, &Point_setitem) - @INIT - """) - p = mod.Point(1, 2) - # check __setitem__ - p[0] = 100 - assert p.x == 100 - p[1] = 200 - assert p.y == 200 - with pytest.raises(IndexError): - p[2] = 300 - # check __delitem__ - del p[0] - assert p.x == -123 - del p[1] - assert p.y == -123 - # check negative indexes - p[-2] = 400 - p[-1] = 500 - assert p.x == 400 - assert p.y == 500 - del p[-2] - assert p.x == -123 - del p[-1] - assert p.y == -123 - - def test_sq_concat_and_sq_inplace_concat(self): - mod = self.make_module(""" - @DEFINE_PointObject - - HPyDef_SLOT(Point_concat, HPy_sq_concat); - static HPy Point_concat_impl(HPyContext *ctx, HPy self, HPy other) - { - HPy s = HPyUnicode_FromString(ctx, "sq_concat"); - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); - HPy_Close(ctx, s); - return res; - } - - HPyDef_SLOT(Point_inplace_concat, HPy_sq_inplace_concat); - static HPy Point_inplace_concat_impl(HPyContext *ctx, HPy self, HPy other) - { - HPy s = HPyUnicode_FromString(ctx, "sq_inplace_concat"); - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); - HPy_Close(ctx, s); - return res; - } - - @EXPORT_POINT_TYPE(&Point_concat, &Point_inplace_concat) - @INIT - """) - p = mod.Point() - res = p + 42 - assert res == (p, "sq_concat", 42) - # - tmp = p - tmp += 43 - assert tmp == (p, "sq_inplace_concat", 43) - - def test_sq_repeat_and_sq_inplace_repeat(self): - mod = self.make_module(""" - @DEFINE_PointObject - - HPyDef_SLOT(Point_repeat, HPy_sq_repeat); - static HPy Point_repeat_impl(HPyContext *ctx, HPy self, HPy_ssize_t t) - { - HPy s = HPyUnicode_FromString(ctx, "sq_repeat"); - HPy other = HPyLong_FromLong(ctx, (long) t); - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); - HPy_Close(ctx, other); - HPy_Close(ctx, s); - return res; - } - - HPyDef_SLOT(Point_inplace_repeat, HPy_sq_inplace_repeat); - static HPy Point_inplace_repeat_impl(HPyContext *ctx, HPy self, HPy_ssize_t t) - { - HPy s = HPyUnicode_FromString(ctx, "sq_inplace_repeat"); - HPy other = HPyLong_FromLong(ctx, (long) t); - HPy res = HPyTuple_Pack(ctx, 3, self, s, other); - HPy_Close(ctx, other); - HPy_Close(ctx, s); - return res; - } - - @EXPORT_POINT_TYPE(&Point_repeat, &Point_inplace_repeat) - @INIT - """) - p = mod.Point() - res = p * 42 - assert res == (p, "sq_repeat", 42) - # - tmp = p - tmp *= 43 - assert tmp == (p, "sq_inplace_repeat", 43) - - def test_sq_contains(self): - import pytest - mod = self.make_module(""" - @DEFINE_PointObject - - HPyDef_SLOT(Point_contains, HPy_sq_contains); - static int Point_contains_impl(HPyContext *ctx, HPy self, HPy other) - { - long val = HPyLong_AsLong(ctx, other); - if (HPyErr_Occurred(ctx)) - return -1; - if (val == 42) - return 1; - return 0; - } - - @EXPORT_POINT_TYPE(&Point_contains) - @INIT - """) - p = mod.Point() - assert 42 in p - assert 43 not in p - with pytest.raises(TypeError): - 'hello' in p - - def test_tp_richcompare(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_SLOT(Point_cmp, HPy_tp_richcompare); - static HPy Point_cmp_impl(HPyContext *ctx, HPy self, HPy o, HPy_RichCmpOp op) - { - // XXX we should check the type of o - PointObject *p1 = PointObject_AsStruct(ctx, self); - PointObject *p2 = PointObject_AsStruct(ctx, o); - HPy_RETURN_RICHCOMPARE(ctx, p1->x, p2->x, op); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_cmp) - @INIT - """) - p1 = mod.Point(10, 10) - p2 = mod.Point(20, 20) - assert p1 == p1 - assert not p1 == p2 - # - assert p1 != p2 - assert not p1 != p1 - # - assert p1 < p2 - assert not p1 < p1 - # - assert not p1 > p2 - assert not p1 > p1 - # - assert p1 <= p2 - assert p1 <= p1 - # - assert not p1 >= p2 - assert p1 >= p1 - - def test_tp_descr_get(self): - mod = self.make_module(""" - @DEFINE_PointObject - @DEFINE_Point_new - - HPyDef_SLOT(Point_get, HPy_tp_descr_get); - static HPy - Point_get_impl(HPyContext *ctx, HPy self, HPy obj, HPy type) - { - if (HPy_IsNull(obj) || HPy_Is(ctx, self, ctx->h_None)) { - return HPy_Dup(ctx, self); - } - return HPyLong_FromLong(ctx, 123); - } - - @EXPORT_POINT_TYPE(&Point_new, &Point_get) - @INIT - """) - p = mod.Point(10, 10) - class Dummy: - point_func = p - assert Dummy.point_func is p - assert Dummy().point_func == 123 diff --git a/graalpython/hpy/test/test_slots_legacy.py b/graalpython/hpy/test/test_slots_legacy.py deleted file mode 100644 index 9cc5feb05c..0000000000 --- a/graalpython/hpy/test/test_slots_legacy.py +++ /dev/null @@ -1,265 +0,0 @@ -""" HPyType slot tests on legacy types. """ - -from .support import HPyTest, make_hpy_abi_fixture -from .test_hpytype_legacy import LegacyPointTemplate -from .test_slots import TestSlots as _TestSlots, TestSqSlots as _TestSqSlots - -hpy_abi = make_hpy_abi_fixture('with hybrid') - -class TestLegacySlots(_TestSlots): - ExtensionTemplate = LegacyPointTemplate - - -class TestLegacySqSlots(_TestSqSlots): - ExtensionTemplate = LegacyPointTemplate - - -class TestCustomLegacySlotsFeatures(HPyTest): - - def test_legacy_slots(self): - mod = self.make_module(""" - #include - - static PyObject *Dummy_repr(PyObject *self) - { - return PyUnicode_FromString("myrepr"); - } - - static PyObject *Dummy_add(PyObject *self, PyObject *other) - { - return Py_BuildValue("OO", self, other); - } - - HPyDef_SLOT(Dummy_abs, HPy_nb_absolute); - static HPy Dummy_abs_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - static HPyDef *Dummy_defines[] = { - &Dummy_abs, - NULL - }; - static PyType_Slot Dummy_type_slots[] = { - {Py_tp_repr, (void*)Dummy_repr}, - {Py_nb_add, (void*)Dummy_add}, - {0, 0}, - }; - static HPyType_Spec Dummy_spec = { - .name = "mytest.Dummy", - .builtin_shape = HPyType_BuiltinShape_Legacy, - .legacy_slots = Dummy_type_slots, - .defines = Dummy_defines - }; - - @EXPORT_TYPE("Dummy", Dummy_spec) - @INIT - """) - d = mod.Dummy() - assert repr(d) == 'myrepr' - assert d + 42 == (d, 42) - assert abs(d) == 1234 - - def test_legacy_slots_methods(self): - mod = self.make_module(""" - #include - - static PyObject *Dummy_foo(PyObject *self, PyObject *arg) - { - Py_INCREF(arg); - return arg; - } - - HPyDef_METH(Dummy_bar, "bar", HPyFunc_NOARGS) - static HPy Dummy_bar_impl(HPyContext *ctx, HPy self) - { - return HPyLong_FromLong(ctx, 1234); - } - - static PyMethodDef dummy_methods[] = { - {"foo", Dummy_foo, METH_O}, - {NULL, NULL} /* Sentinel */ - }; - - static PyType_Slot dummy_type_slots[] = { - {Py_tp_methods, dummy_methods}, - {0, 0}, - }; - - static HPyDef *dummy_type_defines[] = { - &Dummy_bar, - NULL - }; - - static HPyType_Spec dummy_type_spec = { - .name = "mytest.Dummy", - .builtin_shape = HPyType_BuiltinShape_Legacy, - .legacy_slots = dummy_type_slots, - .defines = dummy_type_defines - }; - - @EXPORT_TYPE("Dummy", dummy_type_spec) - @INIT - """) - d = mod.Dummy() - assert d.foo(21) == 21 - assert d.bar() == 1234 - - def test_legacy_slots_members(self): - import pytest - mod = self.make_module(""" - #include - #include "structmember.h" - - typedef struct { - PyObject_HEAD - long x; - long y; - } PointObject; - - HPyDef_SLOT(Point_new, HPy_tp_new) - static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = 7; - point->y = 3; - return h_point; - } - - HPyDef_MEMBER(Point_x, "x", HPyMember_LONG, offsetof(PointObject, x)) - - // legacy members - static PyMemberDef legacy_members[] = { - {"y", T_LONG, offsetof(PointObject, y), 0}, - {"y_ro", T_LONG, offsetof(PointObject, y), READONLY}, - {NULL} - }; - - static PyType_Slot legacy_slots[] = { - {Py_tp_members, legacy_members}, - {0, NULL} - }; - - static HPyDef *Point_defines[] = { - &Point_new, - &Point_x, - NULL - }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = HPyType_BuiltinShape_Legacy, - .legacy_slots = legacy_slots, - .defines = Point_defines - }; - - @EXPORT_TYPE("Point", Point_spec) - @INIT - """) - p = mod.Point() - assert p.x == 7 - assert p.y == 3 - assert p.y_ro == 3 - p.x = 123 - p.y = 456 - with pytest.raises(AttributeError): - p.y_ro = 789 - assert p.x == 123 - assert p.y == 456 - - def test_legacy_slots_getsets(self): - mod = self.make_module(""" - #include - - typedef struct { - PyObject_HEAD - long x; - long y; - } PointObject; - - HPyDef_SLOT(Point_new, HPy_tp_new) - static HPy Point_new_impl(HPyContext *ctx, HPy cls, const HPy *args, - HPy_ssize_t nargs, HPy kw) - { - PointObject *point; - HPy h_point = HPy_New(ctx, cls, &point); - if (HPy_IsNull(h_point)) - return HPy_NULL; - point->x = 7; - point->y = 3; - return h_point; - } - - static PyObject *z_get(PointObject *point, void *closure) - { - long z = point->x*10 + point->y + (long)(HPy_ssize_t)closure; - return PyLong_FromLong(z); - } - - // legacy getsets - static PyGetSetDef legacy_getsets[] = { - {"z", (getter)z_get, NULL, NULL, (void *)2000}, - {NULL} - }; - - static PyType_Slot legacy_slots[] = { - {Py_tp_getset, legacy_getsets}, - {0, NULL} - }; - - static HPyDef *Point_defines[] = { - &Point_new, - NULL - }; - static HPyType_Spec Point_spec = { - .name = "mytest.Point", - .basicsize = sizeof(PointObject), - .builtin_shape = HPyType_BuiltinShape_Legacy, - .legacy_slots = legacy_slots, - .defines = Point_defines - }; - - @EXPORT_TYPE("Point", Point_spec) - @INIT - """) - p = mod.Point() - assert p.z == 2073 - - def test_legacy_slots_fails_without_legacy(self): - import pytest - mod_src = """ - #include - - static PyObject *Dummy_foo(PyObject *self, PyObject *arg) - { - Py_INCREF(arg); - return arg; - } - - static PyMethodDef dummy_methods[] = { - {"foo", Dummy_foo, METH_O}, - {NULL, NULL} /* Sentinel */ - }; - - static PyType_Slot dummy_type_slots[] = { - {Py_tp_methods, dummy_methods}, - {0, 0}, - }; - - static HPyType_Spec dummy_type_spec = { - .name = "mytest.Dummy", - .builtin_shape = HPyType_BuiltinShape_Object, - .legacy_slots = dummy_type_slots, - }; - - @EXPORT_TYPE("Dummy", dummy_type_spec) - @INIT - """ - with pytest.raises(TypeError) as err: - self.make_module(mod_src) - assert str(err.value) == ( - "cannot specify .legacy_slots without setting .builtin_shape=HPyType_BuiltinShape_Legacy") diff --git a/graalpython/hpy/test/test_support.py b/graalpython/hpy/test/test_support.py deleted file mode 100644 index dbf8745dcd..0000000000 --- a/graalpython/hpy/test/test_support.py +++ /dev/null @@ -1,50 +0,0 @@ -import pytest -from pathlib import Path -from . import support - - -def expand_template(template, name): - return support.DefaultExtensionTemplate(template, name).expand() - - -def test_expand_template(): - expanded = expand_template(""" - @EXPORT(f) - @EXPORT(g) - some more C stuff - @INIT - """, name='mytest') - defines_table = ['&f,', '&g,'] - defines = '\n '.join(defines_table) - init_code = support.DefaultExtensionTemplate.INIT_TEMPLATE % { - 'defines': defines, - 'legacy_methods': 'NULL', - 'name': 'mytest', - 'init_types': '', - 'globals_defs': '', - 'globals_field': '', - } - assert expanded.rstrip() == f"""#include - -some more C stuff -{init_code} -""".rstrip() - - -TEST_DIR = Path(__file__).parent - - -def test_source_dump(tmpdir): - import pytest - test_file = 'test_00_basic' - parts = ['TestBasic', 'test_noop_function'] - rc = pytest.main(['--dump-dir=' + str(tmpdir), '::'.join([str(TEST_DIR.joinpath(test_file + ".py"))] + parts)]) - assert rc == 0 - expected_dir = '_'.join([test_file] + parts) - print("expected_dir = " + expected_dir) - test_dump_dir = None - for child in Path(tmpdir).iterdir(): - if expected_dir in str(child): - test_dump_dir = Path(child) - assert test_dump_dir and test_dump_dir.exists() - assert test_dump_dir.joinpath('mytest.c').exists() diff --git a/graalpython/hpy/test/test_tracker.py b/graalpython/hpy/test/test_tracker.py deleted file mode 100644 index 5df8371bde..0000000000 --- a/graalpython/hpy/test/test_tracker.py +++ /dev/null @@ -1,120 +0,0 @@ -""" -NOTE: this tests are also meant to be run as PyPy "applevel" tests. - -This means that global imports will NOT be visible inside the test -functions. In particular, you have to "import pytest" inside the test in order -to be able to use e.g. pytest.raises (which on PyPy will be implemented by a -"fake pytest module") -""" -from .support import HPyTest - - -class TestHPyTracker(HPyTest): - def hpytracker_module(self, ops, size=0): - return self.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - {{ - HPyTracker ht; - HPy result = HPy_NULL; - ht = HPyTracker_New(ctx, {size}); - if HPy_IsNull(ht) {{ - return HPy_NULL; - }} - {ops} - HPyTracker_Close(ctx, ht); - if (HPy_IsNull(result)) - result = HPy_Dup(ctx, ctx->h_None); - return result; - }} - @EXPORT(f) - @INIT - """.format(ops=ops, size=size)) - - def test_new_and_free(self): - mod = self.hpytracker_module(ops="") - mod.f() - - def test_new_with_size_and_free(self): - mod = self.hpytracker_module(ops="", size=10) - mod.f() - - def test_add_and_free(self): - mod = self.hpytracker_module(ops=""" - HPyTracker_Add(ctx, ht, HPy_Dup(ctx, args[0])); - """) - mod.f(5) - - def test_add_and_remove_all(self): - mod = self.hpytracker_module(ops=""" - HPyTracker_Add(ctx, ht, args[0]); - HPyTracker_ForgetAll(ctx, ht); - """) - assert mod.f(5) is None - - def test_remove_all_on_nothing(self): - mod = self.hpytracker_module(ops=""" - HPyTracker_ForgetAll(ctx, ht); - """) - assert mod.f() is None - - def test_squares_example(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(squares, "squares", HPyFunc_VARARGS) - static HPy squares_impl(HPyContext *ctx, HPy self, - const HPy *args, size_t nargs) - { - long i, n; - long n_err = -1; // simulate an error at the given index - int result; - HPy key, value; - HPyTracker ht; - - if (!HPyArg_Parse(ctx, NULL, args, nargs, "l|l", &n, &n_err)) - return HPy_NULL; - - ht = HPyTracker_New(ctx, 0); // track key-value pairs - if HPy_IsNull(ht) - return HPy_NULL; - - HPy dict = HPyDict_New(ctx); - if (HPy_IsNull(dict)) - goto error; - - for (i=1; i<=n; i++) { - if (i==n_err) - goto error; - key = HPyLong_FromLong(ctx, i); - if (HPy_IsNull(key)) - goto error; - if (HPyTracker_Add(ctx, ht, key) < 0) - goto error; - value = HPyLong_FromLong(ctx, i * i); - if (HPy_IsNull(value)) - goto error; - if (HPyTracker_Add(ctx, ht, value) < 0) - goto error; - result = HPy_SetItem(ctx, dict, key, value); - if (result < 0) - goto error; - } - - HPyTracker_Close(ctx, ht); - return dict; - - error: - HPyTracker_Close(ctx, ht); - HPy_Close(ctx, dict); - HPyErr_SetString(ctx, ctx->h_ValueError, "Failed!"); - return HPy_NULL; - } - @EXPORT(squares) - @INIT - """) - assert mod.squares(5) == {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} - assert mod.squares(100) == dict((i, i**2) for i in range(1, 101)) - with pytest.raises(ValueError) as err: - mod.squares(5, 3) - assert str(err.value) == "Failed!" diff --git a/graalpython/hpy/test/trace/test_trace.py b/graalpython/hpy/test/trace/test_trace.py deleted file mode 100644 index 275d314dfe..0000000000 --- a/graalpython/hpy/test/trace/test_trace.py +++ /dev/null @@ -1,127 +0,0 @@ -import pytest -from hpy.trace import get_call_counts, get_durations, set_trace_functions - -@pytest.fixture -def hpy_abi(): - return "trace" - - -def get_call_counter(): - from collections import Counter - return Counter(get_call_counts()) - - -def _assert_unchanged_except(expected, actual, *ignore): - import pytest - for x in expected.keys(): - if x not in ignore and actual[x] != expected[x]: - pytest.fail("%s unexpectedly changed (expected %d but was %d)." % - (x, expected[x], actual[x])) - - -def test_get_call_counts(compiler): - import pytest - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly two args"); - return HPy_NULL; - } - return HPy_Add(ctx, args[0], args[1]); - } - - @EXPORT(f) - @INIT - """) - # Don't rely on absolute call count numbers since the module setup could - # already do some API calls we don't expect. - call_counter_0 = get_call_counter() - - assert mod.f(1, 2) == 3 - assert get_call_counter() - call_counter_0 == {"ctx_Add": 1} - assert mod.f(10, 20) == 30 - assert get_call_counter() - call_counter_0 == {"ctx_Add": 2} - with pytest.raises(TypeError): - mod.f(1, 2, 3) - assert get_call_counter() - call_counter_0 == {"ctx_Add": 2, "ctx_Err_SetString": 1} - - -def test_get_durations(compiler): - import time - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_O) - static HPy f_impl(HPyContext *ctx, HPy self, HPy arg) - { - if (!HPyCallable_Check(ctx, arg)) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected callable"); - return HPy_NULL; - } - return HPy_CallTupleDict(ctx, arg, HPy_NULL, HPy_NULL); - } - - @EXPORT(f) - @INIT - """) - # Don't rely on absolute durations numbers since the module setup could - # already do some API calls we don't expect. - durations0 = get_durations().copy() - - def callback(): - time.sleep(0.3) - return 123 - - assert mod.f(callback) == 123 - assert get_durations()["ctx_CallTupleDict"] >= durations0["ctx_CallTupleDict"] + 3e5 - _assert_unchanged_except(durations0, get_durations(), "ctx_CallTupleDict", "ctx_Callable_Check") - - -def test_trace_funcs(compiler): - import pytest - mod = compiler.make_module(""" - HPyDef_METH(f, "f", HPyFunc_VARARGS) - static HPy f_impl(HPyContext *ctx, HPy self, const HPy *args, size_t nargs) - { - if (nargs != 2) { - HPyErr_SetString(ctx, ctx->h_TypeError, "expected exactly two args"); - return HPy_NULL; - } - return HPy_Add(ctx, args[0], args[1]); - } - - @EXPORT(f) - @INIT - """) - on_enter_cnt = 0 - on_exit_cnt = 0 - - def on_enter(name): - assert name == "ctx_Add" - nonlocal on_enter_cnt - on_enter_cnt += 1 - - def on_exit(name): - assert name == "ctx_Add" - nonlocal on_exit_cnt - on_exit_cnt += 1 - - set_trace_functions(on_enter) - assert on_enter_cnt == 0 - assert on_exit_cnt == 0 - assert mod.f(1, 2) == 3 - assert on_enter_cnt == 1 - assert on_exit_cnt == 0 - # on_enter should stay untouched - set_trace_functions(on_exit=on_exit) - assert mod.f(2, 3) == 5 - assert on_enter_cnt == 2 - assert on_exit_cnt == 1 - # clear on_enter func - set_trace_functions(on_enter=None) - assert mod.f(2, 3) == 5 - assert on_enter_cnt == 2 - assert on_exit_cnt == 2 - - with pytest.raises(TypeError): - set_trace_functions(1) diff --git a/mx.graalpython/copyrights/hpy.copyright.hash b/mx.graalpython/copyrights/hpy.copyright.hash deleted file mode 100644 index 0ca10bc209..0000000000 --- a/mx.graalpython/copyrights/hpy.copyright.hash +++ /dev/null @@ -1,23 +0,0 @@ -# MIT License -# -# Copyright (c) 2026, Oracle and/or its affiliates. -# Copyright (c) 2019 pyhandle -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - diff --git a/mx.graalpython/copyrights/hpy.copyright.hash.regex b/mx.graalpython/copyrights/hpy.copyright.hash.regex deleted file mode 100644 index 34fc654e7d..0000000000 --- a/mx.graalpython/copyrights/hpy.copyright.hash.regex +++ /dev/null @@ -1,23 +0,0 @@ -(?:# -\*- encoding: utf-8 -\*-\n)?# MIT License -#\s* -# Copyright \(c\) (?:20[0-9][0-9], )*(20[0-9][0-9]), Oracle and/or its affiliates. -# Copyright \(c\) 2019 pyhandle -#\s* -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files \(the "Software"\), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -#\s* -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -#\s* -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -.* diff --git a/mx.graalpython/copyrights/hpy.copyright.star b/mx.graalpython/copyrights/hpy.copyright.star deleted file mode 100644 index 45b29a8a16..0000000000 --- a/mx.graalpython/copyrights/hpy.copyright.star +++ /dev/null @@ -1,24 +0,0 @@ -/* MIT License - * - * Copyright (c) 2026, Oracle and/or its affiliates. - * Copyright (c) 2019 pyhandle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - diff --git a/mx.graalpython/copyrights/hpy.copyright.star.regex b/mx.graalpython/copyrights/hpy.copyright.star.regex deleted file mode 100644 index 19b7a52d06..0000000000 --- a/mx.graalpython/copyrights/hpy.copyright.star.regex +++ /dev/null @@ -1,24 +0,0 @@ -/\* MIT License - \*\s* - \* Copyright \(c\) (?:20[0-9][0-9], )*(20[0-9][0-9]), Oracle and/or its affiliates.\s* - \* Copyright \(c\) 2019 pyhandle - \*\s* - \* Permission is hereby granted, free of charge, to any person obtaining a copy - \* of this software and associated documentation files \(the "Software"\), to deal - \* in the Software without restriction, including without limitation the rights - \* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - \* copies of the Software, and to permit persons to whom the Software is - \* furnished to do so, subject to the following conditions: - \*\s* - \* The above copyright notice and this permission notice shall be included in all - \* copies or substantial portions of the Software. - \*\s* - \* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - \* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - \* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - \* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - \* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - \* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - \* SOFTWARE. - \*/ -.* diff --git a/mx.graalpython/downstream_tests.py b/mx.graalpython/downstream_tests.py index 004e05307a..e4948235b3 100644 --- a/mx.graalpython/downstream_tests.py +++ b/mx.graalpython/downstream_tests.py @@ -70,50 +70,6 @@ def decorator(fn): return decorator -@downstream_test('hpy') -def downstream_test_hpy(graalpy, testdir=None, args=None, env=None, check=True, timeout=None): - if not testdir: - testdir = Path('downstream-tests').absolute() - shutil.rmtree(testdir, ignore_errors=True) - testdir.mkdir(exist_ok=True) - hpy_root = DIR / "graalpython" / "hpy" - shutil.copytree(hpy_root, testdir / "hpy") - hpy_root = testdir / "hpy" - hpy_test_root = hpy_root / "test" - venv = testdir / 'hpy_venv' - run([graalpy, "-m", "venv", str(venv)]) - run_in_venv(venv, [ - "pip", - "install", - "pytest==9.1.1", - "pytest-xdist==3.8.0", - "pytest-rerunfailures==16.4", - "filelock==3.30.0", - ]) - env = env or os.environ.copy() - env["SETUPTOOLS_SCM_PRETEND_VERSION"] = "0.9.0" - run_in_venv(venv, ["pip", "install", "-e", "."], cwd=str(hpy_root), env=env) - parallelism = str(min(os.cpu_count(), int(os.cpu_count() / 4))) - args = args or [] - args = [ - "python", - "--vm.ea", - "--experimental-options=true", - "--python.EnableDebuggingBuiltins", - *args, - "-m", "pytest", - "-v", - # for those cases where testing invalid handles corrupts the process so - # much that we crash - we don't recover gracefully in some cases :( - "--reruns", "3", - "-n", parallelism, - str(hpy_test_root), - # test_distutils is just slow and testing the build infrastructure - "-k", "not test_distutils" - ] - return run_in_venv(venv, args, env=env, cwd=str(hpy_root), check=check, timeout=timeout) - - @downstream_test('pybind11') def downstream_test_pybind11(graalpy, testdir): run(['git', 'clone', 'https://github.com/pybind/pybind11.git', '--depth', '1'], cwd=testdir) diff --git a/mx.graalpython/mx_graalpython.py b/mx.graalpython/mx_graalpython.py index 02a5c69858..7119113729 100644 --- a/mx.graalpython/mx_graalpython.py +++ b/mx.graalpython/mx_graalpython.py @@ -1097,8 +1097,6 @@ class GraalPythonTags(object): unittest_multi_sandboxed = 'python-unittest-multi-context-sandboxed' unittest_jython = 'python-unittest-jython' unittest_arrow = 'python-unittest-arrow-storage' - unittest_hpy = 'python-unittest-hpy' - unittest_hpy_sandboxed = 'python-unittest-hpy-sandboxed' unittest_standalone = 'python-unittest-standalone' tagged = 'python-tagged-unittest' svmbuild = 'python-svm-build' @@ -1819,17 +1817,6 @@ def run_sandboxed_tests(python_binary, report, args=None, **kwargs): run_tagged_unittests(python_binary, args=args, paths=paths, report=report, **kwargs) -def run_hpy_unittests(python_binary, args=None, env=None, nonZeroIsFatal=True, timeout=None, report: Union[Task, bool, None] = False): - t0 = time.time() - result = downstream_tests.downstream_test_hpy(python_binary, args=args, env=env, check=nonZeroIsFatal, timeout=timeout) - if isinstance(report, mx.Task): - mx_gate.make_test_report([{ - "name": report.title, - "status": "PASSED" if result == 0 else "FAILED", - "duration": int((time.time() - t0) * 1000) - }], report.title) - - def run_tagged_unittests(python_binary, env=None, cwd=None, nonZeroIsFatal=True, checkIfWithGraalPythonEE=False, report: Union[Task, bool, None] = False, parallel=8, exclude=None, paths=(), args=None): if checkIfWithGraalPythonEE: @@ -2059,14 +2046,6 @@ def graalpython_gate_runner(_, tasks): if task: run_python_unittests(graalpy_standalone_jvm(), args=["--python.UseNativePrimitiveStorageStrategy"], report=report(), nonZeroIsFatal=nonZeroIsFatal) - with Task('GraalPython HPy tests', tasks, tags=[GraalPythonTags.unittest_hpy]) as task: - if task: - run_hpy_unittests(graalpy_standalone_native(), nonZeroIsFatal=nonZeroIsFatal, report=report()) - - with Task('GraalPython HPy sandboxed tests', tasks, tags=[GraalPythonTags.unittest_hpy_sandboxed]) as task: - if task: - run_hpy_unittests(graalpy_standalone_native_enterprise(), args=SANDBOXED_OPTIONS, report=report()) - with Task('GraalPython standalone module tests', tasks, tags=[GraalPythonTags.unittest_standalone]) as task: if task: gvm_jdk = graalvm_jdk() @@ -2796,7 +2775,6 @@ def python_checkcopyrights(args): if any(x in line for x in [ "lib-python/3", ".test/testData", - "/hpy/", "com.oracle.graal.python.test.integration/src/org.graalvm.python.vfs/", "com.oracle.graal.python.test.integration/src/GRAALPY-VFS/", "com.oracle.graal.python.benchmarks/python/micro/pyperformance/", @@ -3071,7 +3049,6 @@ def python_coverage(args): # Run only a few tagged tests that are relevant to the files in lib-graalpython {"tagged": True, "paths": ["test_re.py", "test_unicodedata.py"]}, {"args": ["--python.EmulateJython"], "paths": ["test_interop.py"]}, - {"hpy": True}, ] common_coverage_args = [ @@ -3094,8 +3071,6 @@ def python_coverage(args): env['GRAAL_PYTHON_VM_ARGS'] = " ".join(extra_args) if kwds.pop("tagged", False): run_tagged_unittests(executable, env=env, nonZeroIsFatal=False, **kwds) # pylint: disable=unexpected-keyword-arg; - elif kwds.pop("hpy", False): - run_hpy_unittests(executable, env=env, nonZeroIsFatal=False, timeout=5*60*60) # hpy unittests are really slow under coverage else: run_python_unittests(executable, env=env, nonZeroIsFatal=False, timeout=3600, **kwds) # pylint: disable=unexpected-keyword-arg; diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 9691f0fe28..2d6a7c5fe0 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -338,27 +338,6 @@ ], }, - # HPy - "hpy": { - "subDir": "graalpython", - "vpath": True, - "type": "GraalpythonProject", - "defaultBuild": False, - "args": [ - "/build.py", - "--out", - "", - "--cflags", - "-I/jni_gen -I/-// -I/include", - ], - "platformDependent": True, - "buildDependencies": [ - "com.oracle.graal.python", - "GRAALPYTHON-LAUNCHER", - "regex:TREGEX", - ], - }, - "com.oracle.graal.python.resources": { "subDir": "graalpython", "sourceDirs": ["src"],