@@ -18,6 +18,10 @@ pub fn build(b: *std.Build) void {
1818 const is_wasm = target .result .cpu .arch == .wasm32 or
1919 target .result .cpu .arch == .wasm64 ;
2020
21+ // Detect WASM atomics — enables multi-threaded mode for Web Workers
22+ const has_wasm_atomics = is_wasm and
23+ std .Target .wasm .featureSetHas (target .result .cpu .features , .atomics );
24+
2125 // Package dependencies
2226 const zolt_pool_dep = b .dependency ("zolt_pool" , .{
2327 .target = target ,
@@ -31,37 +35,6 @@ pub fn build(b: *std.Build) void {
3135 });
3236 const zolt_arith_mod = zolt_arith_dep .module ("zolt_arith" );
3337
34- // Main library
35- const lib = b .addLibrary (.{
36- .name = "zolt" ,
37- .root_module = b .createModule (.{
38- .root_source_file = b .path ("src/root.zig" ),
39- .target = target ,
40- .optimize = optimize ,
41- .imports = &.{
42- .{ .name = "zolt_pool" , .module = zolt_pool_mod },
43- .{ .name = "zolt_arith" , .module = zolt_arith_mod },
44- },
45- }),
46- });
47- if (is_apple_silicon ) linkMetalFrameworks (lib .root_module );
48- b .installArtifact (lib );
49-
50- // C-API static library (for FFI from Rust/C/WASM)
51- const capi_lib = b .addLibrary (.{
52- .name = "zolt_capi" ,
53- .root_module = b .createModule (.{
54- .root_source_file = b .path ("src/c_api.zig" ),
55- .target = target ,
56- .optimize = optimize ,
57- .imports = &.{
58- .{ .name = "zolt_pool" , .module = zolt_pool_mod },
59- .{ .name = "zolt_arith" , .module = zolt_arith_mod },
60- },
61- }),
62- });
63- if (is_apple_silicon ) linkMetalFrameworks (capi_lib .root_module );
64- b .installArtifact (capi_lib );
6538
6639 // Export zolt module for dependency consumption
6740 _ = b .addModule ("zolt" , .{
@@ -74,9 +47,115 @@ pub fn build(b: *std.Build) void {
7447 },
7548 });
7649
77- // ── Native-only targets (executables, tests, benchmarks) ─────────
50+ // ── WASM executable target (browser-loadable .wasm module) ─────────
51+ if (is_wasm ) {
52+ const wasm_mod = b .addExecutable (.{
53+ .name = "zolt_capi" ,
54+ .root_module = b .createModule (.{
55+ .root_source_file = b .path ("src/c_api.zig" ),
56+ .target = target ,
57+ .optimize = optimize ,
58+ .imports = &.{
59+ .{ .name = "zolt_pool" , .module = zolt_pool_mod },
60+ .{ .name = "zolt_arith" , .module = zolt_arith_mod },
61+ },
62+ }),
63+ });
64+ wasm_mod .entry = .disabled ;
65+ wasm_mod .initial_memory = 256 * 1024 * 1024 ; // 256 MB
66+ wasm_mod .max_memory = if (target .result .cpu .arch == .wasm64 )
67+ 16 * 1024 * 1024 * 1024 // 16 GB (wasm64, wasm-ld max)
68+ else
69+ 4 * 1024 * 1024 * 1024 ; // 4 GB (wasm32 max)
70+ wasm_mod .root_module .export_symbol_names = if (has_wasm_atomics )
71+ &.{
72+ "zolt_alloc" ,
73+ "zolt_free" ,
74+ "zolt_thread_pool_create" ,
75+ "zolt_thread_pool_destroy" ,
76+ "zolt_load_elf" ,
77+ "zolt_load_elf_bytes" ,
78+ "zolt_loaded_elf_size" ,
79+ "zolt_loaded_elf_destroy" ,
80+ "zolt_prove" ,
81+ "zolt_proof_result_size" ,
82+ "zolt_proof_result_ptr" ,
83+ "zolt_proof_result_destroy" ,
84+ "zolt_thread_pool_create_wasm" ,
85+ "zolt_thread_pool_ptr" ,
86+ "zolt_worker_entry" ,
87+ // Workers need their own stack and TLS regions
88+ "__stack_pointer" ,
89+ "__tls_base" ,
90+ "__tls_size" ,
91+ "__tls_align" ,
92+ "__wasm_init_tls" ,
93+ }
94+ else
95+ &.{
96+ "zolt_alloc" ,
97+ "zolt_free" ,
98+ "zolt_thread_pool_create" ,
99+ "zolt_thread_pool_destroy" ,
100+ "zolt_load_elf" ,
101+ "zolt_load_elf_bytes" ,
102+ "zolt_loaded_elf_size" ,
103+ "zolt_loaded_elf_destroy" ,
104+ "zolt_prove" ,
105+ "zolt_proof_result_size" ,
106+ "zolt_proof_result_ptr" ,
107+ "zolt_proof_result_destroy" ,
108+ "zolt_thread_pool_create_wasm" ,
109+ "zolt_thread_pool_ptr" ,
110+ "zolt_worker_entry" ,
111+ };
112+
113+ if (has_wasm_atomics ) {
114+ // Enable shared memory for Web Workers + SharedArrayBuffer
115+ wasm_mod .shared_memory = true ;
116+ wasm_mod .import_memory = true ; // JS creates SharedArrayBuffer
117+ wasm_mod .export_memory = true ; // re-export so JS can access via instance.exports.memory
118+ } else {
119+ wasm_mod .export_memory = true ;
120+ }
121+ b .installArtifact (wasm_mod );
122+ }
123+
124+ // ── Native-only targets (libraries, executables, tests, benchmarks) ──
78125 // These require OS threads, filesystem, and can't run on WASM.
79126 if (! is_wasm ) {
127+ // Main library
128+ const lib = b .addLibrary (.{
129+ .name = "zolt" ,
130+ .root_module = b .createModule (.{
131+ .root_source_file = b .path ("src/root.zig" ),
132+ .target = target ,
133+ .optimize = optimize ,
134+ .imports = &.{
135+ .{ .name = "zolt_pool" , .module = zolt_pool_mod },
136+ .{ .name = "zolt_arith" , .module = zolt_arith_mod },
137+ },
138+ }),
139+ });
140+ if (is_apple_silicon ) linkMetalFrameworks (lib .root_module );
141+ b .installArtifact (lib );
142+
143+ // C-API static library (for FFI from Rust/C)
144+ const capi_lib = b .addLibrary (.{
145+ .name = "zolt_capi" ,
146+ .root_module = b .createModule (.{
147+ .root_source_file = b .path ("src/c_api.zig" ),
148+ .target = target ,
149+ .optimize = optimize ,
150+ .imports = &.{
151+ .{ .name = "zolt_pool" , .module = zolt_pool_mod },
152+ .{ .name = "zolt_arith" , .module = zolt_arith_mod },
153+ },
154+ }),
155+ });
156+ if (is_apple_silicon ) linkMetalFrameworks (capi_lib .root_module );
157+ b .installArtifact (capi_lib );
158+
80159 // Main executable (for testing/demo)
81160 const exe = b .addExecutable (.{
82161 .name = "zolt" ,
0 commit comments