remixlabs / wasicaml Goto Github PK
View Code? Open in Web Editor NEWTranslate OCaml bytecode to WebAssembly
License: Other
Translate OCaml bytecode to WebAssembly
License: Other
The problem could be that it needs the emulated exceptions for running. But we could also be just lucky.
as we cannot reallocate the stack
i.e. we'd like to know the information that a directly called function f1 calls another function f2.
The Wc_tracefuncs
analysis could exploit this for the transitive closure over the called functions.
Building wasicaml fails on node v16.4.0 with the above error. Probably this option has been made the default, since removing it from bin-template/wasi_run
allows us to compile and use wasicaml just fine.
Extension of #7
As an extension of #2:
A second function definition is provided for small functions that can be directly called. This second definition passes one OCaml arg per Wasm arg:
function letrecX_direct(i32 envptr, i32 param1, i32 param2, ...) : i32
This shall only be done if:
Also, note that fp
is unavailable. So nothing can be stored on the stack. Because there are no allocations, all intermediate values can be put into local variables.
e.g.
Currently there are 10 bits for the subfunction number. Throw an error when we have more then 2^10 subfunctions.
The complete stack is straightened right now but this is not necessary.
Extension of #5 - not only float/int32/64/nativeint artithmetic.
In particular:
Tail calls are already specified but not yet widely available. Nevertheless, we can run experiments with them and make them optional -enable-tail-calls
.
In particular, the startover
hack can then be removed.
Sort of straight-forward,... but there is a difficulty. Most values are finally converted to OCaml values, and this means that some memory needs to be allocated. In particular, this affects straighten_stack
, and there can now be allocations during that procedure.
Another option is to do the allocation at the original place, but to skip it when it is not needed.
Instead of using the clang
assembler we could also write the binary wasm code directly.
arg0
in fp[0]
)Wc_apply_direct
Currently most operations return RIntVal
but they can process either RInt
or RIntVal
.
For an optimized representation we need to know the users of a value. During the liveness pass #6 we could also gather information about the best representation of ints.
to keep the exception backtraces more accurate
Many smaller functions do not access the environment, and thus it is not needed to pass a real address as envptr
parameter to these functions.
Analysis: must be recursive - e.g. a function does not access the environment because there are only direct calls that do not need the environment, ...
The spec is in the final round, so why not try it out?
maybe it is better to return a 0 in order to signal an exception? This would avoid the JS-based throw
function.
We cannot, however, avoid the JS-based try
function because the exception could also be thrown by a C function, and we still need to catch that.
If Wasm tail calls are available, we can factor out the RESTART
code into a separate function that finally does a return_call
to the function for the non-restart case.
Also, the code pointer shifting is no longer needed (saves some instructions).
it is already implemented and we just need to assign a memory cell for each cache
In wasm, direct calls are cheaper than indirect calls. Also, direct calls can be inlined.
The idea is to scan the code for instruction sequences like:
Currently there is an indirection via wasicaml_wrapthrow
, and OCaml functions even tend to return exceptions via a NULL pointer. Better:
throw
instruction insteadrethrow
if possibleAlso, look at how we can interpret stack traces from JS.
Extension of #6:
When we know the liveness range of a store, we can also check whether there is the chance of a GC in that range. If not, values can be stored in local variables, which is generally cheaper.
It would be useful to know when a stored value falls out of use, in particular for branching. Right now it is tried to make the stores equal when there are several jumps to the same label. Often, this is needless work.
I've prepared a minimal demo at https://github.com/copy/wasicaml-demo/tree/js_to_ocaml. It fails in Firefox with "RuntimeError: indirect call to null" and in Chromium with "RuntimeError: function signature mismatch".
The C call works (i.e., this line gets printed: https://github.com/copy/wasicaml-demo/blob/js_to_ocaml/stubs.c#L12). The assertion below also doesn't fail, so the issue is likely in caml_callback
.
this is caml_change_max_stack_size
or comment it out in caml_gc_set
A self call of the same "let rec" can be recognized by the Koffsetclosure
instruction that precedes Kapply
.
A direct call is a bit cheaper than an indirect call (no wasm function type check).
Currently, you can get backtraces from JS only.
We already prevent local variables from being allocated and write all values to the stack. More is possible:
blockinit3(value, offset, p1, p2, p3)
to write three values at value[offset]
, value[offset+1]
and value[offset+2]
(will need such functions for e.g. n=1 to n=5, and also shr
versions that base on caml_initialize
)for full WASI compatibility
e.g. for min
and max
we could deduce this:
let min x y = if x < y then x else y
Because a function cannot be compared, we can follow that neither x
nor y
is a function.
Not sure why this cannot be concluded yet...
This is only advantageous when a function is called directly, and when tail calls are available.
We need to generate two wasm functions:
The former function would do grab
and restart
, and call the other function.
It seems that ~/.wasicaml
is still baked in somewhere at runtime. --prefix
does install into the given directory, but tools still search in ~/.wasicaml
:
% PATH=/tmp/prefix/bin:$PATH wasicaml a.out -o test
* parsing...
number instructions: 2560
number labels: 210
* creating CFG...
number nodes: 266
* linearize...
number functions: 111
* validating...
* translating to WASM...
* print as .wat...
* print as .s (llvm integrated assembler syntax)...
* assemble...
+ /home/fabian/.wasicaml/bin/wasi_cc -o 'a.out.o' -c 'a.out.s'
/bin/sh: line 1: /home/fabian/.wasicaml/bin/wasi_cc: No such file or directory
SYSTEM: /home/fabian/.wasicaml/bin/wasi_cc -o 'a.out.o' -c 'a.out.s'
Error: Command failed: /home/fabian/.wasicaml/bin/wasi_cc -o 'a.out.o' -c 'a.out.s'
at checkExecSyncError (node:child_process:826:11)
at execSync (node:child_process:900:15)
at /tmp/prefix/js/main.js:68:13
at <anonymous>:wasm-function[476]:0x1f403
at <anonymous>:wasm-function[151]:0xe63c
at wasicaml_call (<anonymous>:wasm-function[28]:0x3488)
at /tmp/prefix/js/main.js:23:38
at wasicaml_wraptry (<anonymous>:wasm-function[26]:0x3448)
at <anonymous>:wasm-function[150]:0xc9da
at _start (<anonymous>:wasm-function[25]:0x32fd) {
status: 127,
signal: null,
output: [ null, null, null ],
pid: 56512,
stdout: null,
stderr: null
}
command failed
A symbolic link from ~/.wasicaml to the prefix directory temporarily fixes the issue.
in particular
domain_field_<name>
<name>_tag
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.