@thi.ng/wasm-api 1.0.0 → 1.1.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/CHANGELOG.md +10 -1
- package/README.md +112 -161
- package/api.d.ts +1 -0
- package/api.js +1 -0
- package/bridge.d.ts +1 -1
- package/bridge.js +5 -2
- package/include/wasmapi.h +0 -2
- package/package.json +5 -5
- package/zig/lib.zig +0 -3
- package/include/wasmapi_types.h +0 -35
- package/zig/types.zig +0 -52
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-11-
|
|
3
|
+
- **Last updated**: 2022-11-28T13:36:49Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,15 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [1.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@1.1.0) (2022-11-28)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- update panic handler, add event support ([ab940d9](https://github.com/thi-ng/umbrella/commit/ab940d9))
|
|
17
|
+
- update panic handler to broadcast event w/ panic message
|
|
18
|
+
- only throw Panic error if no listeners could be notified
|
|
19
|
+
- add `EVENT_PANIC` constant
|
|
20
|
+
|
|
12
21
|
# [1.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@1.0.0) (2022-11-23)
|
|
13
22
|
|
|
14
23
|
#### 🛑 Breaking changes
|
package/README.md
CHANGED
|
@@ -10,11 +10,12 @@ This project is part of the
|
|
|
10
10
|
[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo.
|
|
11
11
|
|
|
12
12
|
- [About](#about)
|
|
13
|
-
|
|
13
|
+
- [Custom API modules](#custom-api-modules)
|
|
14
14
|
- [Building Zig projects with these hybrid API modules](#building-zig-projects-with-these-hybrid-api-modules)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- [
|
|
15
|
+
- [String handling](#string-handling)
|
|
16
|
+
- [Memory allocations](#memory-allocations)
|
|
17
|
+
- [API module auto-initialization](#api-module-auto-initialization)
|
|
18
|
+
- [Object indices & handles](#object-indices--handles)
|
|
18
19
|
- [Status](#status)
|
|
19
20
|
- [Support packages](#support-packages)
|
|
20
21
|
- [Installation](#installation)
|
|
@@ -59,13 +60,12 @@ WebGL, WebGPU, WebAudio etc. is being actively worked on.
|
|
|
59
60
|
for (currently) Zig & TypeScript and C11. For TS fully type checked and
|
|
60
61
|
memory-mapped (zero-copy) accessors of WASM-side data are generated. In
|
|
61
62
|
principle, all languages with a WASM target are supported, however currently
|
|
62
|
-
only bindings for these mentioned langs are included.
|
|
63
|
-
custom bindings, e.g. based on the flexible primitives provided here.
|
|
63
|
+
only bindings for these mentioned langs are included.
|
|
64
64
|
8. [CLI
|
|
65
65
|
frontend/utility](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-bindgen/README.md#cli-generator)
|
|
66
66
|
for the code generator(s)
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
## Custom API modules
|
|
69
69
|
|
|
70
70
|
The
|
|
71
71
|
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
|
|
@@ -83,40 +83,40 @@ following example provides a brief overview:
|
|
|
83
83
|
import { IWasmAPI, WasmBridge } from "@thi.ng/wasm-api";
|
|
84
84
|
|
|
85
85
|
export class CustomAPI implements IWasmAPI {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
86
|
+
// Unique API module identifier to group WASM imports,
|
|
87
|
+
// must match ID used by native code (see further below).
|
|
88
|
+
readonly id = "custom";
|
|
89
|
+
// optionally list IDs of other API modules this module depends on
|
|
90
|
+
// these are used to infer the correct initialization order
|
|
91
|
+
readonly dependencies = [];
|
|
92
|
+
|
|
93
|
+
parent!: WasmBridge;
|
|
94
|
+
|
|
95
|
+
async init(parent: WasmBridge) {
|
|
96
|
+
this.parent = parent;
|
|
97
|
+
this.parent.logger.debug("initializing custom API");
|
|
98
|
+
|
|
99
|
+
// any other tasks you might need to do...
|
|
100
|
+
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns object of functions to import as externals into the
|
|
106
|
+
* WASM module during instantiation. These imports are merged
|
|
107
|
+
* into a larger imports object alongside the bridge's core API...
|
|
108
|
+
*/
|
|
109
|
+
getImports(): WebAssembly.Imports {
|
|
110
|
+
return {
|
|
111
|
+
/**
|
|
112
|
+
* Writes `num` random float32 numbers from given address
|
|
113
|
+
*/
|
|
114
|
+
fillRandom: (addr: number, num: number) => {
|
|
115
|
+
addr >>>= 2;
|
|
116
|
+
while(num-- > 0) this.parent.f32[addr++] = Math.random();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
120
|
}
|
|
121
121
|
```
|
|
122
122
|
|
|
@@ -127,7 +127,8 @@ export const bridge = new WasmBridge([new CustomAPI()]);
|
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
In Zig (or any other language of your choice) we can then utilize this custom
|
|
130
|
-
API like so (Please also see [example
|
|
130
|
+
API like so (Please also see [example
|
|
131
|
+
projects](https://github.com/thi-ng/umbrella/tree/develop/examples/zig-canvas/)
|
|
131
132
|
& other example snippets in this readme):
|
|
132
133
|
|
|
133
134
|
Bindings file / lib:
|
|
@@ -151,16 +152,16 @@ const js = @import("wasmapi");
|
|
|
151
152
|
const custom = @import("custom.zig");
|
|
152
153
|
|
|
153
154
|
export fn test_randomVec4() void {
|
|
154
|
-
|
|
155
|
+
var foo = [4]f32{ 1, 2, 3, 4 };
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
// print original
|
|
158
|
+
js.printF32Array(foo[0..]);
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
// populate foo with random numbers
|
|
161
|
+
custom.fillRandom(&foo, foo.len);
|
|
161
162
|
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
// print result
|
|
164
|
+
js.printF32Array(foo[0..]);
|
|
164
165
|
}
|
|
165
166
|
```
|
|
166
167
|
|
|
@@ -177,7 +178,7 @@ To avoid guesswork about the internals of these API modules, all of them are
|
|
|
177
178
|
using an overall uniform structure, with the main Zig entry point in
|
|
178
179
|
`/zig/lib.zig`...
|
|
179
180
|
|
|
180
|
-
|
|
181
|
+
## String handling
|
|
181
182
|
|
|
182
183
|
Most low-level languages deal with strings very differently and alas there's no
|
|
183
184
|
general standard. Some have UTF-8/16 support, others don't. In some languages
|
|
@@ -190,7 +191,16 @@ and
|
|
|
190
191
|
[`setString()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#setString)
|
|
191
192
|
for details.
|
|
192
193
|
|
|
193
|
-
|
|
194
|
+
Furthermore, the package provides these string wrapper types:
|
|
195
|
+
|
|
196
|
+
- [`WasmStringPtr`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmStringPtr.html)
|
|
197
|
+
- [`WasmStringSlice`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmStringSlice.html)
|
|
198
|
+
|
|
199
|
+
Finally, see more information in the
|
|
200
|
+
[@thi.ng/wasm-api-bindgen](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-bindgen/README.md#string-handling)
|
|
201
|
+
package readme.
|
|
202
|
+
|
|
203
|
+
## Memory allocations
|
|
194
204
|
|
|
195
205
|
If explicitly enabled on the WASM side, the `WasmBridge` includes support for
|
|
196
206
|
malloc/free-style allocations (within the linear WASM memory) from the JS side.
|
|
@@ -199,9 +209,9 @@ The actual allocator is implementation specific and suitable generic mechanisms
|
|
|
199
209
|
are defined for both the included Zig & C bindings. Please see for further
|
|
200
210
|
reference:
|
|
201
211
|
|
|
202
|
-
- [`/zig/lib.zig`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/lib.zig#
|
|
212
|
+
- [`/zig/lib.zig`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/lib.zig#L34-L68):
|
|
203
213
|
comments about WASM-side allocator handling in Zig
|
|
204
|
-
- [`/include/wasmapi.h`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/include/wasmapi.h#
|
|
214
|
+
- [`/include/wasmapi.h`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/include/wasmapi.h#L18-L28):
|
|
205
215
|
comments about WASM-side allocator handling in C/C++
|
|
206
216
|
- [`WasmBridge.allocate()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#allocate):
|
|
207
217
|
allocating memory from JS side
|
|
@@ -217,26 +227,37 @@ for more details...
|
|
|
217
227
|
|
|
218
228
|
```ts
|
|
219
229
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
230
|
+
// allocate 256 bytes of memory for passing a string to WASM side
|
|
231
|
+
// the function returns a tuple of `[address, len]`
|
|
232
|
+
const [addr, len] = bridge.allocate(256);
|
|
223
233
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
234
|
+
// write zero terminated string to reserved memory (max. `len` bytes)
|
|
235
|
+
// function returns number of bytes written (excl. sentinel)
|
|
236
|
+
const num = bridge.setString("hello WASM world!", addr, len, true);
|
|
227
237
|
|
|
228
|
-
|
|
229
|
-
|
|
238
|
+
// call WASM function doing something w/ the string
|
|
239
|
+
bridge.exports.doSomethingWithString(addr, num);
|
|
230
240
|
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
// cleanup
|
|
242
|
+
bridge.free([addr, len]);
|
|
233
243
|
} catch(e) {
|
|
234
|
-
|
|
235
|
-
|
|
244
|
+
// deal with allocation error
|
|
245
|
+
// ...
|
|
236
246
|
}
|
|
237
247
|
```
|
|
238
248
|
|
|
239
|
-
###
|
|
249
|
+
### API module auto-initialization
|
|
250
|
+
|
|
251
|
+
The supplied child APIs
|
|
252
|
+
([wasm-api-dom](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-dom),
|
|
253
|
+
[wasm-api-schedule](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-schedule)
|
|
254
|
+
etc.) use an auto-intialization hook related to the above `WASM_ALLOCATOR`
|
|
255
|
+
mechanism: If that allocator is available, the WASM side of these modules will
|
|
256
|
+
auto initialize and thus reduce boilerplate. However, if no such central
|
|
257
|
+
allocator is defined and/or a custom allocator should be used, then these API
|
|
258
|
+
modules will be have to be initialized manually.
|
|
259
|
+
|
|
260
|
+
## Object indices & handles
|
|
240
261
|
|
|
241
262
|
Since only numeric values can be exchanged between the WASM module and the JS
|
|
242
263
|
host, any JS native objects the WASM side might want to be working with must be
|
|
@@ -283,13 +304,14 @@ canvases.delete(0);
|
|
|
283
304
|
// true
|
|
284
305
|
```
|
|
285
306
|
|
|
286
|
-
|
|
307
|
+
The supplied Zig core library also includes a
|
|
287
308
|
[`ManagedIndex`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/managed-index.zig)
|
|
288
|
-
for similar
|
|
309
|
+
for similar resource management on the Zig side of the application. For example,
|
|
310
|
+
in the
|
|
289
311
|
[@thi.ng/wasm-api-dom](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-dom/)
|
|
290
312
|
&
|
|
291
|
-
[@thi.ng/wasm-api-
|
|
292
|
-
|
|
313
|
+
[@thi.ng/wasm-api-schedule](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-schedule/)
|
|
314
|
+
packages this is used to manage Zig-side event listeners.
|
|
293
315
|
|
|
294
316
|
## Status
|
|
295
317
|
|
|
@@ -326,7 +348,7 @@ node --experimental-repl-await
|
|
|
326
348
|
> const wasmApi = await import("@thi.ng/wasm-api");
|
|
327
349
|
```
|
|
328
350
|
|
|
329
|
-
Package sizes (gzipped, pre-treeshake): ESM: 2.
|
|
351
|
+
Package sizes (gzipped, pre-treeshake): ESM: 2.73 KB
|
|
330
352
|
|
|
331
353
|
## Dependencies
|
|
332
354
|
|
|
@@ -364,21 +386,21 @@ import { readFileSync } from "fs";
|
|
|
364
386
|
|
|
365
387
|
// WASM exports from our dummy module (below)
|
|
366
388
|
interface App extends WasmExports {
|
|
367
|
-
|
|
389
|
+
start: () => void;
|
|
368
390
|
}
|
|
369
391
|
|
|
370
392
|
(async () => {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
393
|
+
// new API bridge with defaults
|
|
394
|
+
// (i.e. no child API modules and using console logger)
|
|
395
|
+
const bridge = new WasmBridge<App>();
|
|
374
396
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
397
|
+
// instantiate WASM module using imports provided by the bridge
|
|
398
|
+
// this also initializes any bindings & bridge child APIs (if any)
|
|
399
|
+
// (also accepts a fetch() `Response` as input)
|
|
400
|
+
await bridge.instantiate(readFileSync("hello.wasm"));
|
|
379
401
|
|
|
380
|
-
|
|
381
|
-
|
|
402
|
+
// call an exported WASM function
|
|
403
|
+
bridge.exports.start();
|
|
382
404
|
})();
|
|
383
405
|
```
|
|
384
406
|
|
|
@@ -386,19 +408,15 @@ interface App extends WasmExports {
|
|
|
386
408
|
|
|
387
409
|
Requires [Zig](https://ziglang.org) to be installed:
|
|
388
410
|
|
|
389
|
-
```zig
|
|
411
|
+
```zig tangle:export/hello.zig
|
|
390
412
|
//! Example Zig application (hello.zig)
|
|
391
413
|
|
|
392
414
|
/// import externals
|
|
393
415
|
/// see build command for configuration
|
|
394
416
|
const js = @import("wasmapi");
|
|
395
|
-
const std = @import("std");
|
|
396
|
-
|
|
397
|
-
// set custom memory allocator (here to disable)
|
|
398
|
-
pub const WASM_ALLOCATOR: ?std.mem.Allocator = null;
|
|
399
417
|
|
|
400
418
|
export fn start() void {
|
|
401
|
-
|
|
419
|
+
js.printStr("hello world!");
|
|
402
420
|
}
|
|
403
421
|
```
|
|
404
422
|
|
|
@@ -409,10 +427,10 @@ folder):
|
|
|
409
427
|
```bash
|
|
410
428
|
# compile WASM binary
|
|
411
429
|
zig build-lib \
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
430
|
+
--pkg-begin wasmapi node_modules/@thi.ng/wasm-api/zig/lib.zig --pkg-end \
|
|
431
|
+
-target wasm32-freestanding \
|
|
432
|
+
-O ReleaseSmall -dynamic \
|
|
433
|
+
hello.zig
|
|
416
434
|
|
|
417
435
|
# disassemble WASM
|
|
418
436
|
wasm-dis -o hello.wast hello.wasm
|
|
@@ -451,11 +469,11 @@ The resulting WASM:
|
|
|
451
469
|
|
|
452
470
|
Requires [Emscripten](https://emscripten.org/) to be installed:
|
|
453
471
|
|
|
454
|
-
```c
|
|
472
|
+
```c tangle:export/hello.c
|
|
455
473
|
#include <wasmapi.h>
|
|
456
474
|
|
|
457
|
-
void
|
|
458
|
-
|
|
475
|
+
void WASMAPI_KEEP start() {
|
|
476
|
+
wasm_printStrZ("hello world!");
|
|
459
477
|
}
|
|
460
478
|
```
|
|
461
479
|
|
|
@@ -467,73 +485,6 @@ emcc -Os -Inode_modules/@thi.ng/wasm-api/include \
|
|
|
467
485
|
-o hello.wasm hello.c
|
|
468
486
|
```
|
|
469
487
|
|
|
470
|
-
Resulting WASM:
|
|
471
|
-
|
|
472
|
-
```wasm
|
|
473
|
-
(module
|
|
474
|
-
(type $i32_=>_none (func (param i32)))
|
|
475
|
-
(type $none_=>_none (func))
|
|
476
|
-
(type $i32_=>_i32 (func (param i32) (result i32)))
|
|
477
|
-
(type $none_=>_i32 (func (result i32)))
|
|
478
|
-
(type $i32_i32_=>_none (func (param i32 i32)))
|
|
479
|
-
(import "wasmapi" "_printStr0" (func $fimport$0 (param i32)))
|
|
480
|
-
(global $global$0 (mut i32) (i32.const 5243936))
|
|
481
|
-
(memory $0 256 256)
|
|
482
|
-
(data (i32.const 1024) "hello world!")
|
|
483
|
-
(table $0 2 2 funcref)
|
|
484
|
-
(elem (i32.const 1) $0)
|
|
485
|
-
(export "memory" (memory $0))
|
|
486
|
-
(export "_wasm_allocate" (func $1))
|
|
487
|
-
(export "_wasm_free" (func $2))
|
|
488
|
-
(export "start" (func $3))
|
|
489
|
-
(export "__indirect_function_table" (table $0))
|
|
490
|
-
(export "_initialize" (func $0))
|
|
491
|
-
(export "__errno_location" (func $7))
|
|
492
|
-
(export "stackSave" (func $4))
|
|
493
|
-
(export "stackRestore" (func $5))
|
|
494
|
-
(export "stackAlloc" (func $6))
|
|
495
|
-
(func $0
|
|
496
|
-
(nop)
|
|
497
|
-
)
|
|
498
|
-
(func $1 (param $0 i32) (result i32)
|
|
499
|
-
(i32.const 0)
|
|
500
|
-
)
|
|
501
|
-
(func $2 (param $0 i32) (param $1 i32)
|
|
502
|
-
(nop)
|
|
503
|
-
)
|
|
504
|
-
(func $3
|
|
505
|
-
(call $fimport$0
|
|
506
|
-
(i32.const 1024)
|
|
507
|
-
)
|
|
508
|
-
)
|
|
509
|
-
(func $4 (result i32)
|
|
510
|
-
(global.get $global$0)
|
|
511
|
-
)
|
|
512
|
-
(func $5 (param $0 i32)
|
|
513
|
-
(global.set $global$0
|
|
514
|
-
(local.get $0)
|
|
515
|
-
)
|
|
516
|
-
)
|
|
517
|
-
(func $6 (param $0 i32) (result i32)
|
|
518
|
-
(global.set $global$0
|
|
519
|
-
(local.tee $0
|
|
520
|
-
(i32.and
|
|
521
|
-
(i32.sub
|
|
522
|
-
(global.get $global$0)
|
|
523
|
-
(local.get $0)
|
|
524
|
-
)
|
|
525
|
-
(i32.const -16)
|
|
526
|
-
)
|
|
527
|
-
)
|
|
528
|
-
)
|
|
529
|
-
(local.get $0)
|
|
530
|
-
)
|
|
531
|
-
(func $7 (result i32)
|
|
532
|
-
(i32.const 1040)
|
|
533
|
-
)
|
|
534
|
-
)
|
|
535
|
-
```
|
|
536
|
-
|
|
537
488
|
## Authors
|
|
538
489
|
|
|
539
490
|
Karsten Schmidt
|
package/api.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Fn, IDeref, ILength } from "@thi.ng/api";
|
|
2
2
|
import type { WasmBridge } from "./bridge.js";
|
|
3
3
|
export declare const EVENT_MEMORY_CHANGED = "memory-changed";
|
|
4
|
+
export declare const EVENT_PANIC = "panic";
|
|
4
5
|
export declare type BigIntArray = bigint[] | BigInt64Array | BigUint64Array;
|
|
5
6
|
export declare type ReadonlyWasmString = IDeref<string> & ILength & {
|
|
6
7
|
readonly addr: number;
|
package/api.js
CHANGED
package/bridge.d.ts
CHANGED
|
@@ -181,6 +181,6 @@ export declare class WasmBridge<T extends WasmExports = WasmExports> implements
|
|
|
181
181
|
/** {@inheritDoc @thi.ng/api#INotify.removeListener} */
|
|
182
182
|
removeListener(id: string, fn: Listener, scope?: any): boolean;
|
|
183
183
|
/** {@inheritDoc @thi.ng/api#INotify.notify} */
|
|
184
|
-
notify(event: Event):
|
|
184
|
+
notify(event: Event): boolean;
|
|
185
185
|
}
|
|
186
186
|
//# sourceMappingURL=bridge.d.ts.map
|
package/bridge.js
CHANGED
|
@@ -5,7 +5,7 @@ import { assert } from "@thi.ng/errors/assert";
|
|
|
5
5
|
import { defError } from "@thi.ng/errors/deferror";
|
|
6
6
|
import { hexdumpLines, U16, U32, U64BIG, U8 } from "@thi.ng/hex";
|
|
7
7
|
import { ConsoleLogger } from "@thi.ng/logger/console";
|
|
8
|
-
import { EVENT_MEMORY_CHANGED, } from "./api.js";
|
|
8
|
+
import { EVENT_MEMORY_CHANGED, EVENT_PANIC, } from "./api.js";
|
|
9
9
|
export const Panic = defError(() => "Panic");
|
|
10
10
|
export const OutOfMemoryError = defError(() => "Out of memory");
|
|
11
11
|
/**
|
|
@@ -69,7 +69,10 @@ let WasmBridge = class WasmBridge {
|
|
|
69
69
|
debugger;
|
|
70
70
|
},
|
|
71
71
|
_panic: (addr, len) => {
|
|
72
|
-
|
|
72
|
+
const msg = this.getString(addr, len);
|
|
73
|
+
if (!this.notify({ id: EVENT_PANIC, value: msg })) {
|
|
74
|
+
throw new Panic(msg);
|
|
75
|
+
}
|
|
73
76
|
},
|
|
74
77
|
timer: () => performance.now(),
|
|
75
78
|
epoch: () => BigInt(Date.now()),
|
package/include/wasmapi.h
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/wasm-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Generic, modular, extensible API bridge and infrastructure for hybrid JS & WebAssembly projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi zig/lib.zig --pkg-end test/custom.zig && wasm-dis -o custom.wast custom.wasm && cp custom.wasm test"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@thi.ng/api": "^8.
|
|
39
|
-
"@thi.ng/arrays": "^2.4.
|
|
38
|
+
"@thi.ng/api": "^8.5.0",
|
|
39
|
+
"@thi.ng/arrays": "^2.4.3",
|
|
40
40
|
"@thi.ng/checks": "^3.3.3",
|
|
41
41
|
"@thi.ng/errors": "^2.2.4",
|
|
42
42
|
"@thi.ng/hex": "^2.3.0",
|
|
43
|
-
"@thi.ng/idgen": "^2.1.
|
|
43
|
+
"@thi.ng/idgen": "^2.1.19",
|
|
44
44
|
"@thi.ng/logger": "^1.4.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"status": "alpha",
|
|
111
111
|
"year": 2022
|
|
112
112
|
},
|
|
113
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "75ec32ff7f1b7b5e72e7a04ace24732cd5d6c774\n"
|
|
114
114
|
}
|
package/zig/lib.zig
CHANGED
package/include/wasmapi_types.h
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#ifdef __cplusplus
|
|
4
|
-
extern "C" {
|
|
5
|
-
#endif
|
|
6
|
-
|
|
7
|
-
#include <stddef.h>
|
|
8
|
-
|
|
9
|
-
typedef char* WASM_StringPtr;
|
|
10
|
-
typedef const char* WASM_ConstStringPtr;
|
|
11
|
-
|
|
12
|
-
typedef void* WASM_OpaquePtr;
|
|
13
|
-
typedef const void* WASM_ConstOpaquePtr;
|
|
14
|
-
|
|
15
|
-
// slice-based string
|
|
16
|
-
typedef struct { WASM_StringPtr ptr; size_t len; } WASM_String;
|
|
17
|
-
typedef struct { WASM_ConstStringPtr ptr; size_t len; } WASM_ConstString;
|
|
18
|
-
|
|
19
|
-
// defines slice wrapper structs for given pointer types
|
|
20
|
-
#define WASMAPI_SLICE(PREFIX, NAME, PTR, CONSTPTR) \
|
|
21
|
-
typedef struct { PTR* ptr; size_t len; } PREFIX##NAME##Slice; \
|
|
22
|
-
typedef struct { CONSTPTR* ptr; size_t len; } PREFIX##Const##NAME##Slice;
|
|
23
|
-
|
|
24
|
-
// slice of string slices
|
|
25
|
-
WASMAPI_SLICE(WASM_, String, WASM_String, WASM_ConstString)
|
|
26
|
-
|
|
27
|
-
// slice of string pointers
|
|
28
|
-
WASMAPI_SLICE(WASM_, StringPtr, WASM_StringPtr, WASM_ConstStringPtr)
|
|
29
|
-
|
|
30
|
-
// slice of opaque pointers
|
|
31
|
-
WASMAPI_SLICE(WASM_, OpaquePtr, WASM_OpaquePtr, WASM_ConstOpaquePtr)
|
|
32
|
-
|
|
33
|
-
#ifdef __cplusplus
|
|
34
|
-
}
|
|
35
|
-
#endif
|
package/zig/types.zig
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//! Common helper types used by the thi.ng/wasm-api code gen
|
|
2
|
-
//! None of these type have any further dependencies on the main wasm-api package
|
|
3
|
-
|
|
4
|
-
/// Higher-order generic slice wrapper for `extern struct` use cases
|
|
5
|
-
/// S = slice type
|
|
6
|
-
/// P = pointer type
|
|
7
|
-
pub fn Slice(comptime S: type, comptime P: type) type {
|
|
8
|
-
return extern struct {
|
|
9
|
-
ptr: P = @as(S, &.{}).ptr,
|
|
10
|
-
len: usize = 0,
|
|
11
|
-
|
|
12
|
-
pub inline fn wrap(slice: S) @This() {
|
|
13
|
-
return .{
|
|
14
|
-
.ptr = @ptrCast(P, slice.ptr),
|
|
15
|
-
.len = slice.len,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub inline fn toSlice(self: *@This()) S {
|
|
20
|
-
return @ptrCast(*S, self).*;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
pub const StringPtr = [*:0]u8;
|
|
26
|
-
pub const ConstStringPtr = [*:0]const u8;
|
|
27
|
-
|
|
28
|
-
/// `[]u8` slice wrapper for `extern struct` use cases
|
|
29
|
-
pub const String = Slice([]u8, StringPtr);
|
|
30
|
-
/// `[]const u8` slice wrapper for `extern struct` use cases
|
|
31
|
-
pub const ConstString = Slice([]const u8, ConstStringPtr);
|
|
32
|
-
|
|
33
|
-
/// Slice of `String`s
|
|
34
|
-
pub const StringSlice = Slice([]String, [*]String);
|
|
35
|
-
pub const ConstStringSlice = Slice([]ConstString, [*]ConstString);
|
|
36
|
-
|
|
37
|
-
/// Slice of `StringPtr`s
|
|
38
|
-
pub const StringPtrSlice = Slice([]StringPtr, [*]StringPtr);
|
|
39
|
-
pub const ConstStringPtrSlice = Slice([]ConstStringPtr, [*]ConstStringPtr);
|
|
40
|
-
|
|
41
|
-
/// Alias for `*anyopaque`
|
|
42
|
-
pub const OpaquePtr = *anyopaque;
|
|
43
|
-
pub const ConstOpaquePtr = *const anyopaque;
|
|
44
|
-
|
|
45
|
-
/// Slice of `OpaquePtr`s
|
|
46
|
-
pub const OpaquePtrSlice = Slice([]OpaquePtr, [*]OpaquePtr);
|
|
47
|
-
pub const ConstOpaquePtrSlice = Slice([]ConstOpaquePtr, [*]ConstOpaquePtr);
|
|
48
|
-
|
|
49
|
-
/// Syntax sugar for `ConstString.wrap()`
|
|
50
|
-
pub inline fn string(str: []const u8) ConstString {
|
|
51
|
-
return ConstString.wrap(str);
|
|
52
|
-
}
|