Need help with emscripten port


I’ve started ripping code out of the fastcomp patch to see how small it can be while still generating the correct IR.


thanks for keeping this thread updated on the status. the amount of time and effort that’s gone into this is exceedingly non-trivial, so thanks to brson and everyone else who have been steadily working on this over the past many months



The PR landed and there’s some discussion on reddit:

Thanks everyone for the help. This is a great milestone but there’s more to do yet.


Here are two more important improvements to emscripten:

  • This is about delegating all optimization to emcc. Right now we use do our own optimization on LLVM IR and call emcc with the default arguments. emcc though can do better optimizations than rustc here so we should instead have it do all optimizations. This will involve understanding emcc’s optimization options and hacking the rustc backend to pass the right options.
  • Emscripten can remove unwinding from LLVM IR itself, so we can use this feature to remove landing pads from the standard library, so -C panic-runtime=abort will produce optimal code. This will involve modifying the panic_abort crate to pass the appropriate linker options to emcc.


My notes on AsmJs so far:

  • Inline asm!("JavaScript here") is badly needed. Currently the JS is placed in an additional lib.js and the path to it is passed in #[link-args]. This turns from “works” to “ugly” once dependencies are introduced.
  • Exporting function via #[link-args] is already bad for a single binary, and horrible with dependencies. It requires the dependency to publicly export all FFI methods and the final crate to import these into these and declare them in #[link-args]. I guess an attribute on exported functions would be a clean solution for this: #[export, no_mangle] fn test_function(ptr: *const u8, len: usize).
  • Alternatively a way to turn Box<FnMut> into JS objects could be found, eliminating the need to call into AsmJs by exported functions.
  • All my code contains fn main() {}.


What do you need inline Javascript asm for that can’t be solved via a call to emscripten_asm_const_int (like this)?


This doesn’t look too bad. Definitely need to try this out! Thanks @cramertj.


Glad I could help!


Does it work for you? It makes my llc generate an infinite number of the following line:

 var $11 = ;


Nope, doesn’t do that for me. It works fine.


What is the recommended way to integrate cargo and --target=wasm32-unknown-emscripten? I can get it to work as long as I don’t try to export any functions to js land. Once I do I get one kind of erro or another ex:

“”“ cargo rustc --target=wasm32-unknown-emscripten – -Clink-args=”-s EXPORTED_FUNCTIONS=[’_print_hash’]“ error: extra arguments to rustc can only be passed to one target, consider filtering ”""


“”“ error: the link_args attribute is not portable across platforms, it is recommended to use #[link(name = "foo")] instead (see issue #29596) ”""


I know that using a #[link_args = …] should work, see Call from JavaScript


If I use the #[link_args I the error “error: the link_args attribute is not portable across platforms, it is recommended to use #[link(name = “foo”)] instead (see issue #29596)”


If you’re using nightly, you don’t need any kind of link_args tricks anymore, just mark your function with extern and #[no_mangle] as you would for exporting it to C.


nice, is there a way to import/link custom JS functions? -- -Clink_args "--js-library '$path_to_js_file'" should do it, but how can i set that argument from a cargo/rust dependency? I was trying to set it from the build script and by setting rustflags from the toml file (but was getting an error: linker arguments only allowed in the main project due to compatibility issues or something)


@chpio No, you can’t use JS functions directly from native code (even compiled to wasm). --js-library is a different thing that needs to be specifically crafted for Emscripten to understand.


I should have explained my use case: i have a rust crate, which should do “platform independent” stuff, calculating diff values of two lists in my case, which is done in rust. But i also need “platform dependent” code, in my case: applying the diffs onto the dom (im developing a react.js-kind of thing for rust; it’s very POC). So im bundling rust-code and “native” js-code into one crate.

Im doing it right now by patching emscripten, so it accepts emscriptens-js-library scripts being passed by -l and -L arguments. So it behaves on emscriptens-js-library files like they were .a or ‘.o’ files (rustc only allows the -l and -L being passed by a depended crate).

That’s the way im doing it right now, but maybe there is already a way to do this (bundle rust + js code in a depended crate) im not aware of?!

ps: sorry for my english :expressionless:


I’ve heard that emscripten is getting pressure to go ahead with their LLVM 4 upgrade before the Rust upgrade is complete.

This will likely happen, and the outcome for us is that it will invalidate all existing instructions for installing emscripten with Rust - the ‘incoming’ branch of their SDK will not be compatible with Rust master, and instead Rust users will need to install a particular point release.

Can anybody confirm and post working instructions for using Rust with the latest point release? My intent will be to disseminate that info as widely as we can, give emscripten the go-ahead, then deal with the fallout.


While I’m thinking about it, I came up with a seemingly good use case for wasm over the weekend, but don’t expect I can carry the project to completion, if somebody else wanted to.

This blog post laid out simple rules for validating the complexity of passwords, and one if it’s biggest points is that people should deny users the ability to use known common passwords. Basically, these days it is best practice to use the many leaked password lists as a blacklist, since users employing these passwords are trivially targeted.

So the idea here is to take the fst crate and encode that giant password list into a hopefully small FST, and do the search fast and compactly. Create a C interface so anybody can use it server-side, then bind that C interface to a JS interface via wasm so anybody can use it client-side. Package it up to produce builds for common platforms and do a ‘Show HN’ to get some karma.

I did a prototype over the weekend but seems likely won’t get much farther any time soon:


It still works with a released Emscripten version. So we just need to point to which version that is (my local install is v1.37.5, which works for latests Rust stable/nightly just fine)