aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-10-06 17:44:06 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-10-06 17:44:06 -0700
commit332325394c20bb4a3972344144803fcd93476b08 (patch)
treefeddd1057f85282d2c60fd97d5a0529fa0b18048
parentc1dd12998fd862010c7c11e6fa9d003521923a3c (diff)
make EM_ASM use strings on the heap, so it works in asm, and cache the generated functions
-rw-r--r--src/library.js9
-rw-r--r--system/include/emscripten/emscripten.h10
-rw-r--r--tests/test_core.py25
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')