@remix_labs/hub-client 2.2248.0-dev → 2.2249.0
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/miniwasi.js +155 -0
- package/mixcore-common.js +39 -0
- package/package.json +1 -1
package/miniwasi.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
|
|
2
|
+
// Minimal WASI implementation to run mixrt.wasm and mixcore_mini.wasm
|
|
3
|
+
class MiniWASI {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.inst = null; // same field as in bjorn's WASI shim that's used for mixcore
|
|
6
|
+
this.memory = null;
|
|
7
|
+
this.stdout = new Array();
|
|
8
|
+
this.stderr = new Array();
|
|
9
|
+
this.imp_wasi_snapshot_preview1 = {
|
|
10
|
+
"fd_write": this.fd_write.bind(this),
|
|
11
|
+
"fd_close": this.fd_close.bind(this),
|
|
12
|
+
"fd_seek": this.fd_seek.bind(this),
|
|
13
|
+
"fd_fdstat_get": this.fd_fdstat_get.bind(this),
|
|
14
|
+
"environ_sizes_get": this.environ_sizes_get.bind(this),
|
|
15
|
+
"environ_get": this.environ_get.bind(this),
|
|
16
|
+
"random_get": this.random_get.bind(this),
|
|
17
|
+
"proc_exit": this.proc_exit.bind(this),
|
|
18
|
+
"clock_time_get": this.clock_time_get.bind(this),
|
|
19
|
+
"poll_oneoff": this.poll_oneoff.bind(this),
|
|
20
|
+
};
|
|
21
|
+
this.wasiImport = this.imp_wasi_snapshot_preview1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
update() {
|
|
25
|
+
this.memory = this.inst.exports.memory;
|
|
26
|
+
this.mem8 = new Uint8Array(this.memory.buffer);
|
|
27
|
+
this.mem32 = new Uint32Array(this.memory.buffer);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fd_seek(fd, offset_low, offset_high, whence, newOffset) {
|
|
31
|
+
this.update();
|
|
32
|
+
this.abort("unexpected fd_seek call");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
clock_time_get(id, precision, time) {
|
|
36
|
+
const buffer = new DataView(this.memory.buffer);
|
|
37
|
+
if (id === 0 /* CLOCKID_REALTIME */) {
|
|
38
|
+
buffer.setBigUint64(
|
|
39
|
+
time,
|
|
40
|
+
BigInt(new Date().getTime()) * 1_000_000n,
|
|
41
|
+
true,
|
|
42
|
+
);
|
|
43
|
+
} else if (id == 1 /* CLOCKID_MONOTONIC */) {
|
|
44
|
+
let monotonic_time;
|
|
45
|
+
try {
|
|
46
|
+
monotonic_time = BigInt(Math.round(performance.now() * 1000000));
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// performance.now() is only available in browsers.
|
|
49
|
+
// TODO use the perf_hooks builtin module for NodeJS
|
|
50
|
+
monotonic_time = 0n;
|
|
51
|
+
}
|
|
52
|
+
buffer.setBigUint64(time, monotonic_time, true);
|
|
53
|
+
} else {
|
|
54
|
+
// TODO
|
|
55
|
+
buffer.setBigUint64(time, 0n, true);
|
|
56
|
+
}
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
poll_oneoff(in_, out, nsub) {
|
|
61
|
+
this.update();
|
|
62
|
+
this.abort("unexpected poll_oneoff call");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
fd_write(fd, iov, iovcnt, pnum) {
|
|
66
|
+
this.update();
|
|
67
|
+
let buffer;
|
|
68
|
+
let logger;
|
|
69
|
+
switch (fd) {
|
|
70
|
+
case 1:
|
|
71
|
+
buffer = this.stdout;
|
|
72
|
+
logger = console.debug;
|
|
73
|
+
break;
|
|
74
|
+
case 2: // redirect to stdout...
|
|
75
|
+
buffer = this.stdout;
|
|
76
|
+
logger = console.debug;
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
let num = 0;
|
|
82
|
+
for (let i = 0; i < iovcnt; i++) {
|
|
83
|
+
let ptr = this.mem32[((iov)+(i*8))>>2];
|
|
84
|
+
let len = this.mem32[((iov)+(i*8 + 4))>>2];
|
|
85
|
+
for (let j = 0; j < len; j++) {
|
|
86
|
+
let byte = this.mem8[ptr+j];
|
|
87
|
+
if (byte >= 32)
|
|
88
|
+
buffer.push(byte)
|
|
89
|
+
else if (byte == 10) {
|
|
90
|
+
let uint8 = new Uint8Array(buffer);
|
|
91
|
+
console.log("WASM: %s", this.utf8array_to_string(uint8, 0, buffer.length));
|
|
92
|
+
buffer.length = 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
num += len;
|
|
96
|
+
}
|
|
97
|
+
this.mem32[pnum>>2]=num;
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
utf8array_to_string(bytes, idx, count) {
|
|
102
|
+
let limit = idx + count;
|
|
103
|
+
let ptr = idx;
|
|
104
|
+
while (bytes[ptr] && ptr < limit) ptr++;
|
|
105
|
+
return new TextDecoder().decode(bytes.subarray(idx, ptr));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
fd_close(fd) {
|
|
109
|
+
this.update();
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fd_fdstat_get(fd, buf) {
|
|
114
|
+
this.update();
|
|
115
|
+
this.abort("unexpected fd_fdstat_get call");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
environ_sizes_get(ptr_count, ptr_sizes) {
|
|
119
|
+
this.update();
|
|
120
|
+
this.mem32[ptr_count >> 2] = 0;
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
environ_get(ptr_environ, ptr_environ_buf) {
|
|
125
|
+
this.update();
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
random_get(ptr_buf, size) {
|
|
130
|
+
this.update();
|
|
131
|
+
// node's version of getRandom doesn't like to write directly to
|
|
132
|
+
// wasm memory, so this indirection is needed:
|
|
133
|
+
let mem = this.mem8.subarray(ptr_buf, ptr_buf + size);
|
|
134
|
+
let mem2 = new Uint8Array(size);
|
|
135
|
+
if (!globalThis.ThisIsNode) {
|
|
136
|
+
crypto.getRandomValues(mem2);
|
|
137
|
+
} // else 0 according to fair-dice roll
|
|
138
|
+
mem.set(mem2);
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
proc_exit(code) {
|
|
143
|
+
this.update();
|
|
144
|
+
console.log("exit(" + code + ")")
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
abort(msg) {
|
|
148
|
+
let e = new Error();
|
|
149
|
+
let stack = e.stack || "(no stack trace)";
|
|
150
|
+
console.error("WASM ABORT: %s at %s", msg, stack);
|
|
151
|
+
throw new WebAssembly.RuntimeError(msg);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { MiniWASI }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
const CORE_FFI_NAMES = [
|
|
3
|
+
"$destroyHook",
|
|
4
|
+
"$hideHook",
|
|
5
|
+
"$isSyncEnabled",
|
|
6
|
+
"$loadHook",
|
|
7
|
+
"$flush",
|
|
8
|
+
"$mqtt_available",
|
|
9
|
+
"$showHook",
|
|
10
|
+
"$mqtt_enabled",
|
|
11
|
+
"$log",
|
|
12
|
+
"get_env",
|
|
13
|
+
"$outputError",
|
|
14
|
+
"$outputWithVersion",
|
|
15
|
+
"$co_sleep",
|
|
16
|
+
"$decodeError",
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function ffiNameMatches(name, pattern) {
|
|
20
|
+
if (pattern == "CORE") {
|
|
21
|
+
return CORE_FFI_NAMES.includes(name);
|
|
22
|
+
}
|
|
23
|
+
if (pattern.slice(-1) === '*') {
|
|
24
|
+
return name.startsWith(pattern.slice(0, -1));
|
|
25
|
+
}
|
|
26
|
+
return name === pattern;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function filterFFINames(names, enable, disable) {
|
|
30
|
+
if (enable !== undefined) {
|
|
31
|
+
names = names.filter(name => enable.some(pat => ffiNameMatches(name, pat)));
|
|
32
|
+
}
|
|
33
|
+
if (disable !== undefined) {
|
|
34
|
+
names = names.filter(name => !disable.some(pat => ffiNameMatches(name, pat)));
|
|
35
|
+
}
|
|
36
|
+
return names;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { filterFFINames }
|