@gasm-compiler/core
v0.1.1
Published
Gasm Compiler — compile WebAssembly to WGSL (WebGPU Shading Language)
Maintainers
Readme
@gasm-compiler/core
Compile WebAssembly to WGSL for GPU Execution
Transform WebAssembly binaries into WGSL (WebGPU Shading Language) compute shaders. Write your GPU kernels in any language that compiles to WebAssembly (C, C++, Rust, Go, AssemblyScript, or hand-written WAT), then run them on the GPU via WebGPU.
Implements the Gasm v0.1 specification — a GPU-executable subset of WebAssembly.
Installation
npm install @gasm-compiler/coreRequirements: TypeScript 5.0+ (peer dependency)
Quick Start
import { compile } from "@gasm-compiler/core";
// Load a WebAssembly binary (.wasm file)
const wasmBytes = new Uint8Array(await fetch("shader.wasm").then(r => r.arrayBuffer()));
// Compile to WGSL
const wgslCode = compile(wasmBytes);
// Use with WebGPU
const shaderModule = device.createShaderModule({ code: wgslCode });Features
- 120+ WebAssembly instructions mapped to WGSL equivalents
- Full L0 conformance (i32, i64, f32, f64 scalar operations)
- Control flow restructuring — WebAssembly's unstructured branches become WGSL loops/blocks
- Sub-word memory access — i8/i16 loads/stores lowered to word-aligned operations
- Gasm built-in globals for GPU thread identification
- Optional math extension for direct WGSL built-in math calls
- Works in Node.js, Deno, and browsers
Usage
Basic Compilation
import { compile } from "@gasm-compiler/core";
const wgslCode = compile(wasmBytes);Compilation Options
import { compile } from "@gasm-compiler/core";
const wgslCode = compile(wasmBytes, {
workgroupSize: [128, 1, 1], // Default: [64, 1, 1]
debug: true, // Emit source-mapping comments
mathExtension: true, // Enable gasm:math built-ins
});Math Extension
Enable direct mapping of WebAssembly imports to WGSL built-in math functions:
const wgslCode = compile(wasmBytes, {
mathExtension: true, // Enable all levels (M0, M1, M2)
// or: mathExtension: "M0" // Core scalar functions only
// or: mathExtension: "M1" // Core + vector functions
// or: mathExtension: "M2" // All functions
});When enabled, WebAssembly imports like (import "gasm" "sin" (func ...)) compile to direct WGSL built-in calls (sin(...)) with zero overhead.
Math Levels:
- M0 (Core): sin, cos, sqrt, abs, min, max, clamp, floor, ceil, etc.
- M1 (Vector): length, dot, cross, normalize, reflect, refract, etc.
- M2 (Advanced): modf, frexp, ldexp, degrees, radians, bit manipulation
See also:
@gasm-compiler/math-referencefor CPU-side reference implementations of these math functions.
Error Handling
import { compile, isCompileError } from "@gasm-compiler/core";
try {
const wgslCode = compile(wasmBytes);
} catch (error) {
if (isCompileError(error)) {
console.error("Compile Error:", error.message);
if (error.location) {
console.error(` at line ${error.location.line}, column ${error.location.column}`);
}
} else {
throw error;
}
}Browser Usage
import { compile } from "@gasm-compiler/core/browser";
const wgslCode = compile(wasmBytes);Using with WebGPU
import { compile } from "@gasm-compiler/core";
// 1. Compile Wasm → WGSL
const wgslCode = compile(wasmBytes, { workgroupSize: [256, 1, 1] });
// 2. Create shader module
const shaderModule = device.createShaderModule({ code: wgslCode });
// 3. Create compute pipeline
const pipeline = device.createComputePipeline({
layout: "auto",
compute: { module: shaderModule, entryPoint: "main" },
});
// 4. Dispatch
const commandEncoder = device.createCommandEncoder();
const pass = commandEncoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(numWorkgroups);
pass.end();
device.queue.submit([commandEncoder.finish()]);How It Works
The compiler transforms WebAssembly into WGSL through a multi-phase pipeline:
WebAssembly Binary (.wasm)
↓
Parse & Validate (Gasm restrictions)
↓
Convert to SSA form
↓
Restructure control flow (Relooper)
↓
Lower memory operations
↓
WGSL Code Generation
↓
WGSL Compute Shader (.wgsl)Gasm Restrictions
Your WebAssembly module must conform to the Gasm subset:
- Single memory — max 1 linear memory, exported as
"memory" - Single table — max 1 table (for indirect calls)
- Global imports only — no function or memory imports (except Gasm built-in globals)
- Structured control flow — all branches must be restructurable
Gasm Built-in Globals
Import GPU thread identifiers as WebAssembly globals from the "gasm" module:
| Import Name | Maps to WGSL | Type |
|-------------|--------------|------|
| global_invocation_id_x/y/z | @builtin(global_invocation_id) | u32 |
| local_invocation_id_x/y/z | @builtin(local_invocation_id) | u32 |
| workgroup_id_x/y/z | @builtin(workgroup_id) | u32 |
| num_workgroups_x/y/z | @builtin(num_workgroups) | u32 |
Example (WAT):
(module
(import "gasm" "global_invocation_id_x" (global $gid_x i32))
(memory (export "memory") 1)
(func (export "main")
;; Use $gid_x to index into memory per-thread
))Instruction Support
| Category | Examples | WGSL Output |
|----------|---------|-------------|
| Arithmetic | i32.add, f32.mul | a + b, a * b |
| Bitwise | i32.and, i32.shl | a & b, a << (b & 31u) |
| Comparisons | i32.lt_s, f32.eq | a < b, a == b |
| Memory | i32.load, i32.store8 | memory[addr/4u], bit-masking |
| Conversions | i32.trunc_f32_s | i32(trunc(a)) |
| Control Flow | block, loop, br_if | loop { ... }, if (c) { break; } |
| Variables | local.get, global.set | var_N, global_N = val |
API Reference
compile(source, options?)
function compile(source: Uint8Array, options?: CompileOptions): stringCompiles a WebAssembly binary to WGSL.
Parameters:
source— WebAssembly binary asUint8Arrayoptions— OptionalCompileOptions
Returns: WGSL shader code as a string
Throws: CompileError on validation or compilation failure
CompileOptions
interface CompileOptions {
workgroupSize?: [number, number, number]; // Default: [64, 1, 1]
debug?: boolean; // Emit debug comments (default: false)
mathExtension?: boolean | "M0" | "M1" | "M2"; // Enable math built-ins
}CompileError
interface CompileError {
type: "CompileError";
message: string;
location?: { line: number; column: number };
context?: string;
}isCompileError(error)
function isCompileError(error: unknown): error is CompileErrorType guard for CompileError.
Related Packages
@gasm-compiler/cli— Command-line compiler for Wasm/AssemblyScript → WGSL@gasm-compiler/math-reference— CPU-side reference implementations of Gasm math functions
License
See LICENSE for details.
