@thi.ng/wasm-api 0.4.0 → 0.7.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 +60 -1
- package/README.md +403 -16
- package/api.d.ts +213 -3
- package/api.js +9 -1
- package/bin/wasm-api +12 -0
- package/bridge.d.ts +78 -6
- package/bridge.js +96 -14
- package/cli.d.ts +5 -0
- package/cli.js +142 -0
- package/codegen/typescript.d.ts +26 -0
- package/codegen/typescript.js +153 -0
- package/codegen/utils.d.ts +29 -0
- package/codegen/utils.js +29 -0
- package/codegen/zig.d.ts +22 -0
- package/codegen/zig.js +75 -0
- package/codegen.d.ts +16 -0
- package/codegen.js +116 -0
- package/include/wasmapi.h +60 -0
- package/{zig/core.zig → include/wasmapi.zig} +76 -26
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +32 -7
- package/dev/custom.zig +0 -12
- package/dev/fieldinfo.zig +0 -135
- package/dev/hello.zig +0 -9
- package/dev/zig-cache/o/0fd683610fe16c12563bf410950c8193/builtin.zig +0 -39
- package/test/custom.zig +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-08-
|
|
3
|
+
- **Last updated**: 2022-08-15T23:41:37Z
|
|
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,65 @@ 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
|
+
## [0.7.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.7.0) (2022-08-15)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add CLI wrapper for codegens ([683a560](https://github.com/thi-ng/umbrella/commit/683a560))
|
|
17
|
+
- update TSOpts & TS codegen ([4f6bbbf](https://github.com/thi-ng/umbrella/commit/4f6bbbf))
|
|
18
|
+
- add `uppercaseEnum` option to force UC enum IDs
|
|
19
|
+
- update helper predicates ([65b23d4](https://github.com/thi-ng/umbrella/commit/65b23d4))
|
|
20
|
+
|
|
21
|
+
#### 🩹 Bug fixes
|
|
22
|
+
|
|
23
|
+
- allow signed ints for enum tags ([78d0822](https://github.com/thi-ng/umbrella/commit/78d0822))
|
|
24
|
+
- correct TS __mapArray codegen ([289b137](https://github.com/thi-ng/umbrella/commit/289b137))
|
|
25
|
+
|
|
26
|
+
## [0.6.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.6.0) (2022-08-15)
|
|
27
|
+
|
|
28
|
+
#### 🚀 Features
|
|
29
|
+
|
|
30
|
+
- add C11 header/include file, update WasmBridge ([a67dc00](https://github.com/thi-ng/umbrella/commit/a67dc00))
|
|
31
|
+
- migrate headers/includes to /include
|
|
32
|
+
- rename "core" import section => "wasmapi"
|
|
33
|
+
- rename WasmBridge.core => WasmBridge.api
|
|
34
|
+
- update pkg file
|
|
35
|
+
- update codegens, add opts, fix alignments ([5c1fec5](https://github.com/thi-ng/umbrella/commit/5c1fec5))
|
|
36
|
+
- add global CodeGenOpts
|
|
37
|
+
- update generateTypes() to consider new opts
|
|
38
|
+
- add global USIZE type (for pointer sizes & codegens)
|
|
39
|
+
- add options for Zig codegen (extra debug helpers)
|
|
40
|
+
- simplify TS codegen
|
|
41
|
+
- fix sizeOf() for struct fields
|
|
42
|
+
- make prepareType() idempotent
|
|
43
|
+
- add bindings code generator framework ([17ee06f](https://github.com/thi-ng/umbrella/commit/17ee06f))
|
|
44
|
+
- add/update deps
|
|
45
|
+
- add preliminary codegens for Zig & TS
|
|
46
|
+
- add supporting types & utils
|
|
47
|
+
- add generateTypes() codegen facade fn
|
|
48
|
+
- update allocate/free() fns, update Zig core API ([8a55989](https://github.com/thi-ng/umbrella/commit/8a55989))
|
|
49
|
+
- add _wasm_free() Zig impl
|
|
50
|
+
- add printFmt() Zig fn
|
|
51
|
+
- update WasmBridge.allocate() (add clear option)
|
|
52
|
+
- update WasmBridge.free()
|
|
53
|
+
- ensure memory in WasmBridge.getString()
|
|
54
|
+
- add/update docstrings
|
|
55
|
+
|
|
56
|
+
#### ♻️ Refactoring
|
|
57
|
+
|
|
58
|
+
- extract WasmMemViews interface, update test WASM ([4c73e65](https://github.com/thi-ng/umbrella/commit/4c73e65))
|
|
59
|
+
|
|
60
|
+
## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.5.0) (2022-08-08)
|
|
61
|
+
|
|
62
|
+
#### 🚀 Features
|
|
63
|
+
|
|
64
|
+
- add memory allocation ([980c1f2](https://github.com/thi-ng/umbrella/commit/980c1f2))
|
|
65
|
+
- add WasmBridge.allocate()/free()
|
|
66
|
+
- add WasmBridge.growMemory()
|
|
67
|
+
- extract WasmBridge.ensureMemory()
|
|
68
|
+
- update WasmExports
|
|
69
|
+
- update Zig bindings (configurable allocator, GPA as default)
|
|
70
|
+
|
|
12
71
|
## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.4.0) (2022-08-07)
|
|
13
72
|
|
|
14
73
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -12,30 +12,52 @@ This project is part of the
|
|
|
12
12
|
- [About](#about)
|
|
13
13
|
- [Custom API modules](#custom-api-modules)
|
|
14
14
|
- [Object indices & handles](#object-indices--handles)
|
|
15
|
+
- [Data bindings & code generators](#data-bindings--code-generators)
|
|
16
|
+
- [CLI generator](#cli-generator)
|
|
17
|
+
- [Data type definitions](#data-type-definitions)
|
|
18
|
+
- [Example usage](#example-usage)
|
|
15
19
|
- [Status](#status)
|
|
16
20
|
- [Installation](#installation)
|
|
17
21
|
- [Dependencies](#dependencies)
|
|
18
22
|
- [API](#api)
|
|
23
|
+
- [Basic usage example](#basic-usage-example)
|
|
24
|
+
- [Zig version](#zig-version)
|
|
25
|
+
- [C11 version](#c11-version)
|
|
19
26
|
- [Authors](#authors)
|
|
20
27
|
- [License](#license)
|
|
21
28
|
|
|
22
29
|
## About
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
Generic, modular, extensible API bridge, glue code and bindings code generator for hybrid JS & WebAssembly projects.
|
|
25
32
|
|
|
26
|
-
This package provides a
|
|
27
|
-
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
|
|
28
|
-
class as interop basis and a much reduced boilerplate for hybrid JS/WebAssembly
|
|
29
|
-
applications. At the moment only a minimal core API is provided (i.e. for debug
|
|
30
|
-
output, string, pointer, typed array accessors [8/16/32/64 bit (u)ints, 32/64
|
|
31
|
-
bit floats]), but in the future we aim to also supply support modules for DOM
|
|
32
|
-
manipulation, WebGL, WebGPU, WebAudio etc.
|
|
33
|
+
This package provides a the following:
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
1. A small, generic and modular
|
|
36
|
+
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
|
|
37
|
+
class as interop basis and much reduced boilerplate for hybrid JS/WebAssembly
|
|
38
|
+
applications.
|
|
39
|
+
2. A minimal core API for debug output, string, pointer, typed array accessors
|
|
40
|
+
for 8/16/32/64 bit (u)ints and 32/64 bit floats. In the future we aim to also
|
|
41
|
+
supply support modules for DOM manipulation, WebGL, WebGPU, WebAudio etc.
|
|
42
|
+
3. [Include files for C11/C++ and
|
|
43
|
+
Zig](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/include),
|
|
44
|
+
defining WASM imports of the JS [core
|
|
45
|
+
API](https://docs.thi.ng/umbrella/wasm-api/interfaces/CoreAPI.html) defined
|
|
46
|
+
by this package
|
|
47
|
+
4. Extensible shared datatype code generators for (currently)
|
|
48
|
+
[Zig](https://ziglang.org) & TypeScript. The latter also generates fully type
|
|
49
|
+
checked memory-mapped accessors of WASM-side data. In general, all languages
|
|
50
|
+
with a WebAssembly target are supported, however currently only bindings for
|
|
51
|
+
these few langs are included.
|
|
52
|
+
5. [CLI frontend/utility](#cli-generator) to invoke the code generator(s)
|
|
36
53
|
|
|
37
54
|
### Custom API modules
|
|
38
55
|
|
|
56
|
+
The [`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html) is extensible via custom defined API modules. Such API extensions
|
|
57
|
+
will consist of a collection of JS/TS functions & variables, their related
|
|
58
|
+
counterparts (import definitions) for the WASM target and (optionally) some
|
|
59
|
+
shared data types ([bindings for which _can_ be generated by this package too](#data-bindings--code-generators)).
|
|
60
|
+
|
|
39
61
|
On the JS side, custom API modules can be easily integrated via the [`IWasmAPI`
|
|
40
62
|
interface](https://docs.thi.ng/umbrella/wasm-api/interfaces/IWasmAPI.html). The
|
|
41
63
|
following example provides a brief overview:
|
|
@@ -113,12 +135,12 @@ export fn test_randomVec2() void {
|
|
|
113
135
|
|
|
114
136
|
Since only numeric values can be exchanged between the WASM module and the JS
|
|
115
137
|
host, any JS native objects the WASM side might want to be working with must be
|
|
116
|
-
managed in JS. For this purpose the [`ObjectIndex`
|
|
138
|
+
managed manually in JS. For this purpose the [`ObjectIndex`
|
|
117
139
|
class](https://docs.thi.ng/umbrella/wasm-api/classes/ObjectIndex.html) can be
|
|
118
140
|
used by API modules to handle ID generation (incl. recycling, using
|
|
119
141
|
[@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen))
|
|
120
|
-
|
|
121
|
-
then need to be exchanged with the WASM module...
|
|
142
|
+
and the indexing of different types of JS objects/values. Only the numeric IDs
|
|
143
|
+
(handles) will then need to be exchanged with the WASM module...
|
|
122
144
|
|
|
123
145
|
```ts
|
|
124
146
|
import { ObjectIndex } from "@thi.ng/wasm-api";
|
|
@@ -156,6 +178,257 @@ canvases.delete(0);
|
|
|
156
178
|
// true
|
|
157
179
|
```
|
|
158
180
|
|
|
181
|
+
### Data bindings & code generators
|
|
182
|
+
|
|
183
|
+
The package provides an extensible codegeneration framework to simplify the
|
|
184
|
+
bilateral design & exchange of data structures shared between the WASM & JS host
|
|
185
|
+
env. Currently, code generators for TypeScript & Zig are supplied (more are
|
|
186
|
+
planned). A CLI wrapper is worked on too.
|
|
187
|
+
|
|
188
|
+
#### CLI generator
|
|
189
|
+
|
|
190
|
+
The package includes a [small CLI
|
|
191
|
+
wrapper](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/src/cli.ts)
|
|
192
|
+
to invoke the codegenerator(s) from JSON type definitions and to write the
|
|
193
|
+
generated source code(s) to different files:
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
$ npx run @thi.ng/wasm-api
|
|
197
|
+
|
|
198
|
+
█ █ █ │
|
|
199
|
+
██ █ │
|
|
200
|
+
█ █ █ █ █ █ █ █ │ @thi.ng/wasm-api 0.6.0
|
|
201
|
+
█ █ █ █ █ █ █ █ █ │ Multi-language data bindings code generator
|
|
202
|
+
█ │
|
|
203
|
+
█ █ │
|
|
204
|
+
|
|
205
|
+
usage: wasm-api [OPTS] JSON-INPUT-FILE(S) ...
|
|
206
|
+
wasm-api --help
|
|
207
|
+
|
|
208
|
+
Flags:
|
|
209
|
+
|
|
210
|
+
-d, --debug enable debug output
|
|
211
|
+
--dry-run enable dry run (don't overwrite files)
|
|
212
|
+
|
|
213
|
+
Main:
|
|
214
|
+
|
|
215
|
+
-c FILE, --config FILE JSON config file with codegen options
|
|
216
|
+
-l ID[,..], --lang ID[,..] [multiple] target language: "ts", "zig" (default: ["ts","zig"])
|
|
217
|
+
-o FILE, --out FILE [multiple] output file path
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
By default, the CLI generates sources for both TypeScript and Zig (in this
|
|
221
|
+
order!). Order is important, since the output file paths must be given in the
|
|
222
|
+
same order as the target languages. It's recommended to be more explicit. An
|
|
223
|
+
example invocation looks like:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
wasm-api --config codegen-opts.json \
|
|
227
|
+
--lang ts -o src/generated.ts \
|
|
228
|
+
--lang zig -o src.zig/generated.zig \
|
|
229
|
+
typedefs.json
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The structure of the config file is as follows (all optional):
|
|
233
|
+
|
|
234
|
+
```text
|
|
235
|
+
{
|
|
236
|
+
global: { ... },
|
|
237
|
+
ts: { ... },
|
|
238
|
+
zig: { ... },
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
More details about possible
|
|
243
|
+
[`global`](https://docs.thi.ng/umbrella/wasm-api/interfaces/CodeGenOpts.html),
|
|
244
|
+
[`ts`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TSOpts.html) and
|
|
245
|
+
[`zig`](https://docs.thi.ng/umbrella/wasm-api/interfaces/ZigOpts.html) config
|
|
246
|
+
options & values.
|
|
247
|
+
|
|
248
|
+
#### Data type definitions
|
|
249
|
+
|
|
250
|
+
Currently, the code generator supports structs and enums. See API docs for
|
|
251
|
+
further details:
|
|
252
|
+
|
|
253
|
+
- [`Enum`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Enum.html)
|
|
254
|
+
- [`EnumValue`](https://docs.thi.ng/umbrella/wasm-api/interfaces/EnumValue.html)
|
|
255
|
+
- [`Struct`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Struct.html)
|
|
256
|
+
- [`StructField`](https://docs.thi.ng/umbrella/wasm-api/interfaces/StructField.html)
|
|
257
|
+
- [`TopLevelType`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TopLevelType.html)
|
|
258
|
+
|
|
259
|
+
#### Example usage
|
|
260
|
+
|
|
261
|
+
Below is an example file with JSON type definitions and the resulting source
|
|
262
|
+
codes:
|
|
263
|
+
|
|
264
|
+
<details><summary>types.json (Type definitions, click to expand)</summary>
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
[
|
|
268
|
+
{
|
|
269
|
+
"name": "Foo",
|
|
270
|
+
"type": "struct",
|
|
271
|
+
"doc": "Example struct",
|
|
272
|
+
"auto": true,
|
|
273
|
+
"fields": [
|
|
274
|
+
{ "name": "id", "type": "u8", "doc": "Unique ID" },
|
|
275
|
+
{ "name": "bars", "type": "Bar", "tag": "array", "len": 3 },
|
|
276
|
+
{ "name": "color", "type": "f32", "tag": "vec", "len": 4 }
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "Bar",
|
|
281
|
+
"type": "struct",
|
|
282
|
+
"fields": [
|
|
283
|
+
{ "name": "kind", "type": "Kind" },
|
|
284
|
+
{ "name": "flags", "type": "u32" }
|
|
285
|
+
]
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"name": "Kind",
|
|
289
|
+
"type": "enum",
|
|
290
|
+
"tag": "u16",
|
|
291
|
+
"values": [
|
|
292
|
+
"unknown",
|
|
293
|
+
{ "name": "good", "value": 100 },
|
|
294
|
+
{ "name": "best", "value": 1000 }
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
]
|
|
298
|
+
```
|
|
299
|
+
</details>
|
|
300
|
+
|
|
301
|
+
<details><summary>generated.ts (generated TypeScript source, click to expand)</summary>
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
/** Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.189Z - DO NOT EDIT! */
|
|
305
|
+
|
|
306
|
+
import type { WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api";
|
|
307
|
+
|
|
308
|
+
/** Example struct */
|
|
309
|
+
export interface Foo extends WasmTypeBase {
|
|
310
|
+
color: Float32Array;
|
|
311
|
+
bars: Bar[];
|
|
312
|
+
/** Unique ID */
|
|
313
|
+
id: number;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export const $Foo: WasmTypeConstructor<Foo> = (mem) => ({
|
|
317
|
+
get align() { return 16; },
|
|
318
|
+
get size() { return 48; },
|
|
319
|
+
instance: (base) => ({
|
|
320
|
+
get __base() { return base; },
|
|
321
|
+
get __bytes() { return mem.u8.subarray(base, base + 48); },
|
|
322
|
+
get color(): Float32Array {
|
|
323
|
+
const addr = base >>> 2;
|
|
324
|
+
return mem.f32.subarray(addr, addr + 4);
|
|
325
|
+
},
|
|
326
|
+
get bars(): Bar[] {
|
|
327
|
+
const addr = (base + 16);
|
|
328
|
+
const inst = $Bar(mem);
|
|
329
|
+
const slice: Bar[] = [];
|
|
330
|
+
for(let i = 0; i < 3; i++) slice.push(inst.instance(addr + i * 24));
|
|
331
|
+
return slice;
|
|
332
|
+
},
|
|
333
|
+
get id(): number {
|
|
334
|
+
return mem.u8[(base + 40)];
|
|
335
|
+
},
|
|
336
|
+
set id(x: number) {
|
|
337
|
+
mem.u8[(base + 40)] = x;
|
|
338
|
+
},
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
export interface Bar extends WasmTypeBase {
|
|
343
|
+
kind: Kind;
|
|
344
|
+
flags: number;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export const $Bar: WasmTypeConstructor<Bar> = (mem) => ({
|
|
348
|
+
get align() { return 4; },
|
|
349
|
+
get size() { return 8; },
|
|
350
|
+
instance: (base) => ({
|
|
351
|
+
get __base() { return base; },
|
|
352
|
+
get __bytes() { return mem.u8.subarray(base, base + 8); },
|
|
353
|
+
get kind(): Kind {
|
|
354
|
+
return mem.u16[base >>> 1];
|
|
355
|
+
},
|
|
356
|
+
set kind(x: Kind) {
|
|
357
|
+
mem.u16[base >>> 1] = x;
|
|
358
|
+
},
|
|
359
|
+
get flags(): number {
|
|
360
|
+
return mem.u32[(base + 4) >>> 2];
|
|
361
|
+
},
|
|
362
|
+
set flags(x: number) {
|
|
363
|
+
mem.u32[(base + 4) >>> 2] = x;
|
|
364
|
+
},
|
|
365
|
+
})
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
export enum Kind {
|
|
369
|
+
UNKNOWN,
|
|
370
|
+
GOOD = 100,
|
|
371
|
+
BEST = 1000,
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
</details>
|
|
375
|
+
|
|
376
|
+
<details><summary>generated.zig (generated Zig source, click to expand)</summary>
|
|
377
|
+
|
|
378
|
+
```zig
|
|
379
|
+
//! Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.191Z - DO NOT EDIT!
|
|
380
|
+
|
|
381
|
+
/// Example struct
|
|
382
|
+
pub const Foo = struct {
|
|
383
|
+
color: @Vector(4, f32),
|
|
384
|
+
bars: [3]Bar,
|
|
385
|
+
/// Unique ID
|
|
386
|
+
id: u8,
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
pub const Bar = struct {
|
|
390
|
+
kind: Kind,
|
|
391
|
+
flags: u32,
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
pub const Kind = enum(u16) {
|
|
395
|
+
unknown,
|
|
396
|
+
good = 100,
|
|
397
|
+
best = 1000,
|
|
398
|
+
};
|
|
399
|
+
```
|
|
400
|
+
</details>
|
|
401
|
+
|
|
402
|
+
On the TypeScript/JS side, the memory-mapped wrappers (e.g. `$Foo` and `$Bar`)
|
|
403
|
+
can be used in combination with the `WasmBridge` to obtain fully typed views
|
|
404
|
+
(according to the generated types) of the underlying WASM memory. Basic usage is
|
|
405
|
+
like:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
import { WasmBridge } from "@thi.ng/wasm-api";
|
|
409
|
+
import { $Foo, Kind } from "./generated.ts";
|
|
410
|
+
|
|
411
|
+
const bridge = new WasmBridge();
|
|
412
|
+
// bridge initialization omitted here (see other examples below)
|
|
413
|
+
// ...
|
|
414
|
+
|
|
415
|
+
// Create an instance using the bridge's memory views
|
|
416
|
+
// and mapping a `Foo` struct from given address
|
|
417
|
+
// (e.g. obtained from an exported WASM function/value)
|
|
418
|
+
const foo = $Foo(bridge).instance(0x10000);
|
|
419
|
+
|
|
420
|
+
// then use like normal JS object
|
|
421
|
+
foo.color
|
|
422
|
+
// Float32Array(4) [0.1, 0.2, 0.3, 0.4]
|
|
423
|
+
|
|
424
|
+
// this even applies to arrays using other types
|
|
425
|
+
// (setters are currently only supported for scalar values, incl. enums)
|
|
426
|
+
foo.bars[2].kind = Kind.BEST;
|
|
427
|
+
|
|
428
|
+
// IMPORTANT: any modifications like this are directly
|
|
429
|
+
// applied to the underlying WASM memory...
|
|
430
|
+
```
|
|
431
|
+
|
|
159
432
|
### Status
|
|
160
433
|
|
|
161
434
|
**ALPHA** - bleeding edge / work-in-progress
|
|
@@ -185,12 +458,22 @@ node --experimental-repl-await
|
|
|
185
458
|
> const wasmApi = await import("@thi.ng/wasm-api");
|
|
186
459
|
```
|
|
187
460
|
|
|
188
|
-
Package sizes (gzipped, pre-treeshake): ESM:
|
|
461
|
+
Package sizes (gzipped, pre-treeshake): ESM: 4.03 KB
|
|
462
|
+
|
|
463
|
+
**IMPORTANT:** The package includes various code generators and supporting
|
|
464
|
+
functions which are NOT required during runtime. Hence the actual package size
|
|
465
|
+
in production will be MUCH smaller!
|
|
189
466
|
|
|
190
467
|
## Dependencies
|
|
191
468
|
|
|
192
469
|
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
470
|
+
- [@thi.ng/args](https://github.com/thi-ng/umbrella/tree/develop/packages/args)
|
|
471
|
+
- [@thi.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary)
|
|
472
|
+
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
473
|
+
- [@thi.ng/compare](https://github.com/thi-ng/umbrella/tree/develop/packages/compare)
|
|
474
|
+
- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
|
|
193
475
|
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
|
|
476
|
+
- [@thi.ng/file-io](https://github.com/thi-ng/umbrella/tree/develop/packages/file-io)
|
|
194
477
|
- [@thi.ng/hex](https://github.com/thi-ng/umbrella/tree/develop/packages/hex)
|
|
195
478
|
- [@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen)
|
|
196
479
|
- [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
|
|
@@ -199,6 +482,8 @@ Package sizes (gzipped, pre-treeshake): ESM: 1.61 KB
|
|
|
199
482
|
|
|
200
483
|
[Generated API docs](https://docs.thi.ng/umbrella/wasm-api/)
|
|
201
484
|
|
|
485
|
+
## Basic usage example
|
|
486
|
+
|
|
202
487
|
```ts
|
|
203
488
|
import { WasmBridge, WasmExports } from "@thi.ng/wasm-api";
|
|
204
489
|
import { readFileSync } from "fs";
|
|
@@ -223,12 +508,20 @@ interface App extends WasmExports {
|
|
|
223
508
|
})();
|
|
224
509
|
```
|
|
225
510
|
|
|
511
|
+
### Zig version
|
|
512
|
+
|
|
513
|
+
Requires [Zig](https://ziglang.org) to be installed:
|
|
514
|
+
|
|
226
515
|
```zig
|
|
227
516
|
//! Example Zig application (hello.zig)
|
|
228
517
|
|
|
229
518
|
/// import externals
|
|
230
519
|
/// see build command for configuration
|
|
231
520
|
const js = @import("wasmapi");
|
|
521
|
+
const std = @import("std");
|
|
522
|
+
|
|
523
|
+
// set custom memory allocator (here to disable)
|
|
524
|
+
pub const WASM_ALLOCATOR: ?std.mem.Allocator = null;
|
|
232
525
|
|
|
233
526
|
export fn start() void {
|
|
234
527
|
js.printStr("hello world!");
|
|
@@ -242,7 +535,7 @@ folder):
|
|
|
242
535
|
```bash
|
|
243
536
|
# compile WASM binary
|
|
244
537
|
zig build-lib \
|
|
245
|
-
--pkg-begin wasmapi node_modules/@thi.ng/wasm-api/
|
|
538
|
+
--pkg-begin wasmapi node_modules/@thi.ng/wasm-api/include/wasmapi.zig --pkg-end \
|
|
246
539
|
-target wasm32-freestanding \
|
|
247
540
|
-O ReleaseSmall -dynamic --strip \
|
|
248
541
|
hello.zig
|
|
@@ -257,18 +550,112 @@ The resulting WASM:
|
|
|
257
550
|
(module
|
|
258
551
|
(type $i32_i32_=>_none (func (param i32 i32)))
|
|
259
552
|
(type $none_=>_none (func))
|
|
260
|
-
(
|
|
553
|
+
(type $i32_=>_i32 (func (param i32) (result i32)))
|
|
554
|
+
(import "wasmapi" "_printStr" (func $fimport$0 (param i32 i32)))
|
|
261
555
|
(global $global$0 (mut i32) (i32.const 65536))
|
|
262
556
|
(memory $0 2)
|
|
263
557
|
(data (i32.const 65536) "hello world!\00")
|
|
264
558
|
(export "memory" (memory $0))
|
|
265
559
|
(export "start" (func $0))
|
|
560
|
+
(export "_wasm_allocate" (func $1))
|
|
561
|
+
(export "_wasm_free" (func $2))
|
|
266
562
|
(func $0
|
|
267
563
|
(call $fimport$0
|
|
268
564
|
(i32.const 65536)
|
|
269
565
|
(i32.const 12)
|
|
270
566
|
)
|
|
271
567
|
)
|
|
568
|
+
(func $1 (param $0 i32) (result i32)
|
|
569
|
+
(i32.const 0)
|
|
570
|
+
)
|
|
571
|
+
(func $2 (param $0 i32) (param $1 i32)
|
|
572
|
+
)
|
|
573
|
+
)
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### C11 version
|
|
577
|
+
|
|
578
|
+
Requires [Emscripten](https://emscripten.org/) to be installed:
|
|
579
|
+
|
|
580
|
+
```c
|
|
581
|
+
#include <wasmapi.h>
|
|
582
|
+
|
|
583
|
+
void WASM_KEEP start() {
|
|
584
|
+
wasm_printStr0("hello world!");
|
|
585
|
+
}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Building the WASM module:
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
emcc -Os -Inode_modules/@thi.ng/wasm-api/include -DWASMAPI_NO_MALLOC \
|
|
592
|
+
-sERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry \
|
|
593
|
+
-o hello.wasm hello.c
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
Resulting WASM:
|
|
597
|
+
|
|
598
|
+
```wasm
|
|
599
|
+
(module
|
|
600
|
+
(type $i32_=>_none (func (param i32)))
|
|
601
|
+
(type $none_=>_none (func))
|
|
602
|
+
(type $i32_=>_i32 (func (param i32) (result i32)))
|
|
603
|
+
(type $none_=>_i32 (func (result i32)))
|
|
604
|
+
(import "wasmapi" "_printStr0" (func $fimport$0 (param i32)))
|
|
605
|
+
(global $global$0 (mut i32) (i32.const 5243936))
|
|
606
|
+
(memory $0 256 256)
|
|
607
|
+
(data (i32.const 1024) "hello world!")
|
|
608
|
+
(table $0 2 2 funcref)
|
|
609
|
+
(elem (i32.const 1) $0)
|
|
610
|
+
(export "memory" (memory $0))
|
|
611
|
+
(export "_wasm_allocate" (func $1))
|
|
612
|
+
(export "_wasm_free" (func $2))
|
|
613
|
+
(export "start" (func $3))
|
|
614
|
+
(export "__indirect_function_table" (table $0))
|
|
615
|
+
(export "_initialize" (func $0))
|
|
616
|
+
(export "__errno_location" (func $7))
|
|
617
|
+
(export "stackSave" (func $4))
|
|
618
|
+
(export "stackRestore" (func $5))
|
|
619
|
+
(export "stackAlloc" (func $6))
|
|
620
|
+
(func $0
|
|
621
|
+
(nop)
|
|
622
|
+
)
|
|
623
|
+
(func $1 (param $0 i32) (result i32)
|
|
624
|
+
(i32.const 0)
|
|
625
|
+
)
|
|
626
|
+
(func $2 (param $0 i32)
|
|
627
|
+
(nop)
|
|
628
|
+
)
|
|
629
|
+
(func $3
|
|
630
|
+
(call $fimport$0
|
|
631
|
+
(i32.const 1024)
|
|
632
|
+
)
|
|
633
|
+
)
|
|
634
|
+
(func $4 (result i32)
|
|
635
|
+
(global.get $global$0)
|
|
636
|
+
)
|
|
637
|
+
(func $5 (param $0 i32)
|
|
638
|
+
(global.set $global$0
|
|
639
|
+
(local.get $0)
|
|
640
|
+
)
|
|
641
|
+
)
|
|
642
|
+
(func $6 (param $0 i32) (result i32)
|
|
643
|
+
(global.set $global$0
|
|
644
|
+
(local.tee $0
|
|
645
|
+
(i32.and
|
|
646
|
+
(i32.sub
|
|
647
|
+
(global.get $global$0)
|
|
648
|
+
(local.get $0)
|
|
649
|
+
)
|
|
650
|
+
(i32.const -16)
|
|
651
|
+
)
|
|
652
|
+
)
|
|
653
|
+
)
|
|
654
|
+
(local.get $0)
|
|
655
|
+
)
|
|
656
|
+
(func $7 (result i32)
|
|
657
|
+
(i32.const 1040)
|
|
658
|
+
)
|
|
272
659
|
)
|
|
273
660
|
```
|
|
274
661
|
|