From 457e5715bdd73de26930d150edb6d049a9006f6d Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Sun, 19 Apr 2020 04:50:18 +0300 Subject: [PATCH] Update emscripten_lib target --- platforms/emscripten_lib/main.c | 6 +- platforms/emscripten_lib/run_native.js | 28 +++++ platforms/emscripten_lib/run_wasm3.js | 129 +++++++++++++++++++++++ platforms/emscripten_lib/wasm3_run.js | 139 ------------------------- 4 files changed, 160 insertions(+), 142 deletions(-) create mode 100644 platforms/emscripten_lib/run_native.js create mode 100644 platforms/emscripten_lib/run_wasm3.js delete mode 100644 platforms/emscripten_lib/wasm3_run.js diff --git a/platforms/emscripten_lib/main.c b/platforms/emscripten_lib/main.c index 2062955..cfb828d 100644 --- a/platforms/emscripten_lib/main.c +++ b/platforms/emscripten_lib/main.c @@ -43,14 +43,14 @@ void load(IM3Runtime runtime, uint8_t* wasm, size_t fsize) { } EMSCRIPTEN_KEEPALIVE -uint32_t call(IM3Runtime runtime, const char* name, int argc, const char** argv) { +uint32_t call(IM3Runtime runtime, int argc, const char* argv[]) { M3Result result = m3Err_none; IM3Function f; - result = m3_FindFunction (&f, runtime, name); + result = m3_FindFunction (&f, runtime, argv[0]); if (result) return -1; - result = m3_CallWithArgs (f, argc, argv); + result = m3_CallWithArgs (f, argc-1, argv+1); if (result) return -2; return *(uint64_t*)(runtime->stack); diff --git a/platforms/emscripten_lib/run_native.js b/platforms/emscripten_lib/run_native.js new file mode 100644 index 0000000..13c93d1 --- /dev/null +++ b/platforms/emscripten_lib/run_native.js @@ -0,0 +1,28 @@ +'use strict'; + +if (typeof(process) != 'undefined') { // Node.js environment? + var scriptArgs = process.argv.slice(2); + const fs = require('fs'); + var readFile = (fn) => new Uint8Array(fs.readFileSync(fn)); +} else { + var readFile = (fn) => read(fn, 'binary'); +} + +let instances = []; + +(async() => { + const wasm = scriptArgs[0]; + const func = scriptArgs[1]; + const args = scriptArgs.slice(2); + + const binary = readFile(wasm); + + for (let i=0; i<1000; i++) { // V8: 1028 max, SpiderMonkey: 32650 max + let instance = (await WebAssembly.instantiate(binary)).instance; + + instances[i] = instance; + + let result = instance.exports[func](...args); + //console.log(i, result); + } +})(); diff --git a/platforms/emscripten_lib/run_wasm3.js b/platforms/emscripten_lib/run_wasm3.js new file mode 100644 index 0000000..56a80b9 --- /dev/null +++ b/platforms/emscripten_lib/run_wasm3.js @@ -0,0 +1,129 @@ +'use strict'; + +/* + Node.js + ------- + node --v8-options | grep -A1 wasm + --print_wasm_code --code-comments + --wasm_interpret_all --trace_wasm_interpreter + + SpiderMonkey + ------------ + export PATH=/opt/jsshell/:$PATH + js --help | grep wasm + --wasm-compiler=baseline/ion/cranelift/baseline+ion/baseline+cranelift + --wasm-verbose + --ion-full-warmup-threshold=1 +*/ + +if (typeof(process) != 'undefined') { // Node.js environment? + var scriptArgs = process.argv.slice(2); + const fs = require('fs'); + var readFile = (fn) => new Uint8Array(fs.readFileSync(fn)); +} else { + var readFile = (fn) => read(fn, 'binary'); +} + + +// Encode string into Uint8Array (with '\0' terminator) +// Could use TextEncoder instead +function encode(str) { + const len = str.length; + const res = new Uint8Array(len + 1); + let pos = 0; + for (let i = 0; i < len; i++) { + const point = str.charCodeAt(i); + if (point <= 0x007f) { + res[pos++] = point; + } + } + return res.subarray(0, pos + 1); +} + +let instance; +let runtimes = {}; + +const imports = { + "env": { + "emscripten_notify_memory_growth": function() {}, + "emscripten_get_sbrk_ptr": function() {}, + }, + "wasi_snapshot_preview1": { + "fd_close": function() { return -1; }, + "fd_seek": function() { return -1; }, + "fd_write": function() { return -1; }, + "proc_exit": function() { } + } +} + +function load(buff) { + const runtime = instance.exports.new_runtime(); + const ptr = instance.exports.malloc(buff.length); + const mem = new Uint8Array(instance.exports.memory.buffer); + mem.set(buff, ptr); + instance.exports.load(runtime, ptr, buff.length); + runtimes[runtime] = { binary_ptr: ptr } + return runtime; +} + +function unload(runtime) { + if (!runtimes[runtime]) return; + instance.exports.free_runtime(runtime); + instance.exports.free(runtimes[runtime].binary_ptr); + runtimes[runtime] = undefined; +} + +function call(runtime, fname, args) { + // Convert names to buffers + args = [fname].concat(args).map(arg => encode(arg.toString())); + + const arglen = args.length; + let argbytes = arglen*4; + for (let arg of args) { + argbytes += arg.length; + } + + // Allocate the required memory + const buff = instance.exports.malloc(argbytes); + const mem = new Uint8Array(instance.exports.memory.buffer); + const ptrs = new Uint32Array(mem.buffer, buff, arglen); + + // Fill-in memory + let ptr = buff + ptrs.byteLength; + for (let i=0; i { + instance = (await WebAssembly.instantiate(readFile('wasm3.wasm'), imports)).instance; + instance.exports.init(); + + const wasm = scriptArgs[0]; + const func = scriptArgs[1]; + const args = scriptArgs.slice(2); + + const binary = readFile(wasm); + + for (let i=0; i<100000; i++) { + let module = load(binary); + + let result = call(module, func, args); + //console.log(i, result); + + unload(module); + } + + console.log(`Memory size: ${instance.exports.memory.buffer.byteLength/(1024*1024)} MB`); +})(); diff --git a/platforms/emscripten_lib/wasm3_run.js b/platforms/emscripten_lib/wasm3_run.js deleted file mode 100644 index 1fb2c46..0000000 --- a/platforms/emscripten_lib/wasm3_run.js +++ /dev/null @@ -1,139 +0,0 @@ -'use strict'; - -/* - Node.js - ------- - node --v8-options | grep -A1 wasm - --print_wasm_code --code-comments - --wasm_interpret_all --trace_wasm_interpreter - - SpiderMonkey - ------------ - export PATH=/opt/jsshell/:$PATH - js --help | grep wasm - --wasm-compiler=baseline/ion/cranelift/baseline+ion/baseline+cranelift - --wasm-verbose - --ion-full-warmup-threshold=1 -*/ - -const isNodeJS = (typeof(process) != 'undefined'); - -function encode(str) { - var Len = str.length, resPos = -1; - var resArr = new Uint8Array(Len * 3); - for (var i = 0; i !== Len; i += 1) { - var point = str.charCodeAt(i); - if (point <= 0x007f) { - resArr[resPos += 1] = point; - } - } - return resArr.subarray(0, resPos + 1); -} - -if (isNodeJS) { - var scriptArgs = process.argv.slice(2); - const fs = require('fs'); - var readFile = (fn) => new Uint8Array(fs.readFileSync(fn)); -} else { - var readFile = (fn) => read(fn, 'binary'); -} - -const env = { - __memory_base: 0, - __table_base: 0, - "env": { - "emscripten_notify_memory_growth": function() {}, - "emscripten_get_sbrk_ptr": function() {}, - }, - "wasi_snapshot_preview1": { - "fd_close": function() {}, - "fd_seek": function() {}, - "fd_write": function() { return -1; }, - "proc_exit": function() {} - } -} - -var instance; -//let encoder = new TextEncoder('utf-8'); - -function strToMem(s) { - const data = encode(s); - const ptr = instance.exports.malloc(data.length+1); - const buf = new Uint8Array(instance.exports.memory.buffer, ptr, data.length+1); - buf.set(data) - buf[data.length] = 0; - return ptr; -} - -function bufToMem(data) { - const ptr = instance.exports.malloc(data.length); - const buf = new Uint8Array(instance.exports.memory.buffer, ptr, data.length); - buf.set(data) - return ptr; -} - - -function new_runtime() { - return instance.exports.new_runtime(); -} - -function free_runtime(runtime) { - instance.exports.free_runtime(runtime); -} - -function load(runtime, buff) { - const ptr = bufToMem(buff); - instance.exports.load(runtime, ptr, buff.length); -} - -function call(runtime, fname, args) { - const namePtr = strToMem(fname) - - const argsCnt = args.length; - const argsPtr = instance.exports.malloc(argsCnt*4); - const argsArray = new Uint32Array( - instance.exports.memory.buffer, - argsPtr, argsCnt - ); - - args.forEach((item, idx) => { - argsArray[idx] = strToMem(item.toString()); - }) - - return instance.exports.call(runtime, namePtr, argsCnt, argsPtr); -} - -/* TODO: - * - callback/hook exported function calls - * - */ - - -async function main() { - const FILE = scriptArgs[0]; - const FUNC = scriptArgs[1]; - const ARGS = scriptArgs.slice(2); - - for (let i=0; i<25000; i++) { - let rt = new_runtime(); - - load(rt, readFile(FILE)); - - let result = call(rt, FUNC, [1]); - //console.log(i, result); - - free_runtime(rt); - } -} - -try { - WebAssembly.instantiate(readFile('wasm3.wasm'), env).then(result => { - instance = result.instance; - instance.exports.init(); - main(); - - console.log(`Memory size: ${instance.exports.memory.buffer.byteLength}`); - }) -} catch (e) { - console.log(JSON.stringify(e.message)); -}