summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuanzhong Chen <gzchen@google.com>2019-08-16 18:21:08 +0000
committerGuanzhong Chen <gzchen@google.com>2019-08-16 18:21:08 +0000
commitb1cb9fd1aaf0f6d824812ba47ac1d58a6f6961e3 (patch)
treed2059eba5c6feed51ee5640e366917d59cc0989c
parent63b78b678bc2b7739ca5b1ddffbd3d4f7a4f6270 (diff)
downloadbcm5719-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.cpp24
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;
OpenPOWER on IntegriCloud