Support added for exceptions with ASYNCIFY

The general scheme is not very complicated. Changes:

1. Rather than doing `dynCall_vi` on the *foo*__asnc_cb function, we use `invoke_vi`. This is essential if the callback functions are to throw exceptions.
1. If a callback did throw an exception, then we should reenter the parent callback function only if it checks for exceptions at the resume point. Otherwise, the exception should propagate up. We check for this using an extra boolean in the async context: `emscripten_alloc_async_context` now has an extra argument which the C++ code uses to indicate whether the async function is called with "invoke" or "call". (So the `invoke` argument to `emscripten_alloc_async_context` is set when `__THREW__` is checked immediately after the async call. We also update the invoke flag in `emscripten_realloc_context`.)
1. If the exception isn't caught anywhere, we rethrow it finally so that an error message is provided (admittedly not a very clear one, but it's no worse than when an exception is throw out of a synchronous `main`).

This pull request works in conjunction with the pull request to the fastcomp compiler.
Oh I meant the llvm alloca instruction. in the of C functions, the space is
allocated from the heap, which should be fine
On Sep 9, 2014 11:40 PM, "Nicholas Wilson" <notifications@github.com> wrote:

> In src/library_async.js:
>
> > -        ___async_unwind = 1;
> > -        continue;
> > +      if (!___async_cur_frame) {
> > +        // print ugly integer in console, same as if an exception is thrown out of main()
> > +        if (activeException) _emscripten_async_abort_with_exception();
> > +        return;
> > +      }
> > +      catchesExceptions = {{{ makeGetValueAsm('___async_cur_frame', 8, 'i8') }}};
> > +      // When an async function throws an exception, it can't just bubble up as
> > +      // normal (because there isn't a native JavaScript call stack, we're
> > +      // manually reconstructing it here).  We keep rewinding the stack until we
> > +      // find a function that can handle the exception.
> > +      if (!!catchesExceptions | !activeException) {
> > +        __THREW__ = activeException|0;
> > +        invoke_vi({{{ makeGetValueAsm('___async_cur_frame', 12, 'i32') }}},
> > +                  (___async_cur_frame + 12)|0);
>
> Well how about this then?
>
> int test_fn() {
>   emscripten_sleep(10);
>   int* test = (int*)alloca(20);
>   test[0] = 42;
>   emscripten_sleep(10);
>   return test[0];
> }
>
> It doesn't do what you want! The variable "test" causes the realloc to try
> and allocate a bigger async context, which tramples on the memory the
> application developer is trying to use. There's nothing stopping people
> from calling alloca in an __async_cb function, and I bound someone's
> eventually going to try to port a library that does that to emscripten.
>
> In any case, emscripten offers and alloca.h header and purports to
> support it, so it should print a clean assertion failure if someone does
> use it with asyncify.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/kripken/emscripten/pull/2772/files#r17308677>.
>