Skip to content

Commit

Permalink
Added the parameter types parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
DanRuta committed Sep 28, 2017
1 parent 9868e26 commit 9a8201d
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 45 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# wasm-arrays
[![Build Status](https://travis-ci.org/DanRuta/wasm-arrays.svg?branch=master)](https://travis-ci.org/DanRuta/wasm-arrays) [![Coverage Status](https://coveralls.io/repos/github/DanRuta/wasm-arrays/badge.svg?branch=master)](https://coveralls.io/github/DanRuta/wasm-arrays?branch=master)

A couple of helper functions to make WebAssembly array parameters easy to use.

## Importing
Expand All @@ -19,7 +20,7 @@ You can see the ```test.js``` file to see more nodejs examples.

**There are a few examples included in the demo.html, test.js and emscripten.cpp files, for their respective use cases**

The included functions aim to mimick the WebAssembly ccall and cwrap functions. They therefore work the same way. Currently, the parameter types array is not included, but it will be in the near future.
The included functions aim to mimick the WebAssembly ccall and cwrap functions. They therefore work the same way.

If you need to pass an array parameter, you need to just add the parameter to the list of parameters.

Expand All @@ -30,7 +31,7 @@ In the C++ code, this will be turned into two parameters:
#### Example:
JavaScript
```javascript
const result = ccallArrays("addNums", "number", [[1,2,3,4,5,6,7]])
const result = ccallArrays("addNums", "number", ["array"], [[1,2,3,4,5,6,7]])
```
C++
```c++
Expand All @@ -52,7 +53,7 @@ To return an array from WebAssembly, you need to specify the return parameter as
#### Example:
JavaScript
```javascript
const res = ccallArrays("doubleValues", "array", [[1,2,3,4,5]], {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
const res = ccallArrays("doubleValues", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
console.log(res) // [2,4,6,8,10]
```
C++
Expand Down
6 changes: 3 additions & 3 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

window.addEventListener("wasmLoaded", () => {

console.log(ccallArrays("getSetWASMArray", "array", [[1,2,3,4,5], 12345, [2, 10]], {heapIn: "HEAPF32", returnArraySize: 5}))
console.log(ccallArrays("getSetWASMArray", "array", ["array", "number", "array"], [[1,2,3,4,5], 12345, [2, 10]], {heapIn: "HEAPF32", returnArraySize: 5}))

console.log(ccallArrays("get10Nums", "array", null, {heapOut: "HEAP32", returnArraySize: 10}))
console.log(ccallArrays("get10Nums", "array", null, null, {heapOut: "HEAP32", returnArraySize: 10}))

console.log(ccallArrays("addNums", "number", [[1,2,3,4,5]]))
console.log(ccallArrays("addNums", "number", ["array"], [[1,2,3,4,5]]))

})

Expand Down
19 changes: 10 additions & 9 deletions dev/wasm-arrays.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict"

const ccallArrays = (func, returnType, params, {heapIn="HEAPF32", heapOut="HEAPF32", returnArraySize=1}={}) => {
const ccallArrays = (func, returnType, paramTypes=[], params, {heapIn="HEAPF32", heapOut="HEAPF32", returnArraySize=1}={}) => {

const heapMap = {}
heapMap.HEAP8 = Int8Array // int8_t
Expand All @@ -12,21 +12,18 @@ const ccallArrays = (func, returnType, params, {heapIn="HEAPF32", heapOut="HEAPF
heapMap.HEAPF32 = Float32Array // float
heapMap.HEAPF64 = Float64Array // double

let res
let error
const returnTypeParam = returnType=="array" ? "number" : returnType
const parameters = []
const parameterTypes = []
const bufs = []
let res
let error

try {
if (params) {
for (let p=0; p<params.length; p++) {

if (!Array.isArray(params[p])) {
parameters.push(params[p])
parameterTypes.push(typeof params[p])
} else {
if (paramTypes[p] == "array" || Array.isArray(params[p])) {

const typedArray = new heapMap[heapIn](params[p].length)

Expand Down Expand Up @@ -56,6 +53,10 @@ const ccallArrays = (func, returnType, params, {heapIn="HEAPF32", heapOut="HEAPF
parameters.push(params[p].length)
parameterTypes.push("number")
parameterTypes.push("number")

} else {
parameters.push(params[p])
parameterTypes.push(paramTypes[p]==undefined ? "number" : paramTypes[p])
}
}
}
Expand Down Expand Up @@ -84,8 +85,8 @@ const ccallArrays = (func, returnType, params, {heapIn="HEAPF32", heapOut="HEAPF
}
}

const cwrapArrays = (func, returnType, {heapIn="HEAPF32", heapOut="HEAPF32", returnArraySize=1}={}) => {
return params => ccallArrays(func, returnType, params, {heapIn, heapOut, returnArraySize})
const cwrapArrays = (func, returnType, paramTypes, {heapIn="HEAPF32", heapOut="HEAPF32", returnArraySize=1}={}) => {
return params => ccallArrays(func, returnType, paramTypes, params, {heapIn, heapOut, returnArraySize})
}

typeof window=="undefined" && ((exports.ccallArrays = ccallArrays) & (exports.cwrapArrays = cwrapArrays))
2 changes: 1 addition & 1 deletion dist/wasm-arrays.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 28 additions & 29 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,163 +19,162 @@ it("Loads ok", () => {
describe("ccallArrays", () => {

it("Demo Example 1", () => {
const res = ccallArrays("getSetWASMArray", "array", [[1,2,3,4,5], 12345, [2, 10]], {heapIn: "HEAPF32", returnArraySize: 5})
const res = ccallArrays("getSetWASMArray", "array", ["array", "number", "array"], [[1,2,3,4,5], 12345, [2, 10]], {heapIn: "HEAPF32", returnArraySize: 5})
expect(res).to.deep.equal([20,40,60,80,100])
})

it("Demo example 2", () => {
const res = ccallArrays("get10Nums", "array", null, {heapOut: "HEAP32", returnArraySize: 10})
const res = ccallArrays("get10Nums", "array", null, null, {heapOut: "HEAP32", returnArraySize: 10})
expect(res).to.deep.equal([1,2,3,4,5,6,7,8,9,10])
})

it("Demo example 3", () => {
const res = ccallArrays("addNums", "number", [[1,2,3,4,5,6,7]])
const res = ccallArrays("addNums", "number", ["array"], [[1,2,3,4,5,6,7]])
expect(res).to.equal(28)
})

it("HEAP8 in and out using 'HEAP8' config", () => {
const res = ccallArrays("testHEAP8", "array", [[1,2,3,4,5]], {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
const res = ccallArrays("testHEAP8", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU8 in and out using 'HEAPU8' config", () => {
const res = ccallArrays("testHEAPU8", "array", [[1,2,3,4,5]], {heapIn: "HEAPU8", heapOut: "HEAPU8", returnArraySize: 5})
const res = ccallArrays("testHEAPU8", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAPU8", heapOut: "HEAPU8", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAP16 in and out using 'HEAP16' config", () => {
const res = ccallArrays("testHEAP16", "array", [[1,2,3,4,5]], {heapIn: "HEAP16", heapOut: "HEAP16", returnArraySize: 5})
const res = ccallArrays("testHEAP16", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAP16", heapOut: "HEAP16", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU16 in and out using 'HEAPU16' config", () => {
const res = ccallArrays("testHEAPU16", "array", [[1,2,3,4,5]], {heapIn: "HEAPU16", heapOut: "HEAPU16", returnArraySize: 5})
const res = ccallArrays("testHEAPU16", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAPU16", heapOut: "HEAPU16", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAP32 in and out using 'HEAP32' config", () => {
const res = ccallArrays("testHEAP32", "array", [[1,2,3,4,5]], {heapIn: "HEAP32", heapOut: "HEAP32", returnArraySize: 5})
const res = ccallArrays("testHEAP32", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAP32", heapOut: "HEAP32", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU32 in and out using 'HEAPU32' config", () => {
const res = ccallArrays("testHEAPU32", "array", [[1,2,3,4,5]], {heapIn: "HEAPU32", heapOut: "HEAPU32", returnArraySize: 5})
const res = ccallArrays("testHEAPU32", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAPU32", heapOut: "HEAPU32", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPF32 in and out using 'HEAPF32' config", () => {
const res = ccallArrays("testHEAPF32", "array", [[1,2,3,4,5]], {heapIn: "HEAPF32", heapOut: "HEAPF32", returnArraySize: 5})
const res = ccallArrays("testHEAPF32", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAPF32", heapOut: "HEAPF32", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("Defaults the HEAP values to HEAPF32", () => {
const res = ccallArrays("testHEAPF32", "array", [[1,2,3,4,5]], {returnArraySize: 5})
const res = ccallArrays("testHEAPF32", "array", ["array"], [[1,2,3,4,5]], {returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPF64 in and out using 'HEAPF64' config", () => {
const res = ccallArrays("testHEAPF64", "array", [[1,2,3,4,5]], {heapIn: "HEAPF64", heapOut: "HEAPF64", returnArraySize: 5})
const res = ccallArrays("testHEAPF64", "array", ["array"], [[1,2,3,4,5]], {heapIn: "HEAPF64", heapOut: "HEAPF64", returnArraySize: 5})
expect(res).to.deep.equal([2,4,6,8,10])
})

it("Returns original value when return type is not array", () => {
const res = ccallArrays("addNums", null, [[1,2,3]], {heapIn: "HEAP32"})
const res = ccallArrays("addNums", null, ["array"], [[1,2,3]], {heapIn: "HEAP32"})
expect(Array.isArray(res)).to.be.false
})

it("Throws errors, but first it frees the memory using Module._free", () => {
sinon.stub(Module, "_free")
expect(ccallArrays.bind(null, "addNums", "array", [[1,2,3]], {heapIn: "HEAP32", heapOut: "HEAP3fdgd2"})).to.throw()
expect(ccallArrays.bind(null, "addNums", "array", ["array"], [[1,2,3]], {heapIn: "HEAP32", heapOut: "HEAP3fdgd2"})).to.throw()
expect(Module._free).to.be.called
Module._free.restore()
})
})



describe("cwrapArrays", () => {

it("Demo Example 1", () => {
const fn = cwrapArrays("getSetWASMArray", "array", {heapIn: "HEAPF32", returnArraySize: 5})
const fn = cwrapArrays("getSetWASMArray", "array", ["array", "number", "array"], {heapIn: "HEAPF32", returnArraySize: 5})
const res = fn([[1,2,3,4,5], 12345, [2, 10]])
expect(res).to.deep.equal([20,40,60,80,100])
})

it("Demo example 2", () => {
const fn = cwrapArrays("get10Nums", "array", {heapOut: "HEAP32", returnArraySize: 10})
const fn = cwrapArrays("get10Nums", "array", null, {heapOut: "HEAP32", returnArraySize: 10})
const res = fn(null)
expect(res).to.deep.equal([1,2,3,4,5,6,7,8,9,10])
})

it("Demo example 3", () => {
const fn = cwrapArrays("addNums", "number")
const fn = cwrapArrays("addNums", "number", ["array"])
const res = fn([[1,2,3,4,5,6,7]])
expect(res).to.equal(28)
})

it("HEAP8 in and out using 'HEAP8' config", () => {
const fn = cwrapArrays("testHEAP8", "array", {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
const fn = cwrapArrays("testHEAP8", "array", ["array"], {heapIn: "HEAP8", heapOut: "HEAP8", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU8 in and out using 'HEAPU8' config", () => {
const fn = cwrapArrays("testHEAPU8", "array", {heapIn: "HEAPU8", heapOut: "HEAPU8", returnArraySize: 5})
const fn = cwrapArrays("testHEAPU8", "array", ["array"], {heapIn: "HEAPU8", heapOut: "HEAPU8", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAP16 in and out using 'HEAP16' config", () => {
const fn = cwrapArrays("testHEAP16", "array", {heapIn: "HEAP16", heapOut: "HEAP16", returnArraySize: 5})
const fn = cwrapArrays("testHEAP16", "array", ["array"], {heapIn: "HEAP16", heapOut: "HEAP16", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU16 in and out using 'HEAPU16' config", () => {
const fn = cwrapArrays("testHEAPU16", "array", {heapIn: "HEAPU16", heapOut: "HEAPU16", returnArraySize: 5})
const fn = cwrapArrays("testHEAPU16", "array", ["array"], {heapIn: "HEAPU16", heapOut: "HEAPU16", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAP32 in and out using 'HEAP32' config", () => {
const fn = cwrapArrays("testHEAP32", "array", {heapIn: "HEAP32", heapOut: "HEAP32", returnArraySize: 5})
const fn = cwrapArrays("testHEAP32", "array", ["array"], {heapIn: "HEAP32", heapOut: "HEAP32", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPU32 in and out using 'HEAPU32' config", () => {
const fn = cwrapArrays("testHEAPU32", "array", {heapIn: "HEAPU32", heapOut: "HEAPU32", returnArraySize: 5})
const fn = cwrapArrays("testHEAPU32", "array", ["array"], {heapIn: "HEAPU32", heapOut: "HEAPU32", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPF32 in and out using 'HEAPF32' config", () => {
const fn = cwrapArrays("testHEAPF32", "array", {heapIn: "HEAPF32", heapOut: "HEAPF32", returnArraySize: 5})
const fn = cwrapArrays("testHEAPF32", "array", ["array"], {heapIn: "HEAPF32", heapOut: "HEAPF32", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("Defaults the HEAP values to HEAPF32", () => {
const fn = cwrapArrays("testHEAPF32", "array", {returnArraySize: 5})
const fn = cwrapArrays("testHEAPF32", "array", ["array"], {returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("HEAPF64 in and out using 'HEAPF64' config", () => {
const fn = cwrapArrays("testHEAPF64", "array", {heapIn: "HEAPF64", heapOut: "HEAPF64", returnArraySize: 5})
const fn = cwrapArrays("testHEAPF64", "array", ["array"], {heapIn: "HEAPF64", heapOut: "HEAPF64", returnArraySize: 5})
const res = fn([[1,2,3,4,5]])
expect(res).to.deep.equal([2,4,6,8,10])
})

it("Returns original value when return type is not array", () => {
const fn = cwrapArrays("addNums", null, {heapIn: "HEAP32"})
const fn = cwrapArrays("addNums", null, ["array"], {heapIn: "HEAP32"})
const res = fn([[1,2,3]])
expect(Array.isArray(res)).to.be.false
})

it("Throws errors, but first it frees the memory using Module._free", () => {
sinon.stub(Module, "_free")
const fn = cwrapArrays("addNums", "array", {heapIn: "HEAP32", heapOut: "HEAP3fdgd2"})
const fn = cwrapArrays("addNums", "array", ["array"], {heapIn: "HEAP32", heapOut: "HEAP3fdgd2"})
expect(fn.bind(null, [[1,2,3]])).to.throw()
expect(Module._free).to.be.called
Module._free.restore()
Expand Down

0 comments on commit 9a8201d

Please sign in to comment.