diff --git a/loader/src/index.cjs b/loader/src/index.cjs index a12e971a4..001e0462a 100644 --- a/loader/src/index.cjs +++ b/loader/src/index.cjs @@ -5,9 +5,10 @@ const Module = (() => { let _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename return ( - function (binary, _limit) { + function (binaryOrInstantiate, _limit) { var Module = Module || {} - Module.wasmBinary = binary // metering.meterWASM(binary, { meterType: 'i32' }).module + if (typeof binaryOrInstantiate === 'function') Module.instantiateWasm = binaryOrInstantiate + else Module.wasmBinary = binaryOrInstantiate /** * Expose gas on the module @@ -138,7 +139,7 @@ module.exports = async function (binary, limit) { return (buffer, msg, env) => { const originalRandom = Math.random - //const OriginalDate = Date + // const OriginalDate = Date const originalLog = console.log try { /** start mock Math.random */ @@ -175,7 +176,7 @@ module.exports = async function (binary, limit) { /** unmock functions */ // eslint-disable-next-line no-global-assign - //Date = OriginalDate + // Date = OriginalDate Math.random = originalRandom console.log = originalLog /** end unmock */ @@ -190,7 +191,7 @@ module.exports = async function (binary, limit) { } } finally { // eslint-disable-next-line no-global-assign - //Date = OriginalDate + // Date = OriginalDate Math.random = originalRandom console.log = originalLog buffer = null diff --git a/loader/test/index.test.js b/loader/test/index.test.js index 436744a16..0e97ff33a 100644 --- a/loader/test/index.test.js +++ b/loader/test/index.test.js @@ -3,6 +3,8 @@ import { describe, it } from 'node:test' import * as assert from 'node:assert' import fs from 'fs' +import { Readable } from 'node:stream' +import { createReadStream } from 'node:fs' /** * dynamic import, so we can run unit tests against the source @@ -16,7 +18,7 @@ const { default: AoLoader } = await import(MODULE_PATH) const wasmBinary = fs.readFileSync('./test/process/process.wasm') describe('loader', async () => { - it('load and execute message passing contract', async () => { + it('load wasm and evaluate message', async () => { const handle = await AoLoader(wasmBinary) const mainResult = await handle(null, { @@ -41,6 +43,45 @@ describe('loader', async () => { assert.ok(true) }) + it('should use separately instantiated WebAssembly.Instance', async () => { + /** + * Non-blocking! + */ + const wasmModuleP = WebAssembly.compileStreaming( + /** + * Could just be a fetch call result, but demonstrating + * that any Response will do + */ + new Response( + Readable.toWeb(createReadStream('./test/process/process.wasm')), + { headers: { 'Content-Type': 'application/wasm' } } + ) + ) + + const handle = await AoLoader((info, receiveInstance) => { + assert.ok(info) + assert.ok(receiveInstance) + wasmModuleP + /** + * Non-Blocking + */ + .then((mod) => WebAssembly.instantiate(mod, info)) + .then((instance) => receiveInstance(instance)) + }) + const result = await handle(null, + { Owner: 'tom', Target: '1', Tags: [{ name: 'Action', value: 'inc' }], Data: '' }, + { Process: { Id: '1', Tags: [] } } + ) + + assert.equal(result.Output, 1) + + const result2 = await handle(result.Memory, + { Owner: 'tom', Target: '1', Tags: [{ name: 'Action', value: 'inc' }], Data: '' }, + { Process: { Id: '1', Tags: [] } } + ) + assert.equal(result2.Output, 2) + }) + it('should load previous memory', async () => { const handle = await AoLoader(wasmBinary) const result = await handle(null,