Commit 6a5f857a376a1e31ae18a4fd65720456f048c611
added tests
wanderer committed on 3/14/2017, 10:56:03 PMParent: d437e946d7e817f50952f0f77abebbce532e671e
Files changed
index.js | changed |
package.json | changed |
README.md | added |
tests/index.js | added |
tests/wasm/asyncTest.wasm | added |
tests/wasm/asyncTest.wast | added |
tests/wasm/testCode.wasm | added |
tests/wasm/testCode.wast | added |
tests/wasm/testMem.wasm | added |
tests/wasm/testMem.wast | added |
index.js | ||
---|---|---|
@@ -1,50 +1,62 @@ | ||
1 | -module.exports = class Wasm { | |
1 … | +module.exports = class WasmContainer { | |
2 | 2 … | /** |
3 | 3 … | * The interface API is the api the exposed to interfaces. All queries about |
4 | 4 … | * the enviroment and call to the kernel go through this API |
5 | 5 … | */ |
6 | 6 … | constructor (code) { |
7 | 7 … | this._module = WebAssembly.Module(code) |
8 | 8 … | } |
9 … | + | |
10 … | + static get name () { | |
11 … | + return 'wasm' | |
12 … | + } | |
9 | 13 … | /** |
10 | 14 … | * Runs the core VM with a given environment and imports |
11 | 15 … | */ |
12 | - async run (message, kernel, imports) { | |
16 … | + async run (message, kernel, imports = []) { | |
13 | 17 … | const responses = {} |
14 | 18 … | /** |
15 | 19 … | * Builds a import map with an array of given interfaces |
16 | 20 … | */ |
17 | - async function buildImports (kernelApi, kernel, imports) { | |
21 … | + function buildImports (opts, imports) { | |
18 | 22 … | const importMap = {} |
19 | 23 … | for (const Import of imports) { |
20 | - const response = responses[Import.name] = {} | |
21 | - const newIterface = new Import(kernelApi, message, response) | |
22 | - importMap[Import.name] = newIterface.exports | |
23 | - // initailize the import | |
24 | - await newIterface.initialize() | |
24 … | + const name = Import.name | |
25 … | + opts.response = responses[name] = {} | |
26 … | + const newInterface = new Import(opts) | |
27 … | + const props = Object.getOwnPropertyNames(Import.prototype) | |
28 … | + | |
29 … | + // bind the methods to the correct 'this' | |
30 … | + importMap[name] = {} | |
31 … | + for (const prop of props) { | |
32 … | + importMap[name][prop] = newInterface[prop].bind(newInterface) | |
33 … | + } | |
25 | 34 … | } |
26 | 35 … | return importMap |
27 | 36 … | } |
28 | 37 … | |
29 | 38 … | let instance |
30 | - const interfaceApi = { | |
31 | - /** | |
32 | - * adds an aync operation to the operations queue | |
33 | - */ | |
34 | - pushOpsQueue: (promise, callbackIndex, intefaceCallback) => { | |
35 | - this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => { | |
36 | - const result = intefaceCallback(values.pop()) | |
37 | - instance.exports.callback.get(callbackIndex)(result) | |
38 | - }) | |
39 … | + | |
40 … | + const opts = { | |
41 … | + vm: { | |
42 … | + /** | |
43 … | + * adds an aync operation to the operations queue | |
44 … | + */ | |
45 … | + pushOpsQueue: (promise, callbackIndex) => { | |
46 … | + this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => { | |
47 … | + const result = values.pop() | |
48 … | + instance.exports.callback.get(callbackIndex)(result) | |
49 … | + }) | |
50 … | + }, | |
51 … | + memory: () => { | |
52 … | + return instance.exports.memory.buffer | |
53 … | + } | |
39 | 54 … | }, |
40 | - memory: () => { | |
41 | - return instance.exports.memory.buffer | |
42 | - }, | |
43 | - kernel: kernel | |
55 … | + kernel: kernel, | |
56 … | + message: message | |
44 | 57 … | } |
45 | - | |
46 | - const initializedImports = await buildImports(interfaceApi, kernel, imports) | |
58 … | + const initializedImports = buildImports(opts, imports) | |
47 | 59 … | instance = WebAssembly.Instance(this._module, initializedImports) |
48 | 60 … | |
49 | 61 … | if (instance.exports.main) { |
50 | 62 … | instance.exports.main() |
package.json | ||
---|---|---|
@@ -1,11 +1,24 @@ | ||
1 | 1 … | { |
2 | - "name": "wasm-harness", | |
3 | - "version": "1.0.0", | |
2 … | + "name": "wasm-container", | |
3 … | + "version": "0.0.0", | |
4 | 4 … | "description": "", |
5 | - "main": "wasmAgent.js", | |
5 … | + "main": "index.js", | |
6 | 6 … | "scripts": { |
7 | - "test": "echo \"Error: no test specified\" && exit 1" | |
7 … | + "coverage": "node --harmony ./node_modules/istanbul/lib/cli.js cover ./tests/index.js", | |
8 … | + "coveralls": "npm run coverage && coveralls <coverage/lcov.info", | |
9 … | + "lint": "standard", | |
10 … | + "test": "node --harmony ./tests/index.js" | |
8 | 11 … | }, |
9 | 12 … | "author": "", |
10 | - "license": "ISC" | |
13 … | + "license": "ISC", | |
14 … | + "standard": { | |
15 … | + "globals": [ | |
16 … | + "WebAssembly" | |
17 … | + ] | |
18 … | + }, | |
19 … | + "devDependencies": { | |
20 … | + "istanbul": "^1.1.0-alpha.1", | |
21 … | + "standard": "^9.0.1", | |
22 … | + "tape": "^4.6.3" | |
23 … | + } | |
11 | 24 … | } |
README.md |
---|
tests/index.js | ||
---|---|---|
@@ -1,0 +1,84 @@ | ||
1 … | +const tape = require('tape') | |
2 … | +const fs = require('fs') | |
3 … | +const WasmContainer = require('../index.js') | |
4 … | + | |
5 … | +const dir = `${__dirname}/wasm/` | |
6 … | + | |
7 … | +tape('interface tests', async t => { | |
8 … | + const code = fs.readFileSync(`${dir}testCode.wasm`) | |
9 … | + class TestInterface { | |
10 … | + constructor (opts) { | |
11 … | + opts.response.test = 'response!' | |
12 … | + } | |
13 … | + | |
14 … | + static get name () { | |
15 … | + return 'test' | |
16 … | + } | |
17 … | + } | |
18 … | + | |
19 … | + t.equals(WasmContainer.name, 'wasm', 'container should have a name') | |
20 … | + | |
21 … | + const container = new WasmContainer(code) | |
22 … | + t.ok(container instanceof WasmContainer, 'should be instance of a container class') | |
23 … | + | |
24 … | + const promise = container.run() | |
25 … | + await promise | |
26 … | + t.ok(promise instanceof Promise, 'run should return instance of promise') | |
27 … | + | |
28 … | + const results = await container.run(null, null, [TestInterface]) | |
29 … | + t.deepEquals(results, { | |
30 … | + 'test': { | |
31 … | + 'test': 'response!' | |
32 … | + } | |
33 … | + }) | |
34 … | + | |
35 … | + t.end() | |
36 … | +}) | |
37 … | + | |
38 … | +tape('wasm interface test', async t => { | |
39 … | + t.plan(1) | |
40 … | + const code = fs.readFileSync(`${dir}testMem.wasm`) | |
41 … | + class TestInterfaceMem { | |
42 … | + constructor (opts) { | |
43 … | + this.opts = opts | |
44 … | + } | |
45 … | + | |
46 … | + static get name () { | |
47 … | + return 'test' | |
48 … | + } | |
49 … | + | |
50 … | + memory () { | |
51 … | + const memory = this.opts.vm.memory() | |
52 … | + t.ok(memory instanceof ArrayBuffer, 'should have access to memory') | |
53 … | + } | |
54 … | + } | |
55 … | + const container = new WasmContainer(code) | |
56 … | + await container.run(null, null, [TestInterfaceMem]) | |
57 … | +}) | |
58 … | + | |
59 … | +tape('async wasm interface test', async t => { | |
60 … | + t.plan(1) | |
61 … | + const code = fs.readFileSync(`${dir}asyncTest.wasm`) | |
62 … | + class TestInterfaceMem { | |
63 … | + constructor (opts) { | |
64 … | + this.opts = opts | |
65 … | + } | |
66 … | + | |
67 … | + static get name () { | |
68 … | + return 'test' | |
69 … | + } | |
70 … | + | |
71 … | + async (cbOffset) { | |
72 … | + const opPromise = new Promise((resolve, reject) => { | |
73 … | + resolve() | |
74 … | + }) | |
75 … | + this.opts.vm.pushOpsQueue(opPromise, cbOffset) | |
76 … | + } | |
77 … | + | |
78 … | + done () { | |
79 … | + t.ok(true) | |
80 … | + } | |
81 … | + } | |
82 … | + const container = new WasmContainer(code) | |
83 … | + await container.run(null, null, [TestInterfaceMem]) | |
84 … | +}) |
tests/wasm/asyncTest.wast | ||
---|---|---|
@@ -1,0 +1,17 @@ | ||
1 … | +(module | |
2 … | + (import "test" "async" (func $async (param i32))) | |
3 … | + (import "test" "done" (func $done)) | |
4 … | + (table | |
5 … | + (export "callback") | |
6 … | + anyfunc | |
7 … | + (elem | |
8 … | + $callback | |
9 … | + ) | |
10 … | + ) | |
11 … | + (func $callback | |
12 … | + call $done | |
13 … | + ) | |
14 … | + (func $main | |
15 … | + (call $async (i32.const 0)) | |
16 … | + ) | |
17 … | + (export "main" (func $main))) |
tests/wasm/testCode.wast | ||
---|---|---|
@@ -1,0 +1,13 @@ | ||
1 … | +(module | |
2 … | + (func $fac (param i64) (result i64) | |
3 … | + (if i64 | |
4 … | + (i64.lt_s (get_local 0) (i64.const 1)) | |
5 … | + (then (i64.const 1)) | |
6 … | + (else | |
7 … | + (i64.mul | |
8 … | + (get_local 0) | |
9 … | + (call $fac | |
10 … | + (i64.sub | |
11 … | + (get_local 0) | |
12 … | + (i64.const 1))))))) | |
13 … | + (export "fac" (func $fac))) |
Built with git-ssb-web