summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2019-09-18 15:11:44 -0700
committerGitHub <noreply@github.com>2019-09-18 15:11:44 -0700
commit159e9a45877351f89af8ec0a05a7b3fe57d34aad (patch)
treeb427fda2f848aa159380ac75f85d4644ecc9c33e /src
parent844998f1b4f4b0f439875e6b36bc6b821be87939 (diff)
downloadbinaryen-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.cpp18
-rw-r--r--src/wasm-emscripten.h2
-rw-r--r--src/wasm/wasm-emscripten.cpp19
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