Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
89 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,16 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
// @flow | ||
|
||
const runtime = require('@polkadot/client-wasm-runtime'); | ||
import type { RuntimeExports } from '@polkadot/client-wasm-runtime/types'; | ||
|
||
const createMemory = require('./memory'); | ||
const createTable = require('./table'); | ||
|
||
module.exports = function createImports (imports?: WebAssemblyImports = {}, initialMemory?: number, maximumMemory?: number): WebAssemblyImports { | ||
imports.env = imports.env || {}; | ||
imports.env.memoryBase = imports.env.memoryBase || 0; | ||
imports.env.tableBase = imports.env.tableBase || 0; | ||
|
||
if (!imports.env.memory) { | ||
// $FlowFixMe imports.env gets a value above | ||
imports.env.memory = createMemory(initialMemory, maximumMemory); | ||
} | ||
|
||
if (!imports.env.table) { | ||
// $FlowFixMe imports.env gets a value above | ||
imports.env.table = createTable(); | ||
} | ||
|
||
imports.env = Object.assign(imports.env, runtime(imports.env.memory)); | ||
|
||
return imports; | ||
// flowlint-next-line unclear-type:off | ||
module.exports = function createImports (memory: WebAssembly.Memory, table: WebAssembly.Table, runtime: RuntimeExports, imports?: Object = {}): WebAssemblyImports { | ||
return Object.assign({}, imports, { | ||
env: Object.assign({}, runtime, { | ||
memory, | ||
memoryBase: 0, | ||
table, | ||
tableBase: 0 | ||
}) | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,116 +1,42 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
|
||
const runtime = require('@polkadot/client-wasm-runtime'); | ||
const isInstanceOf = require('@polkadot/util/is/instanceOf'); | ||
|
||
const { createImports } = require('./index'); | ||
|
||
describe('createImports', () => { | ||
let imports; | ||
let origWebAssembly; | ||
let memOptions; | ||
|
||
beforeEach(() => { | ||
imports = {}; | ||
origWebAssembly = global.WebAssembly; | ||
|
||
global.WebAssembly = class { | ||
static Memory = class { | ||
constructor (options) { | ||
this.buffer = new Uint8Array(10); | ||
memOptions = options; | ||
} | ||
}; | ||
static Table = class {}; | ||
}; | ||
}); | ||
|
||
afterEach(() => { | ||
global.WebAssembly = origWebAssembly; | ||
}); | ||
|
||
it('works when import has not been specified', () => { | ||
it('sets the memoryBase & tableBase', () => { | ||
expect( | ||
createImports() | ||
).toBeDefined(); | ||
}); | ||
|
||
it('exposes the default imports on env', () => { | ||
expect( | ||
createImports({}).env | ||
).toMatchObject( | ||
Object.keys(runtime).reduce((env, key) => { | ||
env[key] = expect.anything(); | ||
|
||
return env; | ||
}, {}) | ||
); | ||
}); | ||
|
||
it('uses env.memoryBase when supplied', () => { | ||
imports.env = { memoryBase: 'test' }; | ||
imports = createImports(imports); | ||
|
||
expect(imports.env.memoryBase).toEqual('test'); | ||
}); | ||
|
||
it('uses env.tableBase when supplied', () => { | ||
imports.env = { tableBase: 'test' }; | ||
imports = createImports(imports); | ||
|
||
expect(imports.env.tableBase).toEqual('test'); | ||
}); | ||
|
||
it('uses env.memory when supplied', () => { | ||
const memory = { buffer: new Uint8Array(10) }; | ||
|
||
imports.env = { memory }; | ||
imports = createImports(imports); | ||
|
||
expect(imports.env.memory).toEqual(memory); | ||
createImports({}, {}, {}).env | ||
).toMatchObject({ | ||
memoryBase: 0, | ||
tableBase: 0 | ||
}); | ||
}); | ||
|
||
it('creates env.memory when none supplied', () => { | ||
imports = createImports(imports); | ||
it('uses supplied memory', () => { | ||
const memory = { 'some': { 'memory': { 'object': true } } }; | ||
|
||
expect( | ||
isInstanceOf( | ||
imports.env.memory, WebAssembly.Memory | ||
) | ||
).toEqual(true); | ||
createImports(memory, {}, {}).env | ||
).toMatchObject({ | ||
memory | ||
}); | ||
}); | ||
|
||
it('creates env.memory using the supplied initial/maximum', () => { | ||
createImports(imports, 4, 6); | ||
it('uses supplied table', () => { | ||
const table = { 'some': { 'table': { 'object': true } } }; | ||
|
||
expect( | ||
memOptions | ||
).toEqual({ | ||
initial: (4 * 1024) / 64, | ||
maximum: (6 * 1024) / 64 | ||
createImports({}, table, {}).env | ||
).toMatchObject({ | ||
table | ||
}); | ||
}); | ||
|
||
it('uses env.table when supplied', () => { | ||
imports.env = { table: 'test' }; | ||
imports = createImports(imports); | ||
|
||
expect(imports.env.table).toEqual('test'); | ||
}); | ||
|
||
it('creates env.table when none supplied', () => { | ||
imports = createImports(imports); | ||
it('exposes the runtime imports on the env', () => { | ||
const runtime = { 'ext_foo': 1, 'ext_bar': 2, 'ext_baz': 3 }; | ||
|
||
expect( | ||
isInstanceOf( | ||
imports.env.table, WebAssembly.Table | ||
) | ||
).toEqual(true); | ||
}); | ||
|
||
it('sets default environment when none supplied', () => { | ||
imports = createImports(); | ||
|
||
expect(imports.env).toBeDefined(); | ||
createImports({}, {}, runtime).env | ||
).toMatchObject(runtime); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
// @flow | ||
|
||
module.exports = function createInstance (module: WebAssemblyModule, imports: WebAssemblyImports): WebAssemblyInstance { | ||
return new WebAssembly.Instance(module, imports); | ||
module.exports = function createInstance (wasmModule: WebAssemblyModule, imports: WebAssemblyImports): WebAssemblyInstance { | ||
return new WebAssembly.Instance(wasmModule, imports); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
// @flow | ||
|
||
const Wasm = require('./wasm'); | ||
const wasm = require('./wasm'); | ||
|
||
module.exports = Wasm; | ||
module.exports = wasm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,21 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
// @flow | ||
|
||
const assert = require('@polkadot/util/assert'); | ||
const isObject = require('@polkadot/util/is/object'); | ||
import type { ConfigType } from '@polkadot/client/types'; | ||
import type { DbInterface } from '@polkadot/client-db/types'; | ||
import type { WasmExtraImports } from './types'; | ||
|
||
const { createImports, createInstance, createModule } = require('./create'); | ||
const createRuntime = require('@polkadot/client-wasm-runtime'); | ||
|
||
module.exports = class Wasm { | ||
constructor (instance: WebAssemblyInstance) { | ||
const exports = instance.exports; | ||
const { createImports, createInstance, createMemory, createModule, createTable } = require('./create'); | ||
|
||
assert(isObject(exports), 'Expected function exports'); | ||
module.exports = function wasm ({ wasm: { memoryInitial, memoryMaximum } }: ConfigType, db: DbInterface, bytecode: Uint8Array, imports?: WasmExtraImports = {}): WebAssemblyInstance$Exports { | ||
const memory = createMemory(memoryInitial, memoryMaximum); | ||
const table = createTable(); | ||
const runtime = createRuntime(memory, db); | ||
|
||
Object.keys(exports).forEach((key: string) => { | ||
Object.defineProperty(this, key, { | ||
configurable: false, | ||
enumerable: true, | ||
value: exports[key] | ||
}); | ||
}); | ||
} | ||
|
||
static fromCode (bytecode: Uint8Array, _imports?: WebAssemblyImports): Wasm { | ||
const module = createModule(bytecode); | ||
const imports = createImports(_imports); | ||
const instance = createInstance(module, imports); | ||
|
||
return new Wasm(instance); | ||
} | ||
return createInstance( | ||
createModule(bytecode), | ||
createImports(memory, table, runtime, imports) | ||
).exports; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,60 @@ | ||
// ISC, Copyright 2017-2018 Jaco Greeff | ||
|
||
const isInstanceOf = require('@polkadot/util/is/instanceOf'); | ||
|
||
const { loadWasm } = require('../test/helpers'); | ||
const Wasm = require('./wasm'); | ||
const wasm = require('./wasm'); | ||
|
||
describe('Wasm', () => { | ||
describe('checks', () => { | ||
let origWebAssembly; | ||
describe('wasm', () => { | ||
let instance; | ||
|
||
describe('valid modules', () => { | ||
beforeEach(() => { | ||
origWebAssembly = global.WebAssembly; | ||
|
||
global.WebAssembly = class { | ||
static Module = class {}; | ||
static Memory = class {}; | ||
static Table = class {}; | ||
static Instance = class {}; | ||
}; | ||
}); | ||
|
||
afterEach(() => { | ||
global.WebAssembly = origWebAssembly; | ||
instance = wasm( | ||
{ wasm: {} }, {}, | ||
loadWasm('addTwo.wasm') | ||
); | ||
}); | ||
|
||
it('disallows empty exports', () => { | ||
it('allows calls into the module', () => { | ||
expect( | ||
() => new Wasm(new WebAssembly.Instance()) | ||
).toThrow(/Expected function exports/); | ||
instance.addTwo(22, 33) | ||
).toEqual(55); | ||
}); | ||
}); | ||
|
||
describe('instance', () => { | ||
let wasm; | ||
describe('imports', () => { | ||
let callback; | ||
let instance; | ||
|
||
describe('valid modules', () => { | ||
beforeEach(() => { | ||
wasm = Wasm.fromCode( | ||
loadWasm('addTwo.wasm') | ||
); | ||
}); | ||
|
||
it('creates a valid instance via fromCode', () => { | ||
expect( | ||
isInstanceOf(wasm, Wasm) | ||
).toEqual(true); | ||
}); | ||
|
||
it('allows calls into the module', () => { | ||
expect( | ||
wasm.addTwo(22, 33) | ||
).toEqual(55); | ||
}); | ||
beforeEach(() => { | ||
callback = jest.fn(); | ||
instance = wasm( | ||
{ wasm: {} }, {}, | ||
loadWasm('import.wasm'), | ||
{ js: { callback } } | ||
); | ||
}); | ||
|
||
describe('imports', () => { | ||
let callback; | ||
let wasm; | ||
it('allows imports to be called', () => { | ||
instance.go(123); | ||
|
||
beforeEach(() => { | ||
callback = jest.fn(); | ||
wasm = Wasm.fromCode( | ||
loadWasm('import.wasm'), | ||
{ js: { callback } } | ||
); | ||
}); | ||
|
||
it('allows imports to be called', () => { | ||
wasm.go(123); | ||
|
||
expect(callback).toHaveBeenCalledWith(123); | ||
}); | ||
expect(callback).toHaveBeenCalledWith(123); | ||
}); | ||
}); | ||
|
||
describe('start', () => { | ||
let callback; | ||
// let wasm; | ||
|
||
beforeEach(() => { | ||
callback = jest.fn(); | ||
Wasm.fromCode( | ||
loadWasm('start.wasm'), | ||
{ js: { callback } } | ||
); | ||
}); | ||
describe('start', () => { | ||
let callback; | ||
|
||
it('allows imports to be called', () => { | ||
// wasm.go(123); | ||
beforeEach(() => { | ||
callback = jest.fn(); | ||
instance = wasm( | ||
{ wasm: {} }, {}, | ||
loadWasm('start.wasm'), | ||
{ js: { callback } } | ||
); | ||
}); | ||
|
||
expect(callback).toHaveBeenCalledWith(1337); | ||
}); | ||
it('allows imports to be called', () => { | ||
expect(callback).toHaveBeenCalledWith(1337); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters