summaryrefslogtreecommitdiff
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
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.
-rwxr-xr-xscripts/test/lld.py2
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp18
-rw-r--r--src/wasm-emscripten.h2
-rw-r--r--src/wasm/wasm-emscripten.cpp19
-rw-r--r--test/lld/standalone-wasm.wast20
-rw-r--r--test/lld/standalone-wasm.wast.out101
-rw-r--r--test/lld/standalone-wasm2.wast17
-rw-r--r--test/lld/standalone-wasm2.wast.out98
-rw-r--r--test/lld/standalone-wasm3.wast13
-rw-r--r--test/lld/standalone-wasm3.wast.out78
10 files changed, 367 insertions, 1 deletions
diff --git a/scripts/test/lld.py b/scripts/test/lld.py
index 4aafd9549..7372698cd 100755
--- a/scripts/test/lld.py
+++ b/scripts/test/lld.py
@@ -26,6 +26,8 @@ def args_for_finalize(filename):
return ['--check-stack-overflow', '--global-base=568']
elif 'shared' in filename:
return ['--side-module']
+ elif 'standalone-wasm' in filename:
+ return ['--standalone-wasm', '--global-base=568']
else:
return ['--global-base=568']
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
diff --git a/test/lld/standalone-wasm.wast b/test/lld/standalone-wasm.wast
new file mode 100644
index 000000000..2ccbf3f29
--- /dev/null
+++ b/test/lld/standalone-wasm.wast
@@ -0,0 +1,20 @@
+(module
+ (memory $0 2)
+ (table $0 1 1 funcref)
+ (elem (i32.const 0) $foo)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "main" (func $main))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (func $__original_main (result i32)
+ (nop)
+ )
+ (func $main (param $0 i32) (param $1 i32) (result i32)
+ (call $__original_main)
+ )
+ (func $foo (result i32))
+)
+
diff --git a/test/lld/standalone-wasm.wast.out b/test/lld/standalone-wasm.wast.out
new file mode 100644
index 000000000..5e9fa4c91
--- /dev/null
+++ b/test/lld/standalone-wasm.wast.out
@@ -0,0 +1,101 @@
+(module
+ (type $FUNCSIG$i (func (result i32)))
+ (type $FUNCSIG$iii (func (param i32 i32) (result i32)))
+ (memory $0 2)
+ (table $0 1 1 funcref)
+ (elem (i32.const 0) $foo)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "main" (func $main))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (export "stackSave" (func $stackSave))
+ (export "stackAlloc" (func $stackAlloc))
+ (export "stackRestore" (func $stackRestore))
+ (export "__growWasmMemory" (func $__growWasmMemory))
+ (export "_start" (func $_start))
+ (func $__original_main (; 0 ;) (type $FUNCSIG$i) (result i32)
+ (nop)
+ )
+ (func $main (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
+ (call $__original_main)
+ )
+ (func $foo (; 2 ;) (type $FUNCSIG$i) (result i32)
+ (nop)
+ )
+ (func $stackSave (; 3 ;) (result i32)
+ (global.get $global$0)
+ )
+ (func $stackAlloc (; 4 ;) (param $0 i32) (result i32)
+ (local $1 i32)
+ (global.set $global$0
+ (local.tee $1
+ (i32.and
+ (i32.sub
+ (global.get $global$0)
+ (local.get $0)
+ )
+ (i32.const -16)
+ )
+ )
+ )
+ (local.get $1)
+ )
+ (func $stackRestore (; 5 ;) (param $0 i32)
+ (global.set $global$0
+ (local.get $0)
+ )
+ )
+ (func $__growWasmMemory (; 6 ;) (param $newSize i32) (result i32)
+ (memory.grow
+ (local.get $newSize)
+ )
+ )
+ (func $_start (; 7 ;)
+ (drop
+ (call $main
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ )
+)
+(;
+--BEGIN METADATA --
+{
+ "staticBump": 8,
+ "tableSize": 1,
+ "declares": [
+ ],
+ "externs": [
+ ],
+ "implementedFunctions": [
+ "_main",
+ "_stackSave",
+ "_stackAlloc",
+ "_stackRestore",
+ "___growWasmMemory",
+ "__start"
+ ],
+ "exports": [
+ "main",
+ "stackSave",
+ "stackAlloc",
+ "stackRestore",
+ "__growWasmMemory",
+ "_start"
+ ],
+ "namedGlobals": {
+ "__heap_base" : "66112",
+ "__data_end" : "576"
+ },
+ "invokeFuncs": [
+ ],
+ "features": [
+ ],
+ "mainReadsParams": 0
+}
+-- END METADATA --
+;)
diff --git a/test/lld/standalone-wasm2.wast b/test/lld/standalone-wasm2.wast
new file mode 100644
index 000000000..f4c7843b6
--- /dev/null
+++ b/test/lld/standalone-wasm2.wast
@@ -0,0 +1,17 @@
+(module
+ (memory $0 2)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "main" (func $main))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (func $__original_main (param $0 i32) (param $1 i32) (result i32)
+ (nop)
+ )
+ (func $main (param $0 i32) (param $1 i32) (result i32)
+ (call $__original_main (local.get $0) (local.get $1))
+ )
+)
+
diff --git a/test/lld/standalone-wasm2.wast.out b/test/lld/standalone-wasm2.wast.out
new file mode 100644
index 000000000..fe669b414
--- /dev/null
+++ b/test/lld/standalone-wasm2.wast.out
@@ -0,0 +1,98 @@
+(module
+ (type $FUNCSIG$iii (func (param i32 i32) (result i32)))
+ (memory $0 2)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "main" (func $main))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (export "stackSave" (func $stackSave))
+ (export "stackAlloc" (func $stackAlloc))
+ (export "stackRestore" (func $stackRestore))
+ (export "__growWasmMemory" (func $__growWasmMemory))
+ (export "_start" (func $_start))
+ (func $__original_main (; 0 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
+ (nop)
+ )
+ (func $main (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
+ (call $__original_main
+ (local.get $0)
+ (local.get $1)
+ )
+ )
+ (func $stackSave (; 2 ;) (result i32)
+ (global.get $global$0)
+ )
+ (func $stackAlloc (; 3 ;) (param $0 i32) (result i32)
+ (local $1 i32)
+ (global.set $global$0
+ (local.tee $1
+ (i32.and
+ (i32.sub
+ (global.get $global$0)
+ (local.get $0)
+ )
+ (i32.const -16)
+ )
+ )
+ )
+ (local.get $1)
+ )
+ (func $stackRestore (; 4 ;) (param $0 i32)
+ (global.set $global$0
+ (local.get $0)
+ )
+ )
+ (func $__growWasmMemory (; 5 ;) (param $newSize i32) (result i32)
+ (memory.grow
+ (local.get $newSize)
+ )
+ )
+ (func $_start (; 6 ;)
+ (drop
+ (call $main
+ (i32.const 0)
+ (i32.const 0)
+ )
+ )
+ )
+)
+(;
+--BEGIN METADATA --
+{
+ "staticBump": 8,
+ "tableSize": 0,
+ "declares": [
+ ],
+ "externs": [
+ ],
+ "implementedFunctions": [
+ "_main",
+ "_stackSave",
+ "_stackAlloc",
+ "_stackRestore",
+ "___growWasmMemory",
+ "__start"
+ ],
+ "exports": [
+ "main",
+ "stackSave",
+ "stackAlloc",
+ "stackRestore",
+ "__growWasmMemory",
+ "_start"
+ ],
+ "namedGlobals": {
+ "__heap_base" : "66112",
+ "__data_end" : "576"
+ },
+ "invokeFuncs": [
+ ],
+ "features": [
+ ],
+ "mainReadsParams": 1
+}
+-- END METADATA --
+;)
diff --git a/test/lld/standalone-wasm3.wast b/test/lld/standalone-wasm3.wast
new file mode 100644
index 000000000..45c0bed35
--- /dev/null
+++ b/test/lld/standalone-wasm3.wast
@@ -0,0 +1,13 @@
+(module
+ (memory $0 2)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (func $__original_main (param $0 i32) (param $1 i32) (result i32)
+ (nop)
+ )
+)
+
diff --git a/test/lld/standalone-wasm3.wast.out b/test/lld/standalone-wasm3.wast.out
new file mode 100644
index 000000000..a334d96e4
--- /dev/null
+++ b/test/lld/standalone-wasm3.wast.out
@@ -0,0 +1,78 @@
+(module
+ (type $FUNCSIG$iii (func (param i32 i32) (result i32)))
+ (memory $0 2)
+ (global $global$0 (mut i32) (i32.const 66112))
+ (global $global$1 i32 (i32.const 66112))
+ (global $global$2 i32 (i32.const 576))
+ (export "memory" (memory $0))
+ (export "__heap_base" (global $global$1))
+ (export "__data_end" (global $global$2))
+ (export "stackSave" (func $stackSave))
+ (export "stackAlloc" (func $stackAlloc))
+ (export "stackRestore" (func $stackRestore))
+ (export "__growWasmMemory" (func $__growWasmMemory))
+ (func $__original_main (; 0 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
+ (nop)
+ )
+ (func $stackSave (; 1 ;) (result i32)
+ (global.get $global$0)
+ )
+ (func $stackAlloc (; 2 ;) (param $0 i32) (result i32)
+ (local $1 i32)
+ (global.set $global$0
+ (local.tee $1
+ (i32.and
+ (i32.sub
+ (global.get $global$0)
+ (local.get $0)
+ )
+ (i32.const -16)
+ )
+ )
+ )
+ (local.get $1)
+ )
+ (func $stackRestore (; 3 ;) (param $0 i32)
+ (global.set $global$0
+ (local.get $0)
+ )
+ )
+ (func $__growWasmMemory (; 4 ;) (param $newSize i32) (result i32)
+ (memory.grow
+ (local.get $newSize)
+ )
+ )
+)
+(;
+--BEGIN METADATA --
+{
+ "staticBump": 8,
+ "tableSize": 0,
+ "declares": [
+ ],
+ "externs": [
+ ],
+ "implementedFunctions": [
+ "_stackSave",
+ "_stackAlloc",
+ "_stackRestore",
+ "___growWasmMemory"
+ ],
+ "exports": [
+ "stackSave",
+ "stackAlloc",
+ "stackRestore",
+ "__growWasmMemory"
+ ],
+ "namedGlobals": {
+ "__heap_base" : "66112",
+ "__data_end" : "576"
+ },
+ "invokeFuncs": [
+ ],
+ "features": [
+ ],
+ "mainReadsParams": 0
+}
+-- END METADATA --
+;)