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.