FIX Handle large lengths and negative lengths in hiwire_get_length. While investigating this bug:

> ```
> Pyodide has suffered a fatal error. Please report this to the Pyodide maintainers.
> The cause of the fatal error was:
> PythonError: OverflowError: Python int too large to convert to C ssize_t
> ```
> 
> _Originally posted by @amitsaha in https://github.com/pyodide/pyodide/issues/2584#issuecomment-1139530294_

I found a different one. Turns out handling lengths correctly is quite hard.
def test_uncaught_cpp_exceptions(selenium):
    assert (
        selenium.run_js(
            """
            await pyodide.loadPackage("cpp-exceptions-test");
            const Tests = pyodide._api.tests;
            const sitePackages = pyodide.runPython("import site; site.getsitepackages()[0]")
            const idx = pyodide._module.LDSO.loadedLibNames[sitePackages + "/cpp-exceptions-test-throw.so"]
            const throwlib = pyodide._module.LDSO.loadedLibs[idx].module;
            """
            """\
            function t(x){
                try {
                    throwlib.throw_exc(x);
                } catch(e){
                    let errString = Tests.convertCppException(e).toString();
                    errString = errString.replace(/[0-9]+/, "xxx");
                    return errString;
                }
            }
            return [t(1), t(2), t(3), t(4), t(5)];
            """
        )
        == [
            "CppException int: The exception is an object of type int at address xxx "
            "which does not inherit from std::exception",
            "CppException char: The exception is an object of type char at address xxx "
            "which does not inherit from std::exception",
            "CppException std::runtime_error: abc",
            "CppException myexception: My exception happened",
            "CppException char const*: The exception is an object of type char const* at "
            "address xxx which does not inherit from std::exception",
        ]
    )


def test_cpp_exception_catching(selenium):
    assert (
        selenium.run_js(
            """
            await pyodide.loadPackage("cpp-exceptions-test");
            const Module = pyodide._module;
            const sitePackages = pyodide.runPython("import site; site.getsitepackages()[0]")
            const idx = Module.LDSO.loadedLibNames[sitePackages + "/cpp-exceptions-test-catch.so"]
            const catchlib = Module.LDSO.loadedLibs[idx].module;
            """
            """\
            function t(x){
                const ptr = catchlib.catch_exc(x);
                const res = Module.UTF8ToString(ptr);
                Module._free(ptr);
                return res;
            }

            return [t(1), t(2), t(3), t(5)];
            """
        )
        == [
            "caught int 1000",
            "caught char 99",
            "caught runtime_error abc",
            "caught ????",
        ]
    )

def test_uncaught_cpp_exceptions(selenium):
    assert (
        selenium.run_js(
            """
            await pyodide.loadPackage("cpp-exceptions-test");
            const Tests = pyodide._api.tests;
            const sitePackages = pyodide.runPython("import site; site.getsitepackages()[0]")
            const idx = pyodide._module.LDSO.loadedLibNames[sitePackages + "/cpp-exceptions-test-throw.so"]
            const throwlib = pyodide._module.LDSO.loadedLibs[idx].module;
            """
            """\
            function t(x){
                try {
                    throwlib.throw_exc(x);
                } catch(e){
                    let errString = Tests.convertCppException(e).toString();
                    errString = errString.replace(/[0-9]+/, "xxx");
                    return errString;
                }
            }
            return [t(1), t(2), t(3), t(4), t(5)];
            """
        )
        == [
            "CppException int: The exception is an object of type int at address xxx "
            "which does not inherit from std::exception",
            "CppException char: The exception is an object of type char at address xxx "
            "which does not inherit from std::exception",
            "CppException std::runtime_error: abc",
            "CppException myexception: My exception happened",
            "CppException char const*: The exception is an object of type char const* at "
            "address xxx which does not inherit from std::exception",
        ]
    )


def test_cpp_exception_catching(selenium):
    assert (
        selenium.run_js(
            """
            await pyodide.loadPackage("cpp-exceptions-test");
            const Module = pyodide._module;
            const sitePackages = pyodide.runPython("import site; site.getsitepackages()[0]")
            const idx = Module.LDSO.loadedLibNames[sitePackages + "/cpp-exceptions-test-catch.so"]
            const catchlib = Module.LDSO.loadedLibs[idx].module;
            """
            """\
            function t(x){
                const ptr = catchlib.catch_exc(x);
                const res = Module.UTF8ToString(ptr);
                Module._free(ptr);
                return res;
            }

            return [t(1), t(2), t(3), t(5)];
            """
        )
        == [
            "caught int 1000",
            "caught char 99",
            "caught runtime_error abc",
            "caught ????",
        ]
    )
