@thi.ng/wasm-api 0.18.0 → 1.0.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 +190 -102
- package/README.md +96 -468
- package/api.d.ts +24 -329
- package/api.js +0 -15
- package/bridge.d.ts +0 -31
- package/bridge.js +8 -33
- package/include/wasmapi.h +46 -42
- package/include/wasmapi_types.h +35 -0
- package/index.d.ts +0 -5
- package/index.js +0 -5
- package/package.json +15 -47
- package/pointer.d.ts +20 -0
- package/pointer.js +27 -0
- package/string.d.ts +48 -15
- package/string.js +67 -17
- package/zig/lib.zig +6 -31
- package/zig/types.zig +52 -0
- package/bin/wasm-api +0 -12
- package/bin/wasm-api.mjs_ +0 -17
- package/cli.d.ts +0 -5
- package/cli.js +0 -188
- package/codegen/align.d.ts +0 -14
- package/codegen/align.js +0 -35
- package/codegen/c.d.ts +0 -33
- package/codegen/c.js +0 -100
- package/codegen/c11.d.ts +0 -22
- package/codegen/c11.js +0 -145
- package/codegen/typescript.d.ts +0 -25
- package/codegen/typescript.js +0 -240
- package/codegen/utils.d.ts +0 -96
- package/codegen/utils.js +0 -120
- package/codegen/zig.d.ts +0 -23
- package/codegen/zig.js +0 -149
- package/codegen.d.ts +0 -32
- package/codegen.js +0 -198
package/index.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
export * from "./api.js";
|
|
2
2
|
export * from "./bridge.js";
|
|
3
|
-
export * from "./codegen.js";
|
|
4
|
-
export * from "./codegen/c11.js";
|
|
5
|
-
export * from "./codegen/typescript.js";
|
|
6
|
-
export * from "./codegen/utils.js";
|
|
7
|
-
export * from "./codegen/zig.js";
|
|
8
3
|
export * from "./object-index.js";
|
|
9
4
|
export * from "./pointer.js";
|
|
10
5
|
export * from "./string.js";
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/wasm-api",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Generic, modular, extensible API bridge
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generic, modular, extensible API bridge and infrastructure for hybrid JS & WebAssembly projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
7
7
|
"typings": "./index.d.ts",
|
|
8
|
-
"bin": "bin/wasm-api",
|
|
9
8
|
"sideEffects": false,
|
|
10
9
|
"repository": {
|
|
11
10
|
"type": "git",
|
|
@@ -33,30 +32,23 @@
|
|
|
33
32
|
"doc:stats": "tools:module-stats",
|
|
34
33
|
"pub": "yarn npm publish --access public",
|
|
35
34
|
"test": "testament test",
|
|
36
|
-
"test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi zig/
|
|
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"
|
|
37
36
|
},
|
|
38
37
|
"dependencies": {
|
|
39
|
-
"@thi.ng/api": "^8.4.
|
|
40
|
-
"@thi.ng/
|
|
41
|
-
"@thi.ng/
|
|
42
|
-
"@thi.ng/
|
|
43
|
-
"@thi.ng/
|
|
44
|
-
"@thi.ng/
|
|
45
|
-
"@thi.ng/
|
|
46
|
-
"@thi.ng/errors": "^2.2.3",
|
|
47
|
-
"@thi.ng/file-io": "^0.3.17",
|
|
48
|
-
"@thi.ng/hex": "^2.2.2",
|
|
49
|
-
"@thi.ng/idgen": "^2.1.16",
|
|
50
|
-
"@thi.ng/logger": "^1.4.2",
|
|
51
|
-
"@thi.ng/paths": "^5.1.20",
|
|
52
|
-
"@thi.ng/strings": "^3.3.15"
|
|
38
|
+
"@thi.ng/api": "^8.4.6",
|
|
39
|
+
"@thi.ng/arrays": "^2.4.2",
|
|
40
|
+
"@thi.ng/checks": "^3.3.3",
|
|
41
|
+
"@thi.ng/errors": "^2.2.4",
|
|
42
|
+
"@thi.ng/hex": "^2.3.0",
|
|
43
|
+
"@thi.ng/idgen": "^2.1.18",
|
|
44
|
+
"@thi.ng/logger": "^1.4.3"
|
|
53
45
|
},
|
|
54
46
|
"devDependencies": {
|
|
55
47
|
"@microsoft/api-extractor": "^7.33.5",
|
|
56
|
-
"@thi.ng/testament": "^0.3.
|
|
48
|
+
"@thi.ng/testament": "^0.3.5",
|
|
57
49
|
"rimraf": "^3.0.2",
|
|
58
50
|
"tools": "^0.0.1",
|
|
59
|
-
"typedoc": "^0.23.
|
|
51
|
+
"typedoc": "^0.23.20",
|
|
60
52
|
"typescript": "^4.8.4"
|
|
61
53
|
},
|
|
62
54
|
"keywords": [
|
|
@@ -65,16 +57,12 @@
|
|
|
65
57
|
"bindings",
|
|
66
58
|
"browser",
|
|
67
59
|
"c",
|
|
68
|
-
"codegen",
|
|
69
|
-
"enum",
|
|
70
60
|
"event",
|
|
71
61
|
"interop",
|
|
72
62
|
"logger",
|
|
73
63
|
"memory",
|
|
74
64
|
"modular",
|
|
75
|
-
"polyglot",
|
|
76
65
|
"string",
|
|
77
|
-
"struct",
|
|
78
66
|
"typedarray",
|
|
79
67
|
"typescript",
|
|
80
68
|
"utf8",
|
|
@@ -93,10 +81,8 @@
|
|
|
93
81
|
"node": ">=14"
|
|
94
82
|
},
|
|
95
83
|
"files": [
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"bin",
|
|
99
|
-
"codegen",
|
|
84
|
+
"./*.js",
|
|
85
|
+
"./*.d.ts",
|
|
100
86
|
"include",
|
|
101
87
|
"zig"
|
|
102
88
|
],
|
|
@@ -110,24 +96,6 @@
|
|
|
110
96
|
"./bridge": {
|
|
111
97
|
"default": "./bridge.js"
|
|
112
98
|
},
|
|
113
|
-
"./codegen/align": {
|
|
114
|
-
"default": "./codegen/align.js"
|
|
115
|
-
},
|
|
116
|
-
"./codegen/c11": {
|
|
117
|
-
"default": "./codegen/c11.js"
|
|
118
|
-
},
|
|
119
|
-
"./codegen/typescript": {
|
|
120
|
-
"default": "./codegen/typescript.js"
|
|
121
|
-
},
|
|
122
|
-
"./codegen/utils": {
|
|
123
|
-
"default": "./codegen/utils.js"
|
|
124
|
-
},
|
|
125
|
-
"./codegen/zig": {
|
|
126
|
-
"default": "./codegen/zig.js"
|
|
127
|
-
},
|
|
128
|
-
"./codegen": {
|
|
129
|
-
"default": "./codegen.js"
|
|
130
|
-
},
|
|
131
99
|
"./object-index": {
|
|
132
100
|
"default": "./object-index.js"
|
|
133
101
|
},
|
|
@@ -142,5 +110,5 @@
|
|
|
142
110
|
"status": "alpha",
|
|
143
111
|
"year": 2022
|
|
144
112
|
},
|
|
145
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "044ee6a3895720fc78e115032d4d831b63510929\n"
|
|
146
114
|
}
|
package/pointer.d.ts
CHANGED
|
@@ -20,4 +20,24 @@ export declare class Pointer<T> implements IDeref<T> {
|
|
|
20
20
|
set addr(addr: number);
|
|
21
21
|
deref(): T;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Generic pointer facility for {@link WASM64} target, which on
|
|
25
|
+
* {@link Pointer64.deref()} calls wrapper function (provided as ctor arg) to
|
|
26
|
+
* realise the pointer's target value. The pointer's target address can be
|
|
27
|
+
* accessed via {@link Pointer.addr} (read/write).
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* The pointer always behaves like `volatile`, i.e. memoization of target values
|
|
31
|
+
* is purposfully avoided and the wrapper function is executed anew _each_ time
|
|
32
|
+
* the pointer is deref'd.
|
|
33
|
+
*/
|
|
34
|
+
export declare class Pointer64<T> implements IDeref<T> {
|
|
35
|
+
readonly mem: IWasmMemoryAccess;
|
|
36
|
+
readonly base: bigint;
|
|
37
|
+
readonly fn: Fn<bigint, T>;
|
|
38
|
+
constructor(mem: IWasmMemoryAccess, base: bigint, fn: Fn<bigint, T>);
|
|
39
|
+
get addr(): bigint;
|
|
40
|
+
set addr(addr: bigint);
|
|
41
|
+
deref(): T;
|
|
42
|
+
}
|
|
23
43
|
//# sourceMappingURL=pointer.d.ts.map
|
package/pointer.js
CHANGED
|
@@ -25,3 +25,30 @@ export class Pointer {
|
|
|
25
25
|
return this.fn(this.addr);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Generic pointer facility for {@link WASM64} target, which on
|
|
30
|
+
* {@link Pointer64.deref()} calls wrapper function (provided as ctor arg) to
|
|
31
|
+
* realise the pointer's target value. The pointer's target address can be
|
|
32
|
+
* accessed via {@link Pointer.addr} (read/write).
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* The pointer always behaves like `volatile`, i.e. memoization of target values
|
|
36
|
+
* is purposfully avoided and the wrapper function is executed anew _each_ time
|
|
37
|
+
* the pointer is deref'd.
|
|
38
|
+
*/
|
|
39
|
+
export class Pointer64 {
|
|
40
|
+
constructor(mem, base, fn) {
|
|
41
|
+
this.mem = mem;
|
|
42
|
+
this.base = base;
|
|
43
|
+
this.fn = fn;
|
|
44
|
+
}
|
|
45
|
+
get addr() {
|
|
46
|
+
return this.mem.u64[Number(this.base >> BigInt(3))];
|
|
47
|
+
}
|
|
48
|
+
set addr(addr) {
|
|
49
|
+
this.mem.u64[Number(this.base >> BigInt(3))] = addr;
|
|
50
|
+
}
|
|
51
|
+
deref() {
|
|
52
|
+
return this.fn(this.addr);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/string.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { IWasmMemoryAccess, ReadonlyWasmString } from "./api.js";
|
|
1
|
+
import type { IWasmMemoryAccess, MemorySlice, ReadonlyWasmString } from "./api.js";
|
|
2
2
|
/**
|
|
3
3
|
* Memory mapped string wrapper for Zig-style UTF-8 encoded byte slices (aka
|
|
4
4
|
* pointer & length pair). The actual JS string can be obtained via
|
|
5
|
-
* {@link WasmStringSlice.deref} and mutated via
|
|
5
|
+
* {@link WasmStringSlice.deref} and possibly mutated via
|
|
6
|
+
* {@link WasmStringSlice.set}.
|
|
6
7
|
*
|
|
7
8
|
* @remarks
|
|
8
9
|
* Currently only supports wasm32 target, need alt. solution for 64bit (possibly
|
|
@@ -11,9 +12,10 @@ import type { IWasmMemoryAccess, ReadonlyWasmString } from "./api.js";
|
|
|
11
12
|
export declare class WasmStringSlice implements ReadonlyWasmString {
|
|
12
13
|
readonly mem: IWasmMemoryAccess;
|
|
13
14
|
readonly base: number;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
protected isConst: boolean;
|
|
16
|
+
protected terminated: boolean;
|
|
17
|
+
protected maxLen: number;
|
|
18
|
+
constructor(mem: IWasmMemoryAccess, base: number, isConst?: boolean, terminated?: boolean);
|
|
17
19
|
/**
|
|
18
20
|
* Returns string start address (deref'd pointer).
|
|
19
21
|
*/
|
|
@@ -48,23 +50,42 @@ export declare class WasmStringSlice implements ReadonlyWasmString {
|
|
|
48
50
|
/**
|
|
49
51
|
* Sets the slice itself to the new values provided.
|
|
50
52
|
*
|
|
51
|
-
* @param
|
|
52
|
-
* @param
|
|
53
|
+
* @param slice
|
|
54
|
+
* @param terminated
|
|
55
|
+
*/
|
|
56
|
+
setSlice(slice: MemorySlice, terminated: boolean): MemorySlice;
|
|
57
|
+
setSlice(addr: number, len: number, terminated: boolean): MemorySlice;
|
|
58
|
+
/**
|
|
59
|
+
* Encodes given string to UTF-8 (by default zero terminated), allocates
|
|
60
|
+
* memory for it, updates this slice and returns a {@link MemorySlice} of
|
|
61
|
+
* the allocated region.
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* If `terminated` is true, the stored slice length will **NOT** include the
|
|
65
|
+
* sentinel! E.g. the slice length of zero-terminated string `"abc"` is 3,
|
|
66
|
+
* but the number of allocated bytes is 4. This is done for compatibility
|
|
67
|
+
* with Zig's sentinel-terminated slice handling (e.g. `[:0]u8` slices).
|
|
68
|
+
*
|
|
69
|
+
* Regardless of `terminated` setting, the returned `MemorySlice` **always**
|
|
70
|
+
* covers the entire allocated region!
|
|
71
|
+
*
|
|
72
|
+
* @param str
|
|
73
|
+
* @param terminate
|
|
53
74
|
*/
|
|
54
|
-
|
|
75
|
+
setAlloc(str: string, terminate?: boolean): MemorySlice;
|
|
55
76
|
toJSON(): string;
|
|
56
77
|
toString(): string;
|
|
57
78
|
valueOf(): string;
|
|
58
79
|
}
|
|
59
80
|
/**
|
|
60
|
-
* Memory mapped string wrapper for C-style UTF-8 encoded and
|
|
61
|
-
* char pointers. The actual JS string can be obtained via
|
|
81
|
+
* Memory mapped string wrapper for C-style UTF-8 encoded and **always**
|
|
82
|
+
* zero-terminated char pointers. The actual JS string can be obtained via
|
|
62
83
|
* {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
|
|
63
84
|
*/
|
|
64
85
|
export declare class WasmStringPtr implements ReadonlyWasmString {
|
|
65
86
|
readonly mem: IWasmMemoryAccess;
|
|
66
87
|
readonly base: number;
|
|
67
|
-
|
|
88
|
+
protected isConst: boolean;
|
|
68
89
|
constructor(mem: IWasmMemoryAccess, base: number, isConst?: boolean);
|
|
69
90
|
/**
|
|
70
91
|
* Returns string start address (deref'd pointer).
|
|
@@ -81,10 +102,11 @@ export declare class WasmStringPtr implements ReadonlyWasmString {
|
|
|
81
102
|
*/
|
|
82
103
|
deref(): string;
|
|
83
104
|
/**
|
|
84
|
-
* If given a JS string as arg (and if
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* the new one
|
|
105
|
+
* If given a JS string as arg (and if this `WasmStringPtr` instance itself
|
|
106
|
+
* is not a `const` pointer), attempts to overwrite this wrapped string's
|
|
107
|
+
* memory with bytes from given string. If given another
|
|
108
|
+
* {@link WasmStringPtr}, it merely overrides the pointer to the new one
|
|
109
|
+
* (always succeeds).
|
|
88
110
|
*
|
|
89
111
|
* @remarks
|
|
90
112
|
* Unlike with {@link WasmStringSlice.set} this implementation which
|
|
@@ -100,6 +122,17 @@ export declare class WasmStringPtr implements ReadonlyWasmString {
|
|
|
100
122
|
* @param str
|
|
101
123
|
*/
|
|
102
124
|
set(str: string | WasmStringPtr): void;
|
|
125
|
+
/**
|
|
126
|
+
* Encodes given string to UTF-8 (by default zero terminated), allocates
|
|
127
|
+
* memory for it, updates this pointer to new address and returns allocated
|
|
128
|
+
* {@link MemorySlice}.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* See {@link WasmStringSlice.setAlloc} for important details.
|
|
132
|
+
*
|
|
133
|
+
* @param str
|
|
134
|
+
*/
|
|
135
|
+
setAlloc(str: string): MemorySlice;
|
|
103
136
|
toJSON(): string;
|
|
104
137
|
toString(): string;
|
|
105
138
|
valueOf(): string;
|
package/string.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
+
import { isNumber } from "@thi.ng/checks/is-number";
|
|
1
2
|
import { unsupported } from "@thi.ng/errors/unsupported";
|
|
2
3
|
/**
|
|
3
4
|
* Memory mapped string wrapper for Zig-style UTF-8 encoded byte slices (aka
|
|
4
5
|
* pointer & length pair). The actual JS string can be obtained via
|
|
5
|
-
* {@link WasmStringSlice.deref} and mutated via
|
|
6
|
+
* {@link WasmStringSlice.deref} and possibly mutated via
|
|
7
|
+
* {@link WasmStringSlice.set}.
|
|
6
8
|
*
|
|
7
9
|
* @remarks
|
|
8
10
|
* Currently only supports wasm32 target, need alt. solution for 64bit (possibly
|
|
9
11
|
* diff implementation) using bigint addresses (TODO)
|
|
10
12
|
*/
|
|
11
13
|
export class WasmStringSlice {
|
|
12
|
-
constructor(mem, base, isConst = true) {
|
|
14
|
+
constructor(mem, base, isConst = true, terminated = true) {
|
|
13
15
|
this.mem = mem;
|
|
14
16
|
this.base = base;
|
|
15
17
|
this.isConst = isConst;
|
|
16
|
-
this.
|
|
18
|
+
this.terminated = terminated;
|
|
19
|
+
this.maxLen = this.length;
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* Returns string start address (deref'd pointer).
|
|
@@ -58,23 +61,44 @@ export class WasmStringSlice {
|
|
|
58
61
|
if (typeof str === "string") {
|
|
59
62
|
if (this.isConst)
|
|
60
63
|
unsupported("can't mutate const string");
|
|
61
|
-
this.mem.u32[(this.base + 4) >>> 2] = this.mem.setString(str, this.addr, this.
|
|
64
|
+
this.mem.u32[(this.base + 4) >>> 2] = this.mem.setString(str, this.addr, this.maxLen + ~~this.terminated, this.terminated);
|
|
62
65
|
}
|
|
63
66
|
else {
|
|
64
67
|
this.mem.u32[this.base >>> 2] = str.addr;
|
|
65
68
|
this.mem.u32[(this.base + 4) >>> 2] = str.length;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
71
|
+
setSlice(...args) {
|
|
72
|
+
this.mem.ensureMemory();
|
|
73
|
+
const [slice, terminated] = ((isNumber(args[0])
|
|
74
|
+
? [[args[0], args[1]], args[2]]
|
|
75
|
+
: [args[0], args[1]]));
|
|
76
|
+
this.mem.u32[this.base >>> 2] = slice[0];
|
|
77
|
+
this.mem.u32[(this.base + 4) >>> 2] = slice[1];
|
|
78
|
+
this.terminated = terminated;
|
|
79
|
+
return slice;
|
|
80
|
+
}
|
|
68
81
|
/**
|
|
69
|
-
*
|
|
82
|
+
* Encodes given string to UTF-8 (by default zero terminated), allocates
|
|
83
|
+
* memory for it, updates this slice and returns a {@link MemorySlice} of
|
|
84
|
+
* the allocated region.
|
|
70
85
|
*
|
|
71
|
-
* @
|
|
72
|
-
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* If `terminated` is true, the stored slice length will **NOT** include the
|
|
88
|
+
* sentinel! E.g. the slice length of zero-terminated string `"abc"` is 3,
|
|
89
|
+
* but the number of allocated bytes is 4. This is done for compatibility
|
|
90
|
+
* with Zig's sentinel-terminated slice handling (e.g. `[:0]u8` slices).
|
|
91
|
+
*
|
|
92
|
+
* Regardless of `terminated` setting, the returned `MemorySlice` **always**
|
|
93
|
+
* covers the entire allocated region!
|
|
94
|
+
*
|
|
95
|
+
* @param str
|
|
96
|
+
* @param terminate
|
|
73
97
|
*/
|
|
74
|
-
|
|
75
|
-
this.mem
|
|
76
|
-
this.
|
|
77
|
-
|
|
98
|
+
setAlloc(str, terminate = true) {
|
|
99
|
+
const slice = __alloc(this.mem, str, terminate);
|
|
100
|
+
this.setSlice(terminate ? [slice[0], slice[1] - 1] : slice, terminate);
|
|
101
|
+
return slice;
|
|
78
102
|
}
|
|
79
103
|
toJSON() {
|
|
80
104
|
return this.deref();
|
|
@@ -87,8 +111,8 @@ export class WasmStringSlice {
|
|
|
87
111
|
}
|
|
88
112
|
}
|
|
89
113
|
/**
|
|
90
|
-
* Memory mapped string wrapper for C-style UTF-8 encoded and
|
|
91
|
-
* char pointers. The actual JS string can be obtained via
|
|
114
|
+
* Memory mapped string wrapper for C-style UTF-8 encoded and **always**
|
|
115
|
+
* zero-terminated char pointers. The actual JS string can be obtained via
|
|
92
116
|
* {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
|
|
93
117
|
*/
|
|
94
118
|
export class WasmStringPtr {
|
|
@@ -124,10 +148,11 @@ export class WasmStringPtr {
|
|
|
124
148
|
return this.mem.getString(this.addr, this.length);
|
|
125
149
|
}
|
|
126
150
|
/**
|
|
127
|
-
* If given a JS string as arg (and if
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* the new one
|
|
151
|
+
* If given a JS string as arg (and if this `WasmStringPtr` instance itself
|
|
152
|
+
* is not a `const` pointer), attempts to overwrite this wrapped string's
|
|
153
|
+
* memory with bytes from given string. If given another
|
|
154
|
+
* {@link WasmStringPtr}, it merely overrides the pointer to the new one
|
|
155
|
+
* (always succeeds).
|
|
131
156
|
*
|
|
132
157
|
* @remarks
|
|
133
158
|
* Unlike with {@link WasmStringSlice.set} this implementation which
|
|
@@ -152,8 +177,24 @@ export class WasmStringPtr {
|
|
|
152
177
|
}
|
|
153
178
|
else {
|
|
154
179
|
this.addr = str.addr;
|
|
180
|
+
this.isConst = str.isConst;
|
|
155
181
|
}
|
|
156
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Encodes given string to UTF-8 (by default zero terminated), allocates
|
|
185
|
+
* memory for it, updates this pointer to new address and returns allocated
|
|
186
|
+
* {@link MemorySlice}.
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* See {@link WasmStringSlice.setAlloc} for important details.
|
|
190
|
+
*
|
|
191
|
+
* @param str
|
|
192
|
+
*/
|
|
193
|
+
setAlloc(str) {
|
|
194
|
+
const slice = __alloc(this.mem, str, true);
|
|
195
|
+
this.mem.u32[this.base >>> 2] = slice[0];
|
|
196
|
+
return slice;
|
|
197
|
+
}
|
|
157
198
|
toJSON() {
|
|
158
199
|
return this.deref();
|
|
159
200
|
}
|
|
@@ -164,3 +205,12 @@ export class WasmStringPtr {
|
|
|
164
205
|
return this.deref();
|
|
165
206
|
}
|
|
166
207
|
}
|
|
208
|
+
const __alloc = (mem, str, terminate) => {
|
|
209
|
+
const buf = new TextEncoder().encode(str);
|
|
210
|
+
const slice = mem.allocate(buf.length + ~~terminate);
|
|
211
|
+
if (slice[1] > 0) {
|
|
212
|
+
mem.u8.set(buf, slice[0]);
|
|
213
|
+
terminate && (mem.u8[slice[0] + buf.length] = 0);
|
|
214
|
+
}
|
|
215
|
+
return slice;
|
|
216
|
+
};
|
package/zig/lib.zig
CHANGED
|
@@ -2,38 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const std = @import("std");
|
|
4
4
|
const root = @import("root");
|
|
5
|
+
const types = @import("types.zig");
|
|
5
6
|
|
|
6
|
-
pub
|
|
7
|
-
|
|
8
|
-
/// Higher-order slice wrapper for extern struct use cases
|
|
9
|
-
/// S = slice type
|
|
10
|
-
/// P = pointer type
|
|
11
|
-
/// default = point default value
|
|
12
|
-
pub fn Slice(comptime S: type, comptime P: type, comptime default: P) type {
|
|
13
|
-
return extern struct {
|
|
14
|
-
ptr: P = default,
|
|
15
|
-
len: usize = 0,
|
|
16
|
-
|
|
17
|
-
pub fn wrap(slice: S) @This() {
|
|
18
|
-
return .{
|
|
19
|
-
.ptr = @ptrCast(P, slice.ptr),
|
|
20
|
-
.len = slice.len,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
pub fn toSlice(self: *@This()) S {
|
|
25
|
-
return @ptrCast(*S, self).*;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
7
|
+
pub usingnamespace types;
|
|
29
8
|
|
|
30
|
-
|
|
31
|
-
const String = Slice([]const u8, [*:0]const u8, "");
|
|
32
|
-
|
|
33
|
-
/// Syntax sugar for `String.wrap()`
|
|
34
|
-
pub fn string(str: []const u8) String {
|
|
35
|
-
return String.wrap(str);
|
|
36
|
-
}
|
|
9
|
+
pub const ManagedIndex = @import("managed-index.zig").ManagedIndex;
|
|
37
10
|
|
|
38
11
|
/// Similar to @ptrCast intrinsic. Helper function to cast & re-align an
|
|
39
12
|
/// optional `anyopaque` pointer to another given pointer type.
|
|
@@ -197,8 +170,10 @@ pub fn printF64Array(buf: []const f64) void {
|
|
|
197
170
|
_printF64Array(buf.ptr, buf.len);
|
|
198
171
|
}
|
|
199
172
|
|
|
173
|
+
pub extern "wasmapi" fn printHexdump(addr: *const anyopaque, len: usize) void;
|
|
174
|
+
|
|
200
175
|
/// Prints a zero-terminated string using configured JS logger
|
|
201
|
-
pub extern "wasmapi" fn
|
|
176
|
+
pub extern "wasmapi" fn printStrZ(addr: [*:0]const u8) void;
|
|
202
177
|
/// Prints a string of given length using configured JS logger
|
|
203
178
|
pub extern "wasmapi" fn _printStr(addr: [*]const u8, len: usize) void;
|
|
204
179
|
/// Convenience wrapper for _printStr, accepting a slice as arg
|
package/zig/types.zig
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
}
|
package/bin/wasm-api
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
# https://stackoverflow.com/a/246128/294515
|
|
4
|
-
SOURCE="${BASH_SOURCE[0]}"
|
|
5
|
-
while [ -h "$SOURCE" ]; do
|
|
6
|
-
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
7
|
-
SOURCE="$(readlink "$SOURCE")"
|
|
8
|
-
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
9
|
-
done
|
|
10
|
-
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
|
|
11
|
-
|
|
12
|
-
/usr/bin/env node "$DIR/../cli.js" "$DIR" "$@"
|
package/bin/wasm-api.mjs_
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { spawn } from "child_process";
|
|
4
|
-
import { realpathSync } from "fs";
|
|
5
|
-
import { join } from "path";
|
|
6
|
-
const [node, toolsDir, ...args] = process.argv;
|
|
7
|
-
|
|
8
|
-
const cli = join(realpathSync(toolsDir), "..", "..", "cli.js");
|
|
9
|
-
|
|
10
|
-
const child = spawn(node, ["--loader", "ts-node/esm", cli, ...args]);
|
|
11
|
-
|
|
12
|
-
child.stderr.on("data", (d) => {
|
|
13
|
-
const dStr = d.toString().trim();
|
|
14
|
-
!dStr.includes("ExperimentalWarning") ? console.log(dStr) : "";
|
|
15
|
-
});
|
|
16
|
-
child.on("exit", (err) => process.exit(err));
|
|
17
|
-
child.stdout.pipe(process.stdout);
|