Open Shaikh-Ubaid opened 1 year ago
What are the possible ways forward?
One option is to use wasi-libc
: https://github.com/WebAssembly/wasi-libc. This option I think would mean to compile the C runtime library using the wasi-sdk
toolchain (I think), and then somehow make the compiled wasm work with our wasm output.
Another option is to take the frontend language (Fortran or Python) runtime library, that calls into C, and then implement those C functions somehow.
We also have several applications of wasm:
We should ensure that our solution works well for all three use cases.
Another option is to take the frontend language (Fortran or Python) runtime library, that calls into C, and then implement those C functions somehow.
This feels hackish to me. IMO, wasi-libc
is a better direction to take. Might be difficult but feels more robust.
Another option is to take the frontend language (Fortran or Python) runtime library, that calls into C, and then implement those C functions somehow.
This feels hackish to me. IMO, wasi-libc
is a better direction to take. Might be difficult but feels more robust. Is there anything that prevents us from using wasi-libc
?
Nothing is preventing us as far as I know.
Then we should try with wasi-libc
first. If it works then good, otherwise we can go for second option. Its experimental, so we should try early to know any potential blockers with both the options. Supporting this would make WASM backend much more useful and invite a lot of users.
I will share my thoughts on this soon.
The pure Fortran (and Python) library works with wasm, so the only remaining file to tackle is src/libasr/runtime/lfortran_intrinsics.c
. In this file we currently have a lot of functions that do not have to be there:
That leaves the following functions:
memset
, malloc
, realloc
, calloc
and free
. Eventually we can have our own as well; for now we'll use libc --- I think these are only needed in the backend, so each backend can handle these directly; we can also consider moving to ASRclock()
. Probably we can consider creating an ASR node for thisfopen
, fread
, fclose
: these should probably be handled directly via ASR (details to be designed) Given this, it seems to me that we do not need the C runtime library at all, it is just a temporary measure to get things going.
For the WASM backend specifically, I would almost not bother, and rather work on moving more things into the surface language and ASR, one by one.
We now use IntrinsicFunction (might need to sync ASR with LFortran). Just a few functions are ported, but sin
already works.
There are two ways.
In the WASM backend you can implement IntrinsicFunction by changing this:
var imports = {
wasi_snapshot_preview1: {
/* wasi functions */
fd_write: fd_write,
proc_exit: proc_exit,
},
js: {
/* custom functions */
cpu_time: cpu_time,
show_img: show_image,
show_img_color: show_image_color
},
};
Into:
var imports = {
wasi_snapshot_preview1: {
/* wasi functions */
fd_write: fd_write,
proc_exit: proc_exit,
},
lcompilers: {
/* custom functions */
cpu_time: cpu_time,
show_img: show_image,
show_img_color: show_image_color,
sin: ...,
cos: ...,
},
};
Improve the ASR->ASR pass and instead of calling implementation in C, call pure Fortran implementation. Most likely we will implement this in ASR itself, then it is usable for LPython also. See https://github.com/lfortran/lfortran/issues/1435.
At present the wasm
binary generated by lpython/lfortran
works with both node
and wasmtime
. It seems using the first approach shared in https://github.com/lcompilers/lpython/issues/1413#issuecomment-1468467812, we can support the missing math
functions by supplying them in the imports object. This way it could work with node
. I am unsure if we could similarly support the math
functions using wasmtime
(we should investigate if it there is any way to supply custom functions via imports object using wasmtime.)
Regarding 1), I think we can use wasmtime run
with:
--preload <NAME=MODULE_PATH>
Load the given WebAssembly module before the main module
and provide the implementation of our imports in C, compile with clang to wasm and preload the module. Something like that might work and might be quite simple to maintain.
I think here is how we need to move forward: we need to port ALL of our runtime library to ASR, based on the plan above (https://github.com/lcompilers/lpython/issues/1413#issuecomment-1379268440).
malloc
has to be implemented most likely in the frontend langauge, we have to implement our own allocator.That will make pure Fortran or pure LPython code work completely via WASM, and our WASM->x64 backend will generate a standalone binary that will just work. If we need to link with C, then we just generate an .o
, and in wasm we "import" such functions, and we leave it to the user to link it correctly.
The runtime library functions that need access to libc are currently not supported in the
wasm
backend (and therefore also not yet supported in thewasm_x64
andwasm_x86
backends). It seemsWASI
or something similar could be used. This issue to plan/discuss about supporting the runtime library functions in thewasm
backend.