summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-emscripten.cpp41
-rw-r--r--test/lit/wasm-emscripten-finalize/em_js.wat20
2 files changed, 34 insertions, 27 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
diff --git a/test/lit/wasm-emscripten-finalize/em_js.wat b/test/lit/wasm-emscripten-finalize/em_js.wat
index 85b3ece89..02fc32bfc 100644
--- a/test/lit/wasm-emscripten-finalize/em_js.wat
+++ b/test/lit/wasm-emscripten-finalize/em_js.wat
@@ -5,7 +5,7 @@
;; All functions should be stripped from the binary, regardless
;; of internal name
-;; CHECK-NOT: (func
+;; CHECK-NOT: (global
;; The data section that contains only em_js strings should
;; be stripped (shrunk to zero size):
@@ -24,18 +24,12 @@
(data (i32.const 1024) "some JS string data\00xxx")
(data (i32.const 512) "Only em_js strings here\00")
(data (i32.const 2048) "more JS string data\00yyy")
- (export "__em_js__foo" (func $__em_js__foo))
- (export "__em_js__bar" (func $bar))
- (export "__em_js__baz" (func $baz))
+ (export "__em_js__foo" (global $__em_js__foo))
+ (export "__em_js__bar" (global $bar))
+ (export "__em_js__baz" (global $baz))
;; Name matches export name
- (func $__em_js__foo (result i32)
- (i32.const 1024)
- )
+ (global $__em_js__foo i32 (i32.const 1024))
;; Name does not match export name
- (func $bar (result i32)
- (i32.const 2048)
- )
- (func $baz (result i32)
- (i32.const 512)
- )
+ (global $bar i32 (i32.const 2048))
+ (global $baz i32 (i32.const 512))
)