diff options
author | Sam Clegg <sbc@chromium.org> | 2022-08-07 07:08:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-07 07:08:28 -0700 |
commit | 680e4ecb581dd29947ecbaf3fb11817c187c30c9 (patch) | |
tree | 38b4fd822f5335d71be37eef5cff6c8003dd6059 /src | |
parent | da916dbae19d213321225da2658423c09b85205b (diff) | |
download | binaryen-680e4ecb581dd29947ecbaf3fb11817c187c30c9.tar.gz binaryen-680e4ecb581dd29947ecbaf3fb11817c187c30c9.tar.bz2 binaryen-680e4ecb581dd29947ecbaf3fb11817c187c30c9.zip |
Remove metadata generation from wasm-emscripten-finalize (#4863)
This is no longer needed by emscripten as of:
https://github.com/emscripten-core/emscripten/pull/16529
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 34 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 236 |
3 files changed, 3 insertions, 269 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index b4e27ca5c..99d03cec0 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -47,7 +47,6 @@ int main(int argc, const char* argv[]) { std::string outputSourceMapUrl; std::string dataSegmentFile; bool emitBinary = true; - bool emitMetadata = true; bool debugInfo = false; bool DWARF = false; bool sideModule = false; @@ -95,13 +94,6 @@ int main(int argc, const char* argv[]) { WasmEmscriptenFinalizeOption, Options::Arguments::Zero, [&emitBinary](Options*, const std::string&) { emitBinary = false; }) - .add( - "--no-emit-metadata", - "-n", - "Skip the writing to emscripten metadata JSON to stdout.", - WasmEmscriptenFinalizeOption, - Options::Arguments::Zero, - [&emitMetadata](Options*, const std::string&) { emitMetadata = false; }) .add("--global-base", "", "The address at which static globals were placed", @@ -228,9 +220,8 @@ int main(int argc, const char* argv[]) { options.applyFeatures(wasm); ModuleReader reader; // If we are not writing output then we definitely don't need to read debug - // info, as it does not affect the metadata we will emit. (However, if we - // emit output then definitely load the names section so that we roundtrip - // names properly.) + // info. However, if we emit output then definitely load the names section so + // that we roundtrip names properly. reader.setDebugInfo(writeOutput); reader.setDWARF(DWARF && writeOutput); if (!writeOutput) { @@ -296,7 +287,6 @@ int main(int argc, const char* argv[]) { : ABI::LegalizationLevel::Minimal)); } - // Strip target features section (its information is in the metadata) passRunner.add("strip-target-features"); // If DWARF is unused, strip it out. This avoids us keeping it alive @@ -307,15 +297,7 @@ int main(int argc, const char* argv[]) { passRunner.run(); - BYN_TRACE("generated metadata\n"); - // Substantial changes to the wasm are done, enough to create the metadata. - std::string metadata; - if (emitMetadata) { - metadata = generator.generateEmscriptenMetadata(); - } - - // Finally, separate out data segments if relevant (they may have been needed - // for metadata). + // Finally, separate out data segments if relevant if (!dataSegmentFile.empty()) { Output memInitFile(dataSegmentFile, Flags::Binary); if (globalBase == INVALID_BASE) { @@ -338,16 +320,6 @@ int main(int argc, const char* argv[]) { writer.setSourceMapUrl(outputSourceMapUrl); } writer.write(wasm, output); - if (emitMetadata && !emitBinary) { - output << "(;\n"; - output << "--BEGIN METADATA --\n" << metadata << "-- END METADATA --\n"; - output << ";)\n"; - } - } - // If we emit text then we emitted the metadata together with that text - // earlier. Otherwise emit it to stdout. - if (emitMetadata && emitBinary) { - std::cout << metadata; } return 0; } diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index 694eb1368..4d20b8706 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -33,8 +33,6 @@ public: : wasm(wasm), builder(wasm), stackPointerOffset(stackPointerOffset), useStackPointerGlobal(stackPointerOffset == 0) {} - std::string generateEmscriptenMetadata(); - void fixInvokeFunctionNames(); // Emits the data segments to a file. The file contains data from address base diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index f143310ce..0bc74580d 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -188,242 +188,6 @@ struct AsmConst { std::string code; }; -static Address getExportedAddress(Module& wasm, Export* export_) { - Global* g = wasm.getGlobal(export_->value); - auto* addrConst = g->init->dynCast<Const>(); - return addrConst->value.getUnsigned(); -} - -static std::vector<AsmConst> findEmAsmConsts(Module& wasm, - bool minimizeWasmChanges) { - // Newer version of emscripten/llvm export these symbols so we can use them to - // find all the EM_ASM constants. Sadly __start_em_asm and __stop_em_asm - // don't alwasy mark the start and end of segment because in dynamic linking - // we merge all data segments into one. - Export* start = wasm.getExportOrNull("__start_em_asm"); - Export* end = wasm.getExportOrNull("__stop_em_asm"); - if (!start && !end) { - BYN_TRACE("findEmAsmConsts: no start/stop symbols\n"); - return {}; - } - - if (!start || !end) { - Fatal() << "Found only one of __start_em_asm and __stop_em_asm"; - } - - StringConstantTracker stringTracker(wasm); - Address startAddress = getExportedAddress(wasm, start); - Address endAddress = getExportedAddress(wasm, end); - for (Index i = 0; i < wasm.dataSegments.size(); i++) { - Address segmentStart = stringTracker.segmentOffsets[i]; - size_t segmentSize = wasm.dataSegments[i]->data.size(); - if (segmentStart <= startAddress && - segmentStart + segmentSize >= endAddress) { - std::vector<AsmConst> asmConsts; - Address address = startAddress; - while (address < endAddress) { - auto code = stringTracker.stringAtAddr(address); - asmConsts.push_back({address, code}); - address.addr += strlen(code) + 1; - } - assert(asmConsts.size()); - return asmConsts; - } - } - Fatal() << "Segment data not found between symbols __start_em_asm and " - "__stop_em_asm"; -} - -struct EmJsWalker : public PostWalker<EmJsWalker> { - Module& wasm; - StringConstantTracker stringTracker; - - std::map<std::string, std::string> codeByName; - - EmJsWalker(Module& _wasm) : wasm(_wasm), stringTracker(_wasm) {} - - void visitExport(Export* curr) { - if (!curr->name.startsWith(EM_JS_PREFIX.str)) { - return; - } - - Address address; - if (curr->kind == ExternalKind::Global) { - auto* global = wasm.getGlobal(curr->value); - Const* const_ = global->init->cast<Const>(); - address = const_->value.getUnsigned(); - } 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.getUnsigned(); - } else { - return; - } - - auto code = stringTracker.stringAtAddr(address); - auto funcName = std::string(curr->name.stripPrefix(EM_JS_PREFIX.str)); - codeByName[funcName] = code; - } -}; - -EmJsWalker findEmJsFuncsAndReturnWalker(Module& wasm) { - EmJsWalker walker(wasm); - walker.walkModule(&wasm); - return walker; -} - -std::string EmscriptenGlueGenerator::generateEmscriptenMetadata() { - bool commaFirst; - auto nextElement = [&commaFirst]() { - if (commaFirst) { - commaFirst = false; - return "\n "; - } else { - return ",\n "; - } - }; - - std::stringstream meta; - meta << "{\n"; - - std::vector<AsmConst> asmConsts = findEmAsmConsts(wasm, minimizeWasmChanges); - - // print - commaFirst = true; - if (!asmConsts.empty()) { - meta << " \"asmConsts\": {"; - for (auto& asmConst : asmConsts) { - meta << nextElement(); - meta << '"' << asmConst.id << "\": \"" << escape(asmConst.code) << "\""; - } - meta << "\n },\n"; - } - - EmJsWalker emJsWalker = findEmJsFuncsAndReturnWalker(wasm); - if (!emJsWalker.codeByName.empty()) { - meta << " \"emJsFuncs\": {"; - commaFirst = true; - for (auto& [name, code] : emJsWalker.codeByName) { - meta << nextElement(); - meta << '"' << name << "\": \"" << escape(code) << '"'; - } - meta << "\n },\n"; - } - - // Avoid adding duplicate imports to `declares' or `invokeFuncs`. Even - // though we might import the same function multiple times (i.e. with - // different sigs) we only need to list is in the metadata once. - std::set<std::string> declares; - std::set<std::string> invokeFuncs; - - // We use the `base` rather than the `name` of the imports here and below - // becasue this is the externally visible name that the embedder (JS) will - // see. - meta << " \"declares\": ["; - commaFirst = true; - ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { - if (emJsWalker.codeByName.count(import->base.str) == 0 && - !import->base.startsWith("invoke_")) { - if (declares.insert(import->base.str).second) { - meta << nextElement() << '"' << import->base.str << '"'; - } - } - }); - meta << "\n ],\n"; - - meta << " \"globalImports\": ["; - commaFirst = true; - ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) { - meta << nextElement() << '"' << import->base.str << '"'; - }); - meta << "\n ],\n"; - - if (!wasm.exports.empty()) { - meta << " \"exports\": ["; - commaFirst = true; - for (const auto& ex : wasm.exports) { - if (ex->kind == ExternalKind::Function || ex->kind == ExternalKind::Tag) { - meta << nextElement() << '"' << ex->name.str << '"'; - } - } - meta << "\n ],\n"; - - meta << " \"namedGlobals\": {"; - commaFirst = true; - for (const auto& ex : wasm.exports) { - if (ex->kind == ExternalKind::Global) { - const Global* g = wasm.getGlobal(ex->value); - assert(g->type == Type::i32 || g->type == Type::i64); - Const* init = g->init->cast<Const>(); - uint64_t addr = init->value.getInteger(); - meta << nextElement() << '"' << ex->name.str << "\" : \"" << addr - << '"'; - } - } - meta << "\n },\n"; - } - - meta << " \"invokeFuncs\": ["; - commaFirst = true; - ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { - if (import->module == ENV && import->base.startsWith("invoke_")) { - if (invokeFuncs.insert(import->base.str).second) { - meta << nextElement() << '"' << import->base.str << '"'; - } - } - }); - meta << "\n ],\n"; - - // In normal mode we attempt to determine if main takes argumnts or not - // In standalone mode we export _start instead and rely on the presence - // of the __wasi_args_get and __wasi_args_sizes_get syscalls allow us to - // DCE to the argument handling JS code instead. - if (!standalone) { - auto mainReadsParams = false; - auto* exp = wasm.getExportOrNull("main"); - if (!exp) { - exp = wasm.getExportOrNull("__main_argc_argv"); - } - if (exp) { - if (exp->kind == ExternalKind::Function) { - auto* main = wasm.getFunction(exp->value); - mainReadsParams = main->getNumParams() > 0; - if (mainReadsParams) { - // Main could also be stub that just calls __original_main with - // no parameters. - // TODO(sbc): Remove this once https://reviews.llvm.org/D75277 - // lands. - if (auto* call = main->body->dynCast<Call>()) { - if (call->operands.empty()) { - mainReadsParams = false; - } - } - } - } - } - meta << " \"mainReadsParams\": " << int(mainReadsParams) << ",\n"; - } - - meta << " \"features\": ["; - commaFirst = true; - wasm.features.iterFeatures([&](FeatureSet::Feature f) { - meta << nextElement() << "\"--enable-" << FeatureSet::toString(f) << '"'; - }); - meta << "\n ]\n"; - - meta << "}\n"; - - return meta.str(); -} - void EmscriptenGlueGenerator::separateDataSegments(Output* outfile, Address base) { size_t lastEnd = 0; |