@gasm-compiler/core 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +146 -594
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -1,481 +1,49 @@
1
- # Gasm Compiler Core Compiler
1
+ # @gasm-compiler/core
2
2
 
3
3
  **Compile WebAssembly to WGSL for GPU Execution**
4
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.
5
+ 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.
6
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
- ```
7
+ Implements the [Gasm v0.1 specification](https://github.com/gasm-compiler/spec) — a GPU-executable subset of WebAssembly.
279
8
 
280
9
  ---
281
10
 
282
- ## IR Types
283
-
284
- The compiler uses three IR representations:
11
+ ## Installation
285
12
 
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
- }
13
+ ```bash
14
+ npm install @gasm-compiler/core
305
15
  ```
306
16
 
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
17
+ **Requirements:** TypeScript 5.0+ (peer dependency)
313
18
 
314
19
  ---
315
20
 
316
- ### 2. SSAModule (SSA IR)
317
-
318
- **File:** `src/types.ts`
319
- **Purpose:** Static Single Assignment form for analysis
21
+ ## Quick Start
320
22
 
321
23
  ```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
24
+ import { compile } from "@gasm-compiler/core";
363
25
 
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
- }
26
+ // Load a WebAssembly binary (.wasm file)
27
+ const wasmBytes = new Uint8Array(await fetch("shader.wasm").then(r => r.arrayBuffer()));
378
28
 
379
- export interface StructuredFunction {
380
- typeIndex: number;
381
- locals: Local[];
382
- body: StructuredInstruction[];
383
- }
29
+ // Compile to WGSL
30
+ const wgslCode = compile(wasmBytes);
384
31
 
385
- export interface StructuredInstruction {
386
- opcode: number;
387
- name: string;
388
- type?: string;
389
- operands?: string[];
390
- result?: string;
391
- immediates?: unknown[];
392
- }
32
+ // Use with WebGPU
33
+ const shaderModule = device.createShaderModule({ code: wgslCode });
393
34
  ```
394
35
 
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
36
  ---
420
37
 
421
- ## Gasm Conformance
38
+ ## Features
422
39
 
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
- ```
40
+ - 120+ WebAssembly instructions mapped to WGSL equivalents
41
+ - Full L0 conformance (i32, i64, f32, f64 scalar operations)
42
+ - Control flow restructuring — WebAssembly's unstructured branches become WGSL loops/blocks
43
+ - Sub-word memory access — i8/i16 loads/stores lowered to word-aligned operations
44
+ - Gasm built-in globals for GPU thread identification
45
+ - Optional math extension for direct WGSL built-in math calls
46
+ - Works in Node.js, Deno, and browsers
479
47
 
480
48
  ---
481
49
 
