summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/GenerateDynCalls.cpp3
-rw-r--r--src/passes/PostEmscripten.cpp18
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp2
-rw-r--r--src/wasm/wasm-emscripten.cpp130
4 files changed, 3 insertions, 150 deletions
diff --git a/src/passes/GenerateDynCalls.cpp b/src/passes/GenerateDynCalls.cpp
index 8269f6f78..08c8c0ac7 100644
--- a/src/passes/GenerateDynCalls.cpp
+++ b/src/passes/GenerateDynCalls.cpp
@@ -55,7 +55,8 @@ struct GenerateDynCalls : public WalkerPass<PostWalker<GenerateDynCalls>> {
void visitFunction(Function* func) {
// Generate dynCalls for invokes
- if (func->imported() && func->base.startsWith("invoke_")) {
+ if (func->imported() && func->module == ENV &&
+ func->base.startsWith("invoke_")) {
Signature sig = func->sig;
// The first parameter is a pointer to the original function that's called
// by the invoke, so skip it
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp
index 0c7521afc..eea7a1a34 100644
--- a/src/passes/PostEmscripten.cpp
+++ b/src/passes/PostEmscripten.cpp
@@ -78,9 +78,6 @@ struct OptimizeCalls : public WalkerPass<PostWalker<OptimizeCalls>> {
struct PostEmscripten : public Pass {
void run(PassRunner* runner, Module* module) override {
- // Optimize imports
- optimizeImports(runner, module);
-
// Optimize calls
OptimizeCalls().run(runner, module);
@@ -88,21 +85,6 @@ struct PostEmscripten : public Pass {
optimizeExceptions(runner, module);
}
- void optimizeImports(PassRunner* runner, Module* module) {
- // Calling emscripten_longjmp_jmpbuf is the same as emscripten_longjmp.
- Name EMSCRIPTEN_LONGJMP("emscripten_longjmp");
- Name EMSCRIPTEN_LONGJMP_JMPBUF("emscripten_longjmp_jmpbuf");
- ImportInfo info(*module);
- auto* emscripten_longjmp =
- info.getImportedFunction(ENV, EMSCRIPTEN_LONGJMP);
- auto* emscripten_longjmp_jmpbuf =
- info.getImportedFunction(ENV, EMSCRIPTEN_LONGJMP_JMPBUF);
- if (emscripten_longjmp && emscripten_longjmp_jmpbuf) {
- // Both exist, so it is worth renaming so that we have only one.
- emscripten_longjmp_jmpbuf->base = EMSCRIPTEN_LONGJMP;
- }
- }
-
// Optimize exceptions (and setjmp) by removing unnecessary invoke* calls.
// An invoke is a call to JS with a function pointer; JS does a try-catch
// and calls the pointer, catching and reporting any error. If we know no
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index b98e957da..e35c3ea7b 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -259,8 +259,6 @@ int main(int argc, const char* argv[]) {
generator.onlyI64DynCalls = onlyI64DynCalls;
generator.noDynCalls = noDynCalls;
- generator.fixInvokeFunctionNames();
-
std::vector<Name> initializerFunctions;
// The wasm backend emits "__indirect_function_table" as the import name for
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 0406ebcb6..dec824331 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -487,134 +487,6 @@ EmJsWalker fixEmJsFuncsAndReturnWalker(Module& wasm) {
return walker;
}
-// Fixes function name hacks caused by LLVM exception & setjmp/longjmp
-// handling pass for wasm.
-// This does two things:
-// 1. Change emscripten_longjmp_jmpbuf to emscripten_longjmp.
-// In setjmp/longjmp handling pass in wasm backend, what we want to do is
-// to change all function calls to longjmp to calls to emscripten_longjmp.
-// Because we replace all calls to longjmp to emscripten_longjmp, the
-// signature of that function should be the same as longjmp:
-// emscripten_longjmp(jmp_buf, int)
-// But after calling a function that might longjmp, while we test whether
-// a longjmp occurred, we have to load an int address value and call
-// emscripten_longjmp again with that address as the first argument. (Refer
-// to lib/Target/WebAssembly/WebAssemblyEmscriptenEHSjLj.cpp in LLVM for
-// details.)
-// In this case we need the signature of emscripten_longjmp to be (int,
-// int). So we need two different kinds of emscripten_longjmp signatures in
-// LLVM IR. Both signatures will be lowered to (int, int) eventually, but
-// in LLVM IR, types are not lowered yet.
-// So we declare two functions in LLVM:
-// emscripten_longjmp_jmpbuf(jmp_buf, int)
-// emscripten_longjmp(int, int)
-// And we change the name of emscripten_longjmp_jmpbuf to
-// emscripten_longjmp here.
-// 2. Converts invoke wrapper names.
-// Refer to the comments in fixEmExceptionInvoke below.
-struct FixInvokeFunctionNamesWalker
- : public PostWalker<FixInvokeFunctionNamesWalker> {
- Module& wasm;
- std::vector<Name> toRemove;
- std::map<Name, Name> importRenames;
- std::map<Name, Name> functionRenames;
- std::set<Signature> invokeSigs;
- ImportInfo imports;
-
- FixInvokeFunctionNamesWalker(Module& _wasm) : wasm(_wasm), imports(wasm) {}
-
- // Converts invoke wrapper names generated by LLVM backend to real invoke
- // wrapper names that are expected by JavaScript glue code.
- // This is required to support wasm exception handling (asm.js style).
- //
- // LLVM backend lowers
- // invoke @func(arg1, arg2) to label %invoke.cont unwind label %lpad
- // into
- // ... (some code)
- // call @invoke_SIG(func, arg1, arg2)
- // ... (some code)
- // SIG is a mangled string generated based on the LLVM IR-level function
- // signature. In LLVM IR, types are not lowered yet, so this mangling scheme
- // simply takes LLVM's string representtion of parameter types and concatenate
- // them with '_'. For example, the name of an invoke wrapper for function
- // void foo(struct mystruct*, int) will be
- // "__invoke_void_%struct.mystruct*_int".
- // This function converts the names of invoke wrappers based on their lowered
- // argument types and a return type. In the example above, the resulting new
- // wrapper name becomes "invoke_vii".
- Name fixEmExceptionInvoke(const Name& name, Signature sig) {
- std::string nameStr = name.c_str();
- if (nameStr.front() == '"' && nameStr.back() == '"') {
- nameStr = nameStr.substr(1, nameStr.size() - 2);
- }
- if (nameStr.find("__invoke_") != 0) {
- return name;
- }
-
- std::vector<Type> newParams(sig.params.begin() + 1, sig.params.end());
- Signature sigWoOrigFunc = Signature(Type(newParams), sig.results);
- invokeSigs.insert(sigWoOrigFunc);
- return Name("invoke_" +
- getSig(sigWoOrigFunc.results, sigWoOrigFunc.params));
- }
-
- void visitFunction(Function* curr) {
- if (!curr->imported()) {
- return;
- }
-
- Name newname = fixEmExceptionInvoke(curr->base, curr->sig);
- if (newname == curr->base) {
- return;
- }
-
- BYN_TRACE("renaming import: " << curr->module << "." << curr->base << " ("
- << curr->name << ") -> " << newname << "\n");
-
- if (auto* f = imports.getImportedFunction(curr->module, newname)) {
- BYN_TRACE("remove redundant import: " << curr->base << "\n");
- toRemove.push_back(curr->name);
- // Make sure the existing import has the correct internal name.
- if (f->name != newname) {
- functionRenames[f->name] = newname;
- }
- } else {
- BYN_TRACE("rename import: " << curr->base << "\n");
- curr->base = newname;
- }
-
- functionRenames[curr->name] = newname;
-
- // Ensure that an imported functions of this name exists.
- importRenames[curr->base] = newname;
- }
-
- void visitModule(Module* curr) {
- for (auto name : toRemove) {
- wasm.removeFunction(name);
- }
-
- // Rename all uses of the old function to the new import name
- ModuleUtils::renameFunctions(wasm, functionRenames);
-
- // For imports that for renamed, update any associated GOT.func imports.
- for (auto& pair : importRenames) {
- BYN_TRACE("looking for: GOT.func." << pair.first << "\n");
- if (auto g = imports.getImportedGlobal("GOT.func", pair.first)) {
- BYN_TRACE("renaming corresponding GOT entry: " << g->base << " -> "
- << pair.second << "\n");
- g->base = pair.second;
- }
- }
- }
-};
-
-void EmscriptenGlueGenerator::fixInvokeFunctionNames() {
- BYN_TRACE("fixInvokeFunctionNames\n");
- FixInvokeFunctionNamesWalker walker(wasm);
- walker.walkModule(&wasm);
-}
-
void printSignatures(std::ostream& o, const std::set<Signature>& c) {
o << "[";
bool first = true;
@@ -746,7 +618,7 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
meta << " \"invokeFuncs\": [";
commaFirst = true;
ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {
- if (import->base.startsWith("invoke_")) {
+ if (import->module == ENV && import->base.startsWith("invoke_")) {
if (invokeFuncs.insert(import->base.str).second) {
meta << nextElement() << '"' << import->base.str << '"';
}