What does EM_ASM do in the code?

94 views
Skip to first unread message

Rick Battagline

unread,
Jun 3, 2019, 2:47:49 PM6/3/19
to emscripten-discuss
I've been compiling with Emscripten, then disassembling with wasm2wat to try and figure out what is happening in the WebAssembly vs. the JavaScript glue code.  I'm trying to figure out what is going on with EM_ASM.  I compiled the following code:

#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
void hello() {
  EM_ASM({
    console.log("hello world!");
  });
}

If there is a typo I apologize, I was working on a different computer and can't copy and paste.  Anyway, I see the console.log call in both the JavaScript glue code and the disassembled WAT. 

Here is what I see in the JavaScript:

var ASM_CONSTS = [function() {console.log("hello world!"); }];

Based on this, I was expecting that function to be passed in through the imports in the WAT, which maybe it is.  But inside the WAT I see this:

(data (; 0 ;) (i32.const 1024) "{ console.log(\22hello world!\22); }"))

That line in the WAT made me think that perhaps the code is being passed from the WebAssembly into a function that uses a JavaScript eval, although I see no evidence of an eval in the JavaScript code.

Would anyone be willing to help me understand what Emscripten is doing here?

Thanks,
Rick

Jacob Gravelle

unread,
Jun 24, 2019, 2:09:02 PM6/24/19
to emscripten-discuss
EM_ASM is morally a JS lambda embedded in C++ code. The way that this works in the toolchain is Deep Magic, one of the consequences of which is needing to store the data of what JS to generate, in a way that survives the LLVM optimizer, and doesn't otherwise interact with the surrounding code. This winds up being generated as a a data section with the string data. It's effectively dead memory, but we can't strip it because we can't know that statically.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/aaa156de-8ee5-4539-8f74-c00f005e5aed%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

J Decker

unread,
Jun 24, 2019, 2:43:59 PM6/24/19
to emscripten-discuss
What is the... scope(?) of the EM_ASM code?  vs say, pre-js or post-js context?

Like... what is the structure of what it can see for variables?
I've put a local object 'this_' on Module so I can definatly access that accross various EM_ASM emissions, but if I understood more about the context/closure stack, maybe I could do something more efficient?


Alon Zakai

unread,
Jun 25, 2019, 11:59:55 AM6/25/19
to emscripte...@googlegroups.com
An EM_ASM/EM_JS becomes a JS function that is called, basically. And that function is emitted somewhere in the JS code, so it can refer to global things there, like HEAP8 etc. It is also optimized with that code if the JS optimizer and/or closure are run.

(It may be helpful to look at the emitted JS, with maybe -O3 -g1 so it's optimized but also has proper whitespace.)

Reply all
Reply to author
Forward
0 new messages