diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-07-24 13:39:25 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-07-24 13:39:25 -0700 |
commit | 6b819b6cb47be5574260dd3a41a32e59de619b71 (patch) | |
tree | 1e84f1ffaecd80ebd8b98556ce2b630d21d1a00b | |
parent | e6e22495e277b0ae62d9732ff86ccfc2529b5706 (diff) |
do invoke_* on LLVM invokes using function pointers; fixes #1423
-rw-r--r-- | src/jsifier.js | 11 | ||||
-rwxr-xr-x | tests/runner.py | 31 |
2 files changed, 37 insertions, 5 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 30cea99b..b377202d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1211,7 +1211,7 @@ function JSify(data, functionsOnly, givenFunctions) { // in an assignment var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST); var phiSets = calcPhiSets(item); - var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone); + var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, true); var ret; @@ -1368,7 +1368,7 @@ function JSify(data, functionsOnly, givenFunctions) { return ret; }); - function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn) { + function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn, invoke) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); @@ -1433,7 +1433,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 || funcData.setjmpTable) { + if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || 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]) }); @@ -1522,7 +1522,8 @@ 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 && !funcData.setjmpTable) { + var functionTableCall = !byPointerForced && !funcData.setjmpTable && !invoke; + if (functionTableCall) { // normal asm function pointer call callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py Functions.neededTables[sig] = 1; @@ -1537,7 +1538,7 @@ function JSify(data, functionsOnly, givenFunctions) { 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 (!ASM_JS || (!byPointerForced && !funcData.setjmpTable)) callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; + if (!ASM_JS || functionTableCall) callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; } var ret = callIdent + '(' + args.join(', ') + ')'; diff --git a/tests/runner.py b/tests/runner.py index 1792b2bf..e16fc12e 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -2969,6 +2969,37 @@ back self.emcc_args.pop() ; self.emcc_args.pop() # disable closure to work around a closure bug self.do_run(src, 'Throw...Construct...Catched...Destruct...Throw...Construct...Copy...Catched...Destruct...Destruct...') + def test_exception_2(self): + if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly') + Settings.DISABLE_EXCEPTION_CATCHING = 0 + src = r''' + #include <stdexcept> + #include <stdio.h> + + typedef void (*FuncPtr)(); + + void ThrowException() + { + throw std::runtime_error("catch me!"); + } + + FuncPtr ptr = ThrowException; + + int main() + { + try + { + ptr(); + } + catch(...) + { + printf("Exception caught successfully!\n"); + } + return 0; + } + ''' + self.do_run(src, 'Exception caught successfully!') + def test_white_list_exception(self): Settings.DISABLE_EXCEPTION_CATCHING = 2 Settings.EXCEPTION_CATCHING_WHITELIST = ["__Z12somefunctionv"] |