virtual-machine 0.0.30 → 0.0.32
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 +1 -0
- package/build/{chunk-RTJAHMWT.mjs → chunk-PD2KO7C4.mjs} +285 -22
- package/build/cli.js +518 -102
- package/build/index.d.ts +226 -14
- package/build/index.js +396 -29
- package/build/index.mjs +110 -8
- package/build/{riscv_vm-K77G5X4P.mjs → riscv_vm-LL6COL52.mjs} +7 -1
- package/build/worker.js +249 -236
- package/package.json +1 -1
- package/build/worker.d.ts +0 -35
- package/build/worker.mjs +0 -54
package/build/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export { WorkerErrorMessage, WorkerHaltedMessage, WorkerInitMessage, WorkerOutboundMessage, WorkerReadyMessage } from './worker.js';
|
|
2
|
-
|
|
3
1
|
/* tslint:disable */
|
|
4
2
|
/* eslint-disable */
|
|
5
3
|
|
|
@@ -18,6 +16,9 @@ declare class WasmVm {
|
|
|
18
16
|
[Symbol.dispose](): void;
|
|
19
17
|
/**
|
|
20
18
|
* Get a byte from the UART output buffer, if available.
|
|
19
|
+
*
|
|
20
|
+
* In SMP mode, this checks both the shared UART output buffer (for worker output)
|
|
21
|
+
* and the local UART buffer (for hart 0 output).
|
|
21
22
|
*/
|
|
22
23
|
get_output(): number | undefined;
|
|
23
24
|
/**
|
|
@@ -29,15 +30,42 @@ declare class WasmVm {
|
|
|
29
30
|
* Print a status message to UART output (visible in browser).
|
|
30
31
|
*/
|
|
31
32
|
print_status(message: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Start worker threads for secondary harts (1..num_harts).
|
|
35
|
+
*
|
|
36
|
+
* Workers run in parallel with the main thread, sharing DRAM and CLINT
|
|
37
|
+
* via SharedArrayBuffer.
|
|
38
|
+
*
|
|
39
|
+
* # Arguments
|
|
40
|
+
* * `worker_url` - URL to the worker script (e.g., "/worker.js")
|
|
41
|
+
*/
|
|
42
|
+
start_workers(worker_url: string): void;
|
|
32
43
|
/**
|
|
33
44
|
* Get the current network connection status.
|
|
34
45
|
* This checks the actual connection state by seeing if an IP was assigned.
|
|
35
46
|
*/
|
|
36
47
|
network_status(): NetworkStatus;
|
|
48
|
+
/**
|
|
49
|
+
* Create a new VM instance with a specified number of harts.
|
|
50
|
+
*
|
|
51
|
+
* # Arguments
|
|
52
|
+
* * `kernel` - ELF kernel binary
|
|
53
|
+
* * `num_harts` - Number of harts (0 = auto-detect)
|
|
54
|
+
*/
|
|
55
|
+
static new_with_harts(kernel: Uint8Array, num_harts: number): WasmVm;
|
|
37
56
|
/**
|
|
38
57
|
* Get current memory usage (DRAM size) in bytes.
|
|
39
58
|
*/
|
|
40
59
|
get_memory_usage(): bigint;
|
|
60
|
+
/**
|
|
61
|
+
* Get the SharedArrayBuffer for external worker management.
|
|
62
|
+
* Returns None if not in SMP mode.
|
|
63
|
+
*/
|
|
64
|
+
get_shared_buffer(): SharedArrayBuffer | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Terminate all workers.
|
|
67
|
+
*/
|
|
68
|
+
terminate_workers(): void;
|
|
41
69
|
/**
|
|
42
70
|
* Disconnect from the network.
|
|
43
71
|
*/
|
|
@@ -54,17 +82,32 @@ declare class WasmVm {
|
|
|
54
82
|
connect_webtransport(url: string, cert_hash?: string | null): void;
|
|
55
83
|
/**
|
|
56
84
|
* Create a new VM instance and load a kernel (ELF or raw binary).
|
|
85
|
+
*
|
|
86
|
+
* If SharedArrayBuffer is available, the VM will use true parallel
|
|
87
|
+
* execution with Web Workers. Otherwise, falls back to single-threaded mode.
|
|
88
|
+
*
|
|
89
|
+
* Hart count is auto-detected as half of hardware_concurrency.
|
|
90
|
+
* Use `new_with_harts()` to specify a custom hart count.
|
|
57
91
|
*/
|
|
58
92
|
constructor(kernel: Uint8Array);
|
|
59
93
|
/**
|
|
60
|
-
* Execute one instruction on
|
|
94
|
+
* Execute one instruction on hart 0 (primary hart).
|
|
95
|
+
*
|
|
96
|
+
* In SMP mode, secondary harts run in Web Workers and execute in parallel.
|
|
97
|
+
* This method only steps hart 0, which handles I/O coordination.
|
|
98
|
+
*
|
|
61
99
|
* Returns true if the VM is still running, false if halted.
|
|
62
100
|
*/
|
|
63
101
|
step(): boolean;
|
|
64
102
|
/**
|
|
65
103
|
* Push an input byte to the UART.
|
|
104
|
+
* In SMP mode, this also writes to the shared input buffer so workers can receive it.
|
|
66
105
|
*/
|
|
67
106
|
input(byte: number): void;
|
|
107
|
+
/**
|
|
108
|
+
* Check if running in SMP mode (with workers).
|
|
109
|
+
*/
|
|
110
|
+
is_smp(): boolean;
|
|
68
111
|
/**
|
|
69
112
|
* Execute up to N instructions in a batch.
|
|
70
113
|
* Returns the number of instructions actually executed.
|
|
@@ -86,15 +129,75 @@ declare class WasmVm {
|
|
|
86
129
|
* This should be called before starting execution if the kernel needs a filesystem.
|
|
87
130
|
*/
|
|
88
131
|
load_disk(disk_image: Uint8Array): void;
|
|
132
|
+
/**
|
|
133
|
+
* Get the number of harts configured.
|
|
134
|
+
*/
|
|
135
|
+
num_harts(): number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare class WorkerState {
|
|
139
|
+
free(): void;
|
|
140
|
+
[Symbol.dispose](): void;
|
|
141
|
+
/**
|
|
142
|
+
* Execute a batch of instructions and return.
|
|
143
|
+
*
|
|
144
|
+
* This is designed to be called repeatedly from JavaScript, allowing
|
|
145
|
+
* the event loop to yield between batches. This prevents the worker
|
|
146
|
+
* from blocking indefinitely and allows it to respond to messages.
|
|
147
|
+
*
|
|
148
|
+
* Returns a WorkerStepResult indicating whether to continue, halt, etc.
|
|
149
|
+
*/
|
|
150
|
+
step_batch(batch_size: number): WorkerStepResult;
|
|
151
|
+
/**
|
|
152
|
+
* Get the total step count.
|
|
153
|
+
*/
|
|
154
|
+
step_count(): bigint;
|
|
155
|
+
/**
|
|
156
|
+
* Create a new worker state for a secondary hart.
|
|
157
|
+
*/
|
|
158
|
+
constructor(hart_id: number, shared_mem: any, entry_pc: bigint);
|
|
159
|
+
/**
|
|
160
|
+
* Get the hart ID.
|
|
161
|
+
*/
|
|
162
|
+
hart_id(): number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Result of executing a batch of instructions.
|
|
167
|
+
*/
|
|
168
|
+
declare enum WorkerStepResult {
|
|
169
|
+
/**
|
|
170
|
+
* Continue executing - call step_batch again
|
|
171
|
+
*/
|
|
172
|
+
Continue = 0,
|
|
173
|
+
/**
|
|
174
|
+
* Halt requested via control region
|
|
175
|
+
*/
|
|
176
|
+
Halted = 1,
|
|
177
|
+
/**
|
|
178
|
+
* Shutdown requested by guest (RequestedTrap)
|
|
179
|
+
*/
|
|
180
|
+
Shutdown = 2,
|
|
181
|
+
/**
|
|
182
|
+
* Fatal error occurred
|
|
183
|
+
*/
|
|
184
|
+
Error = 3,
|
|
89
185
|
}
|
|
90
186
|
|
|
91
187
|
/**
|
|
92
|
-
*
|
|
188
|
+
* Check interrupts for this hart using the shared CLINT.
|
|
93
189
|
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
|
|
190
|
+
* This is called periodically by the worker to check for:
|
|
191
|
+
* - Software interrupts (IPI via MSIP)
|
|
192
|
+
* - Timer interrupts (MTIP)
|
|
193
|
+
*/
|
|
194
|
+
declare function worker_check_interrupts(hart_id: number, shared_mem: any): bigint;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Legacy worker entry point - DEPRECATED.
|
|
198
|
+
*
|
|
199
|
+
* This function runs a blocking infinite loop. Use WorkerState + step_batch instead
|
|
200
|
+
* for cooperative scheduling that doesn't block the worker's event loop.
|
|
98
201
|
*/
|
|
99
202
|
declare function worker_entry(hart_id: number, shared_mem: any, entry_pc: bigint): void;
|
|
100
203
|
|
|
@@ -103,27 +206,40 @@ type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Modul
|
|
|
103
206
|
interface InitOutput {
|
|
104
207
|
readonly memory: WebAssembly.Memory;
|
|
105
208
|
readonly __wbg_wasmvm_free: (a: number, b: number) => void;
|
|
209
|
+
readonly __wbg_workerstate_free: (a: number, b: number) => void;
|
|
106
210
|
readonly wasmvm_connect_webtransport: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
|
107
211
|
readonly wasmvm_disconnect_network: (a: number) => void;
|
|
108
212
|
readonly wasmvm_get_memory_usage: (a: number) => bigint;
|
|
109
213
|
readonly wasmvm_get_output: (a: number) => number;
|
|
214
|
+
readonly wasmvm_get_shared_buffer: (a: number) => any;
|
|
110
215
|
readonly wasmvm_halt_code: (a: number) => bigint;
|
|
111
216
|
readonly wasmvm_input: (a: number, b: number) => void;
|
|
112
217
|
readonly wasmvm_is_halted: (a: number) => number;
|
|
218
|
+
readonly wasmvm_is_smp: (a: number) => number;
|
|
113
219
|
readonly wasmvm_load_disk: (a: number, b: number, c: number) => void;
|
|
114
220
|
readonly wasmvm_network_status: (a: number) => number;
|
|
115
221
|
readonly wasmvm_new: (a: number, b: number) => [number, number, number];
|
|
222
|
+
readonly wasmvm_new_with_harts: (a: number, b: number, c: number) => [number, number, number];
|
|
223
|
+
readonly wasmvm_num_harts: (a: number) => number;
|
|
116
224
|
readonly wasmvm_print_banner: (a: number) => void;
|
|
117
225
|
readonly wasmvm_print_status: (a: number, b: number, c: number) => void;
|
|
226
|
+
readonly wasmvm_start_workers: (a: number, b: number, c: number) => [number, number];
|
|
118
227
|
readonly wasmvm_step: (a: number) => number;
|
|
119
228
|
readonly wasmvm_step_n: (a: number, b: number) => number;
|
|
229
|
+
readonly wasmvm_terminate_workers: (a: number) => void;
|
|
120
230
|
readonly wasmvm_uart_output_pending: (a: number) => number;
|
|
231
|
+
readonly worker_check_interrupts: (a: number, b: any) => bigint;
|
|
121
232
|
readonly worker_entry: (a: number, b: any, c: bigint) => void;
|
|
122
|
-
readonly
|
|
123
|
-
readonly
|
|
124
|
-
readonly
|
|
233
|
+
readonly workerstate_hart_id: (a: number) => number;
|
|
234
|
+
readonly workerstate_new: (a: number, b: any, c: bigint) => number;
|
|
235
|
+
readonly workerstate_step_batch: (a: number, b: number) => number;
|
|
236
|
+
readonly workerstate_step_count: (a: number) => bigint;
|
|
125
237
|
readonly wasm_bindgen__convert__closures_____invoke__h39d3e89751b07765: (a: number, b: number, c: any) => void;
|
|
126
238
|
readonly wasm_bindgen__closure__destroy__hf225e18fc5ab9bc1: (a: number, b: number) => void;
|
|
239
|
+
readonly wasm_bindgen__convert__closures_____invoke__h67573e759d30b522: (a: number, b: number) => void;
|
|
240
|
+
readonly wasm_bindgen__closure__destroy__h1c929db64e64ab27: (a: number, b: number) => void;
|
|
241
|
+
readonly wasm_bindgen__convert__closures_____invoke__hb59a63b35a5a8674: (a: number, b: number, c: any) => void;
|
|
242
|
+
readonly wasm_bindgen__convert__closures_____invoke__hf580618779cd5844: (a: number, b: number) => void;
|
|
127
243
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
128
244
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
129
245
|
readonly __wbindgen_exn_store: (a: number) => void;
|
|
@@ -163,12 +279,65 @@ declare const __pkg_riscv_vm_NetworkStatus: typeof NetworkStatus;
|
|
|
163
279
|
type __pkg_riscv_vm_SyncInitInput = SyncInitInput;
|
|
164
280
|
type __pkg_riscv_vm_WasmVm = WasmVm;
|
|
165
281
|
declare const __pkg_riscv_vm_WasmVm: typeof WasmVm;
|
|
282
|
+
type __pkg_riscv_vm_WorkerState = WorkerState;
|
|
283
|
+
declare const __pkg_riscv_vm_WorkerState: typeof WorkerState;
|
|
284
|
+
type __pkg_riscv_vm_WorkerStepResult = WorkerStepResult;
|
|
285
|
+
declare const __pkg_riscv_vm_WorkerStepResult: typeof WorkerStepResult;
|
|
166
286
|
declare const __pkg_riscv_vm_initSync: typeof initSync;
|
|
287
|
+
declare const __pkg_riscv_vm_worker_check_interrupts: typeof worker_check_interrupts;
|
|
167
288
|
declare const __pkg_riscv_vm_worker_entry: typeof worker_entry;
|
|
168
289
|
declare namespace __pkg_riscv_vm {
|
|
169
|
-
export { type __pkg_riscv_vm_InitInput as InitInput, type __pkg_riscv_vm_InitOutput as InitOutput, __pkg_riscv_vm_NetworkStatus as NetworkStatus, type __pkg_riscv_vm_SyncInitInput as SyncInitInput, __pkg_riscv_vm_WasmVm as WasmVm, __wbg_init as default, __pkg_riscv_vm_initSync as initSync, __pkg_riscv_vm_worker_entry as worker_entry };
|
|
290
|
+
export { type __pkg_riscv_vm_InitInput as InitInput, type __pkg_riscv_vm_InitOutput as InitOutput, __pkg_riscv_vm_NetworkStatus as NetworkStatus, type __pkg_riscv_vm_SyncInitInput as SyncInitInput, __pkg_riscv_vm_WasmVm as WasmVm, __pkg_riscv_vm_WorkerState as WorkerState, __pkg_riscv_vm_WorkerStepResult as WorkerStepResult, __wbg_init as default, __pkg_riscv_vm_initSync as initSync, __pkg_riscv_vm_worker_check_interrupts as worker_check_interrupts, __pkg_riscv_vm_worker_entry as worker_entry };
|
|
170
291
|
}
|
|
171
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Worker utility types and functions.
|
|
295
|
+
*
|
|
296
|
+
* This module contains only types and side-effect-free utility functions
|
|
297
|
+
* that can be safely imported in Node.js or browser environments.
|
|
298
|
+
*
|
|
299
|
+
* The actual worker entry point is in worker.ts (browser-only).
|
|
300
|
+
*/
|
|
301
|
+
/** Message sent from main thread to initialize the worker */
|
|
302
|
+
interface WorkerInitMessage {
|
|
303
|
+
hartId: number;
|
|
304
|
+
/** SharedArrayBuffer containing control + CLINT + DRAM */
|
|
305
|
+
sharedMem: SharedArrayBuffer;
|
|
306
|
+
entryPc: number;
|
|
307
|
+
}
|
|
308
|
+
/** Message sent when worker is ready to execute */
|
|
309
|
+
interface WorkerReadyMessage {
|
|
310
|
+
type: "ready";
|
|
311
|
+
hartId: number;
|
|
312
|
+
}
|
|
313
|
+
/** Message sent when worker has halted */
|
|
314
|
+
interface WorkerHaltedMessage {
|
|
315
|
+
type: "halted";
|
|
316
|
+
hartId: number;
|
|
317
|
+
stepCount?: number;
|
|
318
|
+
}
|
|
319
|
+
/** Message sent when an error occurs */
|
|
320
|
+
interface WorkerErrorMessage {
|
|
321
|
+
type: "error";
|
|
322
|
+
hartId?: number;
|
|
323
|
+
error: string;
|
|
324
|
+
}
|
|
325
|
+
type WorkerOutboundMessage = WorkerReadyMessage | WorkerHaltedMessage | WorkerErrorMessage;
|
|
326
|
+
/**
|
|
327
|
+
* Check if halt has been requested in the shared control region.
|
|
328
|
+
* This can be used for JS-side polling if needed.
|
|
329
|
+
*/
|
|
330
|
+
declare function isHaltRequested(sharedMem: SharedArrayBuffer): boolean;
|
|
331
|
+
/**
|
|
332
|
+
* Request halt by setting the flag in shared memory.
|
|
333
|
+
* This can be called from any thread.
|
|
334
|
+
*/
|
|
335
|
+
declare function requestHalt(sharedMem: SharedArrayBuffer): void;
|
|
336
|
+
/**
|
|
337
|
+
* Check if VM has halted.
|
|
338
|
+
*/
|
|
339
|
+
declare function isHalted(sharedMem: SharedArrayBuffer): boolean;
|
|
340
|
+
|
|
172
341
|
declare function WasmInternal(): Promise<typeof __pkg_riscv_vm>;
|
|
173
342
|
|
|
174
343
|
interface VmOptions {
|
|
@@ -178,7 +347,10 @@ interface VmOptions {
|
|
|
178
347
|
workerScript?: string;
|
|
179
348
|
}
|
|
180
349
|
/**
|
|
181
|
-
* Create a VM instance
|
|
350
|
+
* Create a VM instance with optional SMP support.
|
|
351
|
+
*
|
|
352
|
+
* If SharedArrayBuffer is available (requires COOP/COEP headers), the VM
|
|
353
|
+
* will run in true parallel mode with Web Workers for secondary harts.
|
|
182
354
|
*
|
|
183
355
|
* @param kernelData - ELF kernel binary
|
|
184
356
|
* @param options - VM configuration options
|
|
@@ -188,6 +360,9 @@ declare function createVM(kernelData: Uint8Array, options?: VmOptions): Promise<
|
|
|
188
360
|
/**
|
|
189
361
|
* Run the VM with an output callback for UART data.
|
|
190
362
|
*
|
|
363
|
+
* This function manages the main execution loop, stepping hart 0 on the
|
|
364
|
+
* main thread. Secondary harts (if any) run in Web Workers.
|
|
365
|
+
*
|
|
191
366
|
* @param vm - WasmVm instance
|
|
192
367
|
* @param onOutput - Callback for each character output
|
|
193
368
|
* @param options - Run options
|
|
@@ -198,6 +373,7 @@ declare function runVM(vm: WasmVm, onOutput: (char: string) => void, options?: {
|
|
|
198
373
|
}): () => void;
|
|
199
374
|
interface SharedMemorySupport {
|
|
200
375
|
supported: boolean;
|
|
376
|
+
crossOriginIsolated: boolean;
|
|
201
377
|
message: string;
|
|
202
378
|
}
|
|
203
379
|
/**
|
|
@@ -211,5 +387,41 @@ declare function checkSharedMemorySupport(): SharedMemorySupport;
|
|
|
211
387
|
* Check if the page is cross-origin isolated (required for SharedArrayBuffer).
|
|
212
388
|
*/
|
|
213
389
|
declare function isCrossOriginIsolated(): boolean;
|
|
390
|
+
/**
|
|
391
|
+
* Headers required for SharedArrayBuffer support.
|
|
392
|
+
*
|
|
393
|
+
* For Vite dev server, add to vite.config.ts:
|
|
394
|
+
* ```ts
|
|
395
|
+
* server: {
|
|
396
|
+
* headers: {
|
|
397
|
+
* "Cross-Origin-Opener-Policy": "same-origin",
|
|
398
|
+
* "Cross-Origin-Embedder-Policy": "require-corp",
|
|
399
|
+
* },
|
|
400
|
+
* },
|
|
401
|
+
* ```
|
|
402
|
+
*
|
|
403
|
+
* For production, configure your web server to add these headers.
|
|
404
|
+
*/
|
|
405
|
+
declare const REQUIRED_HEADERS: {
|
|
406
|
+
readonly "Cross-Origin-Opener-Policy": "same-origin";
|
|
407
|
+
readonly "Cross-Origin-Embedder-Policy": "require-corp";
|
|
408
|
+
};
|
|
409
|
+
/**
|
|
410
|
+
* Manually create and manage workers for advanced use cases.
|
|
411
|
+
*
|
|
412
|
+
* Most users should use createVM() which handles workers automatically.
|
|
413
|
+
*/
|
|
414
|
+
interface WorkerManager {
|
|
415
|
+
/** Start a worker for a specific hart */
|
|
416
|
+
startWorker(hartId: number, sharedMem: SharedArrayBuffer, entryPc: number, workerScript?: string): Worker;
|
|
417
|
+
/** Terminate all workers */
|
|
418
|
+
terminateAll(): void;
|
|
419
|
+
/** Get number of active workers */
|
|
420
|
+
count(): number;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Create a worker manager for manual worker control.
|
|
424
|
+
*/
|
|
425
|
+
declare function createWorkerManager(): WorkerManager;
|
|
214
426
|
|
|
215
|
-
export { NetworkStatus, type SharedMemorySupport, type VmOptions, WasmInternal, WasmVm, checkSharedMemorySupport, createVM, isCrossOriginIsolated, runVM };
|
|
427
|
+
export { NetworkStatus, REQUIRED_HEADERS, type SharedMemorySupport, type VmOptions, WasmInternal, WasmVm, type WorkerErrorMessage, type WorkerHaltedMessage, type WorkerInitMessage, type WorkerManager, type WorkerOutboundMessage, type WorkerReadyMessage, checkSharedMemorySupport, createVM, createWorkerManager, isCrossOriginIsolated, isHaltRequested, isHalted, requestHalt, runVM };
|