The documentation for building with EMTERPRETIFY_ASYNC=1 [1] indicates that:

To save the state of execution, the interpreter records its current 
> location and all variables on the stack, both of which we cannot do for 
> code that is not run in the interpreter. Note that *this prevents you 
> from using ccall or cwrap to call code which does an asynchronous operation* 
> - the normal JS making that call cannot be paused and resumed by us.


The bolded text above (emphasis mine) seems to be a roundabout way of 
saying that you absolutely must call code that could perform an 
asynchronous operation from either:
    (1) via main() or 
    (2) inside a main loop (as set by emscripten_set_main_loop()),
since I can't think of any other way to invoke code. Is this correct?


For my application - calling into the CPython library - it would be ideal 
if I could, for example, call the CPython _PyEval_EvalCode() function via 
some form of direct call (i.e. ccall, cwrap, or a manual call to 
_PyEval_EvalCode()). In my case it is possible for _PyEval_EvalCode() to be 
suspended as a result of an interior call to emscripten_sleep(). In that 
circumstance it is not clear what would be returned in the event of a 
suspended execution, as opposed to a completed execution that returned a 
particular result.

Imagine a special API similar to cwrap() which gives you a function pointer 
that could be used to invoke a function that could potentially be 
suspended. Here's some made-up syntax which hopefully demonstrates the idea.

*var PyEval_EvalCode = cwrap_async('_PyEval_EvalCode', 'number', ['number', 
'number', 'number']);*

*var result = PyEval_EvalCode(code_object, globals, locals);*
*if (result.suspended) {*
*    // ... Do some stuff, including potentially more calls into C 
functions ...*
*    result = result.resume();*
*    if (result.suspended) {*
*        throw 'Expected resume of PyEval_EvalCode to finish completely, 
for demo purposes.';*
*    } else {*
*        // (Here result.value is guaranteed to exist.)*
*    }*
*} else {*
*    // (Here result.value is guaranteed to exist.)*
*}*
*return result.value;*


This API features:

   - A *cwrap_async* function that is similar to *cwrap*, but whose wrapped 
   function doesn't directly return the result of the function. Instead, it 
   returns a result object { suspended : boolean, resume : function()|null, 
   result : any|null }.
   - If *result.suspended* is true, then *result.resume()* must be called 
   to restore the stack and obtain another result object.
   - if *result.suspended* is false, then *result.value* contains the final 
   return value of the function.

If implementable, I think that would be a nice API to consider for the 
future.

In the meantime I'll introduce an event loop in C that just calls functions 
based on a message queue. Somewhat complex, but should probably work.

- David

 [1]: 
https://github.com/kripken/emscripten/wiki/Emterpreter#emterpreter-async-run-synchronous-code

-- 
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].
For more options, visit https://groups.google.com/d/optout.

Reply via email to