diff options
-rwxr-xr-x | auto_update_tests.py | 2 | ||||
-rwxr-xr-x | scripts/test/lld.py | 2 | ||||
-rw-r--r-- | src/asm2wasm.h | 10 | ||||
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 20 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 14 | ||||
-rw-r--r-- | test/lld/duplicate_imports.wast.out | 3 | ||||
-rw-r--r-- | test/lld/em_asm.wast.out | 3 | ||||
-rw-r--r-- | test/lld/em_asm_table.wast.out | 3 | ||||
-rw-r--r-- | test/lld/hello_world.wast.mem.out | 3 | ||||
-rw-r--r-- | test/lld/hello_world.wast.out | 3 | ||||
-rw-r--r-- | test/lld/init.wast.out | 3 | ||||
-rw-r--r-- | test/lld/recursive.wast.out | 3 | ||||
-rw-r--r-- | test/lld/reserved_func_ptr.wast.jscall.out | 3 | ||||
-rw-r--r-- | test/lld/reserved_func_ptr.wast.out | 3 | ||||
-rw-r--r-- | test/unit.asm.js | 3 | ||||
-rw-r--r-- | test/unit.fromasm | 7 | ||||
-rw-r--r-- | test/unit.fromasm.clamp | 7 | ||||
-rw-r--r-- | test/unit.fromasm.clamp.no-opts | 7 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 7 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 7 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 7 |
22 files changed, 82 insertions, 40 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 9d156472c..bef6a8908 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -87,7 +87,7 @@ def update_lld_tests(): if ext != '.out' and not os.path.exists(out_path): continue cmd = (WASM_EMSCRIPTEN_FINALIZE + - [wast_path, '-S', '--global-base=568'] + ext_args) + [wast_path, '-S', '--global-base=568', '--initial-stack-pointer=16384'] + ext_args) actual = run_command(cmd) with open(out_path, 'w') as o: o.write(actual) diff --git a/scripts/test/lld.py b/scripts/test/lld.py index 03a0733e6..03c96d6c3 100755 --- a/scripts/test/lld.py +++ b/scripts/test/lld.py @@ -38,7 +38,7 @@ def test_wasm_emscripten_finalize(): continue cmd = (WASM_EMSCRIPTEN_FINALIZE + - [wast_path, '-S', '--global-base=568'] + ext_args) + [wast_path, '-S', '--global-base=568', '--initial-stack-pointer=16384'] + ext_args) actual = run_command(cmd) if not os.path.exists(expected_file): diff --git a/src/asm2wasm.h b/src/asm2wasm.h index d958c4b6a..c193791f8 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -426,13 +426,16 @@ public: std::map<IString, MappedGlobal> mappedGlobals; private: - void allocateGlobal(IString name, Type type) { + void allocateGlobal(IString name, Type type, Literal value=Literal()) { assert(mappedGlobals.find(name) == mappedGlobals.end()); + if (value.type == none) { + value = Literal::makeZero(type); + } mappedGlobals.emplace(name, MappedGlobal(type)); wasm.addGlobal(builder.makeGlobal( name, type, - LiteralUtils::makeZero(type, wasm), + builder.makeConst(value), Builder::Mutable )); } @@ -986,8 +989,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { Ref value = pair[1]; if (value->isNumber()) { // global int - assert(value->getNumber() == 0); - allocateGlobal(name, Type::i32); + allocateGlobal(name, Type::i32, Literal(int32_t(value->getInteger()))); } else if (value[0] == BINARY) { // int import assert(value[1] == OR && value[3]->isNumber() && value[3]->getNumber() == 0); diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index 3d74138cc..3ea3629c5 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -36,6 +36,8 @@ using namespace cashew; using namespace wasm; int main(int argc, const char *argv[]) { + const uint64_t INVALID_BASE = -1; + std::string infile; std::string outfile; std::string inputSourceMapFilename; @@ -46,7 +48,8 @@ int main(int argc, const char *argv[]) { bool debugInfo = false; bool legalizeJavaScriptFFI = true; unsigned numReservedFunctionPointers = 0; - uint64_t globalBase; + uint64_t globalBase = INVALID_BASE; + uint64_t initialStackPointer = INVALID_BASE; Options options("wasm-emscripten-finalize", "Performs Emscripten-specific transforms on .wasm files"); options @@ -75,11 +78,16 @@ int main(int argc, const char *argv[]) { const std::string &argument) { numReservedFunctionPointers = std::stoi(argument); }) - .add("--global-base", "", "Where lld started to place globals", + .add("--global-base", "", "The address at which static globals were placed", Options::Arguments::One, [&globalBase](Options*, const std::string&argument ) { globalBase = std::stoull(argument); }) + .add("--initial-stack-pointer", "", "The initial location of the stack pointer", + Options::Arguments::One, + [&initialStackPointer](Options*, const std::string&argument ) { + initialStackPointer = std::stoull(argument); + }) .add("--input-source-map", "-ism", "Consume source map from the specified file", Options::Arguments::One, @@ -141,6 +149,12 @@ int main(int argc, const char *argv[]) { uint32_t dataSize = 0; if (!isSideModule) { + if (globalBase == INVALID_BASE) { + Fatal() << "globalBase must be set"; + } + if (initialStackPointer == INVALID_BASE) { + Fatal() << "initialStackPointer must be set"; + } Export* dataEndExport = wasm.getExport("__data_end"); if (dataEndExport == nullptr) { Fatal() << "__data_end export not found"; @@ -189,7 +203,7 @@ int main(int argc, const char *argv[]) { } else { generator.generateRuntimeFunctions(); generator.generateMemoryGrowthFunction(); - generator.generateStackInitialization(); + generator.generateStackInitialization(initialStackPointer); // 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")) { diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index 2b626a7c9..d078cafbf 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -36,7 +36,7 @@ public: void generateRuntimeFunctions(); Function* generateMemoryGrowthFunction(); - void generateStackInitialization(); + void generateStackInitialization(Address addr); // Create thunks for use with emscripten Runtime.dynCall. Creates one for each // signature in the indirect function table. diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index b18fe0c76..88e66ea07 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -156,19 +156,9 @@ 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); +void EmscriptenGlueGenerator::generateStackInitialization(Address addr) { auto* stackPointer = getStackPointerGlobal(); - assert(stackPointer->init->is<Const>()); - stackPointer->init = builder.makeGetGlobal(import->name, i32); + stackPointer->init->cast<Const>()->value = Literal(int32_t(addr)); } static bool hasI64ResultOrParam(FunctionType* ft) { diff --git a/test/lld/duplicate_imports.wast.out b/test/lld/duplicate_imports.wast.out index 6d3417b26..58f5846e6 100644 --- a/test/lld/duplicate_imports.wast.out +++ b/test/lld/duplicate_imports.wast.out @@ -9,7 +9,6 @@ (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))) @@ -17,7 +16,7 @@ (memory $0 2) (data (i32.const 568) "Hello, world\00") (table $0 1 1 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66128)) (global $global$2 i32 (i32.const 581)) (export "memory" (memory $0)) diff --git a/test/lld/em_asm.wast.out b/test/lld/em_asm.wast.out index 009dedc55..92b1ea76f 100644 --- a/test/lld/em_asm.wast.out +++ b/test/lld/em_asm.wast.out @@ -7,14 +7,13 @@ (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 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66192)) (global $global$2 i32 (i32.const 652)) (export "memory" (memory $0)) diff --git a/test/lld/em_asm_table.wast.out b/test/lld/em_asm_table.wast.out index 35e593dd7..ae3675d40 100644 --- a/test/lld/em_asm_table.wast.out +++ b/test/lld/em_asm_table.wast.out @@ -4,12 +4,11 @@ (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 funcref) (elem (i32.const 1) $fimport$0 $emscripten_asm_const_iii) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 1048)) (export "__data_end" (global $global$1)) (export "stackSave" (func $stackSave)) diff --git a/test/lld/hello_world.wast.mem.out b/test/lld/hello_world.wast.mem.out index 078620bcd..66dafd460 100644 --- a/test/lld/hello_world.wast.mem.out +++ b/test/lld/hello_world.wast.mem.out @@ -3,11 +3,10 @@ (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 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66128)) (global $global$2 i32 (i32.const 581)) (export "memory" (memory $0)) diff --git a/test/lld/hello_world.wast.out b/test/lld/hello_world.wast.out index df89a5756..1b1e199cb 100644 --- a/test/lld/hello_world.wast.out +++ b/test/lld/hello_world.wast.out @@ -3,12 +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) (data (i32.const 568) "Hello, world\00") (table $0 1 1 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66128)) (global $global$2 i32 (i32.const 581)) (export "memory" (memory $0)) diff --git a/test/lld/init.wast.out b/test/lld/init.wast.out index b702fb373..dfff8d5eb 100644 --- a/test/lld/init.wast.out +++ b/test/lld/init.wast.out @@ -1,11 +1,10 @@ (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 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66112)) (global $global$2 i32 (i32.const 576)) (export "memory" (memory $0)) diff --git a/test/lld/recursive.wast.out b/test/lld/recursive.wast.out index 1c1180e1c..e8f32d99c 100644 --- a/test/lld/recursive.wast.out +++ b/test/lld/recursive.wast.out @@ -3,12 +3,11 @@ (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 funcref) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66128)) (global $global$2 i32 (i32.const 587)) (export "memory" (memory $0)) diff --git a/test/lld/reserved_func_ptr.wast.jscall.out b/test/lld/reserved_func_ptr.wast.jscall.out index 6242c3b76..bc9b677d6 100644 --- a/test/lld/reserved_func_ptr.wast.jscall.out +++ b/test/lld/reserved_func_ptr.wast.jscall.out @@ -18,7 +18,6 @@ (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))) @@ -29,7 +28,7 @@ (memory $0 2) (table $0 21 21 funcref) (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) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66112)) (global $global$2 i32 (i32.const 568)) (export "memory" (memory $0)) diff --git a/test/lld/reserved_func_ptr.wast.out b/test/lld/reserved_func_ptr.wast.out index 393178a00..e0d9ea156 100644 --- a/test/lld/reserved_func_ptr.wast.out +++ b/test/lld/reserved_func_ptr.wast.out @@ -8,12 +8,11 @@ (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 funcref) (elem (i32.const 1) $_Z18address_taken_funciii $_Z19address_taken_func2iii) - (global $global$0 (mut i32) (global.get $stack$init)) + (global $global$0 (mut i32) (i32.const 16384)) (global $global$1 i32 (i32.const 66112)) (global $global$2 i32 (i32.const 568)) (export "memory" (memory $0)) diff --git a/test/unit.asm.js b/test/unit.asm.js index 05827ce54..b62c7aefb 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -30,6 +30,8 @@ function asm(global, env, buffer) { var HEAPF32 = new global.Float32Array(buffer); var HEAPF64 = new global.Float64Array(buffer); + var nonZero = 1337; + function big_negative() { var temp = 0.0; temp = +-2147483648; @@ -785,6 +787,7 @@ function asm(global, env, buffer) { emterpretify_assertions_safeHeap(); call_emscripten_log(); mod_detectSign(1.0, 2.31, 9.78); + nonZero = nonZero + 1 | 0; } function v() { diff --git a/test/unit.fromasm b/test/unit.fromasm index b1a24bf5d..c9e20da52 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -26,6 +26,7 @@ (global $Int (mut i32) (i32.const 0)) (global $Double (mut f64) (f64.const 0)) (global $n (mut i32) (global.get $n$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $big_negative)) @@ -1162,6 +1163,12 @@ ) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $vi (; 55 ;) (; has Stack IR ;) (param $0 i32) (nop) diff --git a/test/unit.fromasm.clamp b/test/unit.fromasm.clamp index 58cf67a0d..deec92f97 100644 --- a/test/unit.fromasm.clamp +++ b/test/unit.fromasm.clamp @@ -24,6 +24,7 @@ (global $Int (mut i32) (i32.const 0)) (global $Double (mut f64) (f64.const 0)) (global $n (mut i32) (global.get $n$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $big_negative)) @@ -1238,6 +1239,12 @@ ) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $vi (; 57 ;) (; has Stack IR ;) (param $0 i32) (nop) diff --git a/test/unit.fromasm.clamp.no-opts b/test/unit.fromasm.clamp.no-opts index 7a30149ba..95cb543e2 100644 --- a/test/unit.fromasm.clamp.no-opts +++ b/test/unit.fromasm.clamp.no-opts @@ -31,6 +31,7 @@ (global $tempDoublePtr (mut i32) (global.get $tempDoublePtr$asm2wasm$import)) (global $n (mut i32) (global.get $n$asm2wasm$import)) (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $exportMe)) @@ -2215,6 +2216,12 @@ (f64.const 9.78) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $v (; 83 ;) (nop) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 869873ec1..7ff7a4c18 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -22,6 +22,7 @@ (global $Int (mut i32) (i32.const 0)) (global $Double (mut f64) (f64.const 0)) (global $n (mut i32) (global.get $n$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $big_negative)) @@ -1141,6 +1142,12 @@ (f64.const 1) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $vi (; 54 ;) (; has Stack IR ;) (param $0 i32) (nop) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 74dd7efee..69d1ff2ff 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -31,6 +31,7 @@ (global $tempDoublePtr (mut i32) (global.get $tempDoublePtr$asm2wasm$import)) (global $n (mut i32) (global.get $n$asm2wasm$import)) (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $exportMe)) @@ -2100,6 +2101,12 @@ (f64.const 9.78) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $v (; 78 ;) (nop) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 561062f04..fb82b572f 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -33,6 +33,7 @@ (global $tempDoublePtr (mut i32) (global.get $tempDoublePtr$asm2wasm$import)) (global $n (mut i32) (global.get $n$asm2wasm$import)) (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) + (global $nonZero (mut i32) (i32.const 1337)) (global $exportedNumber i32 (i32.const 42)) (export "big_negative" (func $big_negative)) (export "pick" (func $exportMe)) @@ -2141,6 +2142,12 @@ (f64.const 9.78) ) ) + (global.set $nonZero + (i32.add + (global.get $nonZero) + (i32.const 1) + ) + ) ) (func $v (; 81 ;) (nop) |