Initial Commit
This commit is contained in:
112
packages/api-stack/api/api-sandbox-wasm-host-bridge/tests/fixtures/wasm-opcodes.ts
vendored
Normal file
112
packages/api-stack/api/api-sandbox-wasm-host-bridge/tests/fixtures/wasm-opcodes.ts
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Minimal opcode helpers for hand-encoded WASM function bodies. Only the
|
||||
* subset the bridge's fixture WASM needs is implemented — enough to
|
||||
* model a bump allocator, a memcpy loop, packed i64 returns, an
|
||||
* `unreachable` trap, and load/store of static byte ranges out of the
|
||||
* data section.
|
||||
*/
|
||||
|
||||
import { concat, encodeI32, encodeU32 } from "./leb128.js";
|
||||
|
||||
// Value types.
|
||||
export const VT_I32 = 0x7f;
|
||||
export const VT_I64 = 0x7e;
|
||||
|
||||
// Instructions.
|
||||
export const OP_UNREACHABLE = 0x00;
|
||||
export const OP_NOP = 0x01;
|
||||
export const OP_BLOCK = 0x02;
|
||||
export const OP_LOOP = 0x03;
|
||||
export const OP_BR = 0x0c;
|
||||
export const OP_BR_IF = 0x0d;
|
||||
export const OP_RETURN = 0x0f;
|
||||
export const OP_CALL = 0x10;
|
||||
export const OP_DROP = 0x1a;
|
||||
export const OP_LOCAL_GET = 0x20;
|
||||
export const OP_LOCAL_SET = 0x21;
|
||||
export const OP_LOCAL_TEE = 0x22;
|
||||
export const OP_GLOBAL_GET = 0x23;
|
||||
export const OP_GLOBAL_SET = 0x24;
|
||||
export const OP_I32_LOAD = 0x28;
|
||||
export const OP_I32_LOAD8_U = 0x2d;
|
||||
export const OP_I32_STORE = 0x36;
|
||||
export const OP_I32_STORE8 = 0x3a;
|
||||
export const OP_I32_CONST = 0x41;
|
||||
export const OP_I64_CONST = 0x42;
|
||||
export const OP_I32_EQZ = 0x45;
|
||||
export const OP_I32_LT_U = 0x49;
|
||||
export const OP_I32_ADD = 0x6a;
|
||||
export const OP_I32_SUB = 0x6b;
|
||||
export const OP_I64_OR = 0x84;
|
||||
export const OP_I64_SHL = 0x86;
|
||||
export const OP_I64_EXTEND_I32_U = 0xad;
|
||||
export const OP_END = 0x0b;
|
||||
export const BLOCK_TYPE_EMPTY = 0x40;
|
||||
|
||||
export function opI32Const(v: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_I32_CONST]), encodeI32(v));
|
||||
}
|
||||
|
||||
export function opLocalGet(idx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_LOCAL_GET]), encodeU32(idx));
|
||||
}
|
||||
|
||||
export function opLocalSet(idx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_LOCAL_SET]), encodeU32(idx));
|
||||
}
|
||||
|
||||
export function opLocalTee(idx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_LOCAL_TEE]), encodeU32(idx));
|
||||
}
|
||||
|
||||
export function opGlobalGet(idx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_GLOBAL_GET]), encodeU32(idx));
|
||||
}
|
||||
|
||||
export function opGlobalSet(idx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_GLOBAL_SET]), encodeU32(idx));
|
||||
}
|
||||
|
||||
/** memarg = align (u32) + offset (u32). */
|
||||
function memarg(align = 0, offset = 0): Uint8Array {
|
||||
return concat(encodeU32(align), encodeU32(offset));
|
||||
}
|
||||
|
||||
export function opI32Load8U(): Uint8Array {
|
||||
return concat(new Uint8Array([OP_I32_LOAD8_U]), memarg(0, 0));
|
||||
}
|
||||
|
||||
export function opI32Store8(): Uint8Array {
|
||||
return concat(new Uint8Array([OP_I32_STORE8]), memarg(0, 0));
|
||||
}
|
||||
|
||||
export function opBr(depth: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_BR]), encodeU32(depth));
|
||||
}
|
||||
|
||||
export function opBrIf(depth: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_BR_IF]), encodeU32(depth));
|
||||
}
|
||||
|
||||
export function opCall(funcIdx: number): Uint8Array {
|
||||
return concat(new Uint8Array([OP_CALL]), encodeU32(funcIdx));
|
||||
}
|
||||
|
||||
/** Wrap body bytes as a function body: locals + body + end. */
|
||||
export function funcBody(
|
||||
locals: ReadonlyArray<{ readonly count: number; readonly type: number }>,
|
||||
body: Uint8Array
|
||||
): Uint8Array {
|
||||
const localGroups: Uint8Array[] = [];
|
||||
for (const group of locals) {
|
||||
localGroups.push(
|
||||
concat(encodeU32(group.count), new Uint8Array([group.type]))
|
||||
);
|
||||
}
|
||||
const localsHeader = concat(
|
||||
encodeU32(locals.length),
|
||||
concat(...localGroups)
|
||||
);
|
||||
const inner = concat(localsHeader, body, new Uint8Array([OP_END]));
|
||||
return concat(encodeU32(inner.length), inner);
|
||||
}
|
||||
Reference in New Issue
Block a user