From f7bfc85fae3bebf9ff818905c9bc6df51989ce70 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 18 Feb 2021 08:10:02 -0800 Subject: Allow em_js strings to be exported as globals (#3577) --- src/wasm/wasm-emscripten.cpp | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src') 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(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(); + 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 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 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 -- cgit v1.2.3