From 88335787df2c2a1ae34364b65239e2c72228d0f7 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Sun, 30 Jun 2019 09:04:57 -0700 Subject: [PATCH 1/4] wasm2js: fix export of memory growth, only do it when growth is enabled --- src/wasm2js.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index a14aad2a405..1e1e1505c5e 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -578,8 +578,11 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { Ref descs = ValueBuilder::makeObject(); Ref growDesc = ValueBuilder::makeObject(); ValueBuilder::appendToObjectWithQuotes(descs, IString("grow"), growDesc); - ValueBuilder::appendToObjectWithQuotes( - growDesc, IString("value"), ValueBuilder::makeName(WASM_MEMORY_GROW)); + if (wasm->memory.max > wasm->memory.initial) { + ValueBuilder::appendToObjectWithQuotes( + growDesc, IString("value"), + ValueBuilder::makeName(WASM_MEMORY_GROW)); + } Ref bufferDesc = ValueBuilder::makeObject(); Ref bufferGetter = ValueBuilder::makeFunction(IString("")); bufferGetter[3]->push_back( From ce2d2da9a55ba68f822d821882a1713b64737a04 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 1 Jul 2019 14:26:24 -0700 Subject: [PATCH 2/4] add tests --- test/wasm2js/emscripten-grow-no.2asm.js | 78 ++++++++++++++ test/wasm2js/emscripten-grow-no.2asm.js.opt | 78 ++++++++++++++ test/wasm2js/emscripten-grow-no.wast | 7 ++ test/wasm2js/emscripten-grow-yes.2asm.js | 105 +++++++++++++++++++ test/wasm2js/emscripten-grow-yes.2asm.js.opt | 105 +++++++++++++++++++ test/wasm2js/emscripten-grow-yes.wast | 7 ++ 6 files changed, 380 insertions(+) create mode 100644 test/wasm2js/emscripten-grow-no.2asm.js create mode 100644 test/wasm2js/emscripten-grow-no.2asm.js.opt create mode 100644 test/wasm2js/emscripten-grow-no.wast create mode 100644 test/wasm2js/emscripten-grow-yes.2asm.js create mode 100644 test/wasm2js/emscripten-grow-yes.2asm.js.opt create mode 100644 test/wasm2js/emscripten-grow-yes.wast diff --git a/test/wasm2js/emscripten-grow-no.2asm.js b/test/wasm2js/emscripten-grow-no.2asm.js new file mode 100644 index 00000000000..ad2e6a0faf4 --- /dev/null +++ b/test/wasm2js/emscripten-grow-no.2asm.js @@ -0,0 +1,78 @@ +function instantiate(asmLibraryArg, wasmMemory, wasmTable) { + +function asmFunc(global, env, buffer) { + "almost asm"; + var memory = env.memory; + 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 Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + // EMSCRIPTEN_START_FUNCS; + // EMSCRIPTEN_END_FUNCS; + var FUNCTION_TABLE = []; + return { + "memory": Object.create(Object.prototype, { + "grow": { + + }, + "buffer": { + "get": function () { + return buffer; + } + + } + }) + }; +} + +var writeSegment = ( + function(mem) { + var _mem = new Uint8Array(mem); + return function(offset, s) { + if (typeof Buffer === 'undefined') { + var bytes = atob(s); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes.charCodeAt(i); + } else { + var bytes = Buffer.from(s, 'base64'); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes[i]; + } + } + } + )(wasmMemory.buffer); +writeSegment(1600, "YWJj"); +return asmFunc({ + 'Int8Array': Int8Array, + 'Int16Array': Int16Array, + 'Int32Array': Int32Array, + 'Uint8Array': Uint8Array, + 'Uint16Array': Uint16Array, + 'Uint32Array': Uint32Array, + 'Float32Array': Float32Array, + 'Float64Array': Float64Array, + 'NaN': NaN, + 'Infinity': Infinity, + 'Math': Math + }, + asmLibraryArg, + wasmMemory.buffer +) + +} \ No newline at end of file diff --git a/test/wasm2js/emscripten-grow-no.2asm.js.opt b/test/wasm2js/emscripten-grow-no.2asm.js.opt new file mode 100644 index 00000000000..ad2e6a0faf4 --- /dev/null +++ b/test/wasm2js/emscripten-grow-no.2asm.js.opt @@ -0,0 +1,78 @@ +function instantiate(asmLibraryArg, wasmMemory, wasmTable) { + +function asmFunc(global, env, buffer) { + "almost asm"; + var memory = env.memory; + 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 Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + // EMSCRIPTEN_START_FUNCS; + // EMSCRIPTEN_END_FUNCS; + var FUNCTION_TABLE = []; + return { + "memory": Object.create(Object.prototype, { + "grow": { + + }, + "buffer": { + "get": function () { + return buffer; + } + + } + }) + }; +} + +var writeSegment = ( + function(mem) { + var _mem = new Uint8Array(mem); + return function(offset, s) { + if (typeof Buffer === 'undefined') { + var bytes = atob(s); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes.charCodeAt(i); + } else { + var bytes = Buffer.from(s, 'base64'); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes[i]; + } + } + } + )(wasmMemory.buffer); +writeSegment(1600, "YWJj"); +return asmFunc({ + 'Int8Array': Int8Array, + 'Int16Array': Int16Array, + 'Int32Array': Int32Array, + 'Uint8Array': Uint8Array, + 'Uint16Array': Uint16Array, + 'Uint32Array': Uint32Array, + 'Float32Array': Float32Array, + 'Float64Array': Float64Array, + 'NaN': NaN, + 'Infinity': Infinity, + 'Math': Math + }, + asmLibraryArg, + wasmMemory.buffer +) + +} \ No newline at end of file diff --git a/test/wasm2js/emscripten-grow-no.wast b/test/wasm2js/emscripten-grow-no.wast new file mode 100644 index 00000000000..0cc59550e74 --- /dev/null +++ b/test/wasm2js/emscripten-grow-no.wast @@ -0,0 +1,7 @@ +(module + (type $0 (func)) + (import "env" "memory" (memory $0 256 256)) + (data (i32.const 1600) "abc") + (export "memory" (memory $0)) +) + diff --git a/test/wasm2js/emscripten-grow-yes.2asm.js b/test/wasm2js/emscripten-grow-yes.2asm.js new file mode 100644 index 00000000000..1778680b6c2 --- /dev/null +++ b/test/wasm2js/emscripten-grow-yes.2asm.js @@ -0,0 +1,105 @@ +function instantiate(asmLibraryArg, wasmMemory, wasmTable) { + +function asmFunc(global, env, buffer) { + "almost asm"; + var memory = env.memory; + 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 Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + // EMSCRIPTEN_START_FUNCS; + // EMSCRIPTEN_END_FUNCS; + var FUNCTION_TABLE = []; + function __wasm_memory_grow(pagesToAdd) { + pagesToAdd = pagesToAdd | 0; + var oldPages = __wasm_memory_size() | 0; + var newPages = oldPages + pagesToAdd | 0; + if ((oldPages < newPages) && (newPages < 65536)) { + var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536)); + var newHEAP8 = new global.Int8Array(newBuffer); + newHEAP8.set(HEAP8); + HEAP8 = newHEAP8; + HEAP8 = new global.Int8Array(newBuffer); + HEAP16 = new global.Int16Array(newBuffer); + HEAP32 = new global.Int32Array(newBuffer); + HEAPU8 = new global.Uint8Array(newBuffer); + HEAPU16 = new global.Uint16Array(newBuffer); + HEAPU32 = new global.Uint32Array(newBuffer); + HEAPF32 = new global.Float32Array(newBuffer); + HEAPF64 = new global.Float64Array(newBuffer); + buffer = newBuffer; + memory.buffer = newBuffer; + } + return oldPages; + } + + function __wasm_memory_size() { + return buffer.byteLength / 65536 | 0; + } + + return { + "memory": Object.create(Object.prototype, { + "grow": { + "value": __wasm_memory_grow + }, + "buffer": { + "get": function () { + return buffer; + } + + } + }) + }; +} + +var writeSegment = ( + function(mem) { + var _mem = new Uint8Array(mem); + return function(offset, s) { + if (typeof Buffer === 'undefined') { + var bytes = atob(s); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes.charCodeAt(i); + } else { + var bytes = Buffer.from(s, 'base64'); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes[i]; + } + } + } + )(wasmMemory.buffer); +writeSegment(1600, "YWJj"); +return asmFunc({ + 'Int8Array': Int8Array, + 'Int16Array': Int16Array, + 'Int32Array': Int32Array, + 'Uint8Array': Uint8Array, + 'Uint16Array': Uint16Array, + 'Uint32Array': Uint32Array, + 'Float32Array': Float32Array, + 'Float64Array': Float64Array, + 'NaN': NaN, + 'Infinity': Infinity, + 'Math': Math + }, + asmLibraryArg, + wasmMemory.buffer +) + +} \ No newline at end of file diff --git a/test/wasm2js/emscripten-grow-yes.2asm.js.opt b/test/wasm2js/emscripten-grow-yes.2asm.js.opt new file mode 100644 index 00000000000..1778680b6c2 --- /dev/null +++ b/test/wasm2js/emscripten-grow-yes.2asm.js.opt @@ -0,0 +1,105 @@ +function instantiate(asmLibraryArg, wasmMemory, wasmTable) { + +function asmFunc(global, env, buffer) { + "almost asm"; + var memory = env.memory; + 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 Math_imul = global.Math.imul; + var Math_fround = global.Math.fround; + var Math_abs = global.Math.abs; + var Math_clz32 = global.Math.clz32; + var Math_min = global.Math.min; + var Math_max = global.Math.max; + var Math_floor = global.Math.floor; + var Math_ceil = global.Math.ceil; + var Math_sqrt = global.Math.sqrt; + var abort = env.abort; + var nan = global.NaN; + var infinity = global.Infinity; + // EMSCRIPTEN_START_FUNCS; + // EMSCRIPTEN_END_FUNCS; + var FUNCTION_TABLE = []; + function __wasm_memory_grow(pagesToAdd) { + pagesToAdd = pagesToAdd | 0; + var oldPages = __wasm_memory_size() | 0; + var newPages = oldPages + pagesToAdd | 0; + if ((oldPages < newPages) && (newPages < 65536)) { + var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536)); + var newHEAP8 = new global.Int8Array(newBuffer); + newHEAP8.set(HEAP8); + HEAP8 = newHEAP8; + HEAP8 = new global.Int8Array(newBuffer); + HEAP16 = new global.Int16Array(newBuffer); + HEAP32 = new global.Int32Array(newBuffer); + HEAPU8 = new global.Uint8Array(newBuffer); + HEAPU16 = new global.Uint16Array(newBuffer); + HEAPU32 = new global.Uint32Array(newBuffer); + HEAPF32 = new global.Float32Array(newBuffer); + HEAPF64 = new global.Float64Array(newBuffer); + buffer = newBuffer; + memory.buffer = newBuffer; + } + return oldPages; + } + + function __wasm_memory_size() { + return buffer.byteLength / 65536 | 0; + } + + return { + "memory": Object.create(Object.prototype, { + "grow": { + "value": __wasm_memory_grow + }, + "buffer": { + "get": function () { + return buffer; + } + + } + }) + }; +} + +var writeSegment = ( + function(mem) { + var _mem = new Uint8Array(mem); + return function(offset, s) { + if (typeof Buffer === 'undefined') { + var bytes = atob(s); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes.charCodeAt(i); + } else { + var bytes = Buffer.from(s, 'base64'); + for (var i = 0; i < bytes.length; i++) + _mem[offset + i] = bytes[i]; + } + } + } + )(wasmMemory.buffer); +writeSegment(1600, "YWJj"); +return asmFunc({ + 'Int8Array': Int8Array, + 'Int16Array': Int16Array, + 'Int32Array': Int32Array, + 'Uint8Array': Uint8Array, + 'Uint16Array': Uint16Array, + 'Uint32Array': Uint32Array, + 'Float32Array': Float32Array, + 'Float64Array': Float64Array, + 'NaN': NaN, + 'Infinity': Infinity, + 'Math': Math + }, + asmLibraryArg, + wasmMemory.buffer +) + +} \ No newline at end of file diff --git a/test/wasm2js/emscripten-grow-yes.wast b/test/wasm2js/emscripten-grow-yes.wast new file mode 100644 index 00000000000..7323e8efdd8 --- /dev/null +++ b/test/wasm2js/emscripten-grow-yes.wast @@ -0,0 +1,7 @@ +(module + (type $0 (func)) + (import "env" "memory" (memory $0 256 1024)) + (data (i32.const 1600) "abc") + (export "memory" (memory $0)) +) + From db2d4832c6b26fb7d0c2e5ccce13d382dd9f5fe3 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Jul 2019 16:31:02 -0700 Subject: [PATCH 3/4] format --- src/wasm2js.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wasm2js.h b/src/wasm2js.h index 1e1e1505c5e..5c43325477c 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -580,8 +580,7 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { ValueBuilder::appendToObjectWithQuotes(descs, IString("grow"), growDesc); if (wasm->memory.max > wasm->memory.initial) { ValueBuilder::appendToObjectWithQuotes( - growDesc, IString("value"), - ValueBuilder::makeName(WASM_MEMORY_GROW)); + growDesc, IString("value"), ValueBuilder::makeName(WASM_MEMORY_GROW)); } Ref bufferDesc = ValueBuilder::makeObject(); Ref bufferGetter = ValueBuilder::makeFunction(IString("")); From 1e15b0c5c46e3dc1091a3b8939b5011bd24c5c40 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 3 Jul 2019 10:48:07 -0700 Subject: [PATCH 4/4] update tests --- test/wasm2js/emscripten-grow-no.2asm.js | 5 +++-- test/wasm2js/emscripten-grow-no.2asm.js.opt | 5 +++-- test/wasm2js/emscripten-grow-yes.2asm.js | 5 +++-- test/wasm2js/emscripten-grow-yes.2asm.js.opt | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/test/wasm2js/emscripten-grow-no.2asm.js b/test/wasm2js/emscripten-grow-no.2asm.js index ad2e6a0faf4..7f4c1e4ae6c 100644 --- a/test/wasm2js/emscripten-grow-no.2asm.js +++ b/test/wasm2js/emscripten-grow-no.2asm.js @@ -45,12 +45,13 @@ var writeSegment = ( function(mem) { var _mem = new Uint8Array(mem); return function(offset, s) { + var bytes; if (typeof Buffer === 'undefined') { - var bytes = atob(s); + bytes = atob(s); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes.charCodeAt(i); } else { - var bytes = Buffer.from(s, 'base64'); + bytes = Buffer.from(s, 'base64'); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes[i]; } diff --git a/test/wasm2js/emscripten-grow-no.2asm.js.opt b/test/wasm2js/emscripten-grow-no.2asm.js.opt index ad2e6a0faf4..7f4c1e4ae6c 100644 --- a/test/wasm2js/emscripten-grow-no.2asm.js.opt +++ b/test/wasm2js/emscripten-grow-no.2asm.js.opt @@ -45,12 +45,13 @@ var writeSegment = ( function(mem) { var _mem = new Uint8Array(mem); return function(offset, s) { + var bytes; if (typeof Buffer === 'undefined') { - var bytes = atob(s); + bytes = atob(s); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes.charCodeAt(i); } else { - var bytes = Buffer.from(s, 'base64'); + bytes = Buffer.from(s, 'base64'); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes[i]; } diff --git a/test/wasm2js/emscripten-grow-yes.2asm.js b/test/wasm2js/emscripten-grow-yes.2asm.js index 1778680b6c2..0f0027beb1b 100644 --- a/test/wasm2js/emscripten-grow-yes.2asm.js +++ b/test/wasm2js/emscripten-grow-yes.2asm.js @@ -72,12 +72,13 @@ var writeSegment = ( function(mem) { var _mem = new Uint8Array(mem); return function(offset, s) { + var bytes; if (typeof Buffer === 'undefined') { - var bytes = atob(s); + bytes = atob(s); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes.charCodeAt(i); } else { - var bytes = Buffer.from(s, 'base64'); + bytes = Buffer.from(s, 'base64'); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes[i]; } diff --git a/test/wasm2js/emscripten-grow-yes.2asm.js.opt b/test/wasm2js/emscripten-grow-yes.2asm.js.opt index 1778680b6c2..0f0027beb1b 100644 --- a/test/wasm2js/emscripten-grow-yes.2asm.js.opt +++ b/test/wasm2js/emscripten-grow-yes.2asm.js.opt @@ -72,12 +72,13 @@ var writeSegment = ( function(mem) { var _mem = new Uint8Array(mem); return function(offset, s) { + var bytes; if (typeof Buffer === 'undefined') { - var bytes = atob(s); + bytes = atob(s); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes.charCodeAt(i); } else { - var bytes = Buffer.from(s, 'base64'); + bytes = Buffer.from(s, 'base64'); for (var i = 0; i < bytes.length; i++) _mem[offset + i] = bytes[i]; }