Traps are not catchable by Wasm's try-catch or try_table. If you are going 
to catch them in JS that calls Wasm functions, you can (because traps 
surface as WebAssembly.RuntimeError), but I don't think you can 'reenter' 
the Wasm code that trapped. I'm not sure if I understand your plans 
correctly though.

On Monday, September 15, 2025 at 1:41:28 AM UTC-7 [email protected] wrote:

> > While writing this mail,I realised a possible short-cut to let me get 
> the test harness 
> > running more quickly, without having to generate a wrapper for hundreds 
> of different 
> > functions, with thousands of associated data types and constants. It 
> goes like this:  
> >
> > The calls to the library from the test harness are generated by C 
> macros, and I can 
> > add code to those for the WebAssembly build. So it appears I could use 
> EM_ASM() 
> > to create JavaScript error handlers at each of those call sites, as part 
> of the test 
> > harness source. I could then statically link the library and the test 
> harness for running 
> > tests. Is that plausible?
>
> Over the weekend I realised the difficulty with that: I'd have to get all 
> the arguments into JavaScript variables, pass them into the calls inside 
> the try/catch blocks, and then get them back into Emscripten C/C++ 
> variables. Since they contain loads of arrays, C struts and strings, this 
> amounts to generating a wrapper anyway. 
>
> Alternatively, will catching exceptions with -fwasm-exceptions allow me 
> to catch out-of-bounds exceptions in Emscripten-compiled C++? 
>
> Thanks in advance,
>
> John 
>
> On Fri, Sep 12, 2025 at 4:02 PM John Dallman <[email protected]> wrote:
>
>> > OK, what I want to do isn't possible in Emscripten. 
>>
>> It looks like it is, actually, but it's a bit complicated. Here's the 
>> scheme: am I requiring anything that doesn't exist?
>>
>> I have a great big math library that I want to make available in 
>> WebAssembly form, as a commercial product. It is written in C and C++, and 
>> runs on Android, iOS, Linux, macOS and Windows. Its heritage is from 1980s 
>> and 1990s technical computing, but it is still going strong as a commercial 
>> product. The immediate customers for it want to call it from C/C++ code 
>> that they already use on other platforms (mostly Linux and Windows), rather 
>> than from JavaScript. 
>>
>> This math library has a test harness, also written in C and C++. The test 
>> cases are *not* written in C/C++, but in interpreted LISP, 
>> because that's quite suitable for handling the data that the library 
>> works with, plus it was easy to write our own portable implementation of 
>> the language. 
>>
>> When you run the test harness, it looks for a LISP file to run and starts 
>> interpreting it, which usually starts by reading a lot more LISP files to 
>> set up a working environment. It then starts reading test scripts and 
>> making the calls to the math library that they request. The test harness 
>> does not exit until it has finished running everything it was given, or it 
>> hits an unrecoverable error. On its existing platforms, it can recover from 
>> SIGSEGV, SIGPFE, and other run-time errors, aborting the test that caused 
>> them and continuing with the subsequent test(s).
>>
>> That last part is the problem with a naive WebAssembly implementation, 
>> where the library and the test harness are statically linked together. That 
>> means there's no opportunity for a JavaScript error handler to get involved 
>> before exceptions caused by access violations come flying out of the top of 
>> the test harness. By then, the call stack is gone, and there's no way to 
>> recover from the exception and continue with the next test. 
>>
>> That's where I'd got to when I wrote " . . . what I want to do isn't 
>> possible in Emscripten." I've had what seem like better ideas since then. 
>>
>> WebAssembly "modules" are, as far as I understand, kind of like Windows 
>> DLLs or Linux shared libraries. There's a difference in that you can't link 
>> a module against other modules: inter-module calls have to go via 
>> JavaScript. Is that correct? 
>>
>> I was slow to realise that I can put JavaScript error handlers into any 
>> JavaScript layer. To take advantage of that, I would link my math library 
>> as a module, and its test harness as the main program. The test harness 
>> would call JavaScript code, which would call the library from within a 
>> try/catch block, catch exceptions, call the library's "tidy up" functions, 
>> and return an error code to the test harness. That lets the test harness 
>> recover from exceptions and move on to the next test. It also means I need 
>> to create a JavaScript wrapper for the whole of the library's API, which is 
>> a bit of a big job, but makes the library more generally usable in 
>> WebAssembly code. 
>>
>> While writing this mail,I realised a possible short-cut to let me get the 
>> test harness running more quickly, without having to generate a wrapper for 
>> hundreds of different functions, with thousands of associated data types 
>> and constants. It goes like this:  
>>
>> The calls to the library from the test harness are generated by C macros, 
>> and I can add code to those for the WebAssembly build. So it appears I 
>> could use EM_ASM() to create JavaScript error handlers at each of those 
>> call sites, as part of the test harness source. I could then statically 
>> link the library and the test harness for running tests. Is that plausible?
>>
>> Thanks in advance,
>>
>> John 
>>
>>
>>
>>
>> On Thu, Sep 11, 2025 at 3:00 PM John Dallman <[email protected]> wrote:
>>
>>> OK, what I want to do isn't possible in Emscripten. 
>>>
>>> Thanks, everyone. 
>>>
>>> John
>>>
>>> On Tue, Sep 9, 2025 at 7:37 AM Heejin Ahn <[email protected]> wrote:
>>>
>>>> Correct. Both Emscripten and Wasm SjLj handling requires the setjmp 
>>>> point to be "lower" than the longjmp point, because both use exceptions to 
>>>> simulate setjmp-longjmp.
>>>> So this works:
>>>> ```
>>>> static jmp_buf buf; 
>>>>
>>>> void bar() {
>>>> }
>>>>
>>>> int main() {
>>>>   int jmpval = setjmp(buf);
>>>>   if (jmpval == 0) {
>>>>     printf("first call\n");
>>>>   } else {
>>>>     printf("second call\n");
>>>>     exit(0);
>>>>   }
>>>>   bar();
>>>>   return 0;
>>>> }
>>>> ```
>>>>
>>>> But this does NOT work:
>>>> ```
>>>> static jmp_buf buf;
>>>>
>>>> void foo() {
>>>>   int jmpval = setjmp(buf);
>>>>   if (jmpval == 0) {
>>>>     printf("first call\n");
>>>>   } else {
>>>>     printf("second call\n");
>>>>     exit(0);
>>>>   }
>>>> }
>>>>
>>>> void bar() {
>>>>   longjmp(buf, 1);
>>>> }
>>>>
>>>> int main() {
>>>>   foo();
>>>>   bar();
>>>>   return 0;
>>>> }
>>>> ```
>>>>
>>>> Because by the time longjmp is called, foo's call stack has been 
>>>> destroyed.
>>>>
>>>> On Mon, Sep 8, 2025 at 4:31 PM 'Sam Clegg' via emscripten-discuss <
>>>> [email protected]> wrote:
>>>>
>>>>> If you want to use `longjmp` in emscripten to get back to start of the 
>>>>> failing test, we have two setjmp/longjmp mechanism.  (1) The old 
>>>>> emscripten 
>>>>> method (2) The method using wasm exception handling.
>>>>>
>>>>> However, I believe that in both cases the target of the long jump has 
>>>>> to be above the caller on the stack.  That is, once you unwind the stack 
>>>>> all of the way it will no longer be possible to `longjmp` to the target 
>>>>> in 
>>>>> question since its no longer on the stack.   @Heejin Ahn can you 
>>>>> confirm this?
>>>>>
>>>>> If that is correct then you will need to some kind of alternative 
>>>>> mechanism when running in emscrpten.  Something like this maybe:
>>>>>
>>>>> ```
>>>>> void run_death_test(death_test_fn_t fn) {
>>>>> #ifdef __EMSCRIPTEN__
>>>>>   EM_ASM({
>>>>>      try {
>>>>>           ...call_fn_from_js..
>>>>>          report_failure_to_die()
>>>>>      } catch (e) { 
>>>>>          report_success_if_e_looks_good(e)
>>>>>      }
>>>>>   })
>>>>> #else
>>>>>    setup_longjmp_target():
>>>>>    fn();
>>>>> #endif
>>>>> }
>>>>> ```
>>>>>
>>>>> On Mon, Sep 8, 2025 at 4:17 PM Sam Clegg <[email protected]> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Mon, Sep 8, 2025 at 3:40 AM John Dallman <[email protected]> 
>>>>>> wrote:
>>>>>>
>>>>>>> > Is the test harness and the library-under-test designed to be 
>>>>>>> compiled into the 
>>>>>>> > same executable? 
>>>>>>>
>>>>>>> Yes. We prefer to have the library-under-test be a shared object or 
>>>>>>> Windows DLL, on platforms where that's possible, but we can have the 
>>>>>>> harness and the library linked together, and that's what I'm planning 
>>>>>>> to do 
>>>>>>> for WebAssembly. I'm trying to avoid producing a JS wrapper for an API 
>>>>>>> with 
>>>>>>> hundreds of functions, hundreds of structs, and thousands of constants. 
>>>>>>> It 
>>>>>>> also passes lots of pointers to code and data through the interface. My 
>>>>>>> customers who want a WebAssembly version of the library already have 
>>>>>>> C/C++ 
>>>>>>> or Swift code that calls it and want to use it that way.  
>>>>>>>
>>>>>>> > i.e. on other platforms does it somehow catch and recover from 
>>>>>>> sefaults?
>>>>>>>
>>>>>>> Yes.On platforms with signals, those are turned on for segmentation 
>>>>>>> faults (and for some other signals, depending on the platform). The 
>>>>>>> code is 
>>>>>>> C, which sets regular checkpoints with setjmp() and the signal handling 
>>>>>>> function longjmp()s to the latest checkpoint with a "test aborted" 
>>>>>>> value. 
>>>>>>> That's the basic idea, though it's rather more complicated in practice. 
>>>>>>>
>>>>>>
>>>>>> Oh wow, `longjmp` out of your signal handler sounds pretty gnarly.    
>>>>>> It's going to be even more gnarly trying to make that work with 
>>>>>> emscripten-generated code, but maybe not impossible?
>>>>>>  
>>>>>> Are there segfault tests limited in number?  i.e. would it be 
>>>>>> possible to choose a different approach when running on the web (just 
>>>>>> for 
>>>>>> these few tests)?   
>>>>>>
>>>>>>>
>>>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "emscripten-discuss" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> To view this discussion visit 
>>>>> https://groups.google.com/d/msgid/emscripten-discuss/CAL_va29WgYahkgoafxhXGs%2BPhfpP-o6GzQSgaTA3xRGhdPKRNg%40mail.gmail.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/emscripten-discuss/CAL_va29WgYahkgoafxhXGs%2BPhfpP-o6GzQSgaTA3xRGhdPKRNg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "emscripten-discuss" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to [email protected].
>>>> To view this discussion visit 
>>>> https://groups.google.com/d/msgid/emscripten-discuss/CALJpS1Nzcxx0mzS%2BxHTxrETvyGiuppeOcz68PNdjwNtYaG0YcA%40mail.gmail.com
>>>>  
>>>> <https://groups.google.com/d/msgid/emscripten-discuss/CALJpS1Nzcxx0mzS%2BxHTxrETvyGiuppeOcz68PNdjwNtYaG0YcA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/emscripten-discuss/d915fa8d-6e78-4353-b082-39463517eba9n%40googlegroups.com.

Reply via email to