diff options
author | Alon Zakai <azakai@google.com> | 2019-09-18 15:11:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-18 15:11:44 -0700 |
commit | 159e9a45877351f89af8ec0a05a7b3fe57d34aad (patch) | |
tree | b427fda2f848aa159380ac75f85d4644ecc9c33e /src | |
parent | 844998f1b4f4b0f439875e6b36bc6b821be87939 (diff) | |
download | binaryen-159e9a45877351f89af8ec0a05a7b3fe57d34aad.tar.gz binaryen-159e9a45877351f89af8ec0a05a7b3fe57d34aad.tar.bz2 binaryen-159e9a45877351f89af8ec0a05a7b3fe57d34aad.zip |
Add a --standalone-wasm flag to wasm-emscripten-finalize (#2333)
The flag indicates that we want to run the wasm by itself, without JS support. In that case we don't emit JS dynCalls etc., and we also emit a wasi _start if there is a main, i.e., we try to use the current conventions in the wasm-only space.
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 18 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 19 |
3 files changed, 38 insertions, 1 deletions
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index ea69cabbc..8a246e5d2 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -50,6 +50,8 @@ int main(int argc, const char* argv[]) { bool legalizeJavaScriptFFI = true; bool checkStackOverflow = false; uint64_t globalBase = INVALID_BASE; + bool standaloneWasm = false; + ToolOptions options("wasm-emscripten-finalize", "Performs Emscripten-specific transforms on .wasm files"); options @@ -135,6 +137,14 @@ int main(int argc, const char* argv[]) { [&checkStackOverflow](Options* o, const std::string&) { checkStackOverflow = true; }) + .add("--standalone-wasm", + "", + "Emit a wasm file that does not depend on JS, as much as possible," + " using wasi and other standard conventions etc. where possible", + Options::Arguments::Zero, + [&standaloneWasm](Options* o, const std::string&) { + standaloneWasm = true; + }) .add_positional("INFILE", Options::Arguments::One, [&infile](Options* o, const std::string& argument) { @@ -233,7 +243,13 @@ int main(int argc, const char* argv[]) { } } - generator.generateDynCallThunks(); + if (standaloneWasm) { + // Export a standard wasi "_start" method. + generator.exportWasiStart(); + } else { + // If not standalone wasm then JS is relevant and we need dynCalls. + generator.generateDynCallThunks(); + } // Legalize the wasm. { diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index 1758aa23a..9dc82bc1a 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -56,6 +56,8 @@ public: void enforceStackLimit(); + void exportWasiStart(); + // Emits the data segments to a file. The file contains data from address base // onwards (we must pass in base, as we can't tell it from the wasm - the // first segment may start after a run of zeros, but we need those zeros in diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 978afa296..3aa6f5647 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -22,6 +22,7 @@ #include "asmjs/shared-constants.h" #include "ir/function-type-utils.h" #include "ir/import-utils.h" +#include "ir/literal-utils.h" #include "ir/module-utils.h" #include "shared-constants.h" #include "wasm-builder.h" @@ -1210,4 +1211,22 @@ void EmscriptenGlueGenerator::separateDataSegments(Output* outfile, wasm.memory.segments.clear(); } +void EmscriptenGlueGenerator::exportWasiStart() { + // If main exists, export a function to call it per the wasi standard. + Name main = "main"; + if (!wasm.getFunctionOrNull(main)) { + return; + } + Name _start = "_start"; + Builder builder(wasm); + auto* body = builder.makeDrop(builder.makeCall( + main, + {LiteralUtils::makeZero(i32, wasm), LiteralUtils::makeZero(i32, wasm)}, + i32)); + auto* func = + builder.makeFunction(_start, std::vector<wasm::Type>{}, none, {}, body); + wasm.addFunction(func); + wasm.addExport(builder.makeExport(_start, _start, ExternalKind::Function)); +} + } // namespace wasm |