Show HN: Compiling C in the browser using WebAssembly
wasmer.io
wasmer.io
From the page:
Cranelift is a fast, secure, relatively simple and innovative compiler backend. It takes an intermediate representation of a program generated by some frontend and compiles it to executable machine code. Cranelift is meant to be used as a library within an "embedder".
It is in successful use by the Wasmtime WebAssembly virtual machine, for just-in-time (JIT) and ahead-of-time (AOT) compilation, and also as an experimental backend for the Rust compiler.
Cranelift is an optimizing compiler, but it aims to take a fresh look at which optimizations are necessary. We have explicitly avoided features -- such as advanced alias analysis or use of undefined behavior -- that have historically led to subtle miscompilations in other compilers. Cranelift consists of about 200 thousand lines of code; in contrast, e.g. LLVM consists of over 20 million lines of code, a hundred times larger. This difference also allows Cranelift to be relatively approachable to developers, researchers, auditors and others who wish to understand how it works.
[1] http://troubles.md/why-do-we-need-the-relooper-algorithm-aga...
[2] https://medium.com/leaningtech/solving-the-structured-contro...
That might be true if your source language has goto, but for other languages that start with structured control flow, it's possible to just carry the structure through and emit Wasm directly from the AST.
https://old.reddit.com/r/C_Programming/comments/16kg48y/mind...
https://old.reddit.com/r/programminghorror/comments/ylc7f3/w...
Found a comment from the author of https://github.com/stclib/STC apparently and then came across this example:
https://stackoverflow.com/a/76887723
int coro_a(struct a* g)
{
cco_routine (g) {
printf("entering a\n");
for (g->i = 0; g->i < 3; g->i++) {
printf("A step %d\n", g->i);
cco_yield();
}
cco_final:
printf("returning from a\n");
}
return 0; // done
}
gcc -E -ISTC/include co.cAfter running it through a preprocessor, it gives me this.
int coro_a(struct a* g)
{
for (int* _state = &(g)->cco_state; *_state != CCO_STATE_DONE; *_state = CCO_STATE_DONE) _resume: switch (*_state) case 0: {
printf("entering a\n");
for (g->i = 0; g->i < 3; g->i++) {
printf("A step %d\n", g->i);
do { *_state = 14; return CCO_YIELD; goto _resume; case 14:; } while (0);
}
*_state = CCO_STATE_FINAL; case CCO_STATE_FINAL:
printf("returning from a\n");
}
return 0;
}So then the question becomes, which things are you allowed to jump over? In C++, I don’t really know, the restrictions seem fairly stringent. In C, you can jump over anything except a declaration using a variably modified type (i.e. a variable-length array, a pointer to one, etc.), but keep in mind that the variables whose declarations you’ve jumped over will be uninitialized even if the declaration does have an initializer.
We wait for grischka to decide when to announce a new release https://lists.nongnu.org/archive/html/tinycc-devel/2024-10/m...
YoWASP has also had an LLVM toolchain working in Wasm for a while too[1], although it seems like this version solves the subprocess problem by providing an implementation of `posix_spawn` whereas the YoWASP one uses some patches to avoid subprocesses altogether
My biggest question marks around this version are about runtime/platform support. As I understand it, this toolchain uses WASIX, which (AFAICT) works with Wasmer's own runtime and with a browser shim, but with none of the other runtimes. Are there plans to get WASIX more widely adopted across more runtimes, or to get WASIX caught up to the latest WASI standard (preview2)? Or maybe even better, bring the missing features from WASIX to mainline WASI like `posix_spawn`[2]? I'd love to be able to adopt this toolchain, but it doesn't seem like WASIX support has really caught on across the other runtimes
[1]: https://discourse.llvm.org/t/rfc-building-llvm-for-webassemb... [2]: https://github.com/WebAssembly/WASI/issues/414
Shameless plug: we are hosting a WebVM Hackathon next week (11-14 October) over Discord. For more information: https://cheerpx.io/hackathon
jslinux: 4.7s
wasmer: 1.3s
webvm: 1.2s
There's a xeus-cling Jupyter kernel, which supports interactive C++ in notebooks: https://github.com/jupyter-xeus/xeus-cling
There's not yet a JupyterLite (WASM) kernel for C or C++.
Expecting performance while compiling C in the browser feels redundant right now though.
What syntax can be used to run emception? Thank you.
There is a fork at https://github.com/emception/emception that is trying to make it more production ready, but it looks like that may have stalled
I'm working on something similar, where students can compile intel assembly and run it client-side: https://github.com/robalb/x86-64-playground
I currently have a use case that uses a server running an emscripten build (using SMODULARIZE and some exports, I suppose it’s not a true dylib)
panicked at /Users/syrusakbary/Development/wasmer/lib/api/src/js/instance.rs:62:84:
called `Result::unwrap()` on an `Err` value: JsValue(Function(bound 846))
Stack:
fe/_.wbg.__wbg_new_abda76e883ba8a5f@https://wasmer.sh/assets/index-CgFg6VHw.js:17:6582
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[1125]:0x2b4276
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[2888]:0x3ab373
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[8254]:0x435ed3
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[4825]:0x3fa7de
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[517]:0x1af753
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[294]:0xbed03
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[2039]:0x34b10e
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[2896]:0x3abaa1
@https://wasmer.sh/assets/wasmer_js_bg-BruS15W0.wasm:wasm-function[9393]:0x43fde1
S@https://wasmer.sh/assets/index-CgFg6VHw.js:11:424
c@https://wasmer.sh/assets/index-CgFg6VHw.js:11:264Is this how big a clang toolchain usually is?
I only have to bring this up because network providers still insist on measuring bits
May as well count the 8/10 encoding in a CD-ROM as extra bits. Oh excuse me, extra megabytes
https://www.destroyallsoftware.com/talks/the-birth-and-death...
Then it becomes a fully self-sustaining OS that can live forever in a browser.
Ideally http3 over webtransport-p2p!
Then add some network discovery so we can advertise & find what's available on our networks!
What is it that needs reviving?
I don't know why it's fallen off, to be honest, or what was raised against it. Highly desireable to a lot of p2p folk, a very promising webrtc datatransport replacement.
All you need is a virtual filesystem of some sort, a way to download, a way to upload, an editor, a compiler, and a VT100 JS library. We already have WASI for the rest.
If the JS is too undesired, then perhaps go the old framebuffer graphics mode (e.g. a region of the WASM memory that is interpreted as an ASCII screen, or maybe even as a full bitmap buffer). Then JavaScript side just needs to forward keyboard/mouse into memory and that screen region out of memory.
WASIX already does all the other stuff you mentioned, including in the browser. The one thing it's missing is GUI, mainly because there's no standard GUI interface in POSIX.
Because we can"