Skip to content

Commit

Permalink
wasm-emscripten-finalize: import env.STACKTOP, like asm2wasm does
Browse files Browse the repository at this point in the history
  • Loading branch information
kripken committed Dec 12, 2018
1 parent 3307ca8 commit 7edaebe
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/tools/wasm-emscripten-finalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ int main(int argc, const char *argv[]) {
} else {
generator.generateRuntimeFunctions();
generator.generateMemoryGrowthFunction();
generator.generateStackInitialization();
// emscripten calls this by default for side libraries so we only need
// to include in as a static ctor for main module case.
if (wasm.getExportOrNull("__post_instantiate")) {
Expand Down
1 change: 1 addition & 0 deletions src/wasm-emscripten.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class EmscriptenGlueGenerator {

void generateRuntimeFunctions();
Function* generateMemoryGrowthFunction();
void generateStackInitialization();

// Create thunks for use with emscripten Runtime.dynCall. Creates one for each
// signature in the indirect function table.
Expand Down
28 changes: 23 additions & 5 deletions src/wasm/wasm-emscripten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ cashew::IString EM_JS_PREFIX("__em_js__");
static Name STACK_SAVE("stackSave"),
STACK_RESTORE("stackRestore"),
STACK_ALLOC("stackAlloc"),
STACK_INIT("stack$init"),
DUMMY_FUNC("__wasm_nullptr");

void addExportedFunction(Module& wasm, Function* function) {
Expand Down Expand Up @@ -155,6 +156,21 @@ Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
return growFunction;
}

void EmscriptenGlueGenerator::generateStackInitialization() {
// Replace a global with a constant initial value with an imported
// initial value, which emscripten JS will send us.
// TODO: with mutable imported globals, we can avoid adding another
// global for the import.
Builder builder(wasm);
auto* import = builder.makeGlobal(STACK_INIT, i32, nullptr, Builder::Immutable);
import->module = ENV;
import->base = STACKTOP;
wasm.addGlobal(import);
auto* stackPointer = getStackPointerGlobal();
assert(stackPointer->init->is<Const>());
stackPointer->init = builder.makeGetGlobal(import->name, i32);
}

static bool hasI64ResultOrParam(FunctionType* ft) {
if (ft->result == i64) return true;
for (auto ty : ft->params) {
Expand Down Expand Up @@ -227,18 +243,18 @@ static Function* ensureFunctionImport(Module* module, Name name, std::string sig
}

struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
RemoveStackPointer(Global* StackPointer) : StackPointer(StackPointer) {}
RemoveStackPointer(Global* stackPointer) : stackPointer(stackPointer) {}

void visitGetGlobal(GetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == StackPointer) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
ensureFunctionImport(getModule(), STACK_SAVE, "i");
if (!builder) builder = make_unique<Builder>(*getModule());
replaceCurrent(builder->makeCall(STACK_SAVE, {}, i32));
}
}

void visitSetGlobal(SetGlobal* curr) {
if (getModule()->getGlobalOrNull(curr->name) == StackPointer) {
if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {
ensureFunctionImport(getModule(), STACK_RESTORE, "vi");
if (!builder) builder = make_unique<Builder>(*getModule());
replaceCurrent(builder->makeCall(STACK_RESTORE, {curr->value}, none));
Expand All @@ -247,7 +263,7 @@ struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {

private:
std::unique_ptr<Builder> builder;
Global* StackPointer;
Global* stackPointer;
};

void EmscriptenGlueGenerator::replaceStackPointerGlobal() {
Expand Down Expand Up @@ -833,7 +849,9 @@ std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(
meta << " \"externs\": [";
commaFirst = true;
ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) {
meta << nextElement() << "\"_" << import->base.str << '"';
if (!(import->module == ENV && import->name == STACK_INIT)) {
meta << nextElement() << "\"_" << import->base.str << '"';
}
});
meta << "\n ],\n";

Expand Down
3 changes: 2 additions & 1 deletion test/lld/duplicate_imports.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
(type $legaltype$puts2 (func (param i32 i32) (result i32)))
(type $legaltype$invoke_ffd (func (param i32 f64 f64) (result f64)))
(type $legaltype$invoke_ffd2 (func (param i32 f64 f64) (result f64)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "puts" (func $puts1 (param i32) (result i32)))
(import "env" "puts" (func $legalimport$puts2 (param i32 i32) (result i32)))
(import "env" "invoke_ffd" (func $legalimport$invoke_ffd (param i32 f64 f64) (result f64)))
(import "env" "invoke_ffd" (func $legalimport$invoke_ffd2 (param i32 f64 f64) (result f64)))
(memory $0 2)
(data (i32.const 568) "Hello, world\00")
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66128))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/em_asm.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "emscripten_asm_const_i" (func $emscripten_asm_const_i (param i32) (result i32)))
(import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32)))
(import "env" "emscripten_asm_const_ii" (func $emscripten_asm_const_ii (param i32 i32) (result i32)))
(memory $0 2)
(data (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00")
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66192))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66192))
(global $global$2 i32 (i32.const 652))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/em_asm_table.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
(import "env" "memory" (memory $0 8192))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "emscripten_log" (func $fimport$0 (param i32 i32)))
(import "env" "emscripten_asm_const_iii" (func $emscripten_asm_const_iii (param i32 i32 i32) (result i32)))
(table $0 159609 anyfunc)
(elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii)
(global $global$0 (mut i32) (i32.const 1024))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 1048))
(export "__data_end" (global $global$1))
(export "stackSave" (func $stackSave))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/hello_world.wast.mem.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
(type $1 (func (result i32)))
(type $2 (func))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "puts" (func $puts (param i32) (result i32)))
(memory $0 2)
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66128))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/hello_world.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
(type $1 (func (result i32)))
(type $2 (func))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "puts" (func $puts (param i32) (result i32)))
(memory $0 2)
(data (i32.const 568) "Hello, world\00")
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66128))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/init.wast.out
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
(module
(type $0 (func))
(type $1 (func (result i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(memory $0 2)
(data (i32.const 568) "\00\00\00\00\00\00\00\00")
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66112))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66112))
(global $global$2 i32 (i32.const 576))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/recursive.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
(type $1 (func (result i32)))
(type $2 (func))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "printf" (func $printf (param i32 i32) (result i32)))
(memory $0 2)
(data (i32.const 568) "%d:%d\n\00Result: %d\n\00")
(table $0 1 1 anyfunc)
(global $global$0 (mut i32) (i32.const 66128))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 587))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/reserved_func_ptr.wast.jscall.out
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
(type $FUNCSIG$v (func))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "_Z4atoiPKc" (func $_Z4atoiPKc (param i32) (result i32)))
(import "env" "jsCall_ddi" (func $jsCall_ddi (param i32 f64 i32) (result f64)))
(import "env" "jsCall_fffi" (func $jsCall_fffi (param i32 f32 f32 i32) (result f32)))
Expand All @@ -28,7 +29,7 @@
(memory $0 2)
(table $0 21 21 anyfunc)
(elem (i32.const 1) $_Z18address_taken_funciii $_Z19address_taken_func2iii $jsCall_ddi_0 $jsCall_ddi_1 $jsCall_ddi_2 $jsCall_fffi_0 $jsCall_fffi_1 $jsCall_fffi_2 $jsCall_iii_0 $jsCall_iii_1 $jsCall_iii_2 $jsCall_v_0 $jsCall_v_1 $jsCall_v_2 $jsCall_vi_0 $jsCall_vi_1 $jsCall_vi_2 $jsCall_viii_0 $jsCall_viii_1 $jsCall_viii_2)
(global $global$0 (mut i32) (i32.const 66112))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66112))
(global $global$2 i32 (i32.const 568))
(export "memory" (memory $0))
Expand Down
3 changes: 2 additions & 1 deletion test/lld/reserved_func_ptr.wast.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
(type $6 (func (param i32) (result i32)))
(type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$viii (func (param i32 i32 i32)))
(import "env" "STACKTOP" (global $stack$init i32))
(import "env" "_Z4atoiPKc" (func $_Z4atoiPKc (param i32) (result i32)))
(memory $0 2)
(table $0 3 3 anyfunc)
(elem (i32.const 1) $_Z18address_taken_funciii $_Z19address_taken_func2iii)
(global $global$0 (mut i32) (i32.const 66112))
(global $global$0 (mut i32) (get_global $stack$init))
(global $global$1 i32 (i32.const 66112))
(global $global$2 i32 (i32.const 568))
(export "memory" (memory $0))
Expand Down

0 comments on commit 7edaebe

Please sign in to comment.