-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How does this project work? #15
Comments
Hi @jcbhmr , Thank you for the detail analisys! I'll try to explain how emception works: The reddit comment is correct. But since then a few things changed:
Now, the high level overview. Emception is basically Emscripten runningi n the browser.
The interaction between all these processes is through their standard output, and files in the filesystem. To be able to run Emscripten in the browser we need:
The solution to 1 is easy, "just" compile all the The solution to 2 is easy as well given all the upstream effort of Pyodide before, and more recently of CPython to add WebAssembly as a compilation target using Emscripten. The solution to 3 is wasy as well using QuickJS. The main challenge is to identify the minimum subset of NodeJS libraries required to run the the Emscripten JS scripts. That's what Point 4 is a bit more challenging. Emscripten doesn't try to emulate a multiprocess environment. This means that the system calls to start a subprocess ( Point 5 is a problem because each Emscripten module (i.e., the python interpreter, Finally, point 6 is where all the packs come in. You can think of a pack as a homebrew zip file (more like a tar file). That's what
To save time when compiling, Emception also shipt the precompiled standard libraries. That's the Emscripten cache you mentioned. But the cache takes a lot of space, and most likely you won't need every single cached library. To work around that problem Emception uses a lazy cache. The files are only downloaded when they are needed. The lazy cache code is based on Emscripten's own I think the There's a lot of Emception uses brotli for compression. Brotli is a compression algorithm (like zip), but brotli can achieve much higher compression ratio in this case. Emception is hosted in github pages. Unfortunately github pages doesn't support brotli precompresses assets. Because of that, Emception tries to ship as many assets as a brotli compressed package file. This inclues the WebAssembly files, and that's why the Finally, since the brotli comrpession doesn't come from the webserver, the native decompressor in your browser won't decomrpess the package. That's why Emception ships a brotli decompressor. All of this is brought together in the Another point is that Emception executes in a blocking manner, and the execution can take a little while. To avoid blocking the main browser thread, it runs the code in a WebWorker, and uses comlink to simplify the interaction with it. I hope that was helpful and answered your questions! |
Thanks for your detailed response!
If I were to, say, fork the llvm-project repo and add in the llvm-project.patch changes, what else would I need to do in the pipeline to get the a llvm-box.wasm file? Is there even an llvm-box.wasm file that gets generated somehow? That seems like a good place to start breaking things apart into constituent projects. https://github.com/jcbhmr/llvm-box#readme |
First, the patch. Under some circumstances I don't know if there are any negative side effects to doing this. It seems to work fine on the way emscripten uses clang. See the comments around that code, maybe it will shed some light into it. I also don't know if there are other invocations of clang that could create a subprocess. It seems there are none in the way emscripten uses clang. At least I haven't found any so far. The second part of the patch is less important. Clang likes to append its major version to the binary name. When running with emcmake that meant it would generate files named Then, to building If you try to compile now, after que a while it will fail. That's because If you try to build now, it should work. You should get one This is where the part of bundling it as one binary starts. After configuring Each Moreover, each executable uses some global state, which is initializes even before main is called. This is done through functions specially tagged to run before main. Finally, a new All of this should work as long as the object files are WebAssembly files. This is not true of you build with If you want an independent The patching of the Again, hope that helps! |
In the build-llvm.sh script, there's this proxyfs.js thing; what is that? Line 56 in 3660655
|
@jcbhmr it's coming from this one https://emscripten.org/docs/api_reference/Filesystem-API.html#proxyfs |
@jprendes What does the patch-ninja.sh script do? https://github.com/jprendes/emception/blob/master/patch-ninja.sh The gist that I was able to read from it is that it dynamically somehow creates a new llvm-box target in the generated Ninja stuff that comes from CMake. If I wanted to add a target to CMakeLists.txt, what would I need to do to replicate the llvm-box target from Ninja in CMake? How would I go about doing that? I assume I'd add something to the bottom of this file https://github.com/jcbhmr/llvm-box/blob/get-it-working/llvm/CMakeLists.txt#L1301 like add_custom_target(my_custom_target
DEPENDS
"${CMAKE_CURRENT_BINARY_DIR}/generated_file"
)
add_custom_command(
OUTPUT
"${CMAKE_CURRENT_BINARY_DIR}/generated_file"
COMMENT
"This is generating my custom command"
COMMAND
${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/generated_file
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/source_file
) I got the gist of how to make a cmake custom target thing from this https://dev.to/iblancasa/learning-cmake-3-understanding-addcustomcommand-and-addcustomtarget-43gp |
@pmp-p btw I never thanked you; thank you this answered that question! |
@jcbhmr , I've created the |
Hello! 👋
First, some context: I want to have a C++ => WASM demo that runs in the browser. All the options (list below) seem to be in various states of decay.
My benchmark of "working" is that tool $X can compile this and maybe run it (depending on the tool).
Here's my non-exhaustive list of C++ => WASM things that I found and tried
std::cout
+std::string
test#include <string>
causes it to chokeI am interested in learning more about how this project works in order to (hopefully) get some kind of higher-level API working. #7
How does this project work?
This is the big question that I have. Here's what I've gathered so far. I'd love more input and commentary of how this all works, the pain points, all of it. Tell me everything you tell your rubber ducky. 🦆
Working backwards from the demo:
I also did some digging and found this quote on reddit:
— u/jprendes from I made Emception
The text was updated successfully, but these errors were encountered: