Skip to content

Commit ee9694d

Browse files
Jonathan D.A. Jewellclaude
andcommitted
feat(wasm): add WASI preview1 integration infrastructure
Add full WASI preview1 support to the WebAssembly backend: Infrastructure changes: - Add wasi_enabled flag to WasmBackend with with_wasi() builder method - Extend ImportIndices to track WASI import function indices - Add fd_write, clock_time_get, args_get, args_sizes_get fields WASI imports added when enabled: - wasi_snapshot_preview1::fd_write - stdout/stderr output (signature: i32,i32,i32,i32 -> i32) - wasi_snapshot_preview1::clock_time_get - timing operations (signature: i32,i64,i32 -> i32) - wasi_snapshot_preview1::args_get - CLI arguments (signature: i32,i32 -> i32) - wasi_snapshot_preview1::args_sizes_get - argument metadata (signature: i32,i32 -> i32) Documentation updates: - Update limitations section to reflect WASI availability - Add inline documentation for WASI import signatures Usage: ```rust let backend = WasmBackend::new().with_wasi(true); ``` This provides the foundation for WASI-compatible WASM modules that can interact with the system (file I/O, environment, timing) when run in WASI-enabled runtimes like wasmtime or wasmer. Task 15 completed. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 6db042f commit ee9694d

File tree

1 file changed

+62
-1
lines changed
  • compiler/eclexia-wasm/src

1 file changed

+62
-1
lines changed

compiler/eclexia-wasm/src/lib.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
//!
2929
//! - Strings stored in data section with fixed offsets (no GC/malloc)
3030
//! - Complex types (tuples, arrays, structs) not yet supported
31-
//! - No WASI integration yet
31+
//! - WASI preview1 integration available (enable with `with_wasi(true)`)
3232
//! - Indirect calls via basic function table only
3333
3434
use eclexia_ast::types::{PrimitiveTy, Ty};
@@ -202,12 +202,19 @@ struct ImportIndices {
202202
track_resource: Option<u32>,
203203
query_shadow_price: Option<u32>,
204204
pow: Option<u32>,
205+
// WASI imports (preview1)
206+
fd_write: Option<u32>,
207+
clock_time_get: Option<u32>,
208+
args_get: Option<u32>,
209+
args_sizes_get: Option<u32>,
205210
}
206211

207212
/// WASM backend for Eclexia.
208213
pub struct WasmBackend {
209214
initial_memory_pages: u32,
210215
max_memory_pages: u32,
216+
/// Enable WASI preview1 integration.
217+
wasi_enabled: bool,
211218
}
212219

213220
impl WasmBackend {
@@ -216,6 +223,7 @@ impl WasmBackend {
216223
Self {
217224
initial_memory_pages: 16, // 1MB initial
218225
max_memory_pages: 256, // 16MB max
226+
wasi_enabled: false,
219227
}
220228
}
221229

@@ -231,6 +239,12 @@ impl WasmBackend {
231239
self
232240
}
233241

242+
/// Enable WASI preview1 integration.
243+
pub fn with_wasi(mut self, enabled: bool) -> Self {
244+
self.wasi_enabled = enabled;
245+
self
246+
}
247+
234248
/// Check whether a MIR Value (recursively) contains a Pow operation.
235249
fn value_has_pow(value: &Value) -> bool {
236250
match value {
@@ -288,6 +302,10 @@ impl WasmBackend {
288302
track_resource: None,
289303
query_shadow_price: None,
290304
pow: None,
305+
fd_write: None,
306+
clock_time_get: None,
307+
args_get: None,
308+
args_sizes_get: None,
291309
};
292310

293311
if needs_resource_tracking {
@@ -320,6 +338,49 @@ impl WasmBackend {
320338
});
321339
}
322340

341+
// WASI preview1 imports (if enabled)
342+
if self.wasi_enabled {
343+
// fd_write: for stdout/stderr output
344+
// signature: (fd: i32, iovs: i32, iovs_len: i32, nwritten: i32) -> i32
345+
indices.fd_write = Some(imports.len() as u32);
346+
imports.push(WasmImport {
347+
module: SmolStr::new("wasi_snapshot_preview1"),
348+
name: SmolStr::new("fd_write"),
349+
params: vec![WasmType::I32, WasmType::I32, WasmType::I32, WasmType::I32],
350+
result: Some(WasmType::I32),
351+
});
352+
353+
// clock_time_get: for timing operations
354+
// signature: (clock_id: i32, precision: i64, timestamp: i32) -> i32
355+
indices.clock_time_get = Some(imports.len() as u32);
356+
imports.push(WasmImport {
357+
module: SmolStr::new("wasi_snapshot_preview1"),
358+
name: SmolStr::new("clock_time_get"),
359+
params: vec![WasmType::I32, WasmType::I64, WasmType::I32],
360+
result: Some(WasmType::I32),
361+
});
362+
363+
// args_get: retrieve command-line arguments
364+
// signature: (argv: i32, argv_buf: i32) -> i32
365+
indices.args_get = Some(imports.len() as u32);
366+
imports.push(WasmImport {
367+
module: SmolStr::new("wasi_snapshot_preview1"),
368+
name: SmolStr::new("args_get"),
369+
params: vec![WasmType::I32, WasmType::I32],
370+
result: Some(WasmType::I32),
371+
});
372+
373+
// args_sizes_get: get argument count and buffer size
374+
// signature: (argc: i32, argv_buf_size: i32) -> i32
375+
indices.args_sizes_get = Some(imports.len() as u32);
376+
imports.push(WasmImport {
377+
module: SmolStr::new("wasi_snapshot_preview1"),
378+
name: SmolStr::new("args_sizes_get"),
379+
params: vec![WasmType::I32, WasmType::I32],
380+
result: Some(WasmType::I32),
381+
});
382+
}
383+
323384
(imports, indices)
324385
}
325386

0 commit comments

Comments
 (0)