virtual-machine 0.0.31 → 0.0.35
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-CP2XF74Q.mjs → chunk-P2U2K4X3.mjs} +366 -20
- package/build/cli.js +662 -110
- package/build/index.d.ts +274 -14
- package/build/index.js +477 -27
- package/build/index.mjs +110 -8
- package/build/{riscv_vm-FJMOWX7R.mjs → riscv_vm-MDACKNLN.mjs} +7 -1
- package/build/worker.js +254 -234
- package/native/index.d.ts +61 -0
- package/native/index.js +125 -0
- package/native/index.mjs +9 -0
- package/package.json +28 -4
- package/build/worker.d.ts +0 -35
- package/build/worker.mjs +0 -54
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
/** Connection status for JavaScript */
|
|
7
|
+
export const enum ConnectionStatus {
|
|
8
|
+
Disconnected = 0,
|
|
9
|
+
Connecting = 1,
|
|
10
|
+
Connected = 2,
|
|
11
|
+
Error = 3
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* WebTransport client for Node.js.
|
|
15
|
+
*
|
|
16
|
+
* This class provides WebTransport connectivity using the same implementation
|
|
17
|
+
* as the native Rust VM. It maintains a persistent connection with automatic
|
|
18
|
+
* reconnection and heartbeat handling.
|
|
19
|
+
*/
|
|
20
|
+
export declare class WebTransportClient {
|
|
21
|
+
/**
|
|
22
|
+
* Create a new WebTransport client and start connecting.
|
|
23
|
+
*
|
|
24
|
+
* @param url - WebTransport server URL (e.g., "https://localhost:4433")
|
|
25
|
+
* @param certHash - Optional certificate hash for self-signed certs (hex string)
|
|
26
|
+
*/
|
|
27
|
+
constructor(url: string, certHash?: string | undefined | null)
|
|
28
|
+
/** Check if connected to the relay server. */
|
|
29
|
+
isConnected(): boolean
|
|
30
|
+
/** Check if registered with the relay (IP assigned). */
|
|
31
|
+
isRegistered(): boolean
|
|
32
|
+
/** Get current connection status. */
|
|
33
|
+
status(): ConnectionStatus
|
|
34
|
+
/** Get the MAC address as a hex string. */
|
|
35
|
+
macAddress(): string
|
|
36
|
+
/** Get the MAC address as a byte array. */
|
|
37
|
+
macBytes(): Array<number>
|
|
38
|
+
/** Get the assigned IP address (if any) as a string. */
|
|
39
|
+
assignedIp(): string | null
|
|
40
|
+
/** Get the assigned IP address as bytes (if any). */
|
|
41
|
+
assignedIpBytes(): Array<number> | null
|
|
42
|
+
/** Get the number of connection attempts. */
|
|
43
|
+
connectionAttempts(): number
|
|
44
|
+
/**
|
|
45
|
+
* Send an Ethernet frame to the relay.
|
|
46
|
+
* Returns true if sent successfully, false if not connected.
|
|
47
|
+
*/
|
|
48
|
+
send(data: Buffer): boolean
|
|
49
|
+
/**
|
|
50
|
+
* Receive an Ethernet frame from the relay (non-blocking).
|
|
51
|
+
* Returns the frame data or undefined if no frame available.
|
|
52
|
+
*/
|
|
53
|
+
recv(): Buffer | null
|
|
54
|
+
/**
|
|
55
|
+
* Receive all pending Ethernet frames (non-blocking).
|
|
56
|
+
* Returns an array of frame buffers.
|
|
57
|
+
*/
|
|
58
|
+
recvAll(): Array<Buffer>
|
|
59
|
+
/** Shut down the connection and cleanup. */
|
|
60
|
+
shutdown(): void
|
|
61
|
+
}
|
package/native/index.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Native bindings loader for riscv-vm
|
|
7
|
+
*
|
|
8
|
+
* This module detects the current platform and loads the appropriate
|
|
9
|
+
* pre-built native binary. All binaries are bundled in this package.
|
|
10
|
+
*
|
|
11
|
+
* Supported platforms:
|
|
12
|
+
* - darwin-x64 (macOS Intel)
|
|
13
|
+
* - darwin-arm64 (macOS Apple Silicon)
|
|
14
|
+
* - linux-x64-gnu (Linux x64 glibc)
|
|
15
|
+
* - linux-x64-musl (Linux x64 musl/Alpine)
|
|
16
|
+
* - linux-arm64-gnu (Linux ARM64 glibc)
|
|
17
|
+
* - linux-arm64-musl (Linux ARM64 musl/Alpine)
|
|
18
|
+
* - win32-x64-msvc (Windows x64)
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const { existsSync, readFileSync } = require('fs')
|
|
22
|
+
const { join } = require('path')
|
|
23
|
+
|
|
24
|
+
const { platform, arch } = process
|
|
25
|
+
|
|
26
|
+
let nativeBinding = null
|
|
27
|
+
let loadError = null
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Detect if running on musl libc (Alpine Linux, etc.)
|
|
31
|
+
*/
|
|
32
|
+
function isMusl() {
|
|
33
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
34
|
+
try {
|
|
35
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
36
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
37
|
+
} catch (e) {
|
|
38
|
+
return true
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
42
|
+
return !glibcVersionRuntime
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Load a native binding from the native directory
|
|
48
|
+
*/
|
|
49
|
+
function loadNativeBinding(filename) {
|
|
50
|
+
const filepath = join(__dirname, filename)
|
|
51
|
+
if (!existsSync(filepath)) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Native binding not found: ${filename}\n` +
|
|
54
|
+
`Expected at: ${filepath}\n` +
|
|
55
|
+
`Platform: ${platform}, Architecture: ${arch}\n\n` +
|
|
56
|
+
`This platform may not be supported, or the package was not installed correctly.\n` +
|
|
57
|
+
`Try reinstalling the package: npm install virtual-machine`
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
return require(filepath)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Determine the correct native binding filename for the current platform
|
|
65
|
+
*/
|
|
66
|
+
function getNativeBindingFilename() {
|
|
67
|
+
switch (platform) {
|
|
68
|
+
case 'darwin':
|
|
69
|
+
switch (arch) {
|
|
70
|
+
case 'x64':
|
|
71
|
+
return 'riscv-vm-native.darwin-x64.node'
|
|
72
|
+
case 'arm64':
|
|
73
|
+
return 'riscv-vm-native.darwin-arm64.node'
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
case 'linux':
|
|
79
|
+
const musl = isMusl()
|
|
80
|
+
switch (arch) {
|
|
81
|
+
case 'x64':
|
|
82
|
+
return musl
|
|
83
|
+
? 'riscv-vm-native.linux-x64-musl.node'
|
|
84
|
+
: 'riscv-vm-native.linux-x64-gnu.node'
|
|
85
|
+
case 'arm64':
|
|
86
|
+
return musl
|
|
87
|
+
? 'riscv-vm-native.linux-arm64-musl.node'
|
|
88
|
+
: 'riscv-vm-native.linux-arm64-gnu.node'
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case 'win32':
|
|
94
|
+
switch (arch) {
|
|
95
|
+
case 'x64':
|
|
96
|
+
return 'riscv-vm-native.win32-x64-msvc.node'
|
|
97
|
+
default:
|
|
98
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
default:
|
|
102
|
+
throw new Error(`Unsupported platform: ${platform}`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Load the native binding
|
|
107
|
+
try {
|
|
108
|
+
const filename = getNativeBindingFilename()
|
|
109
|
+
nativeBinding = loadNativeBinding(filename)
|
|
110
|
+
} catch (e) {
|
|
111
|
+
loadError = e
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!nativeBinding) {
|
|
115
|
+
if (loadError) {
|
|
116
|
+
throw loadError
|
|
117
|
+
}
|
|
118
|
+
throw new Error('Failed to load native binding')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Export the native binding APIs
|
|
122
|
+
const { ConnectionStatus, WebTransportClient } = nativeBinding
|
|
123
|
+
|
|
124
|
+
module.exports.ConnectionStatus = ConnectionStatus
|
|
125
|
+
module.exports.WebTransportClient = WebTransportClient
|
package/native/index.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virtual-machine",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.0.35",
|
|
4
|
+
"description": "RISC-V Virtual Machine with WASM and Node.js native support",
|
|
5
5
|
"bin": "build/cli.js",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -19,13 +19,36 @@
|
|
|
19
19
|
"types": "./build/worker.d.ts",
|
|
20
20
|
"import": "./build/worker.mjs",
|
|
21
21
|
"require": "./build/worker.js"
|
|
22
|
+
},
|
|
23
|
+
"./native": {
|
|
24
|
+
"import": "./native/index.mjs",
|
|
25
|
+
"require": "./native/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"napi": {
|
|
29
|
+
"name": "riscv-vm-native",
|
|
30
|
+
"triples": {
|
|
31
|
+
"defaults": false,
|
|
32
|
+
"additional": [
|
|
33
|
+
"x86_64-apple-darwin",
|
|
34
|
+
"aarch64-apple-darwin",
|
|
35
|
+
"x86_64-unknown-linux-gnu",
|
|
36
|
+
"aarch64-unknown-linux-gnu",
|
|
37
|
+
"x86_64-unknown-linux-musl",
|
|
38
|
+
"aarch64-unknown-linux-musl",
|
|
39
|
+
"x86_64-pc-windows-msvc"
|
|
40
|
+
]
|
|
22
41
|
}
|
|
23
42
|
},
|
|
24
43
|
"files": [
|
|
25
|
-
"build"
|
|
44
|
+
"build",
|
|
45
|
+
"native"
|
|
26
46
|
],
|
|
27
47
|
"scripts": {
|
|
28
|
-
"build": "rm -rf build && sh build.sh"
|
|
48
|
+
"build": "rm -rf build && sh build.sh",
|
|
49
|
+
"build:native": "napi build --platform --release --features napi --cargo-cwd . --cargo-flags=\"--lib\" native",
|
|
50
|
+
"build:native:debug": "napi build --platform --features napi --cargo-cwd . --cargo-flags=\"--lib\" native",
|
|
51
|
+
"build:all": "npm run build && npm run build:native"
|
|
29
52
|
},
|
|
30
53
|
"repository": {
|
|
31
54
|
"type": "git",
|
|
@@ -39,6 +62,7 @@
|
|
|
39
62
|
"packageManager": "yarn@4.11.0+sha512.4e54aeace9141df2f0177c266b05ec50dc044638157dae128c471ba65994ac802122d7ab35bcd9e81641228b7dcf24867d28e750e0bcae8a05277d600008ad54",
|
|
40
63
|
"devDependencies": {
|
|
41
64
|
"@esbuild-plugins/node-resolve": "^0.2.2",
|
|
65
|
+
"@napi-rs/cli": "^2.18.0",
|
|
42
66
|
"@trust0/ridb-build": "^0.0.21",
|
|
43
67
|
"@types/node": "^24.10.1",
|
|
44
68
|
"tsup": "^8.4.0",
|
package/build/worker.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Web Worker entry point for RISC-V hart.
|
|
3
|
-
*
|
|
4
|
-
* This worker runs a secondary RISC-V hart sharing memory with the main thread
|
|
5
|
-
* via SharedArrayBuffer.
|
|
6
|
-
*
|
|
7
|
-
* Communication protocol:
|
|
8
|
-
* Main → Worker: WorkerInitMessage
|
|
9
|
-
* Worker → Main: WorkerReadyMessage | WorkerHaltedMessage | WorkerErrorMessage
|
|
10
|
-
*/
|
|
11
|
-
/** Message sent from main thread to initialize the worker */
|
|
12
|
-
interface WorkerInitMessage {
|
|
13
|
-
hartId: number;
|
|
14
|
-
sharedMem: SharedArrayBuffer;
|
|
15
|
-
entryPc: number;
|
|
16
|
-
}
|
|
17
|
-
/** Message sent when worker is ready to execute */
|
|
18
|
-
interface WorkerReadyMessage {
|
|
19
|
-
type: "ready";
|
|
20
|
-
hartId: number;
|
|
21
|
-
}
|
|
22
|
-
/** Message sent when worker has halted */
|
|
23
|
-
interface WorkerHaltedMessage {
|
|
24
|
-
type: "halted";
|
|
25
|
-
hartId: number;
|
|
26
|
-
}
|
|
27
|
-
/** Message sent when an error occurs */
|
|
28
|
-
interface WorkerErrorMessage {
|
|
29
|
-
type: "error";
|
|
30
|
-
hartId?: number;
|
|
31
|
-
error: string;
|
|
32
|
-
}
|
|
33
|
-
type WorkerOutboundMessage = WorkerReadyMessage | WorkerHaltedMessage | WorkerErrorMessage;
|
|
34
|
-
|
|
35
|
-
export type { WorkerErrorMessage, WorkerHaltedMessage, WorkerInitMessage, WorkerOutboundMessage, WorkerReadyMessage };
|
package/build/worker.mjs
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
riscv_vm_default,
|
|
3
|
-
worker_entry
|
|
4
|
-
} from "./chunk-CP2XF74Q.mjs";
|
|
5
|
-
|
|
6
|
-
// worker.ts
|
|
7
|
-
var initialized = false;
|
|
8
|
-
self.onmessage = async (event) => {
|
|
9
|
-
const { hartId, sharedMem, entryPc } = event.data;
|
|
10
|
-
console.log(`[Worker ${hartId}] Received init message`);
|
|
11
|
-
if (!initialized) {
|
|
12
|
-
try {
|
|
13
|
-
await riscv_vm_default();
|
|
14
|
-
initialized = true;
|
|
15
|
-
console.log(`[Worker ${hartId}] WASM initialized`);
|
|
16
|
-
} catch (e) {
|
|
17
|
-
console.error(`[Worker ${hartId}] WASM init failed:`, e);
|
|
18
|
-
const msg = {
|
|
19
|
-
type: "error",
|
|
20
|
-
hartId,
|
|
21
|
-
error: String(e)
|
|
22
|
-
};
|
|
23
|
-
self.postMessage(msg);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const readyMsg = { type: "ready", hartId };
|
|
28
|
-
self.postMessage(readyMsg);
|
|
29
|
-
try {
|
|
30
|
-
const pc = BigInt(Math.floor(entryPc));
|
|
31
|
-
console.log(`[Worker ${hartId}] Starting execution at PC=0x${pc.toString(16)}`);
|
|
32
|
-
worker_entry(hartId, sharedMem, pc);
|
|
33
|
-
} catch (e) {
|
|
34
|
-
console.error(`[Worker ${hartId}] Execution error:`, e);
|
|
35
|
-
const msg = {
|
|
36
|
-
type: "error",
|
|
37
|
-
hartId,
|
|
38
|
-
error: String(e)
|
|
39
|
-
};
|
|
40
|
-
self.postMessage(msg);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
console.log(`[Worker ${hartId}] Halted`);
|
|
44
|
-
const haltedMsg = { type: "halted", hartId };
|
|
45
|
-
self.postMessage(haltedMsg);
|
|
46
|
-
};
|
|
47
|
-
self.onerror = (e) => {
|
|
48
|
-
console.error("[Worker] Uncaught error:", e);
|
|
49
|
-
const msg = {
|
|
50
|
-
type: "error",
|
|
51
|
-
error: e.message || String(e)
|
|
52
|
-
};
|
|
53
|
-
self.postMessage(msg);
|
|
54
|
-
};
|