diff --git a/packages/cpp-exceptions-test/meta.yaml b/packages/cpp-exceptions-test/meta.yaml index 150c7ca8b..0fb50b218 100644 --- a/packages/cpp-exceptions-test/meta.yaml +++ b/packages/cpp-exceptions-test/meta.yaml @@ -10,7 +10,7 @@ source: build: type: shared_library script: | - em++ -c throw.cpp -o throw.o ${SIDE_MODULE_CFLAGS} -fexceptions - em++ -c catch.cpp -o catch.o ${SIDE_MODULE_CFLAGS} -fexceptions + em++ -c throw.cpp -o throw.o ${SIDE_MODULE_CFLAGS} -fexceptions -I${PYTHONINCLUDE} + em++ -c catch.cpp -o catch.o ${SIDE_MODULE_CFLAGS} -fexceptions -I${PYTHONINCLUDE} em++ throw.o ${SIDE_MODULE_LDFLAGS} -o ${DISTDIR}/cpp-exceptions-test-throw.so -fexceptions em++ catch.o ${SIDE_MODULE_LDFLAGS} -o ${DISTDIR}/cpp-exceptions-test-catch.so -fexceptions diff --git a/packages/cpp-exceptions-test/src/catch.cpp b/packages/cpp-exceptions-test/src/catch.cpp index 4624fe92e..a76dbe555 100644 --- a/packages/cpp-exceptions-test/src/catch.cpp +++ b/packages/cpp-exceptions-test/src/catch.cpp @@ -1,11 +1,16 @@ #include using namespace std; +#include +#include #include #include extern "C" char* throw_exc(int x); +extern "C" int +call_pyobj(PyObject* x); + extern "C" char* catch_exc(int x) { @@ -24,3 +29,36 @@ catch_exc(int x) } return msg; } + +extern "C" char* +catch_call_pyobj(PyObject* x) +{ + char* msg; + try { + int res = call_pyobj(x); + asprintf(&msg, "result was: %d", res); + } catch (int param) { + asprintf(&msg, "caught int %d", param); + } catch (char param) { + asprintf(&msg, "caught char %d", param); + } catch (runtime_error& e) { + asprintf(&msg, "caught runtime_error %s", e.what()); + } catch (...) { + asprintf(&msg, "caught ????"); + } + return msg; +} + +jmp_buf my_jump_buffer; +void +longjmp_func(int status); + +extern "C" int +set_jmp_func() +{ + int status = setjmp(my_jump_buffer); + if (status == 0) { + longjmp_func(4); + } + return status; +} diff --git a/packages/cpp-exceptions-test/src/throw.cpp b/packages/cpp-exceptions-test/src/throw.cpp index bfbf1dddd..871df1c6d 100644 --- a/packages/cpp-exceptions-test/src/throw.cpp +++ b/packages/cpp-exceptions-test/src/throw.cpp @@ -1,5 +1,11 @@ +#include #include #include + +#include +#include + +jmp_buf my_jump_buffer; using namespace std; class myexception : public exception @@ -22,3 +28,18 @@ throw_exc(int x) throw "abc"; } } + +extern "C" int +call_pyobj(PyObject* x) +{ + PyObject* result = PyObject_CallNoArgs(x); + int r = PyLong_AsLong(result); + Py_DECREF(result); + return r; +} + +noreturn void +longjmp_func(int status) +{ + longjmp(my_jump_buffer, status + 1); // will return status+1 out of setjmp +} diff --git a/packages/cpp-exceptions-test/test_cpp_exceptions.py b/packages/cpp-exceptions-test/test_cpp_exceptions.py index fe366973f..05f7653ba 100644 --- a/packages/cpp-exceptions-test/test_cpp_exceptions.py +++ b/packages/cpp-exceptions-test/test_cpp_exceptions.py @@ -5,8 +5,6 @@ def test_uncaught_cpp_exceptions(selenium): await pyodide.loadPackage("cpp-exceptions-test"); const Tests = pyodide._api.tests; const throwlib = pyodide._module.LDSO.loadedLibsByName["/usr/lib/cpp-exceptions-test-throw.so"].exports; - """ - """\ function t(x){ try { throwlib.throw_exc(x); @@ -39,8 +37,6 @@ def test_cpp_exception_catching(selenium): await pyodide.loadPackage("cpp-exceptions-test"); const Module = pyodide._module; const catchlib = pyodide._module.LDSO.loadedLibsByName["/usr/lib/cpp-exceptions-test-catch.so"].exports; - """ - """\ function t(x){ const ptr = catchlib.catch_exc(x); const res = Module.UTF8ToString(ptr); @@ -58,3 +54,19 @@ def test_cpp_exception_catching(selenium): "caught ????", ] ) + + +def test_sjlj(selenium): + assert ( + ( + selenium.run_js( + """ + await pyodide.loadPackage("cpp-exceptions-test"); + const Module = pyodide._module; + const catchlib = pyodide._module.LDSO.loadedLibsByName["/usr/lib/cpp-exceptions-test-catch.so"].exports; + return catchlib.set_jmp_func(); + """ + ) + ) + == 5 + )