@thi.ng/wasm-api 0.18.1 → 1.0.1
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 +182 -102
- package/README.md +166 -601
- 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 +44 -42
- 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 +3 -31
- 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 -244
- 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/codegen.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { SIZEOF } from "@thi.ng/api/typedarray";
|
|
2
|
-
import { compareByKey } from "@thi.ng/compare/keys";
|
|
3
|
-
import { compareNumDesc } from "@thi.ng/compare/numeric";
|
|
4
|
-
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
|
|
5
|
-
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
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
|
-
};
|
|
17
|
-
const sizeOf = defmulti((x) => x.type, {}, {
|
|
18
|
-
[DEFAULT]: (field, types, align, opts) => {
|
|
19
|
-
if (field.__size)
|
|
20
|
-
return field.__size;
|
|
21
|
-
if (field.pad != null) {
|
|
22
|
-
field.pad < 1 && illegalArgs(`pad size must be > 0`);
|
|
23
|
-
return (field.__size = field.pad);
|
|
24
|
-
}
|
|
25
|
-
let size = 0;
|
|
26
|
-
if (isPointer(field)) {
|
|
27
|
-
size = opts.target.usizeBytes;
|
|
28
|
-
}
|
|
29
|
-
else if (isSlice(field)) {
|
|
30
|
-
size = opts.target.usizeBytes * 2;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
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);
|
|
40
|
-
if (field.tag == "array" || field.tag === "vec") {
|
|
41
|
-
size *= field.len;
|
|
42
|
-
if (field.sentinel !== undefined && field.tag === "array") {
|
|
43
|
-
size += SIZEOF[field.type];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return (field.__size = align.size(size, field.__align));
|
|
48
|
-
},
|
|
49
|
-
enum: (type) => {
|
|
50
|
-
if (type.__size)
|
|
51
|
-
return type.__size;
|
|
52
|
-
return (type.__size = SIZEOF[type.tag]);
|
|
53
|
-
},
|
|
54
|
-
struct: (type, types, align, opts) => {
|
|
55
|
-
if (type.__size)
|
|
56
|
-
return type.__size;
|
|
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));
|
|
72
|
-
}
|
|
73
|
-
return (type.__size = align.size(maxSize, type.__align));
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
const alignOf = defmulti((x) => x.type, {}, {
|
|
77
|
-
[DEFAULT]: (field, types, align, opts) => {
|
|
78
|
-
if (field.__align)
|
|
79
|
-
return field.__align;
|
|
80
|
-
if (field.type === "usize") {
|
|
81
|
-
field.type = opts.target.usize;
|
|
82
|
-
}
|
|
83
|
-
if (field.pad)
|
|
84
|
-
return (field.__align = 1);
|
|
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));
|
|
90
|
-
},
|
|
91
|
-
enum: (type, _, align) => {
|
|
92
|
-
const e = type;
|
|
93
|
-
if (!e.tag)
|
|
94
|
-
e.tag = "i32";
|
|
95
|
-
return (e.__align = align.align({
|
|
96
|
-
type: e.tag,
|
|
97
|
-
}));
|
|
98
|
-
},
|
|
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));
|
|
110
|
-
}
|
|
111
|
-
return (type.__align = maxAlign);
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
const prepareType = defmulti((x) => x.type, {}, {
|
|
115
|
-
[DEFAULT]: (x, types, alignImpl, opts) => {
|
|
116
|
-
if (x.__align)
|
|
117
|
-
return;
|
|
118
|
-
alignOf(x, types, alignImpl, opts);
|
|
119
|
-
sizeOf(x, types, alignImpl, opts);
|
|
120
|
-
},
|
|
121
|
-
struct: (x, types, align, opts) => {
|
|
122
|
-
if (x.__align)
|
|
123
|
-
return;
|
|
124
|
-
const struct = x;
|
|
125
|
-
alignOf(struct, types, align, opts);
|
|
126
|
-
if (struct.auto) {
|
|
127
|
-
struct.fields.sort(compareByKey("__align", compareNumDesc));
|
|
128
|
-
}
|
|
129
|
-
for (let f of struct.fields) {
|
|
130
|
-
const type = types[f.type];
|
|
131
|
-
if (type) {
|
|
132
|
-
prepareType(type, types, selectAlignment(type), opts);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
sizeOf(struct, types, align, opts);
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
/**
|
|
139
|
-
* Takes a type collection and analyzes each analyzed to compute individual
|
|
140
|
-
* alignments and sizes.
|
|
141
|
-
*
|
|
142
|
-
* @remarks
|
|
143
|
-
* This function is idempotent and called automatically by
|
|
144
|
-
* {@link generateTypes}. Only exported for dev/debug purposes.
|
|
145
|
-
*
|
|
146
|
-
* @param types
|
|
147
|
-
*
|
|
148
|
-
* @internal
|
|
149
|
-
*/
|
|
150
|
-
export const prepareTypes = (types, opts) => {
|
|
151
|
-
for (let id in types) {
|
|
152
|
-
prepareType(types[id], types, selectAlignment(types[id]), opts);
|
|
153
|
-
}
|
|
154
|
-
return types;
|
|
155
|
-
};
|
|
156
|
-
/**
|
|
157
|
-
* Code generator main entry point. Takes an object of {@link TopLevelType}
|
|
158
|
-
* definitions, an actual code generator implementation for a single target
|
|
159
|
-
* language and (optional) global codegen options. Returns generated source code
|
|
160
|
-
* for all given types as a single string.
|
|
161
|
-
*
|
|
162
|
-
* @remarks
|
|
163
|
-
* Before actual code generation the types are first analyzed to compute their
|
|
164
|
-
* alignments and sizes. This is only ever done once (idempotent), even if
|
|
165
|
-
* `generateTypes()` is called multiple times for different target langs.
|
|
166
|
-
*
|
|
167
|
-
* @param types
|
|
168
|
-
* @param codegen
|
|
169
|
-
* @param opts
|
|
170
|
-
*/
|
|
171
|
-
export const generateTypes = (types, codegen, opts = {}) => {
|
|
172
|
-
const $opts = {
|
|
173
|
-
...DEFAULT_CODEGEN_OPTS,
|
|
174
|
-
...opts,
|
|
175
|
-
};
|
|
176
|
-
prepareTypes(types, $opts);
|
|
177
|
-
const res = [];
|
|
178
|
-
if ($opts.header) {
|
|
179
|
-
codegen.doc(`Generated by ${PKG_NAME} at ${new Date().toISOString()} - DO NOT EDIT!`, res, $opts, true);
|
|
180
|
-
res.push("");
|
|
181
|
-
}
|
|
182
|
-
if (codegen.pre) {
|
|
183
|
-
const pre = codegen.pre($opts);
|
|
184
|
-
pre && res.push(pre, "");
|
|
185
|
-
}
|
|
186
|
-
$opts.pre && res.push($opts.pre, "");
|
|
187
|
-
for (let id in types) {
|
|
188
|
-
const type = types[id];
|
|
189
|
-
type.doc && codegen.doc(type.doc, res, $opts);
|
|
190
|
-
codegen[type.type](type, types, res, $opts);
|
|
191
|
-
}
|
|
192
|
-
$opts.post && res.push("", $opts.post);
|
|
193
|
-
if (codegen.post) {
|
|
194
|
-
const post = codegen.post($opts);
|
|
195
|
-
post && res.push("", post);
|
|
196
|
-
}
|
|
197
|
-
return res.join("\n");
|
|
198
|
-
};
|