summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2021-02-18 08:10:02 -0800
committerGitHub <noreply@github.com>2021-02-18 08:10:02 -0800
commitf7bfc85fae3bebf9ff818905c9bc6df51989ce70 (patch)
treecfe41c2e470fb3b93efaf3064cf9b3e1cba10876 /src/wasm
parent3ed396e11f8aa5bd4fd4290eaf2bfbe9b8fbbe9d (diff)
downloadbinaryen-f7bfc85fae3bebf9ff818905c9bc6df51989ce70.tar.gz
binaryen-f7bfc85fae3bebf9ff818905c9bc6df51989ce70.tar.bz2
binaryen-f7bfc85fae3bebf9ff818905c9bc6df51989ce70.zip
Allow em_js strings to be exported as globals (#3577)
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-emscripten.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 99c3216b6..50b4e9b8f 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -409,25 +409,34 @@ struct EmJsWalker : public PostWalker<EmJsWalker> {
EmJsWalker(Module& _wasm) : wasm(_wasm), stringTracker(_wasm) {}
void visitExport(Export* curr) {
- if (curr->kind != ExternalKind::Function) {
+ if (!curr->name.startsWith(EM_JS_PREFIX.str)) {
return;
}
- if (!curr->name.startsWith(EM_JS_PREFIX.str)) {
+
+ int64_t address;
+ if (curr->kind == ExternalKind::Global) {
+ auto* global = wasm.getGlobal(curr->value);
+ Const* const_ = global->init->cast<Const>();
+ address = const_->value.getInteger();
+ } else if (curr->kind == ExternalKind::Function) {
+ auto* func = wasm.getFunction(curr->value);
+ // An EM_JS has a single const in the body. Typically it is just returned,
+ // but in unoptimized code it might be stored to a local and loaded from
+ // there, and in relocatable code it might get added to __memory_base etc.
+ FindAll<Const> consts(func->body);
+ if (consts.list.size() != 1) {
+ Fatal() << "Unexpected generated __em_js__ function body: "
+ << curr->name;
+ }
+ auto* addrConst = consts.list[0];
+ address = addrConst->value.getInteger();
+ } else {
return;
}
+
toRemove.push_back(*curr);
- auto* func = wasm.getFunction(curr->value);
- auto funcName = std::string(curr->name.stripPrefix(EM_JS_PREFIX.str));
- // An EM_JS has a single const in the body. Typically it is just returned,
- // but in unoptimized code it might be stored to a local and loaded from
- // there, and in relocatable code it might get added to __memory_base etc.
- FindAll<Const> consts(func->body);
- if (consts.list.size() != 1) {
- Fatal() << "Unexpected generated __em_js__ function body: " << curr->name;
- }
- auto* addrConst = consts.list[0];
- int64_t address = addrConst->value.getInteger();
auto code = stringTracker.stringAtAddr(address);
+ auto funcName = std::string(curr->name.stripPrefix(EM_JS_PREFIX.str));
codeByName[funcName] = code;
codeAddresses[address] = strlen(code) + 1;
}
@@ -438,8 +447,12 @@ EmJsWalker findEmJsFuncsAndReturnWalker(Module& wasm) {
walker.walkModule(&wasm);
for (const Export& exp : walker.toRemove) {
+ if (exp.kind == ExternalKind::Function) {
+ wasm.removeFunction(exp.value);
+ } else {
+ wasm.removeGlobal(exp.value);
+ }
wasm.removeExport(exp.name);
- wasm.removeFunction(exp.value);
}
// With newer versions of emscripten/llvm we pack all EM_JS strings into