summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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