@thi.ng/wasm-api 0.14.0 → 0.15.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 +36 -1
- package/README.md +173 -108
- package/api.d.ts +78 -21
- package/api.js +10 -4
- package/cli.js +6 -2
- package/codegen/align.d.ts +14 -0
- package/codegen/align.js +35 -0
- package/codegen/c11.js +71 -55
- package/codegen/typescript.js +14 -11
- package/codegen/utils.d.ts +12 -4
- package/codegen/utils.js +8 -0
- package/codegen/zig.js +93 -69
- package/codegen.d.ts +2 -1
- package/codegen.js +77 -54
- package/package.json +13 -9
- package/string.d.ts +4 -0
- package/string.js +4 -0
- package/zig/managed-index.zig +223 -0
- package/{include → zig}/wasmapi.zig +2 -0
package/codegen/zig.js
CHANGED
|
@@ -2,7 +2,7 @@ import { isNumber } from "@thi.ng/checks/is-number";
|
|
|
2
2
|
import { isString } from "@thi.ng/checks/is-string";
|
|
3
3
|
import { unsupported } from "@thi.ng/errors/unsupported";
|
|
4
4
|
import { split } from "@thi.ng/strings/split";
|
|
5
|
-
import { enumName, isPadding, isStringSlice, prefixLines, withIndentation, } from "./utils.js";
|
|
5
|
+
import { enumName, isPadding, isStringSlice, isWasmString, prefixLines, withIndentation, } from "./utils.js";
|
|
6
6
|
/**
|
|
7
7
|
* Zig code generator. Call with options and then pass to {@link generateTypes}
|
|
8
8
|
* (see its docs for further usage).
|
|
@@ -45,75 +45,99 @@ export const ZIG = (opts = {}) => {
|
|
|
45
45
|
acc.push(...withIndentation(lines, INDENT, ...SCOPES));
|
|
46
46
|
},
|
|
47
47
|
struct: (struct, _, acc, opts) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
f.doc && gen.doc(f.doc, res, opts);
|
|
60
|
-
let ftype = f.type === "string"
|
|
61
|
-
? isStringSlice(opts.stringType)
|
|
62
|
-
? f.const !== false
|
|
63
|
-
? "[]const u8"
|
|
64
|
-
: "[]u8"
|
|
65
|
-
: f.const !== false
|
|
66
|
-
? "[*:0]const u8"
|
|
67
|
-
: "[*:0]u8"
|
|
68
|
-
: f.type;
|
|
69
|
-
let defaultVal = "";
|
|
70
|
-
switch (f.tag) {
|
|
71
|
-
case "array":
|
|
72
|
-
ftype =
|
|
73
|
-
f.sentinel !== undefined
|
|
74
|
-
? `[${f.len}:${f.sentinel}]${ftype}`
|
|
75
|
-
: `[${f.len}]${ftype}`;
|
|
76
|
-
break;
|
|
77
|
-
case "slice":
|
|
78
|
-
ftype = `[${f.sentinel !== undefined ? ":" + f.sentinel : ""}]${f.const ? "const " : ""}${ftype}`;
|
|
79
|
-
break;
|
|
80
|
-
case "vec":
|
|
81
|
-
ftype = `@Vector(${f.len}, ${ftype})`;
|
|
82
|
-
break;
|
|
83
|
-
case "ptr":
|
|
84
|
-
ftype = `*${f.const ? "const " : ""}${f.len ? `[${f.len}]` : ""}${ftype}`;
|
|
85
|
-
break;
|
|
86
|
-
case "scalar":
|
|
87
|
-
default:
|
|
88
|
-
if (f.default != undefined) {
|
|
89
|
-
if (!(isString(f.default) || isNumber(f.default))) {
|
|
90
|
-
unsupported(`wrong default value for ${name}.${f.name} (${f.default})`);
|
|
91
|
-
}
|
|
92
|
-
defaultVal = ` = ${JSON.stringify(f.default)}`;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
ftypes[f.name] = ftype;
|
|
96
|
-
res.push(`${f.name}: ${ftype}${defaultVal},`);
|
|
97
|
-
}
|
|
98
|
-
if (struct.body?.zig) {
|
|
99
|
-
res.push("", ...split(struct.body.zig), "");
|
|
100
|
-
}
|
|
101
|
-
res.push("};");
|
|
102
|
-
if (opts.debug) {
|
|
103
|
-
const fn = (fname, body) => res.push("", `export fn ${name}_${fname}() usize {`, `return ${body};`, `}`);
|
|
104
|
-
fn("align", `@alignOf(${name})`);
|
|
105
|
-
fn("size", `@sizeOf(${name})`);
|
|
106
|
-
for (let f of struct.fields) {
|
|
107
|
-
if (isPadding(f))
|
|
108
|
-
continue;
|
|
109
|
-
fn(f.name + "_align", `@alignOf(${ftypes[f.name]})`);
|
|
110
|
-
fn(f.name + "_offset", `@offsetOf(${name}, "${f.name}")`);
|
|
111
|
-
fn(f.name + "_size", `@sizeOf(${ftypes[f.name]})`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
res.push("");
|
|
115
|
-
acc.push(...withIndentation(res, INDENT, ...SCOPES));
|
|
48
|
+
acc.push(...withIndentation([
|
|
49
|
+
`pub const ${struct.name} = ${struct.tag ? struct.tag + " " : ""}struct {`,
|
|
50
|
+
...__generateFields(gen, struct, opts),
|
|
51
|
+
], INDENT, ...SCOPES));
|
|
52
|
+
},
|
|
53
|
+
union: (union, _, acc, opts) => {
|
|
54
|
+
acc.push(...withIndentation([
|
|
55
|
+
`pub const ${union.name} = ${union.tag ? union.tag + " " : ""}union {`,
|
|
56
|
+
...__generateFields(gen, union, opts),
|
|
57
|
+
], INDENT, ...SCOPES));
|
|
116
58
|
},
|
|
117
59
|
};
|
|
118
60
|
return gen;
|
|
119
61
|
};
|
|
62
|
+
const __generateFields = (gen, parent, opts) => {
|
|
63
|
+
const res = [];
|
|
64
|
+
const ftypes = {};
|
|
65
|
+
const isUnion = parent.type === "union";
|
|
66
|
+
const name = parent.name;
|
|
67
|
+
let padID = 0;
|
|
68
|
+
for (let f of parent.fields) {
|
|
69
|
+
// autolabel explicit padding fields
|
|
70
|
+
if (isPadding(f)) {
|
|
71
|
+
parent.tag === "packed"
|
|
72
|
+
? __packedPadding(padID, f.pad, res)
|
|
73
|
+
: res.push(`__pad${padID}: [${f.pad}]u8,`);
|
|
74
|
+
padID++;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
f.doc && gen.doc(f.doc, res, opts);
|
|
78
|
+
let ftype = isWasmString(f.type)
|
|
79
|
+
? isStringSlice(opts.stringType)
|
|
80
|
+
? f.const !== false
|
|
81
|
+
? "[]const u8"
|
|
82
|
+
: "[]u8"
|
|
83
|
+
: f.const !== false
|
|
84
|
+
? "[*:0]const u8"
|
|
85
|
+
: "[*:0]u8"
|
|
86
|
+
: f.type;
|
|
87
|
+
let defaultVal = "";
|
|
88
|
+
switch (f.tag) {
|
|
89
|
+
case "array":
|
|
90
|
+
ftype =
|
|
91
|
+
f.sentinel !== undefined
|
|
92
|
+
? `[${f.len}:${f.sentinel}]${ftype}`
|
|
93
|
+
: `[${f.len}]${ftype}`;
|
|
94
|
+
break;
|
|
95
|
+
case "slice":
|
|
96
|
+
ftype = `[${f.sentinel !== undefined ? ":" + f.sentinel : ""}]${f.const ? "const " : ""}${ftype}`;
|
|
97
|
+
break;
|
|
98
|
+
case "vec":
|
|
99
|
+
ftype = `@Vector(${f.len}, ${ftype})`;
|
|
100
|
+
break;
|
|
101
|
+
case "ptr":
|
|
102
|
+
ftype = `*${f.const ? "const " : ""}${f.len ? `[${f.len}]` : ""}${ftype}`;
|
|
103
|
+
break;
|
|
104
|
+
case "scalar":
|
|
105
|
+
default:
|
|
106
|
+
if (f.default != undefined) {
|
|
107
|
+
if (!(isString(f.default) || isNumber(f.default))) {
|
|
108
|
+
unsupported(`wrong default value for ${name}.${f.name} (${f.default})`);
|
|
109
|
+
}
|
|
110
|
+
defaultVal = ` = ${JSON.stringify(f.default)}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
ftypes[f.name] = ftype;
|
|
114
|
+
res.push(`${f.name}: ${ftype}${defaultVal},`);
|
|
115
|
+
}
|
|
116
|
+
if (parent.body?.zig) {
|
|
117
|
+
res.push("", ...split(parent.body.zig), "");
|
|
118
|
+
}
|
|
119
|
+
res.push("};");
|
|
120
|
+
if (opts.debug) {
|
|
121
|
+
const fn = (fname, body) => res.push("", `export fn ${name}_${fname}() usize {`, `return ${body};`, `}`);
|
|
122
|
+
fn("align", `@alignOf(${name})`);
|
|
123
|
+
fn("size", `@sizeOf(${name})`);
|
|
124
|
+
for (let f of parent.fields) {
|
|
125
|
+
if (isPadding(f))
|
|
126
|
+
continue;
|
|
127
|
+
fn(f.name + "_align", `@alignOf(${ftypes[f.name]})`);
|
|
128
|
+
!isUnion &&
|
|
129
|
+
fn(f.name + "_offset", `@offsetOf(${name}, "${f.name}")`);
|
|
130
|
+
fn(f.name + "_size", `@sizeOf(${ftypes[f.name]})`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
res.push("");
|
|
134
|
+
return res;
|
|
135
|
+
};
|
|
136
|
+
const __packedPadding = (id, n, res) => {
|
|
137
|
+
let i = 0;
|
|
138
|
+
n <<= 3;
|
|
139
|
+
for (; n >= 128; n -= 128, i++) {
|
|
140
|
+
res.push(`__pad${id}_${i}: u128,`);
|
|
141
|
+
}
|
|
142
|
+
res.push(`__pad${id}_${i}: u${n},`);
|
|
143
|
+
};
|
package/codegen.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CodeGenOpts, ICodeGen, TypeColl } from "./api.js";
|
|
2
|
+
export declare const DEFAULT_CODEGEN_OPTS: CodeGenOpts;
|
|
2
3
|
/**
|
|
3
4
|
* Takes a type collection and analyzes each analyzed to compute individual
|
|
4
5
|
* alignments and sizes.
|
|
@@ -11,7 +12,7 @@ import { CodeGenOpts, ICodeGen, TypeColl } from "./api.js";
|
|
|
11
12
|
*
|
|
12
13
|
* @internal
|
|
13
14
|
*/
|
|
14
|
-
export declare const prepareTypes: (types: TypeColl, opts: CodeGenOpts) =>
|
|
15
|
+
export declare const prepareTypes: (types: TypeColl, opts: CodeGenOpts) => TypeColl;
|
|
15
16
|
/**
|
|
16
17
|
* Code generator main entry point. Takes an object of {@link TopLevelType}
|
|
17
18
|
* definitions, an actual code generator implementation for a single target
|
package/codegen.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { SIZEOF } from "@thi.ng/api/typedarray";
|
|
2
|
-
import { align } from "@thi.ng/binary/align";
|
|
3
|
-
import { ceilPow2 } from "@thi.ng/binary/pow";
|
|
4
2
|
import { compareByKey } from "@thi.ng/compare/keys";
|
|
5
3
|
import { compareNumDesc } from "@thi.ng/compare/numeric";
|
|
6
4
|
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
|
|
7
5
|
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
8
|
-
import { PKG_NAME,
|
|
9
|
-
import {
|
|
6
|
+
import { PKG_NAME, WASM32, } from "./api.js";
|
|
7
|
+
import { selectAlignment } from "./codegen/align.js";
|
|
8
|
+
import { isBigNumeric, isNumeric, isPointer, isPointerLike, isSlice, isStringSlice, isWasmString, } from "./codegen/utils.js";
|
|
9
|
+
export const DEFAULT_CODEGEN_OPTS = {
|
|
10
|
+
debug: false,
|
|
11
|
+
header: true,
|
|
12
|
+
lineWidth: 80,
|
|
13
|
+
stringType: "slice",
|
|
14
|
+
target: WASM32,
|
|
15
|
+
uppercaseEnums: true,
|
|
16
|
+
};
|
|
10
17
|
const sizeOf = defmulti((x) => x.type, {}, {
|
|
11
|
-
[DEFAULT]: (field, types, opts) => {
|
|
18
|
+
[DEFAULT]: (field, types, align, opts) => {
|
|
12
19
|
if (field.__size)
|
|
13
20
|
return field.__size;
|
|
14
21
|
if (field.pad != null) {
|
|
@@ -16,18 +23,20 @@ const sizeOf = defmulti((x) => x.type, {}, {
|
|
|
16
23
|
return (field.__size = field.pad);
|
|
17
24
|
}
|
|
18
25
|
let size = 0;
|
|
19
|
-
if (field
|
|
20
|
-
size =
|
|
26
|
+
if (isPointer(field)) {
|
|
27
|
+
size = opts.target.usizeBytes;
|
|
21
28
|
}
|
|
22
|
-
else if (field
|
|
23
|
-
size =
|
|
29
|
+
else if (isSlice(field)) {
|
|
30
|
+
size = opts.target.usizeBytes * 2;
|
|
24
31
|
}
|
|
25
32
|
else {
|
|
26
|
-
size =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
size =
|
|
34
|
+
isNumeric(field.type) || isBigNumeric(field.type)
|
|
35
|
+
? SIZEOF[field.type]
|
|
36
|
+
: isWasmString(field.type)
|
|
37
|
+
? opts.target.usizeBytes *
|
|
38
|
+
(isStringSlice(opts.stringType) ? 2 : 1)
|
|
39
|
+
: sizeOf(types[field.type], types, align, opts);
|
|
31
40
|
if (field.tag == "array" || field.tag === "vec") {
|
|
32
41
|
size *= field.len;
|
|
33
42
|
if (field.sentinel !== undefined && field.tag === "array") {
|
|
@@ -35,79 +44,95 @@ const sizeOf = defmulti((x) => x.type, {}, {
|
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
}
|
|
38
|
-
return (field.__size = align(size, field.__align));
|
|
47
|
+
return (field.__size = align.size(size, field.__align));
|
|
39
48
|
},
|
|
40
49
|
enum: (type) => {
|
|
41
50
|
if (type.__size)
|
|
42
51
|
return type.__size;
|
|
43
52
|
return (type.__size = SIZEOF[type.tag]);
|
|
44
53
|
},
|
|
45
|
-
struct: (type, types, opts) => {
|
|
54
|
+
struct: (type, types, align, opts) => {
|
|
46
55
|
if (type.__size)
|
|
47
56
|
return type.__size;
|
|
48
|
-
|
|
49
|
-
let
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
f
|
|
53
|
-
|
|
57
|
+
let offset = 0;
|
|
58
|
+
for (let f of type.fields) {
|
|
59
|
+
offset = align.offset(offset, f.__align);
|
|
60
|
+
f.__offset = offset;
|
|
61
|
+
offset += sizeOf(f, types, align, opts);
|
|
62
|
+
}
|
|
63
|
+
return (type.__size = align.size(offset, type.__align));
|
|
64
|
+
},
|
|
65
|
+
union: (type, types, align, opts) => {
|
|
66
|
+
if (type.__size)
|
|
67
|
+
return type.__size;
|
|
68
|
+
let maxSize = 0;
|
|
69
|
+
for (let f of type.fields) {
|
|
70
|
+
f.__offset = 0;
|
|
71
|
+
maxSize = Math.max(maxSize, sizeOf(f, types, align, opts));
|
|
54
72
|
}
|
|
55
|
-
return (type.__size = align(
|
|
73
|
+
return (type.__size = align.size(maxSize, type.__align));
|
|
56
74
|
},
|
|
57
75
|
});
|
|
58
76
|
const alignOf = defmulti((x) => x.type, {}, {
|
|
59
|
-
[DEFAULT]: (field, types) => {
|
|
77
|
+
[DEFAULT]: (field, types, align, opts) => {
|
|
60
78
|
if (field.__align)
|
|
61
79
|
return field.__align;
|
|
80
|
+
if (field.type === "usize") {
|
|
81
|
+
field.type = opts.target.usize;
|
|
82
|
+
}
|
|
62
83
|
if (field.pad)
|
|
63
84
|
return (field.__align = 1);
|
|
64
|
-
|
|
65
|
-
?
|
|
66
|
-
:
|
|
67
|
-
?
|
|
68
|
-
: alignOf(types[field.type], types);
|
|
69
|
-
if (field.tag === "vec") {
|
|
70
|
-
align *= ceilPow2(field.len);
|
|
71
|
-
}
|
|
72
|
-
field.__align = align;
|
|
73
|
-
return align;
|
|
85
|
+
return (field.__align = isPointerLike(field)
|
|
86
|
+
? align.align({ type: opts.target.usize })
|
|
87
|
+
: isNumeric(field.type) || isBigNumeric(field.type)
|
|
88
|
+
? align.align(field)
|
|
89
|
+
: alignOf(types[field.type], types, selectAlignment(types[field.type]), opts));
|
|
74
90
|
},
|
|
75
|
-
enum: (type) => {
|
|
91
|
+
enum: (type, _, align) => {
|
|
76
92
|
const e = type;
|
|
77
93
|
if (!e.tag)
|
|
78
94
|
e.tag = "i32";
|
|
79
|
-
return (e.__align =
|
|
95
|
+
return (e.__align = align.align({
|
|
96
|
+
type: e.tag,
|
|
97
|
+
}));
|
|
80
98
|
},
|
|
81
|
-
struct: (type, types) => {
|
|
82
|
-
|
|
83
|
-
let
|
|
84
|
-
|
|
85
|
-
|
|
99
|
+
struct: (type, types, align, opts) => {
|
|
100
|
+
let maxAlign = 1;
|
|
101
|
+
for (let f of type.fields) {
|
|
102
|
+
maxAlign = Math.max(maxAlign, alignOf(f, types, align, opts));
|
|
103
|
+
}
|
|
104
|
+
return (type.__align = maxAlign);
|
|
105
|
+
},
|
|
106
|
+
union: (type, types, align, opts) => {
|
|
107
|
+
let maxAlign = 1;
|
|
108
|
+
for (let f of type.fields) {
|
|
109
|
+
maxAlign = Math.max(maxAlign, alignOf(f, types, align, opts));
|
|
86
110
|
}
|
|
87
111
|
return (type.__align = maxAlign);
|
|
88
112
|
},
|
|
89
113
|
});
|
|
90
114
|
const prepareType = defmulti((x) => x.type, {}, {
|
|
91
|
-
[DEFAULT]: (x, types, opts) => {
|
|
115
|
+
[DEFAULT]: (x, types, alignImpl, opts) => {
|
|
92
116
|
if (x.__align && x.__size)
|
|
93
117
|
return;
|
|
94
|
-
alignOf(x, types);
|
|
95
|
-
sizeOf(x, types, opts);
|
|
118
|
+
alignOf(x, types, alignImpl, opts);
|
|
119
|
+
sizeOf(x, types, alignImpl, opts);
|
|
96
120
|
},
|
|
97
|
-
struct: (x, types, opts) => {
|
|
121
|
+
struct: (x, types, align, opts) => {
|
|
98
122
|
if (x.__align && x.__size)
|
|
99
123
|
return;
|
|
100
124
|
const struct = x;
|
|
101
|
-
alignOf(struct, types);
|
|
125
|
+
alignOf(struct, types, align, opts);
|
|
102
126
|
if (struct.auto) {
|
|
103
127
|
struct.fields.sort(compareByKey("__align", compareNumDesc));
|
|
104
128
|
}
|
|
105
129
|
for (let f of struct.fields) {
|
|
106
|
-
|
|
107
|
-
|
|
130
|
+
const type = types[f.type];
|
|
131
|
+
if (type) {
|
|
132
|
+
prepareType(type, types, selectAlignment(type), opts);
|
|
108
133
|
}
|
|
109
134
|
}
|
|
110
|
-
sizeOf(struct, types, opts);
|
|
135
|
+
sizeOf(struct, types, align, opts);
|
|
111
136
|
},
|
|
112
137
|
});
|
|
113
138
|
/**
|
|
@@ -124,8 +149,9 @@ const prepareType = defmulti((x) => x.type, {}, {
|
|
|
124
149
|
*/
|
|
125
150
|
export const prepareTypes = (types, opts) => {
|
|
126
151
|
for (let id in types) {
|
|
127
|
-
prepareType(types[id], types, opts);
|
|
152
|
+
prepareType(types[id], types, selectAlignment(types[id]), opts);
|
|
128
153
|
}
|
|
154
|
+
return types;
|
|
129
155
|
};
|
|
130
156
|
/**
|
|
131
157
|
* Code generator main entry point. Takes an object of {@link TopLevelType}
|
|
@@ -144,10 +170,7 @@ export const prepareTypes = (types, opts) => {
|
|
|
144
170
|
*/
|
|
145
171
|
export const generateTypes = (types, codegen, opts = {}) => {
|
|
146
172
|
const $opts = {
|
|
147
|
-
|
|
148
|
-
stringType: "slice",
|
|
149
|
-
uppercaseEnums: true,
|
|
150
|
-
lineWidth: 80,
|
|
173
|
+
...DEFAULT_CODEGEN_OPTS,
|
|
151
174
|
...opts,
|
|
152
175
|
};
|
|
153
176
|
prepareTypes(types, $opts);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/wasm-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.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",
|
|
@@ -33,21 +33,21 @@
|
|
|
33
33
|
"doc:stats": "tools:module-stats",
|
|
34
34
|
"pub": "yarn npm publish --access public",
|
|
35
35
|
"test": "testament test",
|
|
36
|
-
"test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi
|
|
36
|
+
"test:build-zig": "zig build-lib -O ReleaseSmall -target wasm32-freestanding -dynamic --strip --pkg-begin wasmapi zig/wasmapi.zig --pkg-end test/custom.zig && wasm-dis -o custom.wast custom.wasm && cp custom.wasm test"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@thi.ng/api": "^8.4.3",
|
|
40
|
-
"@thi.ng/args": "^2.2.
|
|
41
|
-
"@thi.ng/binary": "^3.3.
|
|
42
|
-
"@thi.ng/checks": "^3.3.
|
|
40
|
+
"@thi.ng/args": "^2.2.6",
|
|
41
|
+
"@thi.ng/binary": "^3.3.7",
|
|
42
|
+
"@thi.ng/checks": "^3.3.1",
|
|
43
43
|
"@thi.ng/compare": "^2.1.13",
|
|
44
44
|
"@thi.ng/defmulti": "^2.1.18",
|
|
45
45
|
"@thi.ng/errors": "^2.2.2",
|
|
46
|
-
"@thi.ng/file-io": "^0.3.
|
|
46
|
+
"@thi.ng/file-io": "^0.3.16",
|
|
47
47
|
"@thi.ng/hex": "^2.2.1",
|
|
48
48
|
"@thi.ng/idgen": "^2.1.15",
|
|
49
49
|
"@thi.ng/logger": "^1.4.1",
|
|
50
|
-
"@thi.ng/paths": "^5.1.
|
|
50
|
+
"@thi.ng/paths": "^5.1.19",
|
|
51
51
|
"@thi.ng/strings": "^3.3.14"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
@@ -96,7 +96,8 @@
|
|
|
96
96
|
"*.d.ts",
|
|
97
97
|
"bin",
|
|
98
98
|
"codegen",
|
|
99
|
-
"include"
|
|
99
|
+
"include",
|
|
100
|
+
"zig"
|
|
100
101
|
],
|
|
101
102
|
"exports": {
|
|
102
103
|
".": {
|
|
@@ -108,6 +109,9 @@
|
|
|
108
109
|
"./bridge": {
|
|
109
110
|
"default": "./bridge.js"
|
|
110
111
|
},
|
|
112
|
+
"./codegen/align": {
|
|
113
|
+
"default": "./codegen/align.js"
|
|
114
|
+
},
|
|
111
115
|
"./codegen/c11": {
|
|
112
116
|
"default": "./codegen/c11.js"
|
|
113
117
|
},
|
|
@@ -137,5 +141,5 @@
|
|
|
137
141
|
"status": "alpha",
|
|
138
142
|
"year": 2022
|
|
139
143
|
},
|
|
140
|
-
"gitHead": "
|
|
144
|
+
"gitHead": "cc61bc0a890288bea00b8df81ffd73bc4851ffd3\n"
|
|
141
145
|
}
|
package/string.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { IWasmMemoryAccess, ReadonlyWasmString } from "./api.js";
|
|
|
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
5
|
* {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Currently only supports wasm32 target, need alt. solution for 64bit (possibly
|
|
9
|
+
* diff implementation) using bigint addresses (TODO)
|
|
6
10
|
*/
|
|
7
11
|
export declare class WasmStringSlice implements ReadonlyWasmString {
|
|
8
12
|
readonly mem: IWasmMemoryAccess;
|
package/string.js
CHANGED
|
@@ -3,6 +3,10 @@ import { unsupported } from "@thi.ng/errors/unsupported";
|
|
|
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
5
|
* {@link WasmStringSlice.deref} and mutated via {@link WasmStringSlice.set}.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Currently only supports wasm32 target, need alt. solution for 64bit (possibly
|
|
9
|
+
* diff implementation) using bigint addresses (TODO)
|
|
6
10
|
*/
|
|
7
11
|
export class WasmStringSlice {
|
|
8
12
|
constructor(mem, base, isConst = true) {
|