@thi.ng/wasm-api 0.10.0 → 0.12.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/codegen.d.ts CHANGED
@@ -1,26 +1,4 @@
1
- import { ICodeGen, TypeColl } from "./api.js";
2
- /**
3
- * Global/shared code generator options.
4
- */
5
- export interface CodeGenOpts {
6
- /**
7
- * Optional string to be injected before generated type defs (but after
8
- * codegen's own prelude, if any)
9
- */
10
- pre: string;
11
- /**
12
- * Optional string to be injected after generated type defs (but before
13
- * codegen's own epilogue, if any)
14
- */
15
- post: string;
16
- /**
17
- * Identifier how strings are stored on WASM side, e.g. in Zig string
18
- * literals are slices (8 bytes), in C just plain pointers (4 bytes).
19
- *
20
- * @defaultValue "slice"
21
- */
22
- stringType: "slice" | "ptr";
23
- }
1
+ import { CodeGenOpts, ICodeGen, TypeColl } from "./api.js";
24
2
  /**
25
3
  * Takes a type collection and analyzes each analyzed to compute individual
26
4
  * alignments and sizes.
package/codegen.js CHANGED
@@ -4,12 +4,17 @@ import { ceilPow2 } from "@thi.ng/binary/pow";
4
4
  import { compareByKey } from "@thi.ng/compare/keys";
5
5
  import { compareNumDesc } from "@thi.ng/compare/numeric";
6
6
  import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
7
+ import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
7
8
  import { PKG_NAME, USIZE_SIZE, } from "./api.js";
8
9
  import { isNumeric, isWasmString } from "./codegen/utils.js";
9
10
  const sizeOf = defmulti((x) => x.type, {}, {
10
11
  [DEFAULT]: (field, types, opts) => {
11
12
  if (field.__size)
12
13
  return field.__size;
14
+ if (field.pad != null) {
15
+ field.pad < 1 && illegalArgs(`pad size must be > 0`);
16
+ return (field.__size = field.pad);
17
+ }
13
18
  let size = 0;
14
19
  if (field.tag === "ptr") {
15
20
  size = USIZE_SIZE;
@@ -25,6 +30,9 @@ const sizeOf = defmulti((x) => x.type, {}, {
25
30
  : sizeOf(types[field.type], types, opts);
26
31
  if (field.tag == "array" || field.tag === "vec") {
27
32
  size *= field.len;
33
+ if (field.sentinel !== undefined && field.tag === "array") {
34
+ size += SIZEOF[field.type];
35
+ }
28
36
  }
29
37
  }
30
38
  return (field.__size = align(size, field.__align));
@@ -51,6 +59,8 @@ const alignOf = defmulti((x) => x.type, {}, {
51
59
  [DEFAULT]: (field, types) => {
52
60
  if (field.__align)
53
61
  return field.__align;
62
+ if (field.pad)
63
+ return (field.__align = 1);
54
64
  let align = isNumeric(field.type)
55
65
  ? SIZEOF[field.type]
56
66
  : isWasmString(field.type)
@@ -62,7 +72,10 @@ const alignOf = defmulti((x) => x.type, {}, {
62
72
  field.__align = align;
63
73
  return align;
64
74
  },
65
- enum: (e) => {
75
+ enum: (type) => {
76
+ const e = type;
77
+ if (!e.tag)
78
+ e.tag = "i32";
66
79
  return (e.__align = SIZEOF[e.tag]);
67
80
  },
68
81
  struct: (type, types) => {
@@ -130,19 +143,33 @@ export const prepareTypes = (types, opts) => {
130
143
  * @param opts
131
144
  */
