@wasmgroundup/emit 1.0.2 → 2.1.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/index.d.ts +456 -0
- package/index.js +40 -10
- package/package.json +25 -3
- package/index.test.ts +0 -229
package/index.d.ts
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
export type Byte = number;
|
|
2
|
+
export type Bytes = readonly Byte[];
|
|
3
|
+
|
|
4
|
+
export type Fragment = readonly (Byte | Bytes | Fragment)[];
|
|
5
|
+
|
|
6
|
+
export type SectionId =
|
|
7
|
+
| typeof SECTION_ID_CUSTOM
|
|
8
|
+
| typeof SECTION_ID_TYPE
|
|
9
|
+
| typeof SECTION_ID_IMPORT
|
|
10
|
+
| typeof SECTION_ID_FUNCTION
|
|
11
|
+
| typeof SECTION_ID_TABLE
|
|
12
|
+
| typeof SECTION_ID_MEMORY
|
|
13
|
+
| typeof SECTION_ID_GLOBAL
|
|
14
|
+
| typeof SECTION_ID_EXPORT
|
|
15
|
+
| typeof SECTION_ID_START
|
|
16
|
+
| typeof SECTION_ID_ELEMENT
|
|
17
|
+
| typeof SECTION_ID_CODE
|
|
18
|
+
| typeof SECTION_ID_DATA;
|
|
19
|
+
|
|
20
|
+
declare const brand: unique symbol;
|
|
21
|
+
type Brand<T, B extends string> = T & {readonly [brand]: B};
|
|
22
|
+
|
|
23
|
+
export type typeidx = Brand<Bytes, 'typeidx'>;
|
|
24
|
+
export type funcidx = Brand<Bytes, 'funcidx'>;
|
|
25
|
+
export type localidx = Brand<Bytes, 'localidx'>;
|
|
26
|
+
export type globalidx = Brand<Bytes, 'globalidx'>;
|
|
27
|
+
export type tableidx = Brand<Bytes, 'tableidx'>;
|
|
28
|
+
export type labelidx = Brand<Bytes, 'labelidx'>;
|
|
29
|
+
export type memidx = Brand<Bytes, 'memidx'>;
|
|
30
|
+
export type idx =
|
|
31
|
+
| typeidx
|
|
32
|
+
| funcidx
|
|
33
|
+
| localidx
|
|
34
|
+
| globalidx
|
|
35
|
+
| tableidx
|
|
36
|
+
| labelidx
|
|
37
|
+
| memidx;
|
|
38
|
+
|
|
39
|
+
export function stringToBytes(s: string): Bytes;
|
|
40
|
+
|
|
41
|
+
export function magic(): Bytes;
|
|
42
|
+
export function version(): Bytes;
|
|
43
|
+
|
|
44
|
+
export function u32(v: number): Bytes;
|
|
45
|
+
export function i32(v: number): Bytes;
|
|
46
|
+
|
|
47
|
+
export function section(id: SectionId, contents: Fragment): Fragment;
|
|
48
|
+
export function vec(elements: Fragment): Fragment;
|
|
49
|
+
|
|
50
|
+
// Type section
|
|
51
|
+
// ------------
|
|
52
|
+
|
|
53
|
+
export const SECTION_ID_TYPE: 1;
|
|
54
|
+
|
|
55
|
+
export type valtype = Brand<number, 'valtype'>;
|
|
56
|
+
|
|
57
|
+
export const valtype: {
|
|
58
|
+
i32: valtype;
|
|
59
|
+
i64: valtype;
|
|
60
|
+
f32: valtype;
|
|
61
|
+
f64: valtype;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export function functype(
|
|
65
|
+
paramTypes: readonly valtype[],
|
|
66
|
+
resultTypes: readonly valtype[],
|
|
67
|
+
): Fragment;
|
|
68
|
+
|
|
69
|
+
export function typesec(functypes: readonly Fragment[]): Fragment;
|
|
70
|
+
|
|
71
|
+
// Function section and indices
|
|
72
|
+
// ----------------------------
|
|
73
|
+
|
|
74
|
+
export const SECTION_ID_FUNCTION: 3;
|
|
75
|
+
|
|
76
|
+
export function typeidx(x: number): typeidx;
|
|
77
|
+
export function funcidx(x: number): funcidx;
|
|
78
|
+
export function localidx(x: number): localidx;
|
|
79
|
+
export function labelidx(x: number): labelidx;
|
|
80
|
+
export function tableidx(x: number): tableidx;
|
|
81
|
+
export function globalidx(x: number): globalidx;
|
|
82
|
+
export function memidx(x: number): memidx;
|
|
83
|
+
|
|
84
|
+
export function funcsec(typeidxs: readonly typeidx[]): Fragment;
|
|
85
|
+
|
|
86
|
+
// Code section
|
|
87
|
+
// ------------
|
|
88
|
+
|
|
89
|
+
export const SECTION_ID_CODE: 10;
|
|
90
|
+
|
|
91
|
+
export function code(func: Fragment): Fragment;
|
|
92
|
+
|
|
93
|
+
export function func(locals: readonly Fragment[], body: Fragment): Fragment;
|
|
94
|
+
|
|
95
|
+
export function expr(instrs: readonly Fragment[]): Fragment;
|
|
96
|
+
|
|
97
|
+
export function codesec(codes: readonly Fragment[]): Fragment;
|
|
98
|
+
|
|
99
|
+
// Instructions etc.
|
|
100
|
+
// -----------------
|
|
101
|
+
|
|
102
|
+
// Autogenerated by scripts/gen_instr_type.js. Do not edit manually.
|
|
103
|
+
export const instr: {
|
|
104
|
+
readonly end: 0x0b;
|
|
105
|
+
i32: {
|
|
106
|
+
readonly const: 0x41;
|
|
107
|
+
readonly add: 0x6a;
|
|
108
|
+
readonly sub: 0x6b;
|
|
109
|
+
readonly mul: 0x6c;
|
|
110
|
+
readonly div_s: 0x6d;
|
|
111
|
+
readonly eq: 0x46;
|
|
112
|
+
readonly ne: 0x47;
|
|
113
|
+
readonly lt_s: 0x48;
|
|
114
|
+
readonly lt_u: 0x49;
|
|
115
|
+
readonly gt_s: 0x4a;
|
|
116
|
+
readonly gt_u: 0x4b;
|
|
117
|
+
readonly le_s: 0x4c;
|
|
118
|
+
readonly le_u: 0x4d;
|
|
119
|
+
readonly ge_s: 0x4e;
|
|
120
|
+
readonly ge_u: 0x4f;
|
|
121
|
+
readonly eqz: 0x45;
|
|
122
|
+
readonly and: 0x71;
|
|
123
|
+
readonly or: 0x72;
|
|
124
|
+
readonly load: 0x28;
|
|
125
|
+
readonly store: 0x36;
|
|
126
|
+
readonly load8_s: 0x2c;
|
|
127
|
+
readonly load8_u: 0x2d;
|
|
128
|
+
readonly load16_s: 0x2e;
|
|
129
|
+
readonly load16_u: 0x2f;
|
|
130
|
+
readonly store8: 0x3a;
|
|
131
|
+
readonly store16: 0x3b;
|
|
132
|
+
readonly clz: 0x67;
|
|
133
|
+
readonly ctz: 0x68;
|
|
134
|
+
readonly popcnt: 0x69;
|
|
135
|
+
readonly div_u: 0x6e;
|
|
136
|
+
readonly rem_s: 0x6f;
|
|
137
|
+
readonly rem_u: 0x70;
|
|
138
|
+
readonly xor: 0x73;
|
|
139
|
+
readonly shl: 0x74;
|
|
140
|
+
readonly shr_s: 0x75;
|
|
141
|
+
readonly shr_u: 0x76;
|
|
142
|
+
readonly rotl: 0x77;
|
|
143
|
+
readonly rotr: 0x78;
|
|
144
|
+
readonly wrap_i64: 0xa7;
|
|
145
|
+
readonly trunc_f32_s: 0xa8;
|
|
146
|
+
readonly trunc_f32_u: 0xa9;
|
|
147
|
+
readonly trunc_f64_s: 0xaa;
|
|
148
|
+
readonly trunc_f64_u: 0xab;
|
|
149
|
+
readonly reinterpret_f32: 0xbc;
|
|
150
|
+
};
|
|
151
|
+
i64: {
|
|
152
|
+
readonly const: 0x42;
|
|
153
|
+
readonly load: 0x29;
|
|
154
|
+
readonly load8_s: 0x30;
|
|
155
|
+
readonly load8_u: 0x31;
|
|
156
|
+
readonly load16_s: 0x32;
|
|
157
|
+
readonly load16_u: 0x33;
|
|
158
|
+
readonly load32_s: 0x34;
|
|
159
|
+
readonly load32_u: 0x35;
|
|
160
|
+
readonly store: 0x37;
|
|
161
|
+
readonly store8: 0x3c;
|
|
162
|
+
readonly store16: 0x3d;
|
|
163
|
+
readonly store32: 0x3e;
|
|
164
|
+
readonly eqz: 0x50;
|
|
165
|
+
readonly eq: 0x51;
|
|
166
|
+
readonly ne: 0x52;
|
|
167
|
+
readonly lt_s: 0x53;
|
|
168
|
+
readonly lt_u: 0x54;
|
|
169
|
+
readonly gt_s: 0x55;
|
|
170
|
+
readonly gt_u: 0x56;
|
|
171
|
+
readonly le_s: 0x57;
|
|
172
|
+
readonly le_u: 0x58;
|
|
173
|
+
readonly ge_s: 0x59;
|
|
174
|
+
readonly ge_u: 0x5a;
|
|
175
|
+
readonly clz: 0x79;
|
|
176
|
+
readonly ctz: 0x7a;
|
|
177
|
+
readonly popcnt: 0x7b;
|
|
178
|
+
readonly add: 0x7c;
|
|
179
|
+
readonly sub: 0x7d;
|
|
180
|
+
readonly mul: 0x7e;
|
|
181
|
+
readonly div_s: 0x7f;
|
|
182
|
+
readonly div_u: 0x80;
|
|
183
|
+
readonly rem_s: 0x81;
|
|
184
|
+
readonly rem_u: 0x82;
|
|
185
|
+
readonly and: 0x83;
|
|
186
|
+
readonly or: 0x84;
|
|
187
|
+
readonly xor: 0x85;
|
|
188
|
+
readonly shl: 0x86;
|
|
189
|
+
readonly shr_s: 0x87;
|
|
190
|
+
readonly shr_u: 0x88;
|
|
191
|
+
readonly rotl: 0x89;
|
|
192
|
+
readonly rotr: 0x8a;
|
|
193
|
+
readonly extend_i32_s: 0xac;
|
|
194
|
+
readonly extend_i32_u: 0xad;
|
|
195
|
+
readonly trunc_f32_s: 0xae;
|
|
196
|
+
readonly trunc_f32_u: 0xaf;
|
|
197
|
+
readonly trunc_f64_s: 0xb0;
|
|
198
|
+
readonly trunc_f64_u: 0xb1;
|
|
199
|
+
readonly reinterpret_f64: 0xbd;
|
|
200
|
+
};
|
|
201
|
+
f32: {
|
|
202
|
+
readonly const: 0x43;
|
|
203
|
+
readonly load: 0x2a;
|
|
204
|
+
readonly store: 0x38;
|
|
205
|
+
readonly eq: 0x5b;
|
|
206
|
+
readonly ne: 0x5c;
|
|
207
|
+
readonly lt: 0x5d;
|
|
208
|
+
readonly gt: 0x5e;
|
|
209
|
+
readonly le: 0x5f;
|
|
210
|
+
readonly ge: 0x60;
|
|
211
|
+
readonly abs: 0x8b;
|
|
212
|
+
readonly neg: 0x8c;
|
|
213
|
+
readonly ceil: 0x8d;
|
|
214
|
+
readonly floor: 0x8e;
|
|
215
|
+
readonly trunc: 0x8f;
|
|
216
|
+
readonly nearest: 0x90;
|
|
217
|
+
readonly sqrt: 0x91;
|
|
218
|
+
readonly add: 0x92;
|
|
219
|
+
readonly sub: 0x93;
|
|
220
|
+
readonly mul: 0x94;
|
|
221
|
+
readonly div: 0x95;
|
|
222
|
+
readonly min: 0x96;
|
|
223
|
+
readonly max: 0x97;
|
|
224
|
+
readonly copysign: 0x98;
|
|
225
|
+
readonly convert_i32_s: 0xb2;
|
|
226
|
+
readonly convert_i32_u: 0xb3;
|
|
227
|
+
readonly convert_i64_s: 0xb4;
|
|
228
|
+
readonly convert_i64_u: 0xb5;
|
|
229
|
+
readonly demote_f64: 0xb6;
|
|
230
|
+
readonly reinterpret_i32: 0xbe;
|
|
231
|
+
};
|
|
232
|
+
f64: {
|
|
233
|
+
readonly const: 0x44;
|
|
234
|
+
readonly load: 0x2b;
|
|
235
|
+
readonly store: 0x39;
|
|
236
|
+
readonly eq: 0x61;
|
|
237
|
+
readonly ne: 0x62;
|
|
238
|
+
readonly lt: 0x63;
|
|
239
|
+
readonly gt: 0x64;
|
|
240
|
+
readonly le: 0x65;
|
|
241
|
+
readonly ge: 0x66;
|
|
242
|
+
readonly abs: 0x99;
|
|
243
|
+
readonly neg: 0x9a;
|
|
244
|
+
readonly ceil: 0x9b;
|
|
245
|
+
readonly floor: 0x9c;
|
|
246
|
+
readonly trunc: 0x9d;
|
|
247
|
+
readonly nearest: 0x9e;
|
|
248
|
+
readonly sqrt: 0x9f;
|
|
249
|
+
readonly add: 0xa0;
|
|
250
|
+
readonly sub: 0xa1;
|
|
251
|
+
readonly mul: 0xa2;
|
|
252
|
+
readonly div: 0xa3;
|
|
253
|
+
readonly min: 0xa4;
|
|
254
|
+
readonly max: 0xa5;
|
|
255
|
+
readonly copysign: 0xa6;
|
|
256
|
+
readonly convert_i32_s: 0xb7;
|
|
257
|
+
readonly convert_i32_u: 0xb8;
|
|
258
|
+
readonly convert_i64_s: 0xb9;
|
|
259
|
+
readonly convert_i64_u: 0xba;
|
|
260
|
+
readonly promote_f32: 0xbb;
|
|
261
|
+
readonly reinterpret_i64: 0xbf;
|
|
262
|
+
};
|
|
263
|
+
local: {
|
|
264
|
+
readonly get: 0x20;
|
|
265
|
+
readonly set: 0x21;
|
|
266
|
+
readonly tee: 0x22;
|
|
267
|
+
};
|
|
268
|
+
readonly drop: 0x1a;
|
|
269
|
+
readonly call: 0x10;
|
|
270
|
+
readonly if: 0x04;
|
|
271
|
+
readonly else: 0x05;
|
|
272
|
+
readonly block: 0x02;
|
|
273
|
+
readonly loop: 0x03;
|
|
274
|
+
readonly br: 0x0c;
|
|
275
|
+
readonly br_if: 0x0d;
|
|
276
|
+
memory: {
|
|
277
|
+
readonly size: 0x3f;
|
|
278
|
+
readonly grow: 0x40;
|
|
279
|
+
};
|
|
280
|
+
readonly unreachable: 0x00;
|
|
281
|
+
global: {
|
|
282
|
+
readonly get: 0x23;
|
|
283
|
+
readonly set: 0x24;
|
|
284
|
+
};
|
|
285
|
+
readonly call_indirect: 0x11;
|
|
286
|
+
readonly nop: 0x01;
|
|
287
|
+
readonly br_table: 0x0e;
|
|
288
|
+
readonly return: 0x0f;
|
|
289
|
+
readonly select: 0x1b;
|
|
290
|
+
};
|
|
291
|
+
// End of autogenerated instruction types.
|
|
292
|
+
|
|
293
|
+
export const blocktype: {readonly empty: 0x40} & typeof valtype;
|
|
294
|
+
|
|
295
|
+
export type blocktype = typeof blocktype.empty | valtype | Fragment;
|
|
296
|
+
|
|
297
|
+
// Export section
|
|
298
|
+
// --------------
|
|
299
|
+
|
|
300
|
+
export const SECTION_ID_EXPORT: 7;
|
|
301
|
+
|
|
302
|
+
export function name(s: string): Fragment;
|
|
303
|
+
|
|
304
|
+
export function export_(nm: string, exportdesc: Fragment): Fragment;
|
|
305
|
+
|
|
306
|
+
export function exportsec(exports: readonly Fragment[]): Fragment;
|
|
307
|
+
|
|
308
|
+
export const exportdesc: {
|
|
309
|
+
func(idx: funcidx): Fragment;
|
|
310
|
+
mem(idx: memidx): Fragment;
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// Module
|
|
314
|
+
// ------
|
|
315
|
+
|
|
316
|
+
export type WasmModule = Fragment;
|
|
317
|
+
|
|
318
|
+
export function module(sections: readonly Fragment[]): WasmModule;
|
|
319
|
+
|
|
320
|
+
export function flatten(fragment: Fragment): Uint8Array<ArrayBuffer>;
|
|
321
|
+
|
|
322
|
+
// Locals
|
|
323
|
+
// ------
|
|
324
|
+
|
|
325
|
+
export function locals(n: number, type: valtype): Fragment;
|
|
326
|
+
|
|
327
|
+
// Imports
|
|
328
|
+
// -------
|
|
329
|
+
|
|
330
|
+
export const SECTION_ID_IMPORT: 2;
|
|
331
|
+
|
|
332
|
+
export function import_(mod: string, nm: string, d: Fragment): Fragment;
|
|
333
|
+
|
|
334
|
+
export function importsec(ims: readonly Fragment[]): Fragment;
|
|
335
|
+
|
|
336
|
+
export const importdesc: {
|
|
337
|
+
func(x: typeidx): Fragment;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// Memory
|
|
341
|
+
// ------
|
|
342
|
+
|
|
343
|
+
export const SECTION_ID_MEMORY: 5;
|
|
344
|
+
|
|
345
|
+
export function memsec(mems: readonly Fragment[]): Fragment;
|
|
346
|
+
|
|
347
|
+
export function mem(memtype: Fragment): Fragment;
|
|
348
|
+
|
|
349
|
+
export function memtype(limits: Fragment): Fragment;
|
|
350
|
+
|
|
351
|
+
export const limits: {
|
|
352
|
+
min(n: number): Fragment;
|
|
353
|
+
minmax(n: number, m: number): Fragment;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
export function memarg(align: number, offset: number): Fragment;
|
|
357
|
+
|
|
358
|
+
// Data / custom / names
|
|
359
|
+
// ---------------------
|
|
360
|
+
|
|
361
|
+
export const SECTION_ID_DATA: 11;
|
|
362
|
+
|
|
363
|
+
export function data(x: memidx, e: Fragment, bs: Bytes): Fragment;
|
|
364
|
+
|
|
365
|
+
export function datasec(segs: readonly Fragment[]): Fragment;
|
|
366
|
+
|
|
367
|
+
export const SECTION_ID_CUSTOM: 0;
|
|
368
|
+
|
|
369
|
+
export function custom(nameBytes: Fragment, payload: Fragment): Fragment;
|
|
370
|
+
export function customsec(custom: Fragment): Fragment;
|
|
371
|
+
|
|
372
|
+
export function namesec(namedata: Fragment): Fragment;
|
|
373
|
+
|
|
374
|
+
export function namedata(
|
|
375
|
+
modulenamesubsec: Fragment,
|
|
376
|
+
funcnamesubsec: Fragment,
|
|
377
|
+
localnamesubsec: Fragment,
|
|
378
|
+
): Fragment;
|
|
379
|
+
|
|
380
|
+
export type NameSubsectionId =
|
|
381
|
+
| typeof CUSTOM_NAME_SUB_SEC_MODULE
|
|
382
|
+
| typeof CUSTOM_NAME_SUB_SEC_FUNC
|
|
383
|
+
| typeof CUSTOM_NAME_SUB_SEC_LOCAL;
|
|
384
|
+
|
|
385
|
+
export const CUSTOM_NAME_SUB_SEC_MODULE: 0;
|
|
386
|
+
export function modulenamesubsec(n: string): Fragment;
|
|
387
|
+
|
|
388
|
+
export const CUSTOM_NAME_SUB_SEC_FUNC: 1;
|
|
389
|
+
export function funcnamesubsec(namemap: Fragment): Fragment;
|
|
390
|
+
|
|
391
|
+
export function namesubsection(N: NameSubsectionId, B: Fragment): Fragment;
|
|
392
|
+
|
|
393
|
+
export function namemap(nameassocs: readonly Fragment[]): Fragment;
|
|
394
|
+
|
|
395
|
+
export function nameassoc(idx: idx, n: string): Fragment;
|
|
396
|
+
|
|
397
|
+
export const CUSTOM_NAME_SUB_SEC_LOCAL: 2;
|
|
398
|
+
export function localnamesubsec(indirectnamemap: Fragment): Fragment;
|
|
399
|
+
|
|
400
|
+
export function indirectnamemap(
|
|
401
|
+
indirectnameassocs: readonly Fragment[],
|
|
402
|
+
): Fragment;
|
|
403
|
+
|
|
404
|
+
export function indirectnameassoc(idx: funcidx, namemap: Fragment): Fragment;
|
|
405
|
+
|
|
406
|
+
// Start section
|
|
407
|
+
// -------------
|
|
408
|
+
|
|
409
|
+
export const SECTION_ID_START: 8;
|
|
410
|
+
|
|
411
|
+
export function start(x: number): funcidx;
|
|
412
|
+
|
|
413
|
+
export function startsec(st: funcidx): Fragment;
|
|
414
|
+
|
|
415
|
+
// Globals
|
|
416
|
+
// -------
|
|
417
|
+
|
|
418
|
+
export const SECTION_ID_GLOBAL: 6;
|
|
419
|
+
|
|
420
|
+
export type mut = Brand<number, 'mut'>;
|
|
421
|
+
|
|
422
|
+
export const mut: {
|
|
423
|
+
const: mut;
|
|
424
|
+
var: mut;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export function globaltype(t: valtype, m: mut): Fragment;
|
|
428
|
+
|
|
429
|
+
export function global(gt: Fragment, e: Fragment): Fragment;
|
|
430
|
+
|
|
431
|
+
export function globalsec(globs: readonly Fragment[]): Fragment;
|
|
432
|
+
|
|
433
|
+
// Tables / elements
|
|
434
|
+
// -----------------
|
|
435
|
+
|
|
436
|
+
export const SECTION_ID_TABLE: 4;
|
|
437
|
+
|
|
438
|
+
export const elemtype: {
|
|
439
|
+
readonly funcref: 0x70;
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
export function tabletype(et: typeof elemtype.funcref, lim: Fragment): Fragment;
|
|
443
|
+
|
|
444
|
+
export function table(tt: Fragment): Fragment;
|
|
445
|
+
|
|
446
|
+
export function tablesec(tables: readonly Fragment[]): Fragment;
|
|
447
|
+
|
|
448
|
+
export const SECTION_ID_ELEMENT: 9;
|
|
449
|
+
|
|
450
|
+
export function elem(
|
|
451
|
+
x: tableidx,
|
|
452
|
+
e: Fragment,
|
|
453
|
+
ys: readonly funcidx[],
|
|
454
|
+
): Fragment;
|
|
455
|
+
|
|
456
|
+
export function elemsec(segs: readonly Fragment[]): Fragment;
|
package/index.js
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
// WebAssembly 1.0 Module Builder
|
|
2
2
|
// https://wasmgroundup.com/
|
|
3
|
+
|
|
4
|
+
function byteLength(fragment) {
|
|
5
|
+
let n = 0;
|
|
6
|
+
for (const item of fragment) {
|
|
7
|
+
if (Array.isArray(item)) n += byteLength(item);
|
|
8
|
+
else n += 1;
|
|
9
|
+
}
|
|
10
|
+
return n;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function writeInto(fragment, out, offset) {
|
|
14
|
+
for (const item of fragment) {
|
|
15
|
+
if (Array.isArray(item)) {
|
|
16
|
+
offset = writeInto(item, out, offset);
|
|
17
|
+
} else {
|
|
18
|
+
out[offset++] = item;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return offset;
|
|
22
|
+
}
|
|
23
|
+
|
|
3
24
|
export function stringToBytes(s) {
|
|
4
25
|
const bytes = new TextEncoder().encode(s);
|
|
5
26
|
return Array.from(bytes);
|
|
@@ -86,7 +107,7 @@ export function i32(v) {
|
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
export function section(id, contents) {
|
|
89
|
-
const sizeInBytes = contents
|
|
110
|
+
const sizeInBytes = byteLength(contents);
|
|
90
111
|
return [id, u32(sizeInBytes), contents];
|
|
91
112
|
}
|
|
92
113
|
|
|
@@ -115,12 +136,16 @@ export function funcsec(typeidxs) {
|
|
|
115
136
|
export const SECTION_ID_CODE = 10;
|
|
116
137
|
|
|
117
138
|
export function code(func) {
|
|
118
|
-
const sizeInBytes = func
|
|
139
|
+
const sizeInBytes = byteLength(func);
|
|
119
140
|
return [u32(sizeInBytes), func];
|
|
120
141
|
}
|
|
121
142
|
|
|
122
|
-
export function func(locals,
|
|
123
|
-
return [vec(locals),
|
|
143
|
+
export function func(locals, e) {
|
|
144
|
+
return [vec(locals), e];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function expr(instrs) {
|
|
148
|
+
return [...instrs, instr.end];
|
|
124
149
|
}
|
|
125
150
|
|
|
126
151
|
export function codesec(codes) {
|
|
@@ -149,13 +174,19 @@ export const funcidx = (x) => u32(x);
|
|
|
149
174
|
|
|
150
175
|
export const exportdesc = {
|
|
151
176
|
func(idx) {
|
|
152
|
-
return [0x00,
|
|
177
|
+
return [0x00, idx];
|
|
153
178
|
},
|
|
154
179
|
};
|
|
155
180
|
|
|
156
181
|
export function module(sections) {
|
|
157
182
|
return [magic(), version(), sections];
|
|
158
183
|
}
|
|
184
|
+
|
|
185
|
+
export function flatten(fragment) {
|
|
186
|
+
const out = new Uint8Array(byteLength(fragment));
|
|
187
|
+
writeInto(fragment, out, 0);
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
159
190
|
export const valtype = {
|
|
160
191
|
i32: 0x7f,
|
|
161
192
|
i64: 0x7e,
|
|
@@ -226,7 +257,7 @@ export function importsec(ims) {
|
|
|
226
257
|
export const importdesc = {
|
|
227
258
|
// x:typeidx
|
|
228
259
|
func(x) {
|
|
229
|
-
return [0x00,
|
|
260
|
+
return [0x00, x];
|
|
230
261
|
},
|
|
231
262
|
};
|
|
232
263
|
export const SECTION_ID_MEMORY = 5;
|
|
@@ -256,7 +287,7 @@ export const limits = {
|
|
|
256
287
|
|
|
257
288
|
export const memidx = u32;
|
|
258
289
|
|
|
259
|
-
exportdesc.mem = (idx) => [0x02,
|
|
290
|
+
exportdesc.mem = (idx) => [0x02, idx];
|
|
260
291
|
|
|
261
292
|
instr.memory = {
|
|
262
293
|
size: 0x3f, // [] -> [i32]
|
|
@@ -317,9 +348,8 @@ export function funcnamesubsec(namemap) {
|
|
|
317
348
|
|
|
318
349
|
// N:byte
|
|
319
350
|
export function namesubsection(N, B) {
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
return [N, size, flatB];
|
|
351
|
+
const size = u32(byteLength(B));
|
|
352
|
+
return [N, size, B];
|
|
323
353
|
}
|
|
324
354
|
|
|
325
355
|
export function namemap(nameassocs) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wasmgroundup/emit",
|
|
3
3
|
"description": "A library for creating binary-encoded WebAssembly modules",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"default": "./index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"index.js",
|
|
16
|
+
"index.d.ts"
|
|
17
|
+
],
|
|
7
18
|
"repository": {
|
|
8
19
|
"type": "git",
|
|
9
20
|
"url": "git+https://github.com/wasmgroundup/emit.git"
|
|
@@ -17,5 +28,16 @@
|
|
|
17
28
|
"bugs": {
|
|
18
29
|
"url": "https://github.com/wasmgroundup/emit/issues"
|
|
19
30
|
},
|
|
20
|
-
"homepage": "https://github.com/wasmgroundup/emit#readme"
|
|
21
|
-
|
|
31
|
+
"homepage": "https://github.com/wasmgroundup/emit#readme",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^24.10.1",
|
|
34
|
+
"prettier": "^3.6.2",
|
|
35
|
+
"typescript": "^5.9.3"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsc",
|
|
39
|
+
"format": "npx prettier '**/*.{ts,js,json}' --write",
|
|
40
|
+
"test": "node --test",
|
|
41
|
+
"test:watch": "node --test --watch"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/index.test.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
blocktype,
|
|
5
|
-
code,
|
|
6
|
-
codesec,
|
|
7
|
-
export_,
|
|
8
|
-
exportdesc,
|
|
9
|
-
exportsec,
|
|
10
|
-
func,
|
|
11
|
-
funcidx,
|
|
12
|
-
funcsec,
|
|
13
|
-
functype,
|
|
14
|
-
global,
|
|
15
|
-
globalsec,
|
|
16
|
-
globaltype,
|
|
17
|
-
i32,
|
|
18
|
-
import_,
|
|
19
|
-
importdesc,
|
|
20
|
-
importsec,
|
|
21
|
-
instr,
|
|
22
|
-
module,
|
|
23
|
-
mut,
|
|
24
|
-
typeidx,
|
|
25
|
-
typesec,
|
|
26
|
-
u32,
|
|
27
|
-
valtype,
|
|
28
|
-
} from "./index.js";
|
|
29
|
-
|
|
30
|
-
function blocktype(t?: valtype): number {
|
|
31
|
-
return t ?? 0x40;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function f64(v: number): number[] {
|
|
35
|
-
var buf = new ArrayBuffer(8);
|
|
36
|
-
new Float64Array(buf)[0] = v;
|
|
37
|
-
return Array.from(new Uint8Array(buf));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const PI = 3.141592653589793115997963468544185161590576171875;
|
|
41
|
-
|
|
42
|
-
function fragmentToUInt8Array(frag): Uint8Array {
|
|
43
|
-
return Uint8Array.from((frag as any).flat(Infinity));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
test("u32", () => {
|
|
47
|
-
expect(u32(32768)).toEqual([128, 128, 2]);
|
|
48
|
-
expect(u32(2 ** 32 - 1)).toEqual([255, 255, 255, 255, 15]);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("i32", () => {
|
|
52
|
-
expect(i32(32768)).toEqual([128, 128, 2]);
|
|
53
|
-
expect(i32(2 ** 31 - 1)).toEqual([255, 255, 255, 255, 7]);
|
|
54
|
-
expect(i32(-(2 ** 31 - 1))).toEqual([129, 128, 128, 128, 120]);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test("simple modules", async () => {
|
|
58
|
-
const makeModule = (paramTypes, resultTypes, body) => {
|
|
59
|
-
const mod = module([
|
|
60
|
-
typesec([functype(paramTypes, resultTypes)]),
|
|
61
|
-
funcsec([typeidx(0)]),
|
|
62
|
-
exportsec([export_("main", exportdesc.func(0))]),
|
|
63
|
-
codesec([code(func([], body))]),
|
|
64
|
-
]);
|
|
65
|
-
return fragmentToUInt8Array(mod);
|
|
66
|
-
};
|
|
67
|
-
const runMain = async (bytes, args) => {
|
|
68
|
-
const { instance } = await WebAssembly.instantiate(bytes);
|
|
69
|
-
return instance.exports.main(...args);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// () => ()
|
|
73
|
-
expect(await runMain(makeModule([], [], [instr.end]), [])).toBe(undefined);
|
|
74
|
-
|
|
75
|
-
// () => i32
|
|
76
|
-
expect(
|
|
77
|
-
await runMain(
|
|
78
|
-
makeModule([], [valtype.i32], [instr.i32.const, 1, instr.end]),
|
|
79
|
-
[],
|
|
80
|
-
),
|
|
81
|
-
).toBe(1);
|
|
82
|
-
|
|
83
|
-
// (i32) => i32
|
|
84
|
-
expect(
|
|
85
|
-
await runMain(
|
|
86
|
-
makeModule([valtype.i32], [valtype.i32], [instr.local.get, 0, instr.end]),
|
|
87
|
-
[1],
|
|
88
|
-
),
|
|
89
|
-
).toBe(1);
|
|
90
|
-
expect(
|
|
91
|
-
await runMain(
|
|
92
|
-
makeModule([valtype.i32], [valtype.i32], [instr.local.get, 0, instr.end]),
|
|
93
|
-
[99],
|
|
94
|
-
),
|
|
95
|
-
).toBe(99);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test("imports", async () => {
|
|
99
|
-
const makeModule = () => {
|
|
100
|
-
const mod = module([
|
|
101
|
-
typesec([functype([valtype.i32], [valtype.i32])]),
|
|
102
|
-
importsec([import_("builtins", "addOne", importdesc.func(0))]),
|
|
103
|
-
funcsec([typeidx(0)]),
|
|
104
|
-
exportsec([export_("main", exportdesc.func(1))]),
|
|
105
|
-
codesec([
|
|
106
|
-
code(func([], [instr.local.get, 0, instr.call, funcidx(0), instr.end])),
|
|
107
|
-
]),
|
|
108
|
-
]);
|
|
109
|
-
return fragmentToUInt8Array(mod);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const { instance } = await WebAssembly.instantiate(makeModule(), {
|
|
113
|
-
builtins: {
|
|
114
|
-
addOne(x) {
|
|
115
|
-
return x + 1;
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
expect(instance.exports.main(1)).toBe(2);
|
|
121
|
-
expect(instance.exports.main(2)).toBe(3);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
test("f64", async () => {
|
|
125
|
-
const makeModule = () => {
|
|
126
|
-
const mod = module([
|
|
127
|
-
typesec([functype([], [valtype.f64])]),
|
|
128
|
-
funcsec([typeidx(0), typeidx(0), typeidx(0)]),
|
|
129
|
-
exportsec([
|
|
130
|
-
export_("pi", exportdesc.func(0)),
|
|
131
|
-
export_("nan", exportdesc.func(1)),
|
|
132
|
-
export_("one", exportdesc.func(2)),
|
|
133
|
-
]),
|
|
134
|
-
codesec([
|
|
135
|
-
code(func([], [instr.f64.const, f64(PI), instr.end])),
|
|
136
|
-
code(func([], [instr.f64.const, f64(Number.NaN), instr.end])),
|
|
137
|
-
code(func([], [instr.f64.const, f64(1), instr.end])),
|
|
138
|
-
]),
|
|
139
|
-
]);
|
|
140
|
-
return fragmentToUInt8Array(mod);
|
|
141
|
-
};
|
|
142
|
-
const { instance } = await WebAssembly.instantiate(makeModule());
|
|
143
|
-
expect(instance.exports.pi()).toBe(PI);
|
|
144
|
-
expect(instance.exports.nan()).toBe(Number.NaN);
|
|
145
|
-
expect(instance.exports.one()).toBe(1);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("globals", async () => {
|
|
149
|
-
const makeModule = () => {
|
|
150
|
-
const mod = module([
|
|
151
|
-
typesec([
|
|
152
|
-
functype([], [valtype.f64]), // pi
|
|
153
|
-
functype([], [valtype.i32]), // getVar
|
|
154
|
-
functype([], []), // incVar
|
|
155
|
-
]),
|
|
156
|
-
funcsec([typeidx(0), typeidx(1), typeidx(2)]),
|
|
157
|
-
globalsec([
|
|
158
|
-
global(globaltype(valtype.f64, mut.const), [
|
|
159
|
-
instr.f64.const,
|
|
160
|
-
f64(PI),
|
|
161
|
-
instr.end,
|
|
162
|
-
]),
|
|
163
|
-
global(globaltype(valtype.i32, mut.var), [
|
|
164
|
-
instr.i32.const,
|
|
165
|
-
i32(0),
|
|
166
|
-
instr.end,
|
|
167
|
-
]),
|
|
168
|
-
]),
|
|
169
|
-
exportsec([
|
|
170
|
-
export_("pi", exportdesc.func(0)),
|
|
171
|
-
export_("getVar", exportdesc.func(1)),
|
|
172
|
-
export_("incVar", exportdesc.func(2)),
|
|
173
|
-
]),
|
|
174
|
-
codesec([
|
|
175
|
-
code(func([], [instr.global.get, 0, instr.end])), // pi
|
|
176
|
-
code(func([], [instr.global.get, 1, instr.end])), // getVar
|
|
177
|
-
code(
|
|
178
|
-
// prettier-ignore
|
|
179
|
-
func([], [
|
|
180
|
-
instr.global.get, 1,
|
|
181
|
-
instr.i32.const, 1,
|
|
182
|
-
instr.i32.add,
|
|
183
|
-
instr.global.set, 1,
|
|
184
|
-
instr.end,
|
|
185
|
-
],
|
|
186
|
-
),
|
|
187
|
-
), // incVar
|
|
188
|
-
]),
|
|
189
|
-
]);
|
|
190
|
-
return fragmentToUInt8Array(mod);
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const { exports } = (await WebAssembly.instantiate(makeModule())).instance;
|
|
194
|
-
expect(exports.pi()).toBe(PI);
|
|
195
|
-
expect(exports.getVar()).toBe(0);
|
|
196
|
-
exports.incVar();
|
|
197
|
-
expect(exports.getVar()).toBe(1);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
test("if", async () => {
|
|
201
|
-
const makeModule = () => {
|
|
202
|
-
const mod = module([
|
|
203
|
-
typesec([functype([valtype.i32], [valtype.f64])]),
|
|
204
|
-
funcsec([typeidx(0)]),
|
|
205
|
-
exportsec([export_("maybePi", exportdesc.func(0))]),
|
|
206
|
-
codesec([
|
|
207
|
-
code(
|
|
208
|
-
func(
|
|
209
|
-
[],
|
|
210
|
-
// prettier-ignore
|
|
211
|
-
[
|
|
212
|
-
instr.local.get, 0,
|
|
213
|
-
instr.if, blocktype(valtype.f64),
|
|
214
|
-
instr.f64.const, f64(PI),
|
|
215
|
-
instr.else,
|
|
216
|
-
instr.f64.const, f64(0),
|
|
217
|
-
instr.end,
|
|
218
|
-
instr.end,
|
|
219
|
-
],
|
|
220
|
-
),
|
|
221
|
-
),
|
|
222
|
-
]),
|
|
223
|
-
]);
|
|
224
|
-
return fragmentToUInt8Array(mod);
|
|
225
|
-
};
|
|
226
|
-
const { exports } = (await WebAssembly.instantiate(makeModule())).instance;
|
|
227
|
-
expect(exports.maybePi(1)).toBe(PI);
|
|
228
|
-
expect(exports.maybePi(0)).toBe(0);
|
|
229
|
-
});
|