Blocking operations in the WASM version (JavaScript expertise needed)

| jan
August 4 |

  • | - |

As some have discovered, I picked up the in-browser version of SWI-Prolog. See https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm.

The problem is how to deal with blocking operations like Prolog’s read/1 and anything that reads. The JavaScript/browser model is event driven. So, JavaScript calling some predicate on Prolog to process an event is fine. Prolog having to wait for user input or some other event is not. Instead, control has to go back to JavaScript and JavaScript shall make the Prolog engine resume when the waited for data is available.

Ciao solved that by running Prolog in a separate web worker and using PostMessage to make the worker chat with main JavaScript. See https://oa.upm.es/71073/1/TFG_GUILLERMO_GARCIA_PRADALES.pdf

Please note that this PDF is a student project which does not necessarily describe the latest or the best solution. Indeed some paragraphs are a bit inaccurate. Our aim was to describe this properly in a research paper (but it takes time). There is no need to do “clean-room reverse engineering” with Ciao. Just ask us (we recently opened Github discussions for Ciao but we’d really prefer a common discourse/whatever forum for all prologs…).

We can do the same (I guess), but we also have two alternatives. One was created after discussion with @matthijs: yield from a foreign predicate, i.e., a foreign predicate can ask the VM to return control to its caller, allowing the VM to be resumed later. The other is delimited continuations that do something similar, but I think they won’t work for this because control remains in the Prolog VM.

A “yield”-like primitive is exactly the solution that we showed in the GDE workshop video to do JS interactions. The current toplevel is still not using it (but the next one will do for some interactions).