diff options
| author | Guanzhong Chen <gzchen@google.com> | 2019-08-16 18:21:08 +0000 |
|---|---|---|
| committer | Guanzhong Chen <gzchen@google.com> | 2019-08-16 18:21:08 +0000 |
| commit | b1cb9fd1aaf0f6d824812ba47ac1d58a6f6961e3 (patch) | |
| tree | d2059eba5c6feed51ee5640e366917d59cc0989c | |
| parent | 63b78b678bc2b7739ca5b1ddffbd3d4f7a4f6270 (diff) | |
| download | bcm5719-llvm-b1cb9fd1aaf0f6d824812ba47ac1d58a6f6961e3.tar.gz bcm5719-llvm-b1cb9fd1aaf0f6d824812ba47ac1d58a6f6961e3.zip | |
[WebAssembly] Forbid use of EM_ASM with setjmp/longjmp
Summary:
We tried to support EM_ASM with setjmp/longjmp in binaryen. But with dynamic
linking thrown into the mix, the code is no longer understandable and cannot
be maintained. We also discovered more bugs in the EM_ASM handling code.
To ensure maintainability and correctness of the binaryen code, EM_ASM will
no longer be supported with setjmp/longjmp. This is probably fine since the
support was added recently and haven't be published.
Reviewers: tlively, sbc100, jgravelle-google, kripken
Reviewed By: tlively, kripken
Subscribers: dschuff, hiraditya, aheejin, sunfish, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66356
llvm-svn: 369137
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index 53aede41213..568382bac15 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -274,6 +274,7 @@ class WebAssemblyLowerEmscriptenEHSjLj final : public ModulePass { bool areAllExceptionsAllowed() const { return EHWhitelistSet.empty(); } bool canLongjmp(Module &M, const Value *Callee) const; + bool isEmAsmCall(Module &M, const Value *Callee) const; void rebuildSSA(Function &F); @@ -537,6 +538,23 @@ bool WebAssemblyLowerEmscriptenEHSjLj::canLongjmp(Module &M, return true; } +bool WebAssemblyLowerEmscriptenEHSjLj::isEmAsmCall(Module &M, + const Value *Callee) const { + // This is an exhaustive list from Emscripten's <emscripten/em_asm.h>. + Function *EmAsmConstIntF = M.getFunction("emscripten_asm_const_int"); + Function *EmAsmConstDoubleF = M.getFunction("emscripten_asm_const_double"); + Function *EmAsmConstIntSyncMainF = + M.getFunction("emscripten_asm_const_int_sync_on_main_thread"); + Function *EmAsmConstDoubleSyncMainF = + M.getFunction("emscripten_asm_const_double_sync_on_main_thread"); + Function *EmAsmConstAsyncMainF = + M.getFunction("emscripten_asm_const_async_on_main_thread"); + + return Callee == EmAsmConstIntF || Callee == EmAsmConstDoubleF || + Callee == EmAsmConstIntSyncMainF || + Callee == EmAsmConstDoubleSyncMainF || Callee == EmAsmConstAsyncMainF; +} + // Generate testSetjmp function call seqence with preamble and postamble. // The code this generates is equivalent to the following JavaScript code: // if (%__THREW__.val != 0 & threwValue != 0) { @@ -983,6 +1001,12 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) { const Value *Callee = CI->getCalledValue(); if (!canLongjmp(M, Callee)) continue; + if (isEmAsmCall(M, Callee)) + report_fatal_error("Cannot use EM_ASM* alongside setjmp/longjmp in " + + F.getName() + + ". Please consider using EM_JS, or move the " + "EM_ASM into another function.", + false); Value *Threw = nullptr; BasicBlock *Tail; |

