aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js6
-rw-r--r--src/parseTools.js10
-rw-r--r--src/settings.js2
-rwxr-xr-xtests/runner.py16
4 files changed, 31 insertions, 3 deletions
diff --git a/src/library.js b/src/library.js
index 939da8b1..91270c38 100644
--- a/src/library.js
+++ b/src/library.js
@@ -6220,6 +6220,7 @@ LibraryManager.library = {
saveSetjmp__asm: true,
saveSetjmp__sig: 'iii',
+ saveSetjmp__deps: ['putchar'],
saveSetjmp: function(env, label, table) {
// Not particularly fast: slow table lookup of setjmpId to label. But setjmp
// prevents relooping anyhow, so slowness is to be expected. And typical case
@@ -6233,7 +6234,7 @@ LibraryManager.library = {
#endif
setjmpId = (setjmpId+1)|0;
{{{ makeSetValueAsm('env', '0', 'setjmpId', 'i32') }}};
- while ((i|0) < {{{ MAX_SETJMPS }}}) {
+ while ((i|0) < {{{ 2*MAX_SETJMPS }}}) {
if ({{{ makeGetValueAsm('table', 'i*4', 'i32') }}} == 0) {
{{{ makeSetValueAsm('table', 'i*4', 'setjmpId', 'i32') }}};
{{{ makeSetValueAsm('table', 'i*4+4', 'label', 'i32') }}};
@@ -6243,7 +6244,8 @@ LibraryManager.library = {
}
i = (i+2)|0;
}
- abort(987); // if you hit this, adjust MAX_SETJMPS
+ {{{ makePrintChars('too many setjmps in a function call, build with a higher value for MAX_SETJMPS') }}};
+ abort(0);
return 0;
},
diff --git a/src/parseTools.js b/src/parseTools.js
index 2eb456f1..fe21dfd5 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -2363,3 +2363,13 @@ function getTypeFromHeap(suffix) {
}
}
+// Generates code that prints without printf(), but just putchar (so can be directly inline)
+function makePrintChars(s) {
+ var ret = '';
+ for (var i = 0; i < s.length; i++) {
+ ret += '_putchar(' + s.charCodeAt(i) + ');';
+ }
+ ret += '_putchar(10);';
+ return ret;
+}
+
diff --git a/src/settings.js b/src/settings.js
index 7cd0c02e..d30db173 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -55,7 +55,7 @@ var ALLOW_MEMORY_GROWTH = 0; // If false, we abort with an error if we try to al
// that case we must be careful about optimizations, in particular the
// eliminator). Note that memory growth is only supported with typed
// arrays.
-var MAX_SETJMPS = 10; // size of setjmp table allocated in each function invocation (that has setjmp)
+var MAX_SETJMPS = 20; // size of setjmp table allocated in each function invocation (that has setjmp)
// Code embetterments
var MICRO_OPTS = 1; // Various micro-optimizations, like nativizing variables
diff --git a/tests/runner.py b/tests/runner.py
index 811d32a5..2e01226f 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2489,6 +2489,22 @@ Calling longjmp the second time!
Exception execution path of first function! 1
''')
+ def test_setjmp_many(self):
+ src = r'''
+ #include <stdio.h>
+ #include <setjmp.h>
+
+ int main(int argc) {
+ jmp_buf buf;
+ for (int i = 0; i < NUM; i++) printf("%d\n", setjmp(buf));
+ if (argc-- == 1131) longjmp(buf, 11);
+ return 0;
+ }
+ '''
+ for num in [Settings.MAX_SETJMPS, Settings.MAX_SETJMPS+1]:
+ print num
+ self.do_run(src.replace('NUM', str(num)), '0\n' * num if num <= Settings.MAX_SETJMPS or not Settings.ASM_JS else 'build with a higher value for MAX_SETJMPS')
+
def test_exceptions(self):
if Settings.QUANTUM_SIZE == 1: return self.skip("we don't support libcxx in q1")
if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly')