aboutsummaryrefslogtreecommitdiff
path: root/src/jsifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsifier.js')
-rw-r--r--src/jsifier.js22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index a01b2655..30a06d76 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -487,7 +487,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else if (LibraryManager.library.hasOwnProperty(shortident)) {
item.JS = addFromLibrary(shortident);
} else if (!LibraryManager.library.hasOwnProperty(shortident + '__inline')) {
- if (!(item.ident in DEAD_FUNCTIONS) && !UNRESOLVED_AS_DEAD) {
+ if (!(item.ident in DEAD_FUNCTIONS)) {
item.JS = 'var ' + item.ident + '; // stub for ' + item.ident;
if (ASM_JS) {
error('Unresolved symbol: ' + item.ident + ', this must be corrected for asm.js validation to succeed. Consider adding it to DEAD_FUNCTIONS.');
@@ -713,6 +713,7 @@ function JSify(data, functionsOnly, givenFunctions) {
} else {
ret += 'var setjmpLabel = 0;\n';
ret += 'var setjmpTable = ' + RuntimeGenerator.stackAlloc(4 * (MAX_SETJMPS + 1) * 2) + ';\n';
+ ret += makeSetValue('setjmpTable', '0', '0', 'i32') + ';'; // initialize first entry to 0
}
}
ret += indent + 'while(1) ';
@@ -1370,7 +1371,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]) });
@@ -1441,6 +1442,10 @@ function JSify(data, functionsOnly, givenFunctions) {
if (callIdent in DEAD_FUNCTIONS) {
var ret = 'abort(' + DEAD_FUNCTIONS[callIdent] + ')';
if (ASM_JS) ret = asmCoercion(ret, returnType);
+ if (ASSERTIONS) {
+ assert(DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.indexOf('putchar') >= 0, 'need putchar for DEAD_FUNCTIONS + ASSERTIONS output');
+ ret = '(' + makePrintChars('dead:' + callIdent, ',') + ',' + ret + ')';
+ }
return ret;
}
@@ -1448,20 +1453,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(', ') + ')';
@@ -1475,7 +1481,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (ASM_JS && funcData.setjmpTable) {
// check if a longjmp was done. If a setjmp happened, check if ours. If ours, go to -111 to handle it.
// otherwise, just return - the call to us must also have been an invoke, so the setjmp propagates that way
- ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) > 0)) { setjmpLabel = _testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable); if ((setjmpLabel|0) > 0) { label = -1111; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
+ ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) > 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = -1111; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
}
return ret;