start WAT

This commit is contained in:
nora 2023-07-24 21:57:35 +02:00
parent 1448edc164
commit 05eacea56b
2 changed files with 128 additions and 9 deletions

View file

@ -33,9 +33,9 @@ export type Limits = {
max: u32; max: u32;
}; };
export type Memtype = Limits; export type MemType = Limits;
export type Tabletype = { export type TableType = {
limits: Limits; limits: Limits;
reftype: Reftype; reftype: Reftype;
}; };
@ -54,11 +54,11 @@ export type Externtype =
} }
| { | {
kind: "table"; kind: "table";
type: Tabletype; type: TableType;
} }
| { | {
kind: "mem"; kind: "mem";
type: Memtype; type: MemType;
} }
| { | {
kind: "global"; kind: "global";
@ -289,6 +289,7 @@ export type Module = {
start?: Start; start?: Start;
imports: Vec<Import>; imports: Vec<Import>;
exports: Vec<Export>; exports: Vec<Export>;
_name?: string,
}; };
export type TypeIdx = u32; export type TypeIdx = u32;
@ -305,14 +306,15 @@ export type Func = {
type: TypeIdx; type: TypeIdx;
locals: Vec<Valtype>; locals: Vec<Valtype>;
body: Expr; body: Expr;
_name?: string,
}; };
export type Table = { export type Table = {
type: Tabletype; type: TableType;
}; };
export type Mem = { export type Mem = {
type: Memtype; type: MemType;
}; };
export type GLobal = { export type GLobal = {
@ -357,7 +359,8 @@ export type Import = {
export type ImportDesc = export type ImportDesc =
| { | {
kind: "func"; kind: "func";
idx: FuncIdx; type: TypeIdx;
} }
| { kind: "table"; idx: TableIdx } | { kind: "table"; type: TableType }
| { kind: "mem"; idx: MemIdx | { kind: "global"; idx: GlobalIdx } }; | { kind: "memory"; type: MemType }
| { kind: "global"; type: GlobalType };

116
src/wasm/wat.ts Normal file
View file

@ -0,0 +1,116 @@
// This module converts the Wasm definitions to the WAT
// WebAssembly text format for easier debugging and inspection.
import {
Func,
Functype as FuncType,
GlobalType,
Import,
Instr,
Limits,
Module,
TableType as TableType,
Valtype as ValType,
} from "./defs";
const INLINE_SYM = Symbol.for("inline");
type Sexpr = string | number | Sexpr[] | { inline: Symbol; items: Sexpr[] };
export function writeModuleWat(module: Module) {
const sexprs = sexprModule(module);
console.dir(sexprs, { depth: 100 });
}
// base
function sexprString(s: string): Sexpr {
// TODO: escaping
return `"$${s}"`;
}
// types
function sexprValtype(type: ValType): Sexpr {
return type;
}
function sexprFuncType(type: FuncType): Sexpr {
return ["func", ["param", ...type.params], ["result", ...type.returns]];
}
function sexprLimits(limits: Limits): Sexpr {
return { inline: INLINE_SYM, items: [limits.min, limits.max] };
}
function sexprTableType(type: TableType): Sexpr {
todo();
}
function sexprGlobalType(type: GlobalType): Sexpr {
return type.mut === "const"
? sexprValtype(type.type)
: ["mut", sexprValtype(type.type)];
}
// instrs
function sexprInstr(instr: Instr): Sexpr {
todo();
}
// modules
function sexprType(type: FuncType): Sexpr {
return ["type", sexprFuncType(type)];
}
function sexprImport(import_: Import): Sexpr {
const desc = import_.desc;
let importDesc: Sexpr;
switch (desc.kind) {
case "func":
importDesc = ["type", desc.type];
break;
case "table":
importDesc = sexprTableType(desc.type);
break;
case "memory":
importDesc = sexprLimits(desc.type);
break;
case "global":
importDesc = sexprGlobalType(desc.type);
break;
}
return [
"import",
sexprString(import_.module),
sexprString(import_.name),
[desc.kind, importDesc],
];
}
function sexprFunction(func: Func): Sexpr {
return [
"func",
...(func._name ? [func._name] : []),
["type", func.type],
...func.locals.map((local) => ["local", sexprValtype(local)]),
...func.body.map((instr) => sexprInstr(instr)),
];
}
function sexprModule(module: Module): Sexpr {
return [
"module",
...(module._name ? [module._name] : []),
...module.types.map(sexprType),
...module.imports.map(sexprImport),
...module.funcs.map(sexprFunction),
];
}
function todo(): never {
throw new Error("todo");
}