summaryrefslogtreecommitdiff
path: root/src/s2wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/s2wasm.h')
-rw-r--r--src/s2wasm.h85
1 files changed, 7 insertions, 78 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h
index 0efe0408e..3cb4c7139 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -253,6 +253,7 @@ class S2WasmBuilder {
return new LinkerObject::Relocation(
kind, target, fixEmLongjmp(cleanFunction(name)), offset);
}
+
Expression* relocationToGetGlobal(LinkerObject::Relocation* relocation) {
if (!relocation) {
return nullptr;
@@ -421,6 +422,7 @@ class S2WasmBuilder {
bool isFunctionName(Name name) {
return !!strstr(name.str, "@FUNCTION");
}
+
// Drop the @ and after it.
Name cleanFunction(Name name) {
if (!strchr(name.str, '@')) return name;
@@ -615,7 +617,7 @@ class S2WasmBuilder {
void parseFuncType() {
auto decl = make_unique<FunctionType>();
- Name rawName = getCommaSeparated();
+ Name name = getCommaSeparated();
skipComma();
if(match("void")) {
decl->result = none;
@@ -627,7 +629,6 @@ class S2WasmBuilder {
decl->name = "FUNCSIG$" + sig;
FunctionType *ty = wasm->getFunctionTypeOrNull(decl->name);
- Name name = fixEmEHSjLjNames(rawName, sig);
if (!ty) {
// The wasm module takes ownership of the FunctionType if we insert it.
// Otherwise it's already in the module and ours is freed.
@@ -979,14 +980,11 @@ class S2WasmBuilder {
if (*s == ',') {
skipComma();
int num = getNumInputs();
- auto inputs = getInputs(num);
- for (int i = 0; i < num; i++) {
- curr->operands.push_back(inputs[i]);
+ for (Expression* input : getInputs(num)) {
+ curr->operands.push_back(input);
}
}
- Name target = linkerObj->resolveAlias(
- fixEmEHSjLjNames(rawTarget, curr->type, curr->operands),
- LinkerObject::Relocation::kFunction);
+ Name target = linkerObj->resolveAlias(rawTarget, LinkerObject::Relocation::kFunction);
curr->target = target;
if (!linkerObj->isFunctionImplemented(target)) {
linkerObj->addUndefinedFunctionCall(curr);
@@ -1447,83 +1445,14 @@ class S2WasmBuilder {
}
}
- // 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.
- template<typename ListType>
- Name fixEmEHSjLjNames(const Name &name, Type result,
- const ListType &operands) {
- return fixEmEHSjLjNames(name, getSig(result, operands));
- }
-
- Name fixEmEHSjLjNames(const Name &name, const std::string& sig) {
- if (name == "emscripten_longjmp_jmpbuf")
- return "emscripten_longjmp";
- return fixEmExceptionInvoke(name, sig);
- }
-
// This version only converts emscripten_longjmp_jmpbuf and does not deal
// with invoke wrappers. This is used when we only have a function name as
// relocatable constant.
- Name fixEmLongjmp(const Name &name) {
+ static Name fixEmLongjmp(const Name &name) {
if (name == "emscripten_longjmp_jmpbuf")
return "emscripten_longjmp";
return name;
}
-
- // 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, const std::string& 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::string sigWoOrigFunc = sig.front() + sig.substr(2, sig.size() - 2);
- return Name("invoke_" + sigWoOrigFunc);
- }
-
};
} // namespace wasm