@thi.ng/wasm-api 0.13.0 → 0.14.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-10-04T10:33:14Z
3
+ - **Last updated**: 2022-10-17T12:08:09Z
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,18 @@ 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.14.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.14.0) (2022-10-17)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add ptrCast() zig helper ([72a9406](https://github.com/thi-ng/umbrella/commit/72a9406))
17
+ - add Zig Slice & String wrappers ([28d057e](https://github.com/thi-ng/umbrella/commit/28d057e))
18
+ - allows expressing & converting slices for `extern struct`s
19
+ - ensure memory in WasmStringSlice/Ptr ([c55c6f0](https://github.com/thi-ng/umbrella/commit/c55c6f0))
20
+ - update IWasmMemoryAccess ([28bfff6](https://github.com/thi-ng/umbrella/commit/28bfff6))
21
+ - add IWasmMemoryAccess.ensureMemory()
22
+ - update WasmBridge.setString() to ensure memory
23
+
12
24
  ## [0.13.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.13.0) (2022-10-04)
13
25
 
14
26
  #### 🚀 Features
package/api.d.ts CHANGED
@@ -91,6 +91,11 @@ export interface IWasmMemoryAccess {
91
91
  u64: BigUint64Array;
92
92
  f32: Float32Array;
93
93
  f64: Float64Array;
94
+ /**
95
+ * Initializes and/or updates the various typed WASM memory views (e.g.
96
+ * after growing the WASM memory and the previous buffer becoming detached).
97
+ */
98
+ ensureMemory(): void;
94
99
  /**
95
100
  * Reads UTF-8 encoded string from given address and optional byte length.
96
101
  * The default length is 0, which will be interpreted as a zero-terminated
package/bridge.js CHANGED
@@ -414,6 +414,7 @@ let WasmBridge = class WasmBridge {
414
414
  * @param terminate
415
415
  */
416
416
  setString(str, addr, maxBytes, terminate = true) {
417
+ this.ensureMemory();
417
418
  maxBytes = Math.min(maxBytes, this.u8.length - addr);
418
419
  const len = this.utf8Encoder.encodeInto(str, this.u8.subarray(addr, addr + maxBytes)).written;
419
420
  if (len == null || len >= maxBytes + (terminate ? 0 : 1)) {
package/codegen/c11.js CHANGED
@@ -36,11 +36,10 @@ export const C11 = (opts = {}) => {
36
36
  #ifdef __cplusplus
37
37
  extern "C" {
38
38
  #endif
39
-
40
39
  ${opts.debug ? "\n#include <stdalign.h>" : ""}
41
40
  #include <stddef.h>
42
41
  #include <stdint.h>${opts.pre ? `\n${opts.pre}` : ""}`,
43
- post: () => `${opts.post ? `${opts.post}\n` : ""}#ifdef __cplusplus\n}\n#endif`,
42
+ post: () => `${opts.post ? `${opts.post}\n` : ""}#ifdef __cplusplus\n}\n#endif\n`,
44
43
  doc: (doc, acc, opts) => {
45
44
  acc.push(...prefixLines("// ", doc, opts.lineWidth));
46
45
  },
@@ -3,6 +3,47 @@
3
3
  const std = @import("std");
4
4
  const root = @import("root");
5
5
 
6
+ /// Higher-order slice wrapper for extern struct use cases
7
+ /// S = slice type
8
+ /// P = pointer type
9
+ /// default = point default value
10
+ pub fn Slice(comptime S: type, comptime P: type, comptime default: P) type {
11
+ return extern struct {
12
+ ptr: P = default,
13
+ len: usize = 0,
14
+
15
+ pub fn wrap(slice: S) @This() {
16
+ return .{
17
+ .ptr = @ptrCast(P, slice.ptr),
18
+ .len = slice.len,
19
+ };
20
+ }
21
+
22
+ pub fn toSlice(self: *@This()) S {
23
+ return @ptrCast(*S, self).*;
24
+ }
25
+ };
26
+ }
27
+
28
+ /// []const u8 wrapper for extern struct use cases
29
+ const String = Slice([]const u8, [*:0]const u8, "");
30
+
31
+ /// Syntax sugar for `String.wrap()`
32
+ pub fn string(str: []const u8) String {
33
+ return String.wrap(str);
34
+ }
35
+
36
+ /// Similar to @ptrCast intrinsic. Helper function to cast & re-align an
37
+ /// optional `anyopaque` pointer to another given pointer type.
38
+ /// E.g. useful for retrieving user context data from an opaque extra arg
39
+ /// given to a event listner callback...
40
+ pub fn ptrCast(comptime T: type, ptr: ?*anyopaque) ?T {
41
+ if (ptr == null) return null;
42
+ const info = @typeInfo(T);
43
+ if (info != .Pointer) @compileError("require pointer type");
44
+ return @ptrCast(T, @alignCast(@alignOf(info.Pointer.child), ptr));
45
+ }
46
+
6
47
  /// JS external part of the custom panic handler
7
48
  /// Prints message using configured JS logger and then throws JS error
8
49
  pub extern "wasmapi" fn _panic(addr: [*]const u8, len: usize) noreturn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/wasm-api",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Generic, modular, extensible API bridge, polyglot glue code and bindings code generators for hybrid JS & WebAssembly projects",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -37,22 +37,22 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@thi.ng/api": "^8.4.3",
40
- "@thi.ng/args": "^2.2.3",
40
+ "@thi.ng/args": "^2.2.5",
41
41
  "@thi.ng/binary": "^3.3.6",
42
- "@thi.ng/checks": "^3.2.6",
42
+ "@thi.ng/checks": "^3.3.0",
43
43
  "@thi.ng/compare": "^2.1.13",
44
- "@thi.ng/defmulti": "^2.1.16",
45
- "@thi.ng/errors": "^2.2.1",
46
- "@thi.ng/file-io": "^0.3.13",
44
+ "@thi.ng/defmulti": "^2.1.18",
45
+ "@thi.ng/errors": "^2.2.2",
46
+ "@thi.ng/file-io": "^0.3.15",
47
47
  "@thi.ng/hex": "^2.2.1",
48
- "@thi.ng/idgen": "^2.1.14",
49
- "@thi.ng/logger": "^1.4.0",
50
- "@thi.ng/paths": "^5.1.16",
51
- "@thi.ng/strings": "^3.3.13"
48
+ "@thi.ng/idgen": "^2.1.15",
49
+ "@thi.ng/logger": "^1.4.1",
50
+ "@thi.ng/paths": "^5.1.18",
51
+ "@thi.ng/strings": "^3.3.14"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@microsoft/api-extractor": "^7.31.1",
55
- "@thi.ng/testament": "^0.3.2",
55
+ "@thi.ng/testament": "^0.3.3",
56
56
  "rimraf": "^3.0.2",
57
57
  "tools": "^0.0.1",
58
58
  "typedoc": "^0.22.17",
@@ -62,13 +62,15 @@
62
62
  "allocator",
63
63
  "api",
64
64
  "bindings",
65
+ "browser",
65
66
  "c",
66
67
  "codegen",
67
68
  "enum",
68
69
  "event",
69
- "id",
70
+ "interop",
70
71
  "logger",
71
72
  "memory",
73
+ "modular",
72
74
  "polyglot",
73
75
  "string",
74
76
  "struct",
@@ -77,7 +79,6 @@
77
79
  "utf8",
78
80
  "wasm",
79
81
  "webassembly",
80
- "wrapper",
81
82
  "ziglang"
82
83
  ],
83
84
  "publishConfig": {
@@ -94,8 +95,8 @@
94
95
  "*.js",
95
96
  "*.d.ts",
96
97
  "bin",
97
- "include",
98
- "codegen"
98
+ "codegen",
99
+ "include"
99
100
  ],
100
101
  "exports": {
101
102
  ".": {
@@ -136,5 +137,5 @@
136
137
  "status": "alpha",
137
138
  "year": 2022
138
139
  },
139
- "gitHead": "6f14e9de72c701f9c3c12d2e1bbd34a5dc86197a\n"
140
+ "gitHead": "612b1b0bdf442473f04c2edac3012975a6ca28bb\n"
140
141
  }
package/string.js CHANGED
@@ -15,12 +15,14 @@ export class WasmStringSlice {
15
15
  * Returns string start address (deref'd pointer).
16
16
  */
17
17
  get addr() {
18
+ this.mem.ensureMemory();
18
19
  return this.mem.u32[this.base >>> 2];
19
20
  }
20
21
  /**
21
22
  * Returns string length (read from memory)
22
23
  */
23
24
  get length() {
25
+ this.mem.ensureMemory();
24
26
  return this.mem.u32[(this.base + 4) >>> 2];
25
27
  }
26
28
  /**
@@ -48,6 +50,7 @@ export class WasmStringSlice {
48
50
  * @param str
49
51
  */
50
52
  set(str) {
53
+ this.mem.ensureMemory();
51
54
  if (typeof str === "string") {
52
55
  if (this.isConst)
53
56
  unsupported("can't mutate const string");
@@ -65,6 +68,7 @@ export class WasmStringSlice {
65
68
  * @param len
66
69
  */
67
70
  setSlice(addr, len) {
71
+ this.mem.ensureMemory();
68
72
  this.mem.u32[this.base >>> 2] = addr;
69
73
  this.mem.u32[(this.base + 4) >>> 2] = len;
70
74
  }
@@ -93,18 +97,20 @@ export class WasmStringPtr {
93
97
  * Returns string start address (deref'd pointer).
94
98
  */
95
99
  get addr() {
100
+ this.mem.ensureMemory();
96
101
  return this.mem.u32[this.base >>> 2];
97
102
  }
98
103
  set addr(addr) {
104
+ this.mem.ensureMemory();
99
105
  this.mem.u32[this.base >>> 2] = addr;
100
106
  }
101
107
  /**
102
108
  * Returns computed string length (scanning memory for zero sentinel)
103
109
  */
104
110
  get length() {
105
- const addr = this.addr;
106
- const idx = this.mem.u8.indexOf(0, addr);
107
- return idx >= 0 ? idx - addr : 0;
111
+ this.mem.ensureMemory();
112
+ const idx = this.mem.u8.indexOf(0, this.addr);
113
+ return idx >= 0 ? idx - this.addr : 0;
108
114
  }
109
115
  /**
110
116
  * Returns memory as JS string (aka wrapper for
@@ -137,6 +143,7 @@ export class WasmStringPtr {
137
143
  if (typeof str === "string") {
138
144
  if (this.isConst)
139
145
  unsupported("can't mutate const string");
146
+ this.mem.ensureMemory();
140
147
  this.mem.setString(str, addr, this.mem.u8.byteLength - addr, true);
141
148
  }
142
149
  else {