Skip to content

Commit

Permalink
Add supplemental typing support
Browse files Browse the repository at this point in the history
  • Loading branch information
kateinoigakukun committed Jun 1, 2024
1 parent d492cb2 commit 2991bbb
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 16 deletions.
13 changes: 13 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type ValueType = "i32" | "i64" | "f32" | "f64" | "funcref" | "externref";
type FunctionType = { parameters: ValueType[], results: ValueType[] };
type TableType = { element: "funcref" | "externref", minimum: number, maximum?: number };
type MemoryType = { minimum: number, maximum?: number, shared: boolean, index: "i32" | "i64" };
type GlobalType = { value: ValueType, mutable: boolean };
type ImportEntry = { module: string, name: string } & (
{ kind: "function", type: FunctionType } |
{ kind: "table", type: TableType } |
{ kind: "memory", type: MemoryType } |
{ kind: "global", type: GlobalType }
);

export declare function parseImports(moduleBytes: BufferSource): ImportEntry[]
44 changes: 31 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
// @ts-check
/**
* @typedef {"i32" | "i64" | "f32" | "f64" | "funcref" | "externref"} ValueType
* @typedef { { parameters: ValueType[], results: ValueType[] } } FunctionType
* @typedef { { element: "funcref" | "externref", minimum: number, maximum?: number } } TableType
* @typedef { { minimum: number, maximum?: number, shared: boolean, index: "i32" | "i64" } } MemoryType
* @typedef { { value: ValueType, mutable: boolean } } GlobalType
* @typedef {import("./index.d.ts").ImportEntry } ImportEntry
* @typedef {import("./index.d.ts").FunctionType } FunctionType
* @typedef {import("./index.d.ts").TableType } TableType
* @typedef {import("./index.d.ts").MemoryType } MemoryType
* @typedef {import("./index.d.ts").ValueType } ValueType
*/

/**
* Parse a WebAssembly module bytes and return the imports entries.
*
* @param {BufferSource} moduleBytes - The WebAssembly module bytes.
* @returns { (
* { module: string, name: string } & (
* { kind: "function", type: FunctionType } |
* { kind: "table", type: TableType } |
* { kind: "memory", type: MemoryType } |
* { kind: "global", type: GlobalType }
* )
* )[] } - The imports entries.
* @returns {ImportEntry[]} - The import entries.
* @throws {Error} - If the module bytes are invalid.
*
* @example
Expand Down Expand Up @@ -56,7 +50,13 @@ export function parseImports(moduleBytes) {
parseMagicNumber(parseState);
parseVersion(parseState);

/**
* @type {FunctionType[]}
*/
const types = [];
/**
* @type {ImportEntry[]}
*/
const imports = [];

while (parseState.hasMoreBytes()) {
Expand Down Expand Up @@ -170,8 +170,14 @@ function parseVersion(parseState) {
parseState.assertBytes(expected);
}

/**
* @returns {TableType}
*/
function parseTableType(parseState) {
const elementType = parseState.readByte();
/**
* @type {"funcref" | "externref"}
*/
let element;
switch (elementType) {
case 0x70:
Expand All @@ -191,6 +197,9 @@ function parseTableType(parseState) {
}
}

/**
* @returns {MemoryType}
*/
function parseLimits(parseState) {
const flags = parseState.readByte();
const minimum = parseState.readUnsignedLEB128();
Expand All @@ -212,6 +221,9 @@ function parseGlobalType(parseState) {
return { value, mutable };
}

/**
* @returns {ValueType}
*/
function parseValueType(parseState) {
const type = parseState.readByte();
switch (type) {
Expand All @@ -237,11 +249,17 @@ function parseFunctionType(parseState) {
if (form !== 0x60) {
throw new Error(`Expected function type form 0x60, got ${form}`);
}
/**
* @type {ValueType[]}
*/
const parameters = [];
const parameterCount = parseState.readUnsignedLEB128();
for (let i = 0; i < parameterCount; i++) {
parameters.push(parseValueType(parseState));
}
/**
* @type {ValueType[]}
*/
const results = [];
const resultCount = parseState.readUnsignedLEB128();
for (let i = 0; i < resultCount; i++) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"name": "wasm-imports-parser",
"version": "1.0.0",
"description": "A simple parser for WebAssembly imports",
"main": "index.js",
"type": "module",
"main": "index.js",
"scripts": {
"test": "node --experimental-wasm-type-reflection test/check.mjs && node test/check.mjs"
},
Expand Down
2 changes: 2 additions & 0 deletions polyfill.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export declare const hasWasmTypeReflectionSupport: boolean;
export declare function polyfill(wasm: typeof WebAssembly): typeof WebAssembly;
4 changes: 2 additions & 2 deletions polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export const hasWasmTypeReflectionSupport = (() => {
* Polyfill the WebAssembly object to support "type" field in the import object
* returned by `WebAssembly.Module.imports` function.
*
* @param {WebAssembly} WebAssembly
* @returns {WebAssembly}
* @param {typeof WebAssembly} WebAssembly
* @returns {typeof WebAssembly}
* @example
* import fs from "fs";
* import { polyfill } from "wasm-imports-parser/polyfill";
Expand Down

0 comments on commit 2991bbb

Please sign in to comment.