132
145
  export const generateTypes = (types, codegen, opts = {}) => {
133
- const $opts = { stringType: "slice", ...opts };
146
+ const $opts = {
147
+ header: true,
148
+ stringType: "slice",
149
+ uppercaseEnums: true,
150
+ lineWidth: 80,
151
+ ...opts,
152
+ };
134
153
  prepareTypes(types, $opts);
135
154
  const res = [];
136
- codegen.doc(`Generated by ${PKG_NAME} at ${new Date().toISOString()} - DO NOT EDIT!`, "", res, true);
137
- res.push("");
138
- codegen.pre && res.push(codegen.pre, "");
155
+ if ($opts.header) {
156
+ codegen.doc(`Generated by ${PKG_NAME} at ${new Date().toISOString()} - DO NOT EDIT!`, res, $opts, true);
157
+ res.push("");
158
+ }
159
+ if (codegen.pre) {
160
+ const pre = codegen.pre($opts);
161
+ pre && res.push(pre, "");
162
+ }
139
163
  $opts.pre && res.push($opts.pre, "");
140
164
  for (let id in types) {
141
165
  const type = types[id];
142
- type.doc && codegen.doc(type.doc, "", res);
143
- codegen[type.type](type, types, res);
166
+ type.doc && codegen.doc(type.doc, res, $opts);
167
+ codegen[type.type](type, types, res, $opts);
144
168
  }
145
169
  $opts.post && res.push("", $opts.post);
146
- codegen.post && res.push("", codegen.post);
170
+ if (codegen.post) {
171
+ const post = codegen.post($opts);
172
+ post && res.push("", post);
173
+ }
147
174
  return res.join("\n");
148
175
  };
