From: Wink Saville Date: Sat, 1 Apr 2017 06:32:37 +0000 (-0700) Subject: This now compiles and runs if node v8.0.0 is used. X-Git-Tag: otter-0.2.0~707^2~5^2 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=d64ba9b67d1489f0ac780559c308434cab015a80;p=otter.git This now compiles and runs if node v8.0.0 is used. Node v8.0.0 is not yet released and must be downloaded or compiled from source. My testing was with node tip of tree master at --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5cbb9a79 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +*.swp +*.log diff --git a/README.md b/README.md index ee3b7afe..02cc0ea6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,13 @@ # WebAssembly Types Typescript declaration for WebAssembly JS API + +NOTE: Node.js v8.0.0 is the first version that will +support WebAssembly MVP. Since it's not yet released +we assume its been downloaded or compiled locally +and the executable is ../node/node. According to +[this](https://github.com/nodejs/node/issues/12090#issuecomment-289755110) +v8.0.0 should be released by end of April 2017. + +I tested by compiling [node](https://github.com/nodejs/node) +from sources on master branch at sha1 +[c68da89694b1ff4682131ed6b825e596188cc4ed](https://github.com/nodejs/node/commit/c68da89694b1ff4682131ed6b825e596188cc4ed) diff --git a/package.json b/package.json index 0057103e..7cf46620 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,13 @@ { "scripts": { "pretest": "tsc -p test/tsconfig.json", - "test": "node --expose-wasm test/wasm.js" + "test": "../node/node --expose_wasm test/wasm.js" + }, + "devDependencies": { + "@types/node": "^7.0.12", + "typescript": "^2.2.2" + }, + "dependencies": { + "node": "^0.0.0" } } diff --git a/test/addTwo.tbs b/test/addTwo.tbs new file mode 100755 index 00000000..4d571586 --- /dev/null +++ b/test/addTwo.tbs @@ -0,0 +1,3 @@ +export function addTwo1(a:int32, b:int32): int32 { + return a + b; +} diff --git a/test/addTwo.wasm b/test/addTwo.wasm new file mode 100644 index 00000000..ce8d8ffd Binary files /dev/null and b/test/addTwo.wasm differ diff --git a/test/wasm.js b/test/wasm.js index e205405b..1de64425 100644 --- a/test/wasm.js +++ b/test/wasm.js @@ -2,57 +2,138 @@ * Created by Nidin Vinayakan on 31/03/17. */ /// -let source = new Uint8Array(1); -//Table +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("fs"); +function displayModExports(prompt, mod) { + let exports = WebAssembly.Module.exports(mod); + console.log(`${prompt} length=${exports.length}`); + for (let i in exports) { + let v = exports[i]; + console.log(`${prompt}[${i}] name=${v.name} kind=${v.kind}`); + } +} +function displayModImports(prompt, mod) { + let imports = WebAssembly.Module.imports(mod); + console.log(`${prompt} length=${imports.length}`); + for (let i in imports) { + let v = imports[i]; + console.log(`${prompt}[${i}] name=${v.name} kind=${v.kind}`); + } +} +function readFileAsync(filePath) { + return new Promise((resolve, reject) => { + fs.readFile(filePath, (err, data) => { + if (err) { + return reject(err); + } + else { + return resolve(new Uint8Array(data)); + } + }); + }); +} +// Table let table = new WebAssembly.Table({ element: "anyfunc", initial: 1, maximum: 10 }); console.log(`table.length=${table.length}`); console.log(`table.get(0)=${table.get(0)}`); -table.set(0, function () { -}); +//table.set(0, function () { +//}); table.grow(1); -//Memory -let memory = new WebAssembly.Memory({ initial: 2, maximum: 4 }); -console.log(`memory.grow(8)=${memory.grow(8)}`); +// Memory +let memory = new WebAssembly.Memory({ initial: 2, maximum: 8 }); +console.log(`memory.grow(6)=${memory.grow(6)}`); let u8 = new Uint8Array(memory.buffer); u8[0] = 1; u8[1] = 2; console.log(`u8[0]=${u8[0]}`); console.log(`u8[1]=${u8[1]}`); -//Module -let wasmModule = new WebAssembly.Module(source); -//customSections +let data = fs.readFileSync('./test/addTwo.wasm'); +let wasmDataU8 = new Uint8Array(data); +console.log(`data.buffer.byteLength=${data.buffer.byteLength}`); +console.log(`wasmDataU8.length=${wasmDataU8.length}`); +console.log(`wasmDataU8[0]=${wasmDataU8[0].toString(16)}`); +console.log(`wasmDataU8[1]=${wasmDataU8[1].toString(16)}`); +console.log(`wasmDataU8[2]=${wasmDataU8[2].toString(16)}`); +console.log(`wasmDataU8[3]=${wasmDataU8[3].toString(16)}`); +console.log(`wasmDataU8[4]=${wasmDataU8[4].toString(16)}`); +console.log(`wasmDataU8[5]=${wasmDataU8[5].toString(16)}`); +console.log(`wasmDataU8[6]=${wasmDataU8[6].toString(16)}`); +console.log(`wasmDataU8[7]=${wasmDataU8[7].toString(16)}`); +// Validate +let valid = WebAssembly.validate(wasmDataU8); +console.log("wasmDataU8 is " + (valid ? "" : "not ") + "a valid wasm wasmModule"); +// Module +let wasmModule = new WebAssembly.Module(wasmDataU8); +console.log(`wasmModule=${wasmModule}`); +// CustomSections let nameSections = WebAssembly.Module.customSections(wasmModule, "name"); +console.log(`Module contains ${nameSections.length} name sections`); if (nameSections.length != 0) { console.log("Module contains a name section"); console.log(nameSections[0]); } -//exports -console.log(WebAssembly.Module.exports(wasmModule).length); -console.log(WebAssembly.Module.exports(wasmModule)[0].name); -console.log(WebAssembly.Module.exports(wasmModule)[0].kind); -//imports -console.log(WebAssembly.Module.imports(wasmModule).length); -console.log(WebAssembly.Module.imports(wasmModule)[0].module); -console.log(WebAssembly.Module.imports(wasmModule)[0].name); -console.log(WebAssembly.Module.imports(wasmModule)[0].kind); -//Instance +// Display Exports +displayModExports('wasmModule.exports', wasmModule); +// Display Imports +displayModImports('wasmModule.imports', wasmModule); +// Instance let instance = new WebAssembly.Instance(wasmModule); -console.log(instance.exports.exported_func()); -let bytes = new ArrayBuffer(1); //dummy bytes -//validate -let valid = WebAssembly.validate(bytes); -console.log("The given bytes are " + (valid ? "" : "not ") + "a valid wasm wasmModule"); -//compile -WebAssembly.compile(bytes).then((module) => { - console.log(wasmModule); +console.log(`instance=${instance}`); +console.log(`instance.exports=${instance.exports}`); +//displayExports('instance.exports', instance.exports); +console.log(`addTwo1(1,2)=${instance.exports.addTwo1(1, 2)}`); +// Instantiate +// Primary overload — taking wasm binary code +WebAssembly.instantiate(wasmDataU8).then((result) => { + console.log(`Primary overload mod=${result.module}`); + console.log(`Primary overload inst=${result.instance}`); + console.log(`Primary exec instance.exports..addTwo1(-1,1)=${result.instance.exports.addTwo1(-1, 1)}`); }); -//instantiate -//Primary overload — taking wasm binary code -WebAssembly.instantiate(bytes).then((result) => { - console.log(result.module); - console.log(result.instance); -}); -//Secondary overload — taking a wasmModule object instance +// Instantiate +// Secondary overload — taking a Module object WebAssembly.instantiate(wasmModule).then((instance) => { - console.log(instance); + console.log(`Secondary overload instance=${instance}`); + console.log(`Secondary exec instance.exports..addTwo1(0,-1)=${instance.exports.addTwo1(0, -1)}`); +}); +function instantiateFile(filePath) { + return __awaiter(this, void 0, void 0, function* () { + console.log("instantiateFile:+ readFile"); + let instance = yield readFileAsync("./test/addTwo.wasm") + .then(data => { + console.log("instantiateFile fileRead:"); + console.log(`data.length=${data.length}`); + console.log(`data[0]=${data[0].toString(16)}`); + console.log(`data[1]=${data[1].toString(16)}`); + console.log(`data[2]=${data[2].toString(16)}`); + console.log(`data[3]=${data[3].toString(16)}`); + console.log(`data[4]=${data[4].toString(16)}`); + console.log(`data[5]=${data[5].toString(16)}`); + console.log(`data[6]=${data[6].toString(16)}`); + console.log(`data[7]=${data[7].toString(16)}`); + // Compile + console.log("instantiateFile compile:"); + return Promise.resolve(WebAssembly.compile(data)); + }) + .then(mod => { + console.log("instantiateFile compiled return Module:"); + return Promise.resolve(WebAssembly.instantiate(mod)); + }); + console.log("instantiateFile:-"); + return instance; + }); +} +// Use instantiateFile +console.log("call instantiateFile"); +instantiateFile("./test/addTwo.wasm").then(inst => { + console.log(`done instantiateFile inst=${inst}`); + console.log(`exec inst.exports..addTwo1(0,0)=${inst.exports.addTwo1(0, 0)}`); }); diff --git a/test/wasm.ts b/test/wasm.ts index 4ae6e94b..194e3a8b 100644 --- a/test/wasm.ts +++ b/test/wasm.ts @@ -3,65 +3,142 @@ */ /// -let source: Uint8Array = new Uint8Array(1); +import * as fs from "fs"; -//Table +function displayModExports(prompt: string, mod: WebAssembly.Module) { + let exports = WebAssembly.Module.exports(mod); + console.log(`${prompt} length=${exports.length}`); + for (let i in exports) { + let v = exports[i]; + console.log(`${prompt}[${i}] name=${v.name} kind=${v.kind}`); + } +} + +function displayModImports(prompt: string, mod: WebAssembly.Module) { + let imports = WebAssembly.Module.imports(mod); + console.log(`${prompt} length=${imports.length}`); + for (let i in imports) { + let v = imports[i]; + console.log(`${prompt}[${i}] name=${v.name} kind=${v.kind}`); + } +} + +function readFileAsync(filePath: string): Promise { + return new Promise((resolve, reject) => { + fs.readFile(filePath, (err, data) => { + if (err) { + return reject(err); + } else { + return resolve(new Uint8Array(data)); + } + }); + }); +} + +// Table let table = new WebAssembly.Table({element: "anyfunc", initial: 1, maximum: 10}); console.log(`table.length=${table.length}`); console.log(`table.get(0)=${table.get(0)}`); -table.set(0, function () { -}); +//table.set(0, function () { +//}); table.grow(1); -//Memory -let memory = new WebAssembly.Memory({initial: 2, maximum: 4}); -console.log(`memory.grow(8)=${memory.grow(8)}`); +// Memory +let memory = new WebAssembly.Memory({initial: 2, maximum: 8}); +console.log(`memory.grow(6)=${memory.grow(6)}`); let u8 = new Uint8Array(memory.buffer); u8[0] = 1; u8[1] = 2; console.log(`u8[0]=${u8[0]}`); console.log(`u8[1]=${u8[1]}`); -//Module -let wasmModule = new WebAssembly.Module(source); -//customSections +let data = fs.readFileSync('./test/addTwo.wasm'); +let wasmDataU8 = new Uint8Array(data); +console.log(`data.buffer.byteLength=${data.buffer.byteLength}`); +console.log(`wasmDataU8.length=${wasmDataU8.length}`); +console.log(`wasmDataU8[0]=${wasmDataU8[0].toString(16)}`); +console.log(`wasmDataU8[1]=${wasmDataU8[1].toString(16)}`); +console.log(`wasmDataU8[2]=${wasmDataU8[2].toString(16)}`); +console.log(`wasmDataU8[3]=${wasmDataU8[3].toString(16)}`); +console.log(`wasmDataU8[4]=${wasmDataU8[4].toString(16)}`); +console.log(`wasmDataU8[5]=${wasmDataU8[5].toString(16)}`); +console.log(`wasmDataU8[6]=${wasmDataU8[6].toString(16)}`); +console.log(`wasmDataU8[7]=${wasmDataU8[7].toString(16)}`); + +// Validate +let valid = WebAssembly.validate(wasmDataU8); +console.log("wasmDataU8 is " + (valid ? "" : "not ") + "a valid wasm wasmModule"); + +// Module +let wasmModule = new WebAssembly.Module(wasmDataU8); +console.log(`wasmModule=${wasmModule}`); + +// CustomSections let nameSections = WebAssembly.Module.customSections(wasmModule, "name"); +console.log(`Module contains ${nameSections.length} name sections`); if (nameSections.length != 0) { - console.log("Module contains a name section"); - console.log(nameSections[0]); + console.log("Module contains a name section"); + console.log(nameSections[0]); } -//exports -console.log(WebAssembly.Module.exports(wasmModule).length); -console.log(WebAssembly.Module.exports(wasmModule)[0].name); -console.log(WebAssembly.Module.exports(wasmModule)[0].kind); -//imports -console.log(WebAssembly.Module.imports(wasmModule).length); -console.log(WebAssembly.Module.imports(wasmModule)[0].module); -console.log(WebAssembly.Module.imports(wasmModule)[0].name); -console.log(WebAssembly.Module.imports(wasmModule)[0].kind); - -//Instance -let instance = new WebAssembly.Instance(wasmModule); -console.log(instance.exports.exported_func()); +// Display Exports +displayModExports('wasmModule.exports', wasmModule); -let bytes = new ArrayBuffer(1);//dummy bytes -//validate -let valid = WebAssembly.validate(bytes); -console.log("The given bytes are " + (valid ? "" : "not ") + "a valid wasm wasmModule"); +// Display Imports +displayModImports('wasmModule.imports', wasmModule); -//compile -WebAssembly.compile(bytes).then((module: WebAssembly.Module) => { - console.log(wasmModule); -}); +// Instance +let instance = new WebAssembly.Instance(wasmModule); +console.log(`instance=${instance}`); +console.log(`instance.exports=${instance.exports}`); +//displayExports('instance.exports', instance.exports); +console.log(`addTwo1(1,2)=${instance.exports.addTwo1(1,2)}`); -//instantiate -//Primary overload — taking wasm binary code -WebAssembly.instantiate(bytes).then((result: WebAssembly.ResultObject) => { - console.log(result.module); - console.log(result.instance); +// Instantiate +// Primary overload — taking wasm binary code +WebAssembly.instantiate(wasmDataU8).then((result: WebAssembly.ResultObject) => { + console.log(`Primary overload mod=${result.module}`); + console.log(`Primary overload inst=${result.instance}`); + console.log(`Primary exec instance.exports..addTwo1(-1,1)=${result.instance.exports.addTwo1(-1,1)}`); }); -//Secondary overload — taking a wasmModule object instance + +// Instantiate +// Secondary overload — taking a Module object WebAssembly.instantiate(wasmModule).then((instance: WebAssembly.Instance) => { - console.log(instance); + console.log(`Secondary overload instance=${instance}`); + console.log(`Secondary exec instance.exports..addTwo1(0,-1)=${instance.exports.addTwo1(0,-1)}`); +}); + +async function instantiateFile(filePath: string): Promise { + console.log("instantiateFile:+ readFile"); + let instance = await readFileAsync("./test/addTwo.wasm") + .then(data => { + console.log("instantiateFile fileRead:"); + console.log(`data.length=${data.length}`); + console.log(`data[0]=${data[0].toString(16)}`); + console.log(`data[1]=${data[1].toString(16)}`); + console.log(`data[2]=${data[2].toString(16)}`); + console.log(`data[3]=${data[3].toString(16)}`); + console.log(`data[4]=${data[4].toString(16)}`); + console.log(`data[5]=${data[5].toString(16)}`); + console.log(`data[6]=${data[6].toString(16)}`); + console.log(`data[7]=${data[7].toString(16)}`); + + // Compile + console.log("instantiateFile compile:"); + return Promise.resolve(WebAssembly.compile(data)); + }) + .then(mod => { + console.log("instantiateFile compiled return Module:"); + return Promise.resolve(WebAssembly.instantiate(mod)); + }); + console.log("instantiateFile:-"); + return instance; +} + +// Use instantiateFile +console.log("call instantiateFile"); +instantiateFile("./test/addTwo.wasm").then(inst => { + console.log(`done instantiateFile inst=${inst}`) + console.log(`exec inst.exports..addTwo1(0,0)=${inst.exports.addTwo1(0,0)}`); }); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..747c0607 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,15 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/node@^7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9" + +node@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/node/-/node-0.0.0.tgz#288d62f90530c763eff8d4831ee7343ab3d60793" + +typescript@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c"