aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js13
-rw-r--r--src/library.js6
-rw-r--r--src/parseTools.js10
-rw-r--r--src/settings.js2
4 files changed, 22 insertions, 9 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index a01b2655..9678a56d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1370,7 +1370,7 @@ function JSify(data, functionsOnly, givenFunctions) {
args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) });
if (ASM_JS) {
- if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced) {
+ if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || funcData.setjmpTable) {
args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) });
} else {
args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) });
@@ -1448,20 +1448,21 @@ function JSify(data, functionsOnly, givenFunctions) {
var sig = Functions.getSignature(returnType, argsTypes, hasVarArgs);
if (ASM_JS) {
assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out)
- if (!byPointerForced) {
+ if (!byPointerForced && !funcData.setjmpTable) {
+ // normal asm function pointer call
callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py
} else {
- // This is a forced call, through an invoke_*.
+ // This is a call through an invoke_*, either a forced one, or a setjmp-required one
// note: no need to update argsTypes at this point
- Functions.unimplementedFunctions[callIdent] = sig;
- args.unshift(byPointerForced ? Functions.getIndex(callIdent) : callIdent);
+ if (byPointerForced) Functions.unimplementedFunctions[callIdent] = sig;
+ args.unshift(byPointerForced ? Functions.getIndex(callIdent) : asmCoercion(callIdent, 'i32'));
callIdent = 'invoke_' + sig;
}
} else if (SAFE_DYNCALLS) {
assert(!ASM_JS, 'cannot emit safe dyncalls in asm');
callIdent = '(tempInt=' + callIdent + ',tempInt < 0 || tempInt >= FUNCTION_TABLE.length-1 || !FUNCTION_TABLE[tempInt] ? abort("dyncall error: ' + sig + ' " + FUNCTION_TABLE_NAMES[tempInt]) : tempInt)';
}
- if (!byPointerForced) callIdent = Functions.getTable(sig) + '[' + callIdent + ']';
+ if (!ASM_JS || (!byPointerForced && !funcData.setjmpTable)) callIdent = Functions.getTable(sig) + '[' + callIdent + ']';
}
var ret = callIdent + '(' + args.join(', ') + ')';
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