package/include/wasmapi.h CHANGED
@@ -9,9 +9,8 @@ extern "C" {
9
9
 
10
10
  // Declares an imported symbol from named import module
11
11
  // The prefix is only used for the C side, NOT for exported name
12
- #define WASM_IMPORT(MODULE, TYPE, NAME, PREFIX) \
13
- extern __attribute__((import_module(MODULE), import_name(#NAME))) \
14
- TYPE PREFIX##NAME
12
+ #define WASM_IMPORT(MODULE, TYPE, NAME, PREFIX) \
13
+ extern __attribute__((import_module(MODULE), import_name(#NAME))) TYPE PREFIX##NAME
15
14
 
16
15
  // Same as EMSCRIPTEN_KEEP_ALIVE, ensures symbol will be exported
17
16
  #define WASM_KEEP __attribute__((used))
@@ -19,15 +18,24 @@ extern "C" {
19
18
  // Generate malloc/free wrappers only if explicitly enabled by defining this
20
19
  // symbol. If undefined some function stubs are exported.
21
20
  #ifdef WASMAPI_MALLOC
21
+
22
22
  #include <stdlib.h>
23
23
  size_t WASM_KEEP _wasm_allocate(size_t numBytes) {
24
24
  return (size_t)malloc(numBytes);
25
25
  }
26
- void WASM_KEEP _wasm_free(size_t addr) { free((void*)addr); }
26
+ void WASM_KEEP _wasm_free(size_t addr, size_t numBytes) {
27
+ free((void*)addr);
28
+ }
29
+
27
30
  #else
28
- size_t WASM_KEEP _wasm_allocate(size_t num_bytes) { return 0; }
29
- void WASM_KEEP _wasm_free(size_t addr) {}
30
- #endif
31
+
32
+ size_t WASM_KEEP _wasm_allocate(size_t numBytes) {
33
+ return 0;
34
+ }
35
+ void WASM_KEEP _wasm_free(size_t addr, size_t numBytes) {
36
+ }
37
+
38
+ #endif // WASMAPI_MALLOC
31
39
 
32
40
  WASM_IMPORT("wasmapi", void, printI8, wasm_)(int8_t x);
33
41
  WASM_IMPORT("wasmapi", void, printU8, wasm_)(uint8_t x);
@@ -44,23 +52,29 @@ WASM_IMPORT("wasmapi", void, printU64Hex, wasm_)(uint64_t x);
44
52
  WASM_IMPORT("wasmapi", void, printF32, wasm_)(float x);
45
53
  WASM_IMPORT("wasmapi", void, printF64, wasm_)(double x);
46
54
 
47
- WASM_IMPORT("wasmapi", void, _printI8Array, wasm)(void* addr, size_t len);
48
- WASM_IMPORT("wasmapi", void, _printU8Array, wasm)(void* addr, size_t len);
49
- WASM_IMPORT("wasmapi", void, _printI16Array, wasm)(void* addr, size_t len);
50
- WASM_IMPORT("wasmapi", void, _printU16Array, wasm)(void* addr, size_t len);
51
- WASM_IMPORT("wasmapi", void, _printI32Array, wasm)(void* addr, size_t len);
52
- WASM_IMPORT("wasmapi", void, _printU32Array, wasm)(void* addr, size_t len);
53
- WASM_IMPORT("wasmapi", void, _printI64Array, wasm)(void* addr, size_t len);
54
- WASM_IMPORT("wasmapi", void, _printU64Array, wasm)(void* addr, size_t len);
55
- WASM_IMPORT("wasmapi", void, _printF32Array, wasm)(void* addr, size_t len);
56
- WASM_IMPORT("wasmapi", void, _printF64Array, wasm)(void* addr, size_t len);
55
+ WASM_IMPORT("wasmapi", void, _printI8Array, wasm)(const int8_t* addr, size_t len);
56
+ WASM_IMPORT("wasmapi", void, _printU8Array, wasm)(const uint8_t* addr, size_t len);
57
+ WASM_IMPORT("wasmapi", void, _printI16Array, wasm)(const int16_t* addr, size_t len);
58
+ WASM_IMPORT("wasmapi", void, _printU16Array, wasm)(const uint16_t* addr, size_t len);
59
+ WASM_IMPORT("wasmapi", void, _printI32Array, wasm)(const int32_t* addr, size_t len);
60
+ WASM_IMPORT("wasmapi", void, _printU32Array, wasm)(const uint32_t* addr, size_t len);
61
+ WASM_IMPORT("wasmapi", void, _printI64Array, wasm)(const int64_t* addr, size_t len);
62
+ WASM_IMPORT("wasmapi", void, _printU64Array, wasm)(const uint64_t* addr, size_t len);
63
+ WASM_IMPORT("wasmapi", void, _printF32Array, wasm)(const float* addr, size_t len);
64
+ WASM_IMPORT("wasmapi", void, _printF64Array, wasm)(const double* addr, size_t len);
57
65
 
58
- WASM_IMPORT("wasmapi", void, _printStr0, wasm)(void* addr);
59
- WASM_IMPORT("wasmapi", void, _printStr, wasm)(void* addr, size_t len);
66
+ WASM_IMPORT("wasmapi", void, _printStr0, wasm)(const char* addr);
67
+ WASM_IMPORT("wasmapi", void, _printStr, wasm)(const char* addr, size_t len);
60
68
 
61
69
  WASM_IMPORT("wasmapi", void, debug, wasm_)(void);
70
+ WASM_IMPORT("wasmapi", void, panic, wasm_)(const char*, size_t len);
62
71
 
63
- void wasm_printPtr(void* ptr) { wasm_printU32Hex((size_t)ptr); }
72
+ WASM_IMPORT("wasmapi", double, timer, wasm_)(void);
73
+ WASM_IMPORT("wasmapi", uint64_t, epoch, wasm_)(void);
74
+
75
+ void wasm_printPtr(const void* ptr) {
76
+ wasm_printU32Hex((size_t)ptr);
77
+ }
64
78
 
65
79
  #ifdef __cplusplus
66
80
  }
@@ -3,9 +3,24 @@
3
3
  const std = @import("std");
4
4
  const root = @import("root");
5
5
 
6
+ /// JS external part of the custom panic handler
7
+ /// Prints message using configured JS logger and then throws JS error
8
+ pub extern "wasmapi" fn _panic(addr: [*]const u8, len: usize) noreturn;
9
+
10
+ /// Custom panic handler which prints given message using configured JS logger
11
+ /// To use this handler, add the following line to your **root** source file:
12
+ ///
13
+ /// ```
14
+ /// pub const panic = @import("wasmapi").panic;
15
+ /// ```
16
+ pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
17
+ _panic(msg.ptr, msg.len);
18
+ unreachable;
19
+ }
20
+
6
21
  /// Obtains the allocator to be exposed to the WASM host env
7
22
  /// (via `_wasm_allocate()` and `_wasm_free()`).
8
- /// If the user defines a public `WASM_ALLOCATOR` in their root file
23
+ /// If the user defines a public `WASM_ALLOCATOR` in their **root** file
9
24
  /// then this allocator will be used, otherwise the implementations
10
25
  /// of the two mentioned functions are no-ops.
11
26
  /// The `WASM_ALLOCATOR` can be changed and/or enabled/disabled dynamically
@@ -32,9 +47,9 @@ pub export fn _wasm_allocate(numBytes: usize) usize {
32
47
  /// Frees chunk of heap memory (previously allocated using `_wasm_allocate()`)
33
48
  /// starting at given address and of given byte length.
34
49
  /// Note: This is a no-op if no allocator is configured (see `allocator()`)
35
- pub export fn _wasm_free(addr: usize, numBytes: usize) void {
50
+ pub export fn _wasm_free(addr: [*]u8, numBytes: usize) void {
36
51
  if (allocator()) |alloc| {
37
- var mem = [2]usize{ addr, numBytes };
52
+ var mem = [2]usize{ @ptrToInt(addr), numBytes };
38
53
  alloc.free(@ptrCast(*[]u8, &mem).*);
39
54
  }
40
55
  }
@@ -60,26 +75,12 @@ pub extern "wasmapi" fn printU32(x: u32) void;
60
75
  /// Prints hex number using configured JS logger
61
76
  pub extern "wasmapi" fn printU32Hex(x: u32) void;
62
77
 
63
- /// Prints decomposed i64 number using configured JS logger
64
- pub extern "wasmapi" fn _printI64(hi: i32, lo: i32) void;
65
- /// Convenience wrapper for _printI64(), accepting an i64
66
- pub fn printI64(x: i64) void {
67
- _printI64(@truncate(i32, x >> 32), @truncate(i32, x));
68
- }
69
-
70
- /// Prints decomposed u64 number using configured JS logger
71
- pub extern "wasmapi" fn _printU64(hi: u32, lo: u32) void;
72
- /// Convenience wrapper for _printU64(), accepting an u64
73
- pub fn printU64(x: u64) void {
74
- _printU64(@truncate(u32, x >> 32), @truncate(u32, x));
75
- }
76
-
77
- /// Prints decomposed u64 hex number using configured JS logger
78
- pub extern "wasmapi" fn _printU64Hex(hi: u32, lo: u32) void;
79
- /// Convenience wrapper for _printU64Hex(), accepting an u64
80
- pub fn printU64Hex(x: u64) void {
81
- _printU64Hex(@truncate(u32, x >> 32), @truncate(u32, x));
82
- }
78
+ /// Prints i64 number using configured JS logger
79
+ pub extern "wasmapi" fn printI64(x: i64) void;
80
+ /// Prints u64 number using configured JS logger
81
+ pub extern "wasmapi" fn printU64(x: u64) void;
82
+ /// Prints u64 hex number using configured JS logger
83
+ pub extern "wasmapi" fn printU64Hex(x: u64) void;
83
84
 
84
85
  /// Prints number using configured JS logger
85
86
  pub extern "wasmapi" fn printF32(x: f32) void;
@@ -92,74 +93,74 @@ pub fn printPtr(ptr: *const anyopaque) void {
92
93
  }
93
94
 
94
95
  /// Prints number array using configured JS logger
95
- pub extern "wasmapi" fn _printI8Array(addr: usize, len: usize) void;
96
+ pub extern "wasmapi" fn _printI8Array(addr: [*]const i8, len: usize) void;
96
97
  /// Prints number array using configured JS logger
97
- pub extern "wasmapi" fn _printU8Array(addr: usize, len: usize) void;
98
+ pub extern "wasmapi" fn _printU8Array(addr: [*]const u8, len: usize) void;
98
99
  /// Prints number array using configured JS logger
99
- pub extern "wasmapi" fn _printI16Array(addr: usize, len: usize) void;
100
+ pub extern "wasmapi" fn _printI16Array(addr: [*]const i16, len: usize) void;
100
101
  /// Prints number array using configured JS logger
101
- pub extern "wasmapi" fn _printU16Array(addr: usize, len: usize) void;
102
+ pub extern "wasmapi" fn _printU16Array(addr: [*]const u16, len: usize) void;
102
103
  /// Prints number array using configured JS logger
103
- pub extern "wasmapi" fn _printI32Array(addr: usize, len: usize) void;
104
+ pub extern "wasmapi" fn _printI32Array(addr: [*]const i32, len: usize) void;
104
105
  /// Prints number array using configured JS logger
105
- pub extern "wasmapi" fn _printU32Array(addr: usize, len: usize) void;
106
+ pub extern "wasmapi" fn _printU32Array(addr: [*]const u32, len: usize) void;
106
107
  /// Prints number array using configured JS logger
107
- pub extern "wasmapi" fn _printI64Array(addr: usize, len: usize) void;
108
+ pub extern "wasmapi" fn _printI64Array(addr: [*]const i64, len: usize) void;
108
109
  /// Prints number array using configured JS logger
109
- pub extern "wasmapi" fn _printU64Array(addr: usize, len: usize) void;
110
+ pub extern "wasmapi" fn _printU64Array(addr: [*]const u64, len: usize) void;
110
111
  /// Prints number array using configured JS logger
111
- pub extern "wasmapi" fn _printF32Array(addr: usize, len: usize) void;
112
+ pub extern "wasmapi" fn _printF32Array(addr: [*]const f32, len: usize) void;
112
113
  /// Prints number array using configured JS logger
113
- pub extern "wasmapi" fn _printF64Array(addr: usize, len: usize) void;
114
+ pub extern "wasmapi" fn _printF64Array(addr: [*]const f64, len: usize) void;
114
115
 
115
116
  /// Prints number array using configured JS logger
116
117
  pub fn printI8Array(buf: []const i8) void {
117
- _printI8Array(@ptrToInt(buf.ptr), buf.len);
118
+ _printI8Array(buf.ptr, buf.len);
118
119
  }
119
120
  /// Prints number array using configured JS logger
120
121
  pub fn printU8Array(buf: []const u8) void {
121
- _printU8Array(@ptrToInt(buf.ptr), buf.len);
122
+ _printU8Array(buf.ptr, buf.len);
122
123
  }
123
124
  /// Prints number array using configured JS logger
124
125
  pub fn printI16Array(buf: []const i16) void {
125
- _printI16Array(@ptrToInt(buf.ptr), buf.len);
126
+ _printI16Array(buf.ptr, buf.len);
126
127
  }
127
128
  /// Prints number array using configured JS logger
128
129
  pub fn printU16Array(buf: []const u16) void {
129
- _printU16Array(@ptrToInt(buf.ptr), buf.len);
130
+ _printU16Array(buf.ptr, buf.len);
130
131
  }
131
132
  /// Prints number array using configured JS logger
132
133
  pub fn printI32Array(buf: []const i32) void {
133
- _printI32Array(@ptrToInt(buf.ptr), buf.len);
134
+ _printI32Array(buf.ptr, buf.len);
134
135
  }
135
136
  /// Prints number array using configured JS logger
136
137
  pub fn printU32Array(buf: []const u32) void {
137
- _printU32Array(@ptrToInt(buf.ptr), buf.len);
138
+ _printU32Array(buf.ptr, buf.len);
138
139
  }
139
140
  /// Prints number array using configured JS logger
140
141
  pub fn printI64Array(buf: []const i64) void {
141
- _printI64Array(@ptrToInt(buf.ptr), buf.len);
142
+ _printI64Array(buf.ptr, buf.len);
142
143
  }
143
144
  /// Prints number array using configured JS logger
144
145
  pub fn printU64Array(buf: []const u64) void {
145
- _printU64Array(@ptrToInt(buf.ptr), buf.len);
146
+ _printU64Array(buf.ptr, buf.len);
146
147
  }
147
148
  /// Prints number array using configured JS logger
148
149
  pub fn printF32Array(buf: []const f32) void {
149
- _printF32Array(@ptrToInt(buf.ptr), buf.len);
150
+ _printF32Array(buf.ptr, buf.len);
150
151
  }
151
152
  /// Prints number array using configured JS logger
152
153
  pub fn printF64Array(buf: []const f64) void {
153
- _printF64Array(@ptrToInt(buf.ptr), buf.len);
154
+ _printF64Array(buf.ptr, buf.len);
154
155
  }
155
156
 
156
157
  /// Prints a zero-terminated string using configured JS logger
157
- pub extern "wasmapi" fn _printStr0(addr: usize) void;
158
+ pub extern "wasmapi" fn _printStr0(addr: [*]const u8) void;
158
159
  /// Prints a string of given length using configured JS logger
159
- pub extern "wasmapi" fn _printStr(addr: usize, len: usize) void;
160
+ pub extern "wasmapi" fn _printStr(addr: [*]const u8, len: usize) void;
160
161
  /// Convenience wrapper for _printStr, accepting a slice as arg
161
162
  pub fn printStr(msg: []const u8) void {
162
- _printStr(@ptrToInt(msg.ptr), msg.len);
163
+ _printStr(msg.ptr, msg.len);
163
164
  }
164
165
 
165
166
  /// Calls std.fmt.allocPrint to format given string, then calls `printStr()`
@@ -175,3 +176,9 @@ pub fn printFmt(comptime fmt: []const u8, args: anytype) void {
175
176
 
176
177
  /// Triggers the JS/browser debugger
177
178
  pub extern "wasmapi" fn debug() void;
179
+
180
+ /// Returns a JS/browser highres timer value (via `performance.now()`)
181
+ pub extern "wasmapi" fn timer() f64;
182
+
183
+ /// Returns a JS/browser Unix epoch (via `Date.now()`)
184
+ pub extern "wasmapi" fn epoch() u64;
package/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export * from "./api.js";
2
2
  export * from "./bridge.js";
3
3
  export * from "./codegen.js";
4
+ export * from "./codegen/c11.js";
4
5
  export * from "./codegen/typescript.js";
5
6
  export * from "./codegen/utils.js";
6
7
  export * from "./codegen/zig.js";
7
8
  export * from "./object-index.js";
9
+ export * from "./pointer.js";
10
+ export * from "./string.js";
8
11
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  export * from "./api.js";
2
2
  export * from "./bridge.js";
3
3
  export * from "./codegen.js";
4
+ export * from "./codegen/c11.js";
4
5
  export * from "./codegen/typescript.js";
5
6
  export * from "./codegen/utils.js";
6
7
  export * from "./codegen/zig.js";
7
8
  export * from "./object-index.js";
9
+ export * from "./pointer.js";
10
+ export * from "./string.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/wasm-api",
3
- "version": "0.10.0",
4
- "description": "Generic, modular, extensible API bridge, glue code and bindings code generator for hybrid JS & WebAssembly projects",
3
+ "version": "0.12.0",
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",
7
7
  "typings": "./index.d.ts",
@@ -36,25 +36,27 @@
36
36
  "test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi include/wasmapi.zig --pkg-end test/custom.zig && wasm-dis -o custom.wast custom.wasm && cp custom.wasm test"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.4.1",
40
- "@thi.ng/args": "^2.2.1",
41
- "@thi.ng/binary": "^3.3.4",
42
- "@thi.ng/checks": "^3.2.4",
43
- "@thi.ng/compare": "^2.1.11",
44
- "@thi.ng/defmulti": "^2.1.13",
45
- "@thi.ng/errors": "^2.1.10",
46
- "@thi.ng/file-io": "^0.3.10",
47
- "@thi.ng/hex": "^2.1.9",
48
- "@thi.ng/idgen": "^2.1.12",
49
- "@thi.ng/logger": "^1.2.1"
39
+ "@thi.ng/api": "^8.4.3",
40
+ "@thi.ng/args": "^2.2.3",
41
+ "@thi.ng/binary": "^3.3.6",
42
+ "@thi.ng/checks": "^3.2.6",
43
+ "@thi.ng/compare": "^2.1.13",
44
+ "@thi.ng/defmulti": "^2.1.15",
45
+ "@thi.ng/errors": "^2.2.1",
46
+ "@thi.ng/file-io": "^0.3.12",
47
+ "@thi.ng/hex": "^2.2.1",
48
+ "@thi.ng/idgen": "^2.1.14",
49
+ "@thi.ng/logger": "^1.3.1",
50
+ "@thi.ng/paths": "^5.1.16",
51
+ "@thi.ng/strings": "^3.3.13"
50
52
  },
51
53
  "devDependencies": {
52
- "@microsoft/api-extractor": "^7.25.0",
53
- "@thi.ng/testament": "^0.2.12",
54
+ "@microsoft/api-extractor": "^7.31.1",
55
+ "@thi.ng/testament": "^0.3.1",
54
56
  "rimraf": "^3.0.2",
55
57
  "tools": "^0.0.1",
56
58
  "typedoc": "^0.22.17",
57
- "typescript": "^4.7.4"
59
+ "typescript": "^4.8.3"
58
60
  },
59
61
  "keywords": [
60
62
  "allocator",
@@ -62,10 +64,12 @@
62
64
  "bindings",
63
65
  "c",
64
66
  "codegen",
67
+ "enum",
65
68
  "event",
66
69
  "id",
67
70
  "logger",
68
71
  "memory",
72
+ "polyglot",
69
73
  "string",
70
74
  "struct",
71
75
  "typedarray",
@@ -103,8 +107,8 @@
103
107
  "./bridge": {
104
108
  "default": "./bridge.js"
105
109
  },
106
- "./codegen": {
107
- "default": "./codegen.js"
110
+ "./codegen/c11": {
111
+ "default": "./codegen/c11.js"
108
112
  },
109
113
  "./codegen/typescript": {
110
114
  "default": "./codegen/typescript.js"
@@ -115,13 +119,22 @@
115
119
  "./codegen/zig": {
116
120
  "default": "./codegen/zig.js"
117
121
  },
122
+ "./codegen": {
123
+ "default": "./codegen.js"
124
+ },
118
125
  "./object-index": {
119
126
  "default": "./object-index.js"
127
+ },
128
+ "./pointer": {
129
+ "default": "./pointer.js"
130
+ },
131
+ "./string": {
132
+ "default": "./string.js"
120
133
  }
121
134
  },
122
135
  "thi.ng": {
123
136
  "status": "alpha",
124
137
  "year": 2022
125
138
  },
126
- "gitHead": "4264b91052b8c1f74db9fd51dc48c830dc0d5829\n"
139
+ "gitHead": "8600007d81a7dc92634a1d54e2c32b14ab30ba80\n"
127
140
  }
package/pointer.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { Fn, IDeref } from "@thi.ng/api";
2
+ import type { IWasmMemoryAccess } from "./api.js";
3
+ /**
4
+ * Generic pointer facility which on {@link Pointer.deref()} calls wrapper
5
+ * function (provided as ctor arg) to realise the pointer's target value. The
6
+ * pointer's target address can be accessed via {@link Pointer.addr}
7
+ * (read/write).
8
+ *
9
+ * @remarks
10
+ * The pointer always behaves like `volatile`, i.e. memoization of target values
11
+ * is purposfully avoided and the wrapper function is executed anew _each_ time
12
+ * the pointer is deref'd.
13
+ */
14
+ export declare class Pointer<T> implements IDeref<T> {
15
+ readonly mem: IWasmMemoryAccess;
16
+ readonly base: number;
17
+ readonly fn: Fn<number, T>;
18
+ constructor(mem: IWasmMemoryAccess, base: number, fn: Fn<number, T>);
19
+ get addr(): number;
20
+ set addr(addr: number);
21
+ deref(): T;
22
+ }
23
+ //# sourceMappingURL=pointer.d.ts.map
package/pointer.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Generic pointer facility which on {@link Pointer.deref()} calls wrapper
3
+ * function (provided as ctor arg) to realise the pointer's target value. The
4
+ * pointer's target address can be accessed via {@link Pointer.addr}
5
+ * (read/write).
6
+ *
7
+ * @remarks
8
+ * The pointer always behaves like `volatile`, i.e. memoization of target values
9
+ * is purposfully avoided and the wrapper function is executed anew _each_ time
10
+ * the pointer is deref'd.
11
+ */
12
+ export class Pointer {
13
+ constructor(mem, base, fn) {
14
+ this.mem = mem;
15
+ this.base = base;
16
+ this.fn = fn;
17
+ }
18
+ get addr() {
19
+ return this.mem.u32[this.base >>> 2];
20
+ }
21
+ set addr(addr) {
22
+ this.mem.u32[this.base >>> 2] = addr;
23
+ }
24
+ deref() {
25
+ return this.fn(this.addr);
26
+ }
27
+ }
package/string.d.ts ADDED
@@ -0,0 +1,96 @@
1
+ import type { IWasmMemoryAccess, ReadonlyWasmString } from "./api.js";
2
+ /**
3
+ * Memory mapped string wrapper for Zig-style UTF-8 encoded byte slices (aka
4
+ * pointer & length pair). The actual JS string can be obtained via
5
+ * {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
6
+ */
7
+ export declare class WasmStringSlice implements ReadonlyWasmString {
8
+ readonly mem: IWasmMemoryAccess;
9
+ readonly base: number;
10
+ readonly isConst: boolean;
11
+ readonly max: number;
12
+ constructor(mem: IWasmMemoryAccess, base: number, isConst?: boolean);
13
+ /**
14
+ * Returns string start address (deref'd pointer).
15
+ */
16
+ get addr(): number;
17
+ /**
18
+ * Returns string length (read from memory)
19
+ */
20
+ get length(): number;
21
+ /**
22
+ * Returns memory as JS string (aka wrapper for
23
+ * {@link WasmBridge.getString}).
24
+ */
25
+ deref(): string;
26
+ /**
27
+ * If given a JS string as arg (and if **not** a const slice), attempts to
28
+ * overwrite this wrapped string's memory with bytes from given string. If
29
+ * given another {@link WasmStringSlice} as arg, only the slice pointer &
30
+ * new length will be updated (always succeeds).
31
+ *
32
+ * @remarks
33
+ * When copying bytes from a JS string, an error will be thrown if the new
34
+ * string is longer than the _original_ length of the slice (i.e. from when
35
+ * this `WasmStringSlice` wrapper instance was created). Also updates the
36
+ * slice's length field to new string length.
37
+ *
38
+ * Passing a `WasmString` instance as arg is faster than JS string since
39
+ * only the slice definition itself will be updated.
40
+ *
41
+ * @param str
42
+ */
43
+ set(str: string | WasmStringSlice): void;
44
+ toJSON(): string;
45
+ toString(): string;
46
+ valueOf(): string;
47
+ }
48
+ /**
49
+ * Memory mapped string wrapper for C-style UTF-8 encoded and zero-terminated
50
+ * char pointers. The actual JS string can be obtained via
51
+ * {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
52
+ */
53
+ export declare class WasmStringPtr implements ReadonlyWasmString {
54
+ readonly mem: IWasmMemoryAccess;
55
+ readonly base: number;
56
+ readonly isConst: boolean;
57
+ constructor(mem: IWasmMemoryAccess, base: number, isConst?: boolean);
58
+ /**
59
+ * Returns string start address (deref'd pointer).
60
+ */
61
+ get addr(): number;
62
+ set addr(addr: number);
63
+ /**
64
+ * Returns computed string length (scanning memory for zero sentinel)
65
+ */
66
+ get length(): number;
67
+ /**
68
+ * Returns memory as JS string (aka wrapper for
69
+ * {@link WasmBridge.getString}).
70
+ */
71
+ deref(): string;
72
+ /**
73
+ * If given a JS string as arg (and if not a const pointer), attempts to
74
+ * overwrite this wrapped string's memory with bytes from given string. If
75
+ * given another {@link WasmStringPtr}, it merely overrides the pointer to
76
+ * the new one (always succeeds).
77
+ *
78
+ * @remarks
79
+ * Unlike with {@link WasmStringSlice.set} this implementation which
80
+ * performs bounds checking when copying bytes from a JS string, this method
81
+ * only throws an error if the new string is longer than the available
82
+ * memory (from the start address until the end of the WASM memory).
83
+ * **Therefore, this is as (un)safe as a C pointer and should be used with
84
+ * caution!**
85
+ *
86
+ * Passing a `WasmStringPtr` instance as arg is faster than JS string since
87
+ * only the pointer itself will be updated.
88
+ *
89
+ * @param str
90
+ */
91
+ set(str: string | WasmStringPtr): void;
92
+ toJSON(): string;
93
+ toString(): string;
94
+ valueOf(): string;
95
+ }
96
+ //# sourceMappingURL=string.d.ts.map