diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-10-06 17:44:06 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-10-06 17:44:06 -0700 |
commit | 332325394c20bb4a3972344144803fcd93476b08 (patch) | |
tree | feddd1057f85282d2c60fd97d5a0529fa0b18048 | |
parent | c1dd12998fd862010c7c11e6fa9d003521923a3c (diff) |
make EM_ASM use strings on the heap, so it works in asm, and cache the generated functions
-rw-r--r-- | src/library.js | 9 | ||||
-rw-r--r-- | system/include/emscripten/emscripten.h | 10 | ||||
-rw-r--r-- | tests/test_core.py | 25 |
3 files changed, 31 insertions, 13 deletions
diff --git a/src/library.js b/src/library.js index 48f613e0..5e71b087 100644 --- a/src/library.js +++ b/src/library.js @@ -8613,6 +8613,15 @@ LibraryManager.library = { Runtime.stackAlloc(-4*i); // free up the stack space we know is ok to free }, + emscripten_asm_const: function(code) { + // code is a constant string on the heap, so we can cache these + if (!Runtime.asmConstCache) Runtime.asmConstCache = {}; + var func = Runtime.asmConstCache[code]; + if (func) return func(); + func = Runtime.asmConstCache[code] = eval('(function(){ ' + Pointer_stringify(code) + ' })'); // new Function does not allow upvars in node + return func(); + }, + //============================ // i64 math //============================ diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h index 430fbc1c..d30620ec 100644 --- a/system/include/emscripten/emscripten.h +++ b/system/include/emscripten/emscripten.h @@ -23,10 +23,13 @@ extern "C" { * * EM_ASM(window.alert('hai')); * + * This also works with asm.js, as it outlines the code (it + * does a function call to reach it). + * * Note: double-quotes (") are not supported, but you can use * single-quotes (') in js anyhow. */ -#define EM_ASM(...) asm(#__VA_ARGS__) +#define EM_ASM(...) emscripten_asm_const(#__VA_ARGS__) /* * Forces LLVM to not dead-code-eliminate a function. Note that @@ -376,6 +379,8 @@ int emscripten_get_worker_queue_size(worker_handle worker); #define EMSCRIPTEN_NETWORK_WEBRTC 1 void emscripten_set_network_backend(int backend); +/* Internal APIs. Be careful with these. */ + /* * Profiling tools. * INIT must be called first, with the maximum identifier that @@ -413,6 +418,9 @@ void emscripten_jcache_printf(const char *format, ...); void emscripten_jcache_printf_(...); /* internal use */ #endif +/* Helper API for EM_ASM - do not call this yourself */ +void emscripten_asm_const(const char *code); + #ifdef __cplusplus } #endif diff --git a/tests/test_core.py b/tests/test_core.py index 80933937..b4668584 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3841,25 +3841,26 @@ def process(filename): self.do_run(src, '4\n200\ndone\n') def test_inlinejs3(self): - if Settings.ASM_JS: return self.skip('asm does not support random code, TODO: something that works in asm') - src = r''' - #include <stdio.h> - #include <emscripten.h> + src = r''' + #include <stdio.h> + #include <emscripten.h> - int main() { - EM_ASM(Module.print('hello dere1')); - EM_ASM( - Module.print('hello dere2'); - ); + int main() { + EM_ASM(Module.print('hello dere1')); + EM_ASM( + Module.print('hello dere2'); + ); + for (int i = 0; i < 3; i++) { EM_ASM( Module.print('hello dere3'); Module.print('hello dere' + 4); ); - return 0; } - ''' + return 0; + } + ''' - self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\n') + self.do_run(src, 'hello dere1\nhello dere2\nhello dere3\nhello dere4\nhello dere3\nhello dere4\nhello dere3\nhello dere4\n') def test_memorygrowth(self): if Settings.USE_TYPED_ARRAYS == 0: return self.skip('memory growth is only supported with typed arrays') |