Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/test/lld.py
Original file line number Diff line number Diff line change
Expand Up @@ -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']

Expand Down
18 changes: 17 additions & 1 deletion src/tools/wasm-emscripten-finalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -233,7 +243,13 @@ int main(int argc, const char* argv[]) {
}
}

generator.generateDynCallThunks();
if (standaloneWasm) {
// Export a standard wasi "_start" method.
generator.exportWasiStart();
Comment thread
sbc100 marked this conversation as resolved.
} else {
// If not standalone wasm then JS is relevant and we need dynCalls.
generator.generateDynCallThunks();
Comment thread
sbc100 marked this conversation as resolved.
}

// Legalize the wasm.
{
Expand Down
2 changes: 2 additions & 0 deletions src/wasm-emscripten.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class EmscriptenGlueGenerator {

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
Expand Down
19 changes: 19 additions & 0 deletions src/wasm/wasm-emscripten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
20 changes: 20 additions & 0 deletions test/lld/standalone-wasm.wast
Original file line number Diff line number Diff line change
@@ -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))
)

101 changes: 101 additions & 0 deletions test/lld/standalone-wasm.wast.out
Original file line number Diff line number Diff line change
@@ -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 --
;)
17 changes: 17 additions & 0 deletions test/lld/standalone-wasm2.wast
Original file line number Diff line number Diff line change
@@ -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))
)
)

98 changes: 98 additions & 0 deletions test/lld/standalone-wasm2.wast.out
Original file line number Diff line number Diff line change
@@ -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 --
;)
13 changes: 13 additions & 0 deletions test/lld/standalone-wasm3.wast
Original file line number Diff line number Diff line change
@@ -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)
)
)

Loading