@@ -486,51 +54,42 @@ fn main(
486
54
  ```typescript
487
55
  import { compile } from "@gasm-compiler/core";
488
56
 
489
- // Load WebAssembly binary
490
- const wasmBytes = await Deno.readFile("shader.wasm");
491
-
492
- // Compile to WGSL
493
57
  const wgslCode = compile(wasmBytes);
494
-
495
- // Use with WebGPU
496
- const shaderModule = device.createShaderModule({ code: wgslCode });
497
58
  ```
498
59
 
499
- ### With Options
60
+ ### Compilation Options
500
61
 
501
62
  ```typescript
502
- import { compile, CompileOptions } from "@gasm-compiler/core";
63
+ import { compile } from "@gasm-compiler/core";
503
64
 
504
- const options: CompileOptions = {
65
+ const wgslCode = compile(wasmBytes, {
505
66
  workgroupSize: [128, 1, 1], // Default: [64, 1, 1]
506
- debug: true, // Emit debug comments
67
+ debug: true, // Emit source-mapping comments
507
68
  mathExtension: true, // Enable gasm:math built-ins
508
- };
509
-
510
- const wgslCode = compile(wasmBytes, options);
69
+ });
511
70
  ```
512
71
 
513
- ### Math Extension (gasm:math)
72
+ ### Math Extension
514
73
 
515
- The `mathExtension` option enables WGSL built-in math functions to be called directly from WebAssembly via imports from the `"gasm"` module:
74
+ Enable direct mapping of WebAssembly imports to WGSL built-in math functions:
516
75
 
517
76
  ```typescript
518
- import { compile } from "@gasm-compiler/core";
519
-
520
77
  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
78
+ mathExtension: true, // Enable all levels (M0, M1, M2)
79
+ // or: mathExtension: "M0" // Core scalar functions only
80
+ // or: mathExtension: "M1" // Core + vector functions
81
+ // or: mathExtension: "M2" // All functions
525
82
  });
526
83
  ```
527
84
 
528
- When enabled, imports like `(import "gasm" "sin" (func ...))` are compiled to direct WGSL built-in calls like `sin(...)` instead of function calls.
85
+ When enabled, WebAssembly imports like `(import "gasm" "sin" (func ...))` compile to direct WGSL built-in calls (`sin(...)`) with zero overhead.
529
86
 
530
87
  **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
88
+ - **M0 (Core):** sin, cos, sqrt, abs, min, max, clamp, floor, ceil, etc.
89
+ - **M1 (Vector):** length, dot, cross, normalize, reflect, refract, etc.
90
+ - **M2 (Advanced):** modf, frexp, ldexp, degrees, radians, bit manipulation
91
+
92
+ > See also: [`@gasm-compiler/math-reference`](https://www.npmjs.com/package/@gasm-compiler/math-reference) for CPU-side reference implementations of these math functions.
534
93
 
535
94
  ### Error Handling
536
95
 
@@ -539,7 +98,6 @@ import { compile, isCompileError } from "@gasm-compiler/core";
539
98
 
540
99
  try {
541
100
  const wgslCode = compile(wasmBytes);
542
- console.log("Compilation successful!");
543
101
  } catch (error) {
544
102
  if (isCompileError(error)) {
545
103
  console.error("Compile Error:", error.message);
@@ -547,123 +105,144 @@ try {
547
105
  console.error(` at line ${error.location.line}, column ${error.location.column}`);
548
106
  }
549
107
  } else {
550
- throw error; // Unexpected error
108
+ throw error;
551
109
  }
552
110
  }
553
111
  ```
554
112
 
555
- ---
113
+ ### Browser Usage
114
+
115
+ ```typescript
116
+ import { compile } from "@gasm-compiler/core/browser";
117
+
118
+ const wgslCode = compile(wasmBytes);
119
+ ```
120
+
121
+ ### Using with WebGPU
556
122
 
557
- ## Testing
123
+ ```typescript
124
+ import { compile } from "@gasm-compiler/core";
558
125
 
559
- ### Running Tests
126
+ // 1. Compile Wasm → WGSL
127
+ const wgslCode = compile(wasmBytes, { workgroupSize: [256, 1, 1] });
560
128
 
561
- ```bash
562
- # Run all tests
563
- pnpm test:core
129
+ // 2. Create shader module
130
+ const shaderModule = device.createShaderModule({ code: wgslCode });
564
131
 
565
- # Or directly with Deno
566
- cd packages/core
567
- deno test --allow-all
132
+ // 3. Create compute pipeline
133
+ const pipeline = device.createComputePipeline({
134
+ layout: "auto",
135
+ compute: { module: shaderModule, entryPoint: "main" },
136
+ });
568
137
 
569
- # Run specific test file
570
- deno test tests/compiler_test.ts --allow-all
138
+ // 4. Dispatch
139
+ const commandEncoder = device.createCommandEncoder();
140
+ const pass = commandEncoder.beginComputePass();
141
+ pass.setPipeline(pipeline);
142
+ pass.setBindGroup(0, bindGroup);
143
+ pass.dispatchWorkgroups(numWorkgroups);
144
+ pass.end();
145
+ device.queue.submit([commandEncoder.finish()]);
571
146
  ```
572
147
 
573
- ### Test Organization
148
+ ---
149
+
150
+ ## How It Works
574
151
 
575
- Tests are organized by phase:
152
+ The compiler transforms WebAssembly into WGSL through a multi-phase pipeline:
576
153
 
577
154
  ```
578
- packages/core/tests/
579
- ├── compiler_test.ts # Integration tests (full pipeline)
580
- └── fixtures/ # Test data files (future)
155
+ WebAssembly Binary (.wasm)
156
+
157
+ Parse & Validate (Gasm restrictions)
158
+
159
+ Convert to SSA form
160
+
161
+ Restructure control flow (Relooper)
162
+
163
+ Lower memory operations
164
+
165
+ WGSL Code Generation
166
+
167
+ WGSL Compute Shader (.wgsl)
581
168
  ```
582
169
 
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
170
+ ### Gasm Restrictions
608
171
 
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);
172
+ Your WebAssembly module must conform to the Gasm subset:
626
173
 
627
- // Verify output
628
- assertEquals(wgslCode.includes("param_0 + param_1"), true);
629
- });
174
+ - **Single memory** — max 1 linear memory, exported as `"memory"`
175
+ - **Single table** — max 1 table (for indirect calls)
176
+ - **Global imports only** — no function or memory imports (except Gasm built-in globals)
177
+ - **Structured control flow** — all branches must be restructurable
178
+
179
+ ### Gasm Built-in Globals
180
+
181
+ Import GPU thread identifiers as WebAssembly globals from the `"gasm"` module:
182
+
183
+ | Import Name | Maps to WGSL | Type |
184
+ |-------------|--------------|------|
185
+ | `global_invocation_id_x/y/z` | `@builtin(global_invocation_id)` | `u32` |
186
+ | `local_invocation_id_x/y/z` | `@builtin(local_invocation_id)` | `u32` |
187
+ | `workgroup_id_x/y/z` | `@builtin(workgroup_id)` | `u32` |
188
+ | `num_workgroups_x/y/z` | `@builtin(num_workgroups)` | `u32` |
189
+
190
+ **Example (WAT):**
191
+ ```wasm
192
+ (module
193
+ (import "gasm" "global_invocation_id_x" (global $gid_x i32))
194
+ (memory (export "memory") 1)
195
+ (func (export "main")
196
+ ;; Use $gid_x to index into memory per-thread
197
+ ))
630
198
  ```
