@gasm-compiler/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,720 @@
1
+ # Gasm Compiler Core Compiler
2
+
3
+ **Compile WebAssembly to WGSL for GPU Execution**
4
+
5
+ This package implements the core compiler that transforms WebAssembly binaries into WGSL (WebGPU Shading Language) code for execution on GPUs. It implements the [Gasm v0.1 specification](../../spec/gasm-v0.1.md), a GPU-executable subset of WebAssembly.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ - [Overview](#overview)
12
+ - [Architecture](#architecture)
13
+ - [Compilation Pipeline](#compilation-pipeline)
14
+ - [IR Types](#ir-types)
15
+ - [Instruction Mapping](#instruction-mapping)
16
+ - [Gasm Conformance](#gasm-conformance)
17
+ - [Usage](#usage)
18
+ - [Testing](#testing)
19
+ - [API Reference](#api-reference)
20
+
21
+ ---
22
+
23
+ ## Overview
24
+
25
+ **Gasm Compiler Core** is a TypeScript/Deno compiler that:
26
+
27
+ 1. **Parses** WebAssembly binaries (Wasm Core 1.0)
28
+ 2. **Validates** GPU execution constraints (Gasm spec)
29
+ 3. **Transforms** stack-based Wasm to structured WGSL
30
+ 4. **Generates** WGSL compute shaders ready for WebGPU
31
+
32
+ ### Key Features
33
+
34
+ - ✅ Full L0 conformance (scalar operations)
35
+ - ✅ 120+ WebAssembly instructions supported
36
+ - ✅ Control flow restructuring (Relooper algorithm)
37
+ - ✅ Memory operation lowering (sub-word access)
38
+ - ✅ Global imports and Gasm built-ins
39
+ - ✅ Type-safe SSA intermediate representation
40
+ - 🚧 L1/L2 conformance (SIMD, atomics) — planned
41
+
42
+ ---
43
+
44
+ ## Architecture
45
+
46
+ The compiler uses a **5-phase pipeline** to transform WebAssembly into WGSL:
47
+
48
+ ```
49
+ ┌─────────────┐
50
+ │ Wasm Binary │ Input: .wasm file (Uint8Array)
51
+ └──────┬──────┘
52
+
53
+ v
54
+ ┌─────────────┐
55
+ │ Phase 1: │ Parse & Validate
56
+ │ Parser │ • Binary format parsing
57
+ │ │ • Gasm restriction validation (Section 10)
58
+ └──────┬──────┘ • Output: WasmModule (stack-based IR)
59
+
60
+ v
61
+ ┌─────────────┐
62
+ │ Phase 2: │ Stack → SSA Conversion
63
+ │ SSA IR │ • Convert stack operations to SSA form
64
+ │ │ • Type inference for locals
65
+ └──────┬──────┘ • Output: SSAModule (SSA IR)
66
+
67
+ v
68
+ ┌─────────────┐
69
+ │ Phase 3: │ Control Flow Restructuring
70
+ │ Relooper │ • Transform unstructured jumps (br, br_if, br_table)
71
+ │ │ • Generate structured blocks/loops
72
+ └──────┬──────┘ • Output: StructuredModule
73
+
74
+ v
75
+ ┌─────────────┐
76
+ │ Phase 4: │ Memory Lowering
77
+ │ MemLower │ • Lower i8/i16 loads/stores to i32 word access
78
+ │ │ • Generate bit-masking and shifting
79
+ └──────┬──────┘ • Output: StructuredModule (memory-lowered)
80
+
81
+ v
82
+ ┌─────────────┐
83
+ │ Phase 5: │ WGSL Code Generation
84
+ │ Codegen │ • Emit WGSL functions, variables, structs
85
+ │ │ • Map Wasm instructions to WGSL expressions
86
+ └──────┬──────┘ • Output: WGSL string
87
+
88
+ v
89
+ ┌─────────────┐
90
+ │ WGSL Code │ Output: Valid WebGPU shader
91
+ └─────────────┘
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Compilation Pipeline
97
+
98
+ ### Phase 1: Parse & Validate
99
+
100
+ **File:** `src/parser.ts`
101
+ **Input:** WebAssembly binary (`Uint8Array`)
102
+ **Output:** `WasmModule` (stack-based IR)
103
+
104
+ **Responsibilities:**
105
+ - Parse Wasm binary format (magic, version, sections)
106
+ - Extract types, imports, functions, tables, memories, globals, exports, code
107
+ - Validate Gasm restrictions:
108
+ - Max 1 memory (no multi-memory)
109
+ - Max 1 table (no multi-table)
110
+ - No imports except globals (built-ins)
111
+ - Memory must be exported as `"memory"`
112
+ - Decode instruction bytecode to IR
113
+
114
+ **Key Functions:**
115
+ ```typescript
116
+ export function parseWasm(binary: Uint8Array): WasmModule
117
+ ```
118
+
119
+ **Error Handling:**
120
+ Throws `CompileError` with descriptive message for invalid binaries or Gasm violations.
121
+
122
+ ---
123
+
124
+ ### Phase 2: Stack → SSA Conversion
125
+
126
+ **File:** `src/phases.ts` → `phaseStackToSSA()`
127
+ **Input:** `WasmModule`
128
+ **Output:** `SSAModule`
129
+
130
+ **Responsibilities:**
131
+ - Convert stack-based operations to Static Single Assignment (SSA) form
132
+ - Infer types for local variables (from usage patterns)
133
+ - Preserve global definitions and imports
134
+ - Generate unique SSA variable names (`%0`, `%1`, `%2`, ...)
135
+
136
+ **Example:**
137
+ ```wasm
138
+ ;; WebAssembly (stack-based)
139
+ local.get 0
140
+ i32.const 1
141
+ i32.add
142
+ local.set 0
143
+ ```
144
+
145
+
146
+
147
+ ```
148
+ // SSA IR
149
+ %0 = local.get 0: i32
150
+ %1 = i32.const 1
151
+ %2 = i32.add %0, %1
152
+ local.set 0, %2
153
+ ```
154
+
155
+ **Key Functions:**
156
+ ```typescript
157
+ export function phaseStackToSSA(module: WasmModule): SSAModule
158
+ ```
159
+
160
+ ---
161
+
162
+ ### Phase 3: Control Flow Restructuring
163
+
164
+ **File:** `src/relooper.ts`
165
+ **Input:** `SSAModule`
166
+ **Output:** `StructuredModule`
167
+
168
+ **Responsibilities:**
169
+ - Apply the **Relooper algorithm** to restructure control flow
170
+ - Transform unstructured jumps (`br`, `br_if`, `br_table`) into structured loops/blocks
171
+ - Generate WGSL-compatible control structures (`if`, `loop`, `break`, `continue`)
172
+
173
+ **Example:**
174
+ ```wasm
175
+ ;; WebAssembly (unstructured)
176
+ block $exit
177
+ loop $loop
178
+ local.get 0
179
+ i32.const 10
180
+ i32.lt_s
181
+ br_if $exit
182
+ ;; loop body
183
+ br $loop
184
+ end
185
+ end
186
+ ```
187
+
188
+
189
+
190
+ ```wgsl
191
+ // WGSL (structured)
192
+ loop {
193
+ if (var_0 < 10i) { break; }
194
+ // loop body
195
+ }
196
+ ```
197
+
198
+ **Key Functions:**
199
+ ```typescript
200
+ export function reloop(module: SSAModule): StructuredModule
201
+ ```
202
+
203
+ ---
204
+
205
+ ### Phase 4: Memory Lowering
206
+
207
+ **File:** `src/phases.ts` → `phaseMemoryLowering()`
208
+ **Input:** `StructuredModule`
209
+ **Output:** `StructuredModule` (memory-lowered)
210
+
211
+ **Responsibilities:**
212
+ - Lower sub-word memory operations (i8/i16) to word-aligned access (i32)
213
+ - Generate bit-masking and shifting for unaligned access
214
+ - Preserve i32/i64/f32/f64 memory operations
215
+
216
+ **Example:**
217
+ ```wasm
218
+ ;; i32.load8_u offset=0 align=1
219
+ i32.load8_u offset=0 align=1
220
+ ```
221
+
222
+
223
+
224
+ ```wgsl
225
+ // WGSL (lowered to word access)
226
+ let word_addr = offset / 4u;
227
+ let byte_offset = offset % 4u;
228
+ let word = memory[word_addr];
229
+ let byte = (word >> (byte_offset * 8u)) & 0xFFu;
230
+ ```
231
+
232
+ **Key Functions:**
233
+ ```typescript
234
+ export function phaseMemoryLowering(module: StructuredModule): StructuredModule
235
+ ```
236
+
237
+ ---
238
+
239
+ ### Phase 5: WGSL Code Generation
240
+
241
+ **File:** `src/phases.ts` → `phaseWgslCodegen()`
242
+ **Input:** `StructuredModule`
243
+ **Output:** WGSL string
244
+
245
+ **Responsibilities:**
246
+ - Emit WGSL variable declarations (globals, locals)
247
+ - Emit function definitions with signatures
248
+ - Emit main entry point with Gasm built-in parameters:
249
+ - `@builtin(global_invocation_id)` → `global_invocation_id_{x,y,z}`
250
+ - `@builtin(local_invocation_id)` → `local_invocation_id_{x,y,z}`
251
+ - `@builtin(workgroup_id)` → `workgroup_id_{x,y,z}`
252
+ - `@builtin(num_workgroups)` → `num_workgroups_{x,y,z}`
253
+ - Map Wasm instructions to WGSL expressions
254
+ - Generate structured control flow (blocks, loops, conditionals)
255
+
256
+ **Example:**
257
+ ```wasm
258
+ (func $add (param i32 i32) (result i32)
259
+ local.get 0
260
+ local.get 1
261
+ i32.add)
262
+ ```
263
+
264
+
265
+
266
+ ```wgsl
267
+ fn func_0(param_0: i32, param_1: i32) -> i32 {
268
+ return param_0 + param_1;
269
+ }
270
+ ```
271
+
272
+ **Key Functions:**
273
+ ```typescript
274
+ export function phaseWgslCodegen(
275
+ module: StructuredModule,
276
+ options?: CompileOptions
277
+ ): string
278
+ ```
279
+
280
+ ---
281
+
282
+ ## IR Types
283
+
284
+ The compiler uses three IR representations:
285
+
286
+ ### 1. WasmModule (Stack-Based IR)
287
+
288
+ **File:** `src/types.ts`
289
+ **Purpose:** Direct representation of WebAssembly binary
290
+
291
+ ```typescript
292
+ export interface WasmModule {
293
+ types: WasmType[];
294
+ imports: Import[];
295
+ functions: WasmFunction[];
296
+ tables: Table[];
297
+ memories: Memory[];
298
+ globals: Global[]; // ImportedGlobal | DefinedGlobal
299
+ exports: Export[];
300
+ start?: number;
301
+ elements: Element[];
302
+ dataSegments: DataSegment[];
303
+ customSections: CustomSection[];
304
+ }
305
+ ```
306
+
307
+ **Key Properties:**
308
+ - `types`: Function signatures (param/result types)
309
+ - `functions`: Function bodies with stack-based instructions
310
+ - `globals`: Global variables (imported built-ins or definitions)
311
+ - `memories`: Linear memory configuration (initial/max pages)
312
+ - `exports`: Exported functions and memory
313
+
314
+ ---
315
+
316
+ ### 2. SSAModule (SSA IR)
317
+
318
+ **File:** `src/types.ts`
319
+ **Purpose:** Static Single Assignment form for analysis
320
+
321
+ ```typescript
322
+ export interface SSAModule {
323
+ types: WasmType[];
324
+ imports: Import[];
325
+ functions: SSAFunction[];
326
+ tables: Table[];
327
+ memories: Memory[];
328
+ globals: Global[];
329
+ exports: Export[];
330
+ start?: number;
331
+ elements: Element[];
332
+ dataSegments: DataSegment[];
333
+ customSections: CustomSection[];
334
+ }
335
+
336
+ export interface SSAFunction {
337
+ typeIndex: number;
338
+ locals: Local[];
339
+ body: SSAInstruction[];
340
+ }
341
+
342
+ export interface SSAInstruction {
343
+ opcode: number;
344
+ name: string;
345
+ type?: string;
346
+ operands?: string[];
347
+ result?: string;
348
+ immediates?: unknown[];
349
+ }
350
+ ```
351
+
352
+ **Key Properties:**
353
+ - `SSAFunction.body`: Instructions with explicit SSA operands/results
354
+ - `SSAInstruction.result`: SSA variable name (e.g., `%0`, `%1`)
355
+ - `SSAInstruction.operands`: SSA variable dependencies (e.g., `["%0", "%1"]`)
356
+
357
+ ---
358
+
359
+ ### 3. StructuredModule (Structured IR)
360
+
361
+ **File:** `src/types.ts`
362
+ **Purpose:** Structured control flow for WGSL generation
363
+
364
+ ```typescript
365
+ export interface StructuredModule {
366
+ types: WasmType[];
367
+ imports: Import[];
368
+ functions: StructuredFunction[];
369
+ tables: Table[];
370
+ memories: Memory[];
371
+ globals: Global[];
372
+ exports: Export[];
373
+ start?: number;
374
+ elements: Element[];
375
+ dataSegments: DataSegment[];
376
+ customSections: CustomSection[];
377
+ }
378
+
379
+ export interface StructuredFunction {
380
+ typeIndex: number;
381
+ locals: Local[];
382
+ body: StructuredInstruction[];
383
+ }
384
+
385
+ export interface StructuredInstruction {
386
+ opcode: number;
387
+ name: string;
388
+ type?: string;
389
+ operands?: string[];
390
+ result?: string;
391
+ immediates?: unknown[];
392
+ }
393
+ ```
394
+
395
+ **Key Properties:**
396
+ - Control flow is fully structured (no `br`, `br_if`, `br_table`)
397
+ - Instructions use WGSL-compatible constructs (`if`, `loop`, `break`)
398
+ - Memory operations are word-aligned (i32/i64/f32/f64 only)
399
+
400
+ ---
401
+
402
+ ## Instruction Mapping
403
+
404
+ The compiler maps 120+ WebAssembly instructions to WGSL equivalents. See the full table in the [Instruction Set Reference](../../docs/instruction-set.md).
405
+
406
+ ### Quick Reference
407
+
408
+ | Category | Example Instructions | WGSL Equivalent |
409
+ |----------|---------------------|-----------------|
410
+ | **Arithmetic** | `i32.add`, `f32.mul` | `a + b`, `a * b` |
411
+ | **Bitwise** | `i32.and`, `i32.shl` | `a & b`, `a << (b & 31u)` |
412
+ | **Comparisons** | `i32.lt_s`, `f32.eq` | `a < b`, `a == b` |
413
+ | **Memory** | `i32.load`, `i32.store8` | `memory[addr/4u]`, bit-masking |
414
+ | **Conversions** | `i32.trunc_f32_s`, `f32.convert_i32_u` | `i32(trunc(a))`, `f32(u32(a))` |
415
+ | **Control Flow** | `block`, `loop`, `br_if` | `{ ... }`, `loop { ... }`, `if (c) { break; }` |
416
+ | **Variables** | `local.get`, `global.set` | `var_N`, `global_N = val` |
417
+ | **Special** | `select`, `memory.size` | `select(a, b, c)`, `arrayLength(&memory)` |
418
+
419
+ ---
420
+
421
+ ## Gasm Conformance
422
+
423
+ The compiler implements **Gasm v0.1 L0 (Core)** conformance:
424
+
425
+ ### Conformance Levels
426
+
427
+ | Level | Features | Status |
428
+ |-------|----------|--------|
429
+ | **L0 (Core)** | Scalar operations (i32, i64, f32, f64) | ✅ Implemented |
430
+ | **L1 (SIMD)** | 128-bit SIMD operations (v128) | 🚧 Planned |
431
+ | **L2 (Extended)** | Atomics + Relaxed SIMD | 🚧 Planned |
432
+
433
+ ### Gasm Restrictions (Section 10)
434
+
435
+ The compiler enforces these restrictions during Phase 1 validation:
436
+
437
+ 1. **Single Memory**: Max 1 memory, must be exported as `"memory"`
438
+ 2. **Single Table**: Max 1 table (for indirect calls)
439
+ 3. **No Imports** (except globals): Only global imports allowed (Gasm built-ins)
440
+ 4. **Deterministic Execution**: No `unreachable` or trapping operations in production code
441
+ 5. **Structured Control Flow**: All `br`, `br_if`, `br_table` must be restructurable (Phase 3)
442
+
443
+ ### Gasm Built-in Globals
444
+
445
+ The compiler automatically maps WGSL built-ins to global imports:
446
+
447
+ | Global Name | WGSL Built-in | Type |
448
+ |-------------|---------------|------|
449
+ | `global_invocation_id_x` | `@builtin(global_invocation_id).x` | `u32` |
450
+ | `global_invocation_id_y` | `@builtin(global_invocation_id).y` | `u32` |
451
+ | `global_invocation_id_z` | `@builtin(global_invocation_id).z` | `u32` |
452
+ | `local_invocation_id_x` | `@builtin(local_invocation_id).x` | `u32` |
453
+ | `local_invocation_id_y` | `@builtin(local_invocation_id).y` | `u32` |
454
+ | `local_invocation_id_z` | `@builtin(local_invocation_id).z` | `u32` |
455
+ | `workgroup_id_x` | `@builtin(workgroup_id).x` | `u32` |
456
+ | `workgroup_id_y` | `@builtin(workgroup_id).y` | `u32` |
457
+ | `workgroup_id_z` | `@builtin(workgroup_id).z` | `u32` |
458
+ | `num_workgroups_x` | `@builtin(num_workgroups).x` | `u32` |
459
+ | `num_workgroups_y` | `@builtin(num_workgroups).y` | `u32` |
460
+ | `num_workgroups_z` | `@builtin(num_workgroups).z` | `u32` |
461
+
462
+ **Example:**
463
+ ```wasm
464
+ (import "gasm" "global_invocation_id_x" (global $gid_x i32))
465
+ ```
466
+
467
+
468
+
469
+ ```wgsl
470
+ @compute @workgroup_size(64)
471
+ fn main(
472
+ @builtin(global_invocation_id) global_invocation_id: vec3<u32>,
473
+ // ... other built-ins
474
+ ) {
475
+ var global_invocation_id_x: u32 = global_invocation_id.x;
476
+ // ... use in function body
477
+ }
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Usage
483
+
484
+ ### Basic Compilation
485
+
486
+ ```typescript
487
+ import { compile } from "@gasm-compiler/core";
488
+
489
+ // Load WebAssembly binary
490
+ const wasmBytes = await Deno.readFile("shader.wasm");
491
+
492
+ // Compile to WGSL
493
+ const wgslCode = compile(wasmBytes);
494
+
495
+ // Use with WebGPU
496
+ const shaderModule = device.createShaderModule({ code: wgslCode });
497
+ ```
498
+
499
+ ### With Options
500
+
501
+ ```typescript
502
+ import { compile, CompileOptions } from "@gasm-compiler/core";
503
+
504
+ const options: CompileOptions = {
505
+ workgroupSize: [128, 1, 1], // Default: [64, 1, 1]
506
+ debug: true, // Emit debug comments
507
+ mathExtension: true, // Enable gasm:math built-ins
508
+ };
509
+
510
+ const wgslCode = compile(wasmBytes, options);
511
+ ```
512
+
513
+ ### Math Extension (gasm:math)
514
+
515
+ The `mathExtension` option enables WGSL built-in math functions to be called directly from WebAssembly via imports from the `"gasm"` module:
516
+
517
+ ```typescript
518
+ import { compile } from "@gasm-compiler/core";
519
+
520
+ const wgslCode = compile(wasmBytes, {
521
+ mathExtension: true, // Enable all levels (M0, M1, M2)
522
+ // or: mathExtension: "M0" // Core scalar functions only
523
+ // or: mathExtension: "M1" // Core + vector functions
524
+ // or: mathExtension: "M2" // All functions
525
+ });
526
+ ```
527
+
528
+ When enabled, imports like `(import "gasm" "sin" (func ...))` are compiled to direct WGSL built-in calls like `sin(...)` instead of function calls.
529
+
530
+ **Math Levels:**
531
+ - **M0 (Core)**: Scalar functions (sin, cos, sqrt, abs, min, max, clamp, etc.)
532
+ - **M1 (Vector)**: Geometric functions (length, dot, cross, normalize, reflect, etc.)
533
+ - **M2 (Advanced)**: modf, frexp, ldexp, degrees, radians, bit manipulation
534
+
535
+ ### Error Handling
536
+
537
+ ```typescript
538
+ import { compile, isCompileError } from "@gasm-compiler/core";
539
+
540
+ try {
541
+ const wgslCode = compile(wasmBytes);
542
+ console.log("Compilation successful!");
543
+ } catch (error) {
544
+ if (isCompileError(error)) {
545
+ console.error("Compile Error:", error.message);
546
+ if (error.location) {
547
+ console.error(` at line ${error.location.line}, column ${error.location.column}`);
548
+ }
549
+ } else {
550
+ throw error; // Unexpected error
551
+ }
552
+ }
553
+ ```
554
+
555
+ ---
556
+
557
+ ## Testing
558
+
559
+ ### Running Tests
560
+
561
+ ```bash
562
+ # Run all tests
563
+ pnpm test:core
564
+
565
+ # Or directly with Deno
566
+ cd packages/core
567
+ deno test --allow-all
568
+
569
+ # Run specific test file
570
+ deno test tests/compiler_test.ts --allow-all
571
+ ```
572
+
573
+ ### Test Organization
574
+
575
+ Tests are organized by phase:
576
+
577
+ ```
578
+ packages/core/tests/
579
+ ├── compiler_test.ts # Integration tests (full pipeline)
580
+ └── fixtures/ # Test data files (future)
581
+ ```
582
+
583
+ **Current Test Coverage (Session 3):**
584
+ - ✅ **Phase 1: Parser validation** (26 tests)
585
+ - ✅ **Phase 2-5: Integration tests** (12 tests)
586
+ - ✅ **i32 Arithmetic** (18 tests)
587
+ - ✅ **i32 Bitwise** (32 tests)
588
+ - ✅ **i32 Comparison** (20 tests)
589
+ - ✅ **i64 Arithmetic** (19 tests)
590
+ - ✅ **i64 Bitwise** (32 tests)
591
+ - ✅ **i64 Comparison** (20 tests)
592
+ - ✅ **f32 Arithmetic** (48 tests)
593
+ - ✅ **f64 Arithmetic** (48 tests)
594
+ - ✅ **Float Comparison** (17 tests)
595
+ - ✅ **Float Edge Cases** (18 tests)
596
+ - ✅ **Type Conversions** (53 tests: 16 original + 37 new comprehensive tests)
597
+ - ✅ **Control Flow** (9 tests)
598
+ - ✅ **Memory Operations** (14 tests)
599
+ - ✅ **Functions, Stack, Constants** (19 tests)
600
+ - ✅ **Error Handling** (19 tests)
601
+ - ✅ **WGSL Output Validation** (40 tests)
602
+ - ✅ **Global & Options** (2 tests)
603
+
604
+ **Total:** 471 tests passing (414ms execution time)
605
+ **Test Files:** 23 organized by instruction category
606
+
607
+ ### Adding New Tests
608
+
609
+ ```typescript
610
+ import { assertEquals } from "jsr:@std/assert";
611
+ import { compile } from "../src/mod.ts";
612
+
613
+ Deno.test("Compiler - Feature Name", () => {
614
+ // Create WebAssembly binary (WAT → Wasm)
615
+ const wat = `
616
+ (module
617
+ (func (export "add") (param i32 i32) (result i32)
618
+ local.get 0
619
+ local.get 1
620
+ i32.add))
621
+ `;
622
+ const wasmBytes = wat2wasm(wat); // Use wat2wasm utility
623
+
624
+ // Compile to WGSL
625
+ const wgslCode = compile(wasmBytes);
626
+
627
+ // Verify output
628
+ assertEquals(wgslCode.includes("param_0 + param_1"), true);
629
+ });
630
+ ```
631
+
632
+ ---
633
+
634
+ ## API Reference
635
+
636
+ ### Main API
637
+
638
+ #### `compile(source: Uint8Array, options?: CompileOptions): string`
639
+
640
+ Compiles a WebAssembly binary to WGSL.
641
+
642
+ **Parameters:**
643
+ - `source`: WebAssembly binary (Uint8Array)
644
+ - `options`: Optional compilation options
645
+
646
+ **Returns:** WGSL shader code (string)
647
+
648
+ **Throws:** `CompileError` if validation or transformation fails
649
+
650
+ ---
651
+
652
+ ### Types
653
+
654
+ #### `CompileOptions`
655
+
656
+ ```typescript
657
+ export interface CompileOptions {
658
+ workgroupSize?: [number, number, number]; // Default: [64, 1, 1]
659
+ debug?: boolean; // Emit debug comments (default: false)
660
+ }
661
+ ```
662
+
663
+ #### `CompileError`
664
+
665
+ ```typescript
666
+ export interface CompileError {
667
+ type: "CompileError";
668
+ message: string;
669
+ location?: { line: number; column: number };
670
+ context?: string;
671
+ }
672
+ ```
673
+
674
+ #### `isCompileError(error: unknown): error is CompileError`
675
+
676
+ Type guard to check if an error is a `CompileError`.
677
+
678
+ ---
679
+
680
+ ### Internal APIs
681
+
682
+ These are exported for testing but not intended for public use:
683
+
684
+ - `parseWasm(binary: Uint8Array): WasmModule` — Parse Wasm binary
685
+ - `phaseStackToSSA(module: WasmModule): SSAModule` — Convert to SSA
686
+ - `reloop(module: SSAModule): StructuredModule` — Restructure control flow
687
+ - `phaseMemoryLowering(module: StructuredModule): StructuredModule` — Lower memory ops
688
+ - `phaseWgslCodegen(module: StructuredModule, options?: CompileOptions): string` — Generate WGSL
689
+
690
+ ---
691
+
692
+ ## Contributing
693
+
694
+ See [AGENTS.md](../../AGENTS.md) for guidelines on working with the core compiler.
695
+
696
+ ### Development Workflow
697
+
698
+ 1. **Write tests first** for new features
699
+ 2. **Run tests** with `pnpm test:core`
700
+ 3. **Keep platform-agnostic** — no Deno-specific APIs in core logic
701
+ 4. **Follow TypeScript strict mode** — all types must be explicit
702
+ 5. **Document public APIs** — JSDoc for all exported functions
703
+
704
+ ---
705
+
706
+ ## License
707
+
708
+ MIT License — See [LICENSE](../../LICENSE) for details.
709
+
710
+ ---
711
+
712
+ ## Related Documentation
713
+
714
+ - [Gasm Specification v0.1](../../spec/gasm-v0.1.md) — GPU-executable WebAssembly spec
715
+ - [Instruction Set Reference](../../docs/instruction-set.md) — Detailed instruction mappings
716
+ - [AGENTS.md](../../AGENTS.md) — Development guidelines for agents
717
+
718
+ ---
719
+
720
+ **Last Updated:** December 2025