First: We had emscripten as a black box
%r3.js, which you could give a string to, and it would evaluate it and give a string back.
Emscripten Rebol as Web Tutorial / Game - It's possible to ignore broader issues of how Rebol might be used on the web, and just build a teaching tool that demonstrates interesting aspects of the design. I feel like Ren-C's advances are largely unpublished and inaccessible, despite a huge amount of deep work. There's little I can do to help that in a society that doesn't really read even the people with ostensible interest in the topic, cough.
#3 seems the easiest. And sometimes I feel like getting it out there for people to try and discuss might build enough interest to get web-savvy people to come get involved and help. At the same time, the more ambitious the tutorial gets, the more its needs line up with #2, where that has to be done anyway.
It's always been a risky gamble to try and run ahead of what the world has demonstrated readiness for. People have been trying to do this for some time...remember Google Native Client? Anyone run any Adobe Flex applications lately?
In this case, the technical issue is that Rebol scripts want to have synchronous effects, whatever that may be. Whether it's a
INPUT or a
PARSE READ HTTP://...they want to take one step after the other. Making it even more necessary is that closures haven't really been figured out; so even if we wanted to get callback-happy, things aren't quite ready for that.
If while making a synchronous request, Rebol doesn't want to lose its state--e.g. how far it has counted in a loop or any state of any local variable on the stack--there are two options:
The emterpreter...which is a somewhat kludgey concept. You compile your C codebase not into WebAssembly directly, but into a bytecode. This is then run by a function called emterpret(). Since you're not running on "bare metal" of the browser, it is possible to suspend the bytecode interpreter (hence preserving all of your stack and variables and such as far as C was concerned when you made the "synchronous" request). Then aysnchronous things happen to fulfill the request, and when they're finished the C code is awoken from "suspended animation" and given the information.
Compile your code directly to WebAssembly and run it on a separate thread, e.g. a web worker. For the heap memory of the emterpreter, use a SharedArrayBuffer so that both the GUI thread and the worker thread have access to it. When the worker wants to make a synchronous request of the GUI, it posts a message containing the request and then uses an Atomics.wait on an indicator of when the result has been written to a specific heap location. The GUI does the requested work, writes the heap location, and does an Atomics.notify.
But this would really only be suitable for #3. While I took pains to build a transmission method that required mixtures of C code and messaging to accomplish the most basic of I/O, no one else would use a
SharedArrayBuffer was not pursued in the first test because it had been disabled in all major browsers due to a Spectre-based security flaw. Now--months later--it's back on in Desktop Chrome...although only with asm.js support by default (you have to do
--enable-features='WebAssembly SharedArrayBuffer' to get it to work with WASM, and it might not work even then). A lot of people are invested in it, but when it's going to come back in other browsers is anyone's guess. So it is a gamble to try to build on, and not necessarily trivial to work with.