631
199
 
200
+ ### Instruction Support
201
+
202
+ | Category | Examples | WGSL Output |
203
+ |----------|---------|-------------|
204
+ | Arithmetic | `i32.add`, `f32.mul` | `a + b`, `a * b` |
205
+ | Bitwise | `i32.and`, `i32.shl` | `a & b`, `a << (b & 31u)` |
206
+ | Comparisons | `i32.lt_s`, `f32.eq` | `a < b`, `a == b` |
207
+ | Memory | `i32.load`, `i32.store8` | `memory[addr/4u]`, bit-masking |
208
+ | Conversions | `i32.trunc_f32_s` | `i32(trunc(a))` |
209
+ | Control Flow | `block`, `loop`, `br_if` | `loop { ... }`, `if (c) { break; }` |
210
+ | Variables | `local.get`, `global.set` | `var_N`, `global_N = val` |
211
+
632
212
  ---
633
213
 
634
214
  ## API Reference
635
215
 
636
- ### Main API
216
+ ### `compile(source, options?)`
637
217
 
638
- #### `compile(source: Uint8Array, options?: CompileOptions): string`
218
+ ```typescript
219
+ function compile(source: Uint8Array, options?: CompileOptions): string
220
+ ```
639
221
 
640
222
  Compiles a WebAssembly binary to WGSL.
641
223
 
642
224
  **Parameters:**
643
- - `source`: WebAssembly binary (Uint8Array)
644
- - `options`: Optional compilation options
645
-
646
- **Returns:** WGSL shader code (string)
225
+ - `source` WebAssembly binary as `Uint8Array`
226
+ - `options` Optional `CompileOptions`
647
227
 
648
- **Throws:** `CompileError` if validation or transformation fails
228
+ **Returns:** WGSL shader code as a string
649
229
 
650
- ---
651
-
652
- ### Types
230
+ **Throws:** `CompileError` on validation or compilation failure
653
231
 
654
- #### `CompileOptions`
232
+ ### `CompileOptions`
655
233
 
656
234
  ```typescript
657
- export interface CompileOptions {
235
+ interface CompileOptions {
658
236
  workgroupSize?: [number, number, number]; // Default: [64, 1, 1]
659
237
  debug?: boolean; // Emit debug comments (default: false)
238
+ mathExtension?: boolean | "M0" | "M1" | "M2"; // Enable math built-ins
660
239
  }
661
240
  ```
662
241
 
663
- #### `CompileError`
242
+ ### `CompileError`
664
243
 
665
244
  ```typescript
666
- export interface CompileError {
245
+ interface CompileError {
667
246
  type: "CompileError";
668
247
  message: string;
669
248
  location?: { line: number; column: number };
@@ -671,50 +250,23 @@ export interface CompileError {
671
250
  }
672
251
  ```
673
252
 
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
253
+ ### `isCompileError(error)`
681
254
 
682
- These are exported for testing but not intended for public use:
255
+ ```typescript
256
+ function isCompileError(error: unknown): error is CompileError
257
+ ```
683
258
 
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
259
+ Type guard for `CompileError`.
689
260
 
690
261
  ---
691
262
 
692
- ## Contributing
693
-
694
- See [AGENTS.md](../../AGENTS.md) for guidelines on working with the core compiler.
263
+ ## Related Packages
695
264
 
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
265
+ - [`@gasm-compiler/cli`](https://www.npmjs.com/package/@gasm-compiler/cli) — Command-line compiler for Wasm/AssemblyScript → WGSL
266
+ - [`@gasm-compiler/math-reference`](https://www.npmjs.com/package/@gasm-compiler/math-reference) — CPU-side reference implementations of Gasm math functions
703
267
 
704
268
  ---
705
269
 
706
270
  ## License
707
271
 
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
272
+ See [LICENSE](./LICENSE) for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gasm-compiler/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Gasm Compiler — compile WebAssembly to WGSL (WebGPU Shading Language)",
5
5
  "type": "module",
6
6
  "main": "./dist/mod.js",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "files": [
38
38
  "dist",
39
+ "!dist/**/*.map",
39
40
  "LICENSE",
40
41
  "README.md"
41
42
  ],