Use the ABC interpreter instead of Sapl
This MR changes the backend of the browser client from Sapl to ABC. It uses a WebAssembly interpreter for ABC together with GraphCopy functionality to communicate expressions from the server to the client. This allows setting Clean functions as callbacks on browser events etc. as before (with the benefit that the values sent to the client can now be lazy).
- The ABC code is not JIT compiled as Sapl, but sent all at once before initializing the frontend. This causes a minor slowdown at startup.
- Dropped the Sapl library,
-saplcompiler option and
- Added the ABC interpreter dependency. Because the WebAssembly interpreter is for 64-bit ABC code, this means dropping 32-bit support (programs that do not use Reals in client-side code may work).
- Because interfacing with the client uses GraphCopy-with-names, set
Application.Profile.DescExL(export local descriptors) should be set to
evalon them. This is slower, so users should do as much as possible in Clean (in particular avoid
- Removed unused functions and types.
- Changed infix priorities, made
.?infix, to reduce the number of parentheses.
decodeOnServerpair has been removed; you are now expected to use JSON for this. See how
iTasks.UI.Editorexpects JSON in
onEditwith a JSON string. Thus you are still limited to sending data from the client to the server. This limitation can in principle be lifted, but that involves security risks and should be done in another MR.
- As noted above, this MR drops 32-bit support for iTasks.
- This has been tested in Firefox (60), Chromium (73), Chrome (74), and Edge (44).
- I have set the client-side heap to 8M, stack is 512K. This means a typical program requires about 20M of WebAssembly memory (interpreter program, stack, double heap due to a copying collector). These values are set in
abc-interpreter.jsand are not yet configurable (see follow-up below).
- Speed: the Ligretto example appears to have become about twice faster on Firefox and spends 90% on rendering now, which would suggest the interpreter is around 10 times faster than Sapl. But this is the program logic alone; rendering will take equally long as before. End results may therefore differ depending on the division between program logic/JS interface/rendering of a particular program. Of these, program logic should be much faster, but JS interfacing will be slower (see above), with rendering remaining the same.
To do before merging
Add support for the bytecode prelinker to
cpmand the IDE (clean-ide!13 (closed))
- Prevent reading bytecode and executable on every serialization cycle; store the symbol tables in memory.
- Prevent memory leaks.
- Checks for garbage collection.
- Check that all (default) project files are updated with the new options where needed.
- Test Microsoft Edge.
- Add abc-interpreter to the bundle-complete and bundle-itasks in clean-build (clean-build!49 (merged)).
Record fields in the generic descriptors for strict fields (clean-compiler-and-rts/stdenv@0d9308cf) can be removed, because they were only needed for
- Make client-side heap and stack size configurable (#287 (closed)).
JSValby first computing the size of the string and then filling it in instead of concatenating small pieces.
Or, don't use
toStringat all but iterate the
- Support passing integer values larger than 2^31 to WebAssembly (#288 (closed)).
decodeOnServerwith a graph-to-string/string-to-graph pair, which would be faster.
- Add stack trace options to the wasm interpreter.
- Add profiling options to the wasm interpreter.
- Avoid sending possibly secret application logic to the client unless necessary (see discussion below) (#290).