diff options
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 41 | ||||
-rw-r--r-- | test/lit/wasm-emscripten-finalize/em_js.wat | 20 |
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)) ) |