diff options
-rw-r--r-- | src/asm2wasm.h | 25 | ||||
-rw-r--r-- | test/dynamicLibrary.asm.js | 136 | ||||
-rw-r--r-- | test/dynamicLibrary.fromasm | 80 | ||||
-rw-r--r-- | test/dynamicLibrary.fromasm.imprecise | 79 | ||||
-rw-r--r-- | test/dynamicLibrary.fromasm.imprecise.no-opts | 191 | ||||
-rw-r--r-- | test/dynamicLibrary.fromasm.no-opts | 191 |
6 files changed, 692 insertions, 10 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 6ed13b79a..fab74189e 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -649,19 +649,24 @@ void Asm2WasmBuilder::processAsm(Ref ast) { type = WasmType::f64; } if (type != WasmType::none) { - // we need imported globals to be mutable, but wasm doesn't support that yet, so we must - // import an immutable and create a mutable global initialized to its value - import->name = Name(std::string(import->name.str) + "$asm2wasm$import"); + // this is a global import->kind = ExternalKind::Global; import->globalType = type; mappedGlobals.emplace(name, type); - { - auto global = new Global(); - global->name = name; - global->type = type; - global->init = builder.makeGetGlobal(import->name, type); - global->mutable_ = true; - wasm.addGlobal(global); + // tableBase and memoryBase are used as segment/element offsets, and must be constant; + // otherwise, an asm.js import of a constant is mutable, e.g. STACKTOP + if (name != "tableBase" && name != "memoryBase") { + // we need imported globals to be mutable, but wasm doesn't support that yet, so we must + // import an immutable and create a mutable global initialized to its value + import->name = Name(std::string(import->name.str) + "$asm2wasm$import"); + { + auto global = new Global(); + global->name = name; + global->type = type; + global->init = builder.makeGetGlobal(import->name, type); + global->mutable_ = true; + wasm.addGlobal(global); + } } } else { import->kind = ExternalKind::Function; diff --git a/test/dynamicLibrary.asm.js b/test/dynamicLibrary.asm.js new file mode 100644 index 000000000..142fd7c98 --- /dev/null +++ b/test/dynamicLibrary.asm.js @@ -0,0 +1,136 @@ +Module["asm"] = (function(global, env, buffer) { + 'almost asm'; + + + var HEAP8 = new global.Int8Array(buffer); + var HEAP16 = new global.Int16Array(buffer); + var HEAP32 = new global.Int32Array(buffer); + var HEAPU8 = new global.Uint8Array(buffer); + var HEAPU16 = new global.Uint16Array(buffer); + var HEAPU32 = new global.Uint32Array(buffer); + var HEAPF32 = new global.Float32Array(buffer); + var HEAPF64 = new global.Float64Array(buffer); + + + var DYNAMICTOP_PTR=env.DYNAMICTOP_PTR|0; + var tempDoublePtr=env.tempDoublePtr|0; + var ABORT=env.ABORT|0; + var memoryBase=env.memoryBase|0; + var tableBase=env.tableBase|0; + + var STACKTOP = 0, STACK_MAX = 0; + + var __THREW__ = 0; + var threwValue = 0; + var setjmpId = 0; + var undef = 0; + var nan = global.NaN, inf = global.Infinity; + var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0; + var tempRet0 = 0; + + var Math_floor=global.Math.floor; + var Math_abs=global.Math.abs; + var Math_sqrt=global.Math.sqrt; + var Math_pow=global.Math.pow; + var Math_cos=global.Math.cos; + var Math_sin=global.Math.sin; + var Math_tan=global.Math.tan; + var Math_acos=global.Math.acos; + var Math_asin=global.Math.asin; + var Math_atan=global.Math.atan; + var Math_atan2=global.Math.atan2; + var Math_exp=global.Math.exp; + var Math_log=global.Math.log; + var Math_ceil=global.Math.ceil; + var Math_imul=global.Math.imul; + var Math_min=global.Math.min; + var Math_max=global.Math.max; + var Math_clz32=global.Math.clz32; + var Math_fround=global.Math.fround; + var abort=env.abort; + var assert=env.assert; + var enlargeMemory=env.enlargeMemory; + var getTotalMemory=env.getTotalMemory; + var abortOnCannotGrowMemory=env.abortOnCannotGrowMemory; + var abortStackOverflow=env.abortStackOverflow; + var setTempRet0=env.setTempRet0; + var getTempRet0=env.getTempRet0; + var _puts=env._puts; + var tempFloat = Math_fround(0); + const f0 = Math_fround(0); + +// EMSCRIPTEN_START_FUNCS + +function stackAlloc(size) { + size = size|0; + var ret = 0; + ret = STACKTOP; + STACKTOP = (STACKTOP + size)|0; + STACKTOP = (STACKTOP + 15)&-16; + if ((STACKTOP|0) >= (STACK_MAX|0)) abortStackOverflow(size|0); + + return ret|0; +} +function stackSave() { + return STACKTOP|0; +} +function stackRestore(top) { + top = top|0; + STACKTOP = top; +} +function establishStackSpace(stackBase, stackMax) { + stackBase = stackBase|0; + stackMax = stackMax|0; + STACKTOP = stackBase; + STACK_MAX = stackMax; +} + +function setThrew(threw, value) { + threw = threw|0; + value = value|0; + if ((__THREW__|0) == 0) { + __THREW__ = threw; + threwValue = value; + } +} + +function ___cxx_global_var_init() { + var label = 0, sp = 0; + sp = STACKTOP; + __ZN3FooC2Ev((memoryBase + (5242912) | 0)); + return; +} +function __ZN3FooC2Ev($0) { + $0 = $0|0; + var $1 = 0, label = 0, sp = 0; + sp = STACKTOP; + STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abortStackOverflow(16|0); + $1 = $0; + (_puts(((memoryBase + (0) | 0)|0))|0); + STACKTOP = sp;return; +} +function __GLOBAL__sub_I_liblib_cpp() { + var label = 0, sp = 0; + sp = STACKTOP; + ___cxx_global_var_init(); + return; +} +function runPostSets() { + var temp = 0; +} +function __post_instantiate() { + STACKTOP = (memoryBase + (32) | 0); + STACK_MAX = STACKTOP + 5242880 | 0; + runPostSets(); + __GLOBAL__sub_I_liblib_cpp(); +} + + + + +// EMSCRIPTEN_END_FUNCS + + + return { __ZN3FooC2Ev: __ZN3FooC2Ev, __post_instantiate: __post_instantiate, runPostSets: runPostSets, _global: 5242912 }; +}) +;
\ No newline at end of file diff --git a/test/dynamicLibrary.fromasm b/test/dynamicLibrary.fromasm new file mode 100644 index 000000000..df7825187 --- /dev/null +++ b/test/dynamicLibrary.fromasm @@ -0,0 +1,80 @@ +(module + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "abortStackOverflow" (func $abortStackOverflow (param i32))) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "tableBase" (global $tableBase i32)) + (global $STACKTOP (mut i32) (i32.const 0)) + (global $STACK_MAX (mut i32) (i32.const 0)) + (global $_global i32 (i32.const 5242912)) + (data (get_global $memoryBase) "dynamicLibrary.asm.js") + (export "__ZN3FooC2Ev" (func $__ZN3FooC2Ev)) + (export "__post_instantiate" (func $__post_instantiate)) + (export "runPostSets" (func $runPostSets)) + (export "_global" (global $_global)) + (func $___cxx_global_var_init + (call $__ZN3FooC2Ev + (i32.add + (get_global $memoryBase) + (i32.const 5242912) + ) + ) + ) + (func $__ZN3FooC2Ev (param $0 i32) + (local $1 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (i32.const 16) + ) + ) + (drop + (call $_puts + (i32.add + (get_global $memoryBase) + (i32.const 0) + ) + ) + ) + (set_global $STACKTOP + (get_local $1) + ) + ) + (func $__GLOBAL__sub_I_liblib_cpp + (call $___cxx_global_var_init) + ) + (func $runPostSets + (nop) + ) + (func $__post_instantiate + (set_global $STACKTOP + (i32.add + (get_global $memoryBase) + (i32.const 32) + ) + ) + (set_global $STACK_MAX + (i32.add + (get_global $STACKTOP) + (i32.const 5242880) + ) + ) + (call $runPostSets) + (call $__GLOBAL__sub_I_liblib_cpp) + ) +) diff --git a/test/dynamicLibrary.fromasm.imprecise b/test/dynamicLibrary.fromasm.imprecise new file mode 100644 index 000000000..357d324cd --- /dev/null +++ b/test/dynamicLibrary.fromasm.imprecise @@ -0,0 +1,79 @@ +(module + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "abortStackOverflow" (func $abortStackOverflow (param i32))) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "tableBase" (global $tableBase i32)) + (global $STACKTOP (mut i32) (i32.const 0)) + (global $STACK_MAX (mut i32) (i32.const 0)) + (global $_global i32 (i32.const 5242912)) + (export "__ZN3FooC2Ev" (func $__ZN3FooC2Ev)) + (export "__post_instantiate" (func $__post_instantiate)) + (export "runPostSets" (func $runPostSets)) + (export "_global" (global $_global)) + (func $___cxx_global_var_init + (call $__ZN3FooC2Ev + (i32.add + (get_global $memoryBase) + (i32.const 5242912) + ) + ) + ) + (func $__ZN3FooC2Ev (param $0 i32) + (local $1 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (i32.const 16) + ) + ) + (drop + (call $_puts + (i32.add + (get_global $memoryBase) + (i32.const 0) + ) + ) + ) + (set_global $STACKTOP + (get_local $1) + ) + ) + (func $__GLOBAL__sub_I_liblib_cpp + (call $___cxx_global_var_init) + ) + (func $runPostSets + (nop) + ) + (func $__post_instantiate + (set_global $STACKTOP + (i32.add + (get_global $memoryBase) + (i32.const 32) + ) + ) + (set_global $STACK_MAX + (i32.add + (get_global $STACKTOP) + (i32.const 5242880) + ) + ) + (call $runPostSets) + (call $__GLOBAL__sub_I_liblib_cpp) + ) +) diff --git a/test/dynamicLibrary.fromasm.imprecise.no-opts b/test/dynamicLibrary.fromasm.imprecise.no-opts new file mode 100644 index 000000000..c29478fdb --- /dev/null +++ b/test/dynamicLibrary.fromasm.imprecise.no-opts @@ -0,0 +1,191 @@ +(module + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "abortStackOverflow" (func $abortStackOverflow (param i32))) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 0 0 anyfunc)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $STACKTOP (mut i32) (i32.const 0)) + (global $STACK_MAX (mut i32) (i32.const 0)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntP (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempBigIntR (mut f64) (f64.const 0)) + (global $tempBigIntI (mut i32) (i32.const 0)) + (global $tempBigIntD (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (global $_global i32 (i32.const 5242912)) + (export "__ZN3FooC2Ev" (func $__ZN3FooC2Ev)) + (export "__post_instantiate" (func $__post_instantiate)) + (export "runPostSets" (func $runPostSets)) + (export "_global" (global $_global)) + (func $stackAlloc (param $size i32) (result i32) + (local $ret i32) + (set_local $ret + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (get_local $size) + ) + ) + (set_global $STACKTOP + (i32.and + (i32.add + (get_global $STACKTOP) + (i32.const 15) + ) + (i32.const -16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (get_local $size) + ) + ) + (return + (get_local $ret) + ) + ) + (func $stackSave (result i32) + (return + (get_global $STACKTOP) + ) + ) + (func $stackRestore (param $top i32) + (set_global $STACKTOP + (get_local $top) + ) + ) + (func $establishStackSpace (param $stackBase i32) (param $stackMax i32) + (set_global $STACKTOP + (get_local $stackBase) + ) + (set_global $STACK_MAX + (get_local $stackMax) + ) + ) + (func $setThrew (param $threw i32) (param $value i32) + (if + (i32.eq + (get_global $__THREW__) + (i32.const 0) + ) + (block + (set_global $__THREW__ + (get_local $threw) + ) + (set_global $threwValue + (get_local $value) + ) + ) + ) + ) + (func $___cxx_global_var_init + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (call $__ZN3FooC2Ev + (i32.add + (get_global $memoryBase) + (i32.const 5242912) + ) + ) + (return) + ) + (func $__ZN3FooC2Ev (param $$0 i32) + (local $$1 i32) + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (i32.const 16) + ) + ) + (set_local $$1 + (get_local $$0) + ) + (drop + (call $_puts + (i32.add + (get_global $memoryBase) + (i32.const 0) + ) + ) + ) + (set_global $STACKTOP + (get_local $sp) + ) + (return) + ) + (func $__GLOBAL__sub_I_liblib_cpp + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (call $___cxx_global_var_init) + (return) + ) + (func $runPostSets + (local $temp i32) + (nop) + ) + (func $__post_instantiate + (set_global $STACKTOP + (i32.add + (get_global $memoryBase) + (i32.const 32) + ) + ) + (set_global $STACK_MAX + (i32.add + (get_global $STACKTOP) + (i32.const 5242880) + ) + ) + (call $runPostSets) + (call $__GLOBAL__sub_I_liblib_cpp) + ) +) diff --git a/test/dynamicLibrary.fromasm.no-opts b/test/dynamicLibrary.fromasm.no-opts new file mode 100644 index 000000000..c29478fdb --- /dev/null +++ b/test/dynamicLibrary.fromasm.no-opts @@ -0,0 +1,191 @@ +(module + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "abortStackOverflow" (func $abortStackOverflow (param i32))) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 0 0 anyfunc)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $STACKTOP (mut i32) (i32.const 0)) + (global $STACK_MAX (mut i32) (i32.const 0)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntP (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempBigIntR (mut f64) (f64.const 0)) + (global $tempBigIntI (mut i32) (i32.const 0)) + (global $tempBigIntD (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (global $_global i32 (i32.const 5242912)) + (export "__ZN3FooC2Ev" (func $__ZN3FooC2Ev)) + (export "__post_instantiate" (func $__post_instantiate)) + (export "runPostSets" (func $runPostSets)) + (export "_global" (global $_global)) + (func $stackAlloc (param $size i32) (result i32) + (local $ret i32) + (set_local $ret + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (get_local $size) + ) + ) + (set_global $STACKTOP + (i32.and + (i32.add + (get_global $STACKTOP) + (i32.const 15) + ) + (i32.const -16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (get_local $size) + ) + ) + (return + (get_local $ret) + ) + ) + (func $stackSave (result i32) + (return + (get_global $STACKTOP) + ) + ) + (func $stackRestore (param $top i32) + (set_global $STACKTOP + (get_local $top) + ) + ) + (func $establishStackSpace (param $stackBase i32) (param $stackMax i32) + (set_global $STACKTOP + (get_local $stackBase) + ) + (set_global $STACK_MAX + (get_local $stackMax) + ) + ) + (func $setThrew (param $threw i32) (param $value i32) + (if + (i32.eq + (get_global $__THREW__) + (i32.const 0) + ) + (block + (set_global $__THREW__ + (get_local $threw) + ) + (set_global $threwValue + (get_local $value) + ) + ) + ) + ) + (func $___cxx_global_var_init + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (call $__ZN3FooC2Ev + (i32.add + (get_global $memoryBase) + (i32.const 5242912) + ) + ) + (return) + ) + (func $__ZN3FooC2Ev (param $$0 i32) + (local $$1 i32) + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (if + (i32.ge_s + (get_global $STACKTOP) + (get_global $STACK_MAX) + ) + (call $abortStackOverflow + (i32.const 16) + ) + ) + (set_local $$1 + (get_local $$0) + ) + (drop + (call $_puts + (i32.add + (get_global $memoryBase) + (i32.const 0) + ) + ) + ) + (set_global $STACKTOP + (get_local $sp) + ) + (return) + ) + (func $__GLOBAL__sub_I_liblib_cpp + (local $label i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) + (call $___cxx_global_var_init) + (return) + ) + (func $runPostSets + (local $temp i32) + (nop) + ) + (func $__post_instantiate + (set_global $STACKTOP + (i32.add + (get_global $memoryBase) + (i32.const 32) + ) + ) + (set_global $STACK_MAX + (i32.add + (get_global $STACKTOP) + (i32.const 5242880) + ) + ) + (call $runPostSets) + (call $__GLOBAL__sub_I_liblib_cpp) + ) +) |