From 61d3b0203bbdf28ce9d1e8ab2ab678013f15ce60 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Tue, 4 Apr 2017 15:43:11 -0700 Subject: [PATCH 1/4] Typescript declaration file for WebAssembly JS API --- types/webassembly-js-api/README.md | 17 +++ types/webassembly-js-api/index.d.ts | 103 ++++++++++++++++++ types/webassembly-js-api/tsconfig.json | 22 ++++ types/webassembly-js-api/tslint.json | 1 + .../webassembly-js-api-tests.ts | 75 +++++++++++++ 5 files changed, 218 insertions(+) create mode 100644 types/webassembly-js-api/README.md create mode 100644 types/webassembly-js-api/index.d.ts create mode 100644 types/webassembly-js-api/tsconfig.json create mode 100644 types/webassembly-js-api/tslint.json create mode 100644 types/webassembly-js-api/webassembly-js-api-tests.ts diff --git a/types/webassembly-js-api/README.md b/types/webassembly-js-api/README.md new file mode 100644 index 0000000000..a034040f92 --- /dev/null +++ b/types/webassembly-js-api/README.md @@ -0,0 +1,17 @@ +# WebAssembly typescript declaration file + +## Installation +``` +npm install @types/webassembly-js-api --save-dev +``` + +The WebAssembly namespace will now be available to your code TypeScript code. +See [WebAssembly JS API](http://webassembly.org/getting-started/js-api/) and the contents of +@types/webassembly-js-api/index.d.ts for more details. + +Do not use an `import * as WebAssembly from "webassembly-js-api"` as this will cause +the `tsc` to emit a `require` statement for the WebAssembly module which doesn't exist as +WebAssembly is part of the global namespace. + +Instead use a `///` statement. +Note: this `` maybe optional, but YMMV. diff --git a/types/webassembly-js-api/index.d.ts b/types/webassembly-js-api/index.d.ts new file mode 100644 index 0000000000..8912892200 --- /dev/null +++ b/types/webassembly-js-api/index.d.ts @@ -0,0 +1,103 @@ +/** + * WebAssembly v1 (MVP) declaration file for TypeScript + * Definitions by: 01alchemist (https://twitter.com/01alchemist) + * and Wink Saville + */ + +declare namespace WebAssembly { + /** + * WebAssembly.Module + */ + class Module { + constructor(bufferSource: ArrayBuffer | Uint8Array); + static customSections(module: Module, sectionName: string): ArrayBuffer[]; + static exports(module: Module): Array<{ + name: string; + kind: string; + }>; + static imports(module: Module): Array<{ + module: string; + name: string; + kind: string; + }>; + } + + /** + * WebAssembly.Instance + */ + class Instance { + readonly exports: any; + constructor(module: Module, importObject?: any); + } + + /** + * WebAssembly.Memory + * Note: A WebAssembly page has a constant size of 65,536 bytes, i.e., 64KiB. + */ + interface MemoryDescriptor { + initial: number; + maximum?: number; + } + + class Memory { + readonly buffer: ArrayBuffer; + constructor(memoryDescriptor: MemoryDescriptor); + grow(numPages: number): number; + } + + /** + * WebAssembly.Table + */ + interface TableDescriptor { + element: "anyfunc"; + initial: number; + maximum?: number; + } + + class Table { + readonly length: number; + constructor(tableDescriptor: TableDescriptor); + get(index: number): (args: any[]) => any; + grow(numElements: number): number; + set(index: number, value: (args: any[]) => any): void; + } + + /** + * Errors + */ + class CompileError extends Error { + readonly fileName: string; + readonly lineNumber: string; + readonly columnNumber: string; + constructor(message?: string, fileName?: string, lineNumber?: number); + toString(): string; + } + + class LinkError extends Error { + readonly fileName: string; + readonly lineNumber: string; + readonly columnNumber: string; + constructor(message?: string, fileName?: string, lineNumber?: number); + toString(): string; + } + + class RuntimeError extends Error { + readonly fileName: string; + readonly lineNumber: string; + readonly columnNumber: string; + constructor(message?: string, fileName?: string, lineNumber?: number); + toString(): string; + } + + function compile(bufferSource: ArrayBuffer | Uint8Array): Promise; + + interface ResultObject { + module: Module; + instance: Instance; + } + + function instantiate(bufferSource: ArrayBuffer | Uint8Array, importObject?: any): Promise; + function instantiate(module: Module, importObject?: any): Promise; + + function validate(bufferSource: ArrayBuffer | Uint8Array): boolean; +} diff --git a/types/webassembly-js-api/tsconfig.json b/types/webassembly-js-api/tsconfig.json new file mode 100644 index 0000000000..581bbbdf29 --- /dev/null +++ b/types/webassembly-js-api/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "webassembly-js-api-tests.ts" + ] +} diff --git a/types/webassembly-js-api/tslint.json b/types/webassembly-js-api/tslint.json new file mode 100644 index 0000000000..377cc837d4 --- /dev/null +++ b/types/webassembly-js-api/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" } diff --git a/types/webassembly-js-api/webassembly-js-api-tests.ts b/types/webassembly-js-api/webassembly-js-api-tests.ts new file mode 100644 index 0000000000..5b62354070 --- /dev/null +++ b/types/webassembly-js-api/webassembly-js-api-tests.ts @@ -0,0 +1,75 @@ +function debug(s: string) { + // debug(s) +} + +// Table +let table = new WebAssembly.Table({element: "anyfunc", initial: 1, maximum: 10}); +debug(`table.length=${table.length}`); +debug(`table.get(0)=${table.get(0)}`); +table.grow(1); + +// Memory +let memory = new WebAssembly.Memory({initial: 2, maximum: 8}); +debug(`memory.grow(6)=${memory.grow(6)}`); +let u8 = new Uint8Array(memory.buffer); +u8[0] = 1; +u8[1] = 2; +debug(`u8[0]=${u8[0]}`); +debug(`u8[1]=${u8[1]}`); + +let wasmDataU8 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7]); +debug(`wasmDataU8.length=${wasmDataU8.length}`); +debug(`wasmDataU8[0]=${wasmDataU8[0].toString(16)}`); +debug(`wasmDataU8[1]=${wasmDataU8[1].toString(16)}`); +debug(`wasmDataU8[2]=${wasmDataU8[2].toString(16)}`); +debug(`wasmDataU8[3]=${wasmDataU8[3].toString(16)}`); +debug(`wasmDataU8[4]=${wasmDataU8[4].toString(16)}`); +debug(`wasmDataU8[5]=${wasmDataU8[5].toString(16)}`); +debug(`wasmDataU8[6]=${wasmDataU8[6].toString(16)}`); +debug(`wasmDataU8[7]=${wasmDataU8[7].toString(16)}`); + +// Validate +let valid = WebAssembly.validate(wasmDataU8); +debug("wasmDataU8 is " + (valid ? "" : "not ") + "a valid wasm wasmModule"); + +// Module +let wasmModule = new WebAssembly.Module(wasmDataU8); +debug(`wasmModule=${wasmModule}`); + +// CustomSections +let nameSections = WebAssembly.Module.customSections(wasmModule, "name"); +debug(`Module contains ${nameSections.length} name sections`); +if (nameSections.length !== 0) { + debug("Module contains a name section"); + debug(nameSections[0].toString()); +} + +// Instance +let instance = new WebAssembly.Instance(wasmModule); +debug(`instance=${instance}`); +debug(`instance.exports=${instance.exports}`); + +// Compile Asynchronously +debug("instantiateAsync compile:"); +WebAssembly.compile(wasmDataU8).then((mod: WebAssembly.Module) => { + debug(`instantiateAsync compiled: ${JSON.stringify(mod)}`); +}); + +// Instantiate +// Primary overload — taking wasm binary code +WebAssembly.instantiate(wasmDataU8).then((result: WebAssembly.ResultObject) => { + debug(`Primary overload mod=${result.module}`); + debug(`Primary overload inst=${result.instance}`); + debug(`Primary exec instance.exports.addTwo1(-1, 1)=${result.instance.exports.addTwo1(-1, 1)}`); +}); + +// Instantiate +// Secondary overload — taking a Module object +WebAssembly.instantiate(wasmModule).then((instance: WebAssembly.Instance) => { + debug(`Secondary overload instance=${instance}`); + debug(`Secondary exec instance.exports.addTwo1(0, -1)=${instance.exports.addTwo1(0, -1)}`); +}); + +// Validate +WebAssembly.validate(new ArrayBuffer(8)); +WebAssembly.validate(wasmDataU8); From 484d180bffb68a6b005f4f846772efe0e52b39a7 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 5 Apr 2017 08:58:42 -0700 Subject: [PATCH 2/4] Add proper header for index.d.ts --- types/webassembly-js-api/index.d.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/types/webassembly-js-api/index.d.ts b/types/webassembly-js-api/index.d.ts index 8912892200..300cdaab54 100644 --- a/types/webassembly-js-api/index.d.ts +++ b/types/webassembly-js-api/index.d.ts @@ -1,9 +1,7 @@ -/** - * WebAssembly v1 (MVP) declaration file for TypeScript - * Definitions by: 01alchemist (https://twitter.com/01alchemist) - * and Wink Saville - */ - +// Type definitions for WebAssembly v1 (MVP) +// Project: https://github.com/winksaville/test-webassembly-js-ts +// Definitions by: 01alchemist (https://twitter.com/01alchemist) && Wink Saville (https://github.com/winksaville) +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare namespace WebAssembly { /** * WebAssembly.Module From cc4ea4af88130defe9894868cfcfc56ca1239251 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 5 Apr 2017 09:12:47 -0700 Subject: [PATCH 3/4] Remove README.md move contents ti index.d.ts Also only a single author. --- types/webassembly-js-api/README.md | 17 ----------------- types/webassembly-js-api/index.d.ts | 26 +++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 18 deletions(-) delete mode 100644 types/webassembly-js-api/README.md diff --git a/types/webassembly-js-api/README.md b/types/webassembly-js-api/README.md deleted file mode 100644 index a034040f92..0000000000 --- a/types/webassembly-js-api/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# WebAssembly typescript declaration file - -## Installation -``` -npm install @types/webassembly-js-api --save-dev -``` - -The WebAssembly namespace will now be available to your code TypeScript code. -See [WebAssembly JS API](http://webassembly.org/getting-started/js-api/) and the contents of -@types/webassembly-js-api/index.d.ts for more details. - -Do not use an `import * as WebAssembly from "webassembly-js-api"` as this will cause -the `tsc` to emit a `require` statement for the WebAssembly module which doesn't exist as -WebAssembly is part of the global namespace. - -Instead use a `///` statement. -Note: this `` maybe optional, but YMMV. diff --git a/types/webassembly-js-api/index.d.ts b/types/webassembly-js-api/index.d.ts index 300cdaab54..d8e7ee0932 100644 --- a/types/webassembly-js-api/index.d.ts +++ b/types/webassembly-js-api/index.d.ts @@ -1,7 +1,31 @@ // Type definitions for WebAssembly v1 (MVP) // Project: https://github.com/winksaville/test-webassembly-js-ts -// Definitions by: 01alchemist (https://twitter.com/01alchemist) && Wink Saville (https://github.com/winksaville) +// Definitions by: 01alchemist // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/** + * WebAssembly v1 (MVP) declaration file for TypeScript + * + * Authors: 01alchemist + * and Wink Saville + * + * ## Installation + * ``` + * npm install @types/webassembly-js-api --save-dev + * ``` + * + * The WebAssembly namespace will now be available to your code TypeScript code. + * See [WebAssembly JS API](http://webassembly.org/getting-started/js-api/) and the contents of + * @types/webassembly-js-api/index.d.ts for more details. + * + * Do not use an `import * as WebAssembly from "webassembly-js-api"` as this will cause + * the `tsc` to emit a `require` statement for the WebAssembly module which doesn't exist as + * WebAssembly is part of the global namespace. + * + * Instead use a `///` statement. + * Note: this `` maybe optional, but YMMV. + */ + declare namespace WebAssembly { /** * WebAssembly.Module From 3b4f31e155fe71a4bd50731f7201454c669ca21d Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 5 Apr 2017 10:12:09 -0700 Subject: [PATCH 4/4] Use comma to separate authors and streamline second comment. --- types/webassembly-js-api/index.d.ts | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/types/webassembly-js-api/index.d.ts b/types/webassembly-js-api/index.d.ts index d8e7ee0932..4e7b0d52bf 100644 --- a/types/webassembly-js-api/index.d.ts +++ b/types/webassembly-js-api/index.d.ts @@ -1,31 +1,13 @@ // Type definitions for WebAssembly v1 (MVP) // Project: https://github.com/winksaville/test-webassembly-js-ts -// Definitions by: 01alchemist +// Definitions by: 01alchemist , Wink Saville // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /** - * WebAssembly v1 (MVP) declaration file for TypeScript - * - * Authors: 01alchemist - * and Wink Saville - * - * ## Installation - * ``` - * npm install @types/webassembly-js-api --save-dev - * ``` - * - * The WebAssembly namespace will now be available to your code TypeScript code. - * See [WebAssembly JS API](http://webassembly.org/getting-started/js-api/) and the contents of - * @types/webassembly-js-api/index.d.ts for more details. - * - * Do not use an `import * as WebAssembly from "webassembly-js-api"` as this will cause - * the `tsc` to emit a `require` statement for the WebAssembly module which doesn't exist as - * WebAssembly is part of the global namespace. - * - * Instead use a `///` statement. - * Note: this `` maybe optional, but YMMV. + * The WebAssembly namespace, see [WebAssembly](https://github.com/webassembly) + * and [WebAssembly JS API](http://webassembly.org/getting-started/js-api/) + * for more information. */ - declare namespace WebAssembly { /** * WebAssembly.Module