@wasmgroundup/emit 0.2.17 → 0.3.2

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.js ADDED
@@ -0,0 +1,393 @@
1
+ // WebAssembly 1.0 Module Builder
2
+ // https://wasmgroundup.com/
3
+ export function stringToBytes(s) {
4
+ const bytes = new TextEncoder().encode(s);
5
+ return Array.from(bytes);
6
+ }
7
+
8
+ export function magic() {
9
+ // [0x00, 0x61, 0x73, 0x6d]
10
+ return stringToBytes('\0asm');
11
+ }
12
+
13
+ export function version() {
14
+ return [0x01, 0x00, 0x00, 0x00];
15
+ }
16
+
17
+ export const SEVEN_BIT_MASK_BIG_INT = 0b01111111n;
18
+ export const CONTINUATION_BIT = 0b10000000;
19
+
20
+ export function u32(v) {
21
+ assert(v >= 0, `Value is negative: ${v}`);
22
+
23
+ let val = BigInt(v);
24
+ let more = true;
25
+ const r = [];
26
+
27
+ while (more) {
28
+ const b = Number(val & SEVEN_BIT_MASK_BIG_INT);
29
+ val = val >> 7n;
30
+ more = val !== 0n;
31
+ if (more) {
32
+ r.push(b | CONTINUATION_BIT);
33
+ } else {
34
+ r.push(b);
35
+ }
36
+ }
37
+
38
+ return r;
39
+ }
40
+
41
+ export function i32(v) {
42
+ let val = BigInt(v);
43
+ const r = [];
44
+
45
+ let more = true;
46
+ while (more) {
47
+ const b = Number(val & 0b01111111n);
48
+ const signBitSet = !!(b & 0x40);
49
+
50
+ val = val >> 7n;
51
+
52
+ if ((val === 0n && !signBitSet) || (val === -1n && signBitSet)) {
53
+ more = false;
54
+ r.push(b);
55
+ } else {
56
+ r.push(b | CONTINUATION_BIT);
57
+ }
58
+ }
59
+
60
+ return r;
61
+ }
62
+
63
+ export function section(id, contents) {
64
+ const sizeInBytes = contents.flat(Infinity).length;
65
+ return [id, u32(sizeInBytes), contents];
66
+ }
67
+
68
+ export function vec(elements) {
69
+ return [u32(elements.length), elements];
70
+ }
71
+
72
+ export const SECTION_ID_TYPE = 1;
73
+
74
+ export function functype(paramTypes, resultTypes) {
75
+ return [0x60, vec(paramTypes), vec(resultTypes)];
76
+ }
77
+
78
+ export function typesec(functypes) {
79
+ return section(SECTION_ID_TYPE, vec(functypes));
80
+ }
81
+
82
+ export const SECTION_ID_FUNCTION = 3;
83
+
84
+ export const typeidx = (x) => u32(x);
85
+
86
+ export function funcsec(typeidxs) {
87
+ return section(SECTION_ID_FUNCTION, vec(typeidxs));
88
+ }
89
+
90
+ export const SECTION_ID_CODE = 10;
91
+
92
+ export function code(func) {
93
+ const sizeInBytes = func.flat(Infinity).length;
94
+ return [u32(sizeInBytes), func];
95
+ }
96
+
97
+ export function func(locals, body) {
98
+ return [vec(locals), body];
99
+ }
100
+
101
+ export function codesec(codes) {
102
+ return section(SECTION_ID_CODE, vec(codes));
103
+ }
104
+
105
+ export const instr = {
106
+ end: 0x0b,
107
+ };
108
+
109
+ export const SECTION_ID_EXPORT = 7;
110
+
111
+ export function name(s) {
112
+ return vec(stringToBytes(s));
113
+ }
114
+
115
+ export function export_(nm, exportdesc) {
116
+ return [name(nm), exportdesc];
117
+ }
118
+
119
+ export function exportsec(exports) {
120
+ return section(SECTION_ID_EXPORT, vec(exports));
121
+ }
122
+
123
+ export const funcidx = (x) => u32(x);
124
+
125
+ export const exportdesc = {
126
+ func(idx) {
127
+ return [0x00, funcidx(idx)];
128
+ },
129
+ };
130
+
131
+ export function module(sections) {
132
+ return [magic(), version(), sections];
133
+ }
134
+ export const valtype = {
135
+ i32: 0x7f,
136
+ i64: 0x7e,
137
+ f32: 0x7d,
138
+ f64: 0x7c,
139
+ };
140
+
141
+ instr.i32 = {const: 0x41};
142
+ instr.i64 = {const: 0x42};
143
+ instr.f32 = {const: 0x43};
144
+ instr.f64 = {const: 0x44};
145
+ instr.i32.add = 0x6a;
146
+ instr.i32.sub = 0x6b;
147
+ instr.i32.mul = 0x6c;
148
+ instr.i32.div_s = 0x6d;
149
+ instr.local = {};
150
+ instr.local.get = 0x20;
151
+ instr.local.set = 0x21;
152
+ instr.local.tee = 0x22;
153
+
154
+ export function locals(n, type) {
155
+ return [u32(n), type];
156
+ }
157
+
158
+ export const localidx = (x) => u32(x);
159
+
160
+ instr.drop = 0x1a;
161
+ instr.call = 0x10;
162
+ instr.if = 0x04;
163
+ instr.else = 0x05;
164
+
165
+ export const blocktype = {empty: 0x40, ...valtype};
166
+
167
+ instr.i32.eq = 0x46; // a == b
168
+ instr.i32.ne = 0x47; // a != b
169
+ instr.i32.lt_s = 0x48; // a < b (signed)
170
+ instr.i32.lt_u = 0x49; // a < b (unsigned)
171
+ instr.i32.gt_s = 0x4a; // a > b (signed)
172
+ instr.i32.gt_u = 0x4b; // a > b (unsigned)
173
+ instr.i32.le_s = 0x4c; // a <= b (signed)
174
+ instr.i32.le_u = 0x4d; // a <= b (unsigned)
175
+ instr.i32.ge_s = 0x4e; // a >= b (signed)
176
+ instr.i32.ge_u = 0x4f; // a >= b (unsigned)
177
+
178
+ instr.i32.eqz = 0x45; // a == 0
179
+
180
+ instr.i32.and = 0x71;
181
+ instr.i32.or = 0x72;
182
+
183
+ export const labelidx = u32;
184
+
185
+ instr.block = 0x02;
186
+ instr.loop = 0x03;
187
+ instr.br = 0x0c;
188
+ instr.br_if = 0x0d;
189
+ export const SECTION_ID_IMPORT = 2;
190
+
191
+ // mod:name nm:name d:importdesc
192
+ export function import_(mod, nm, d) {
193
+ return [name(mod), name(nm), d];
194
+ }
195
+
196
+ // im*:vec(import)
197
+ export function importsec(ims) {
198
+ return section(SECTION_ID_IMPORT, vec(ims));
199
+ }
200
+
201
+ export const importdesc = {
202
+ // x:typeidx
203
+ func(x) {
204
+ return [0x00, typeidx(x)];
205
+ },
206
+ };
207
+ export const SECTION_ID_MEMORY = 5;
208
+
209
+ export function memsec(mems) {
210
+ return section(SECTION_ID_MEMORY, vec(mems));
211
+ }
212
+
213
+ export function mem(memtype) {
214
+ return memtype;
215
+ }
216
+
217
+ export function memtype(limits) {
218
+ return limits;
219
+ }
220
+
221
+ export const limits = {
222
+ // n:u32
223
+ min(n) {
224
+ return [0x00, u32(n)];
225
+ },
226
+ // n:u32, m:u32
227
+ minmax(n, m) {
228
+ return [0x01, u32(n), u32(m)];
229
+ },
230
+ };
231
+
232
+ export const memidx = u32;
233
+
234
+ exportdesc.mem = (idx) => [0x02, memidx(idx)];
235
+
236
+ instr.memory = {
237
+ size: 0x3f, // [] -> [i32]
238
+ grow: 0x40, // [i32] -> [i32]
239
+ };
240
+
241
+ instr.i32.load = 0x28; // [i32] -> [i32]
242
+ instr.i32.store = 0x36; // [i32, i32] -> []
243
+
244
+ // align:u32, offset:u32
245
+ export function memarg(align, offset) {
246
+ return [u32(align), u32(offset)];
247
+ }
248
+ export function int32ToBytes(v) {
249
+ return [v & 0xff, (v >> 8) & 0xff, (v >> 16) & 0xff, (v >> 24) & 0xff];
250
+ }
251
+
252
+ instr.unreachable = 0x00;
253
+
254
+ export const SECTION_ID_DATA = 11;
255
+
256
+ // x:memidx e:expr bs:vec(byte)
257
+ export function data(x, e, bs) {
258
+ return [x, e, vec(bs)];
259
+ }
260
+
261
+ export function datasec(segs) {
262
+ return section(SECTION_ID_DATA, vec(segs));
263
+ }
264
+ export const SECTION_ID_CUSTOM = 0;
265
+
266
+ export function custom(name, bytes) {
267
+ return [name, bytes];
268
+ }
269
+
270
+ export function customsec(custom) {
271
+ return section(SECTION_ID_CUSTOM, custom);
272
+ }
273
+
274
+ export function namesec(namedata) {
275
+ return customsec(custom(name('name'), namedata));
276
+ }
277
+
278
+ // n:name
279
+ export function namedata(modulenamesubsec, funcnamesubsec, localnamesubsec) {
280
+ return [modulenamesubsec, funcnamesubsec, localnamesubsec];
281
+ }
282
+
283
+ export const CUSTOM_NAME_SUB_SEC_MODULE = 0;
284
+ export function modulenamesubsec(n) {
285
+ return namesubsection(CUSTOM_NAME_SUB_SEC_MODULE, name(n));
286
+ }
287
+
288
+ export const CUSTOM_NAME_SUB_SEC_FUNC = 1;
289
+ export function funcnamesubsec(namemap) {
290
+ return namesubsection(CUSTOM_NAME_SUB_SEC_FUNC, namemap);
291
+ }
292
+
293
+ // N:byte
294
+ export function namesubsection(N, B) {
295
+ const flatB = B.flat(Infinity);
296
+ const size = u32(flatB.length);
297
+ return [N, size, flatB];
298
+ }
299
+
300
+ export function namemap(nameassocs) {
301
+ return vec(nameassocs);
302
+ }
303
+
304
+ export function nameassoc(idx, n) {
305
+ return [idx, name(n)];
306
+ }
307
+
308
+ export const CUSTOM_NAME_SUB_SEC_LOCAL = 2;
309
+ export function localnamesubsec(indirectnamemap) {
310
+ return namesubsection(CUSTOM_NAME_SUB_SEC_LOCAL, indirectnamemap);
311
+ }
312
+
313
+ export function indirectnamemap(indirectnameassocs) {
314
+ return vec(indirectnameassocs);
315
+ }
316
+
317
+ export function indirectnameassoc(idx, namemap) {
318
+ return [idx, namemap];
319
+ }
320
+ export const SECTION_ID_START = 8;
321
+
322
+ export const start = (x) => funcidx(x);
323
+
324
+ // st:start
325
+ export function startsec(st) {
326
+ return section(SECTION_ID_START, st);
327
+ }
328
+
329
+ instr.global = {};
330
+ instr.global.get = 0x23;
331
+ instr.global.set = 0x24;
332
+
333
+ export const globalidx = (x) => u32(x);
334
+
335
+ export const SECTION_ID_GLOBAL = 6;
336
+
337
+ export const mut = {
338
+ const: 0x00,
339
+ var: 0x01,
340
+ };
341
+
342
+ // t:valtype m:mut
343
+ export function globaltype(t, m) {
344
+ return [t, m];
345
+ }
346
+
347
+ // gt:globaltype e:expr
348
+ export function global(gt, e) {
349
+ return [gt, e];
350
+ }
351
+
352
+ // glob*:vec(global)
353
+ export function globalsec(globs) {
354
+ return section(SECTION_ID_GLOBAL, vec(globs));
355
+ }
356
+
357
+ export const SECTION_ID_TABLE = 4;
358
+
359
+ export const elemtype = {funcref: 0x70};
360
+
361
+ // et:elemtype lim:limits
362
+ export function tabletype(et, lim) {
363
+ return [et, lim];
364
+ }
365
+
366
+ // tt:tabletype
367
+ export function table(tt) {
368
+ return tt;
369
+ }
370
+
371
+ export function tablesec(tables) {
372
+ return section(SECTION_ID_TABLE, vec(tables));
373
+ }
374
+
375
+ export const tableidx = (x) => u32(x);
376
+
377
+ instr.call_indirect = 0x11; // [i32] -> []
378
+
379
+ export const SECTION_ID_ELEMENT = 9;
380
+
381
+ // x:tableidx e:expr y∗:vec(funcidx)
382
+ export function elem(x, e, ys) {
383
+ return [x, e, vec(ys)];
384
+ }
385
+
386
+ export function elemsec(segs) {
387
+ return section(SECTION_ID_ELEMENT, vec(segs));
388
+ }
389
+ export function assert(cond, msg) {
390
+ if (!cond) {
391
+ throw new Error(msg);
392
+ }
393
+ }
package/index.test.ts CHANGED
@@ -1,14 +1,12 @@
1
1
  import { expect, test } from "bun:test";
2
2
 
3
3
  import {
4
- BytecodeFragment,
5
4
  blocktype,
6
5
  code,
7
6
  codesec,
8
7
  export_,
9
8
  exportdesc,
10
9
  exportsec,
11
- f64,
12
10
  func,
13
11
  funcidx,
14
12
  funcsec,
@@ -25,15 +23,37 @@ import {
25
23
  mut,
26
24
  typeidx,
27
25
  typesec,
26
+ u32,
28
27
  valtype,
29
- } from "./index";
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
+ }
30
39
 
31
40
  const PI = 3.141592653589793115997963468544185161590576171875;
32
41
 
33
- function fragmentToUInt8Array(frag: BytecodeFragment): Uint8Array {
42
+ function fragmentToUInt8Array(frag): Uint8Array {
34
43
  return Uint8Array.from((frag as any).flat(Infinity));
35
44
  }
36
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
+
37
57
  test("simple modules", async () => {
38
58
  const makeModule = (paramTypes, resultTypes, body) => {
39
59
  const mod = module([
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@wasmgroundup/emit",
3
3
  "description": "A library for creating binary-encoded WebAssembly modules",
4
- "version": "0.2.17",
4
+ "version": "0.3.2",
5
5
  "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
6
+ "main": "index.js",
8
7
  "repository": {
9
8
  "type": "git",
10
9
  "url": "git+https://github.com/wasmgroundup/emit.git"
@@ -18,16 +17,5 @@
18
17
  "bugs": {
19
18
  "url": "https://github.com/wasmgroundup/emit/issues"
20
19
  },
21
- "homepage": "https://github.com/wasmgroundup/emit#readme",
22
- "scripts": {
23
- "check": "tsc --noEmit",
24
- "format": "prettier --write .",
25
- "prepublishOnly": "tsc"
26
- },
27
- "dependencies": {
28
- "prettier": "^3.0.3"
29
- },
30
- "devDependencies": {
31
- "typescript": "^5.2.2"
32
- }
20
+ "homepage": "https://github.com/wasmgroundup/emit#readme"
33
21
  }
package/dist/index.d.ts DELETED
@@ -1,141 +0,0 @@
1
- type BytecodeFragment = (number | BytecodeFragment)[];
2
- declare enum valtype {
3
- i32 = 127,
4
- i64 = 126,
5
- f32 = 125,
6
- f64 = 124
7
- }
8
- declare function blocktype(t?: valtype): number;
9
- declare function vec<T extends BytecodeFragment>(elements: T): BytecodeFragment;
10
- declare function section(id: number, contents: BytecodeFragment): (number | BytecodeFragment)[];
11
- declare function functype(paramTypes: valtype[], resultTypes: valtype[]): BytecodeFragment;
12
- declare function typesec(functypes: BytecodeFragment): BytecodeFragment;
13
- declare const typeidx: typeof u32;
14
- declare function funcsec(typeidxs: BytecodeFragment): BytecodeFragment;
15
- declare function code(func: BytecodeFragment): BytecodeFragment;
16
- declare function func(locals: BytecodeFragment, body: BytecodeFragment): BytecodeFragment;
17
- declare function codesec(codes: BytecodeFragment): BytecodeFragment;
18
- declare function name(s: string): BytecodeFragment;
19
- declare function export_(nm: string, exportdesc: BytecodeFragment): BytecodeFragment;
20
- declare function exportsec(exports: BytecodeFragment): BytecodeFragment;
21
- declare const funcidx: typeof u32;
22
- declare const exportdesc: {
23
- func(idx: number): BytecodeFragment;
24
- table(idx: number): BytecodeFragment;
25
- mem(idx: number): BytecodeFragment;
26
- global(idx: number): BytecodeFragment;
27
- };
28
- declare function module(sections: any): BytecodeFragment;
29
- declare const instr: {
30
- unreachable: number;
31
- nop: number;
32
- block: number;
33
- loop: number;
34
- if: number;
35
- else: number;
36
- end: number;
37
- br: number;
38
- br_if: number;
39
- br_table: number;
40
- return: number;
41
- call: number;
42
- call_indirect: number;
43
- drop: number;
44
- select: number;
45
- local: {
46
- get: number;
47
- set: number;
48
- tee: number;
49
- };
50
- global: {
51
- get: number;
52
- set: number;
53
- tee: number;
54
- };
55
- memory: {
56
- size: number;
57
- grow: number;
58
- };
59
- i32: {
60
- load: number;
61
- const: number;
62
- eqz: number;
63
- eq: number;
64
- ne: number;
65
- lt_s: number;
66
- lt_u: number;
67
- gt_s: number;
68
- gt_u: number;
69
- le_s: number;
70
- le_u: number;
71
- ge_s: number;
72
- ge_u: number;
73
- add: number;
74
- sub: number;
75
- mul: number;
76
- };
77
- i64: {
78
- store32: number;
79
- const: number;
80
- add: number;
81
- sub: number;
82
- mul: number;
83
- };
84
- f32: {
85
- const: number;
86
- add: number;
87
- sub: number;
88
- mul: number;
89
- div: number;
90
- };
91
- f64: {
92
- load: number;
93
- store: number;
94
- const: number;
95
- add: number;
96
- sub: number;
97
- mul: number;
98
- div: number;
99
- reinterpret_i64: number;
100
- };
101
- };
102
- declare function u32(v: number | bigint): number[];
103
- declare function i32(v: number | bigint): number[];
104
- declare function f64(v: number): number[];
105
- declare function locals(n: number, type: valtype): BytecodeFragment;
106
- declare function import_(mod: string, nm: string, d: BytecodeFragment): BytecodeFragment;
107
- declare function importsec(ims: BytecodeFragment): BytecodeFragment;
108
- declare const importdesc: {
109
- func(x: BytecodeFragment): BytecodeFragment;
110
- table(tt: BytecodeFragment): BytecodeFragment;
111
- mem(mt: BytecodeFragment): BytecodeFragment;
112
- global(gt: BytecodeFragment): BytecodeFragment;
113
- };
114
- declare function memsec(mems: BytecodeFragment[]): (number | BytecodeFragment)[];
115
- declare function memtype(limits: BytecodeFragment): BytecodeFragment;
116
- declare const limits: {
117
- min(n: number): (number | number[])[];
118
- minmax(n: number, m: number): (number | number[])[];
119
- };
120
- declare const mut: {
121
- const: number;
122
- var: number;
123
- };
124
- declare function globaltype(t: any, m: any): any[];
125
- declare function global(gt: any, e: any): any[];
126
- declare function globalsec(globs: BytecodeFragment[]): (number | BytecodeFragment)[];
127
- declare function tabletype(elemtype: number, limits: BytecodeFragment): (number | BytecodeFragment)[];
128
- declare function table(tabletype: BytecodeFragment): BytecodeFragment;
129
- declare function tablesec(tables: BytecodeFragment[]): (number | BytecodeFragment)[];
130
- declare const elemtype: {
131
- funcref: number;
132
- };
133
- declare const tableidx: typeof u32;
134
- declare const start: typeof u32;
135
- declare function startsec(st: BytecodeFragment): (number | BytecodeFragment)[];
136
- declare function data(x: BytecodeFragment, e: BytecodeFragment, bs: BytecodeFragment[]): BytecodeFragment[];
137
- declare function datasec(segs: BytecodeFragment[]): (number | BytecodeFragment)[];
138
- declare function elem(x: BytecodeFragment, e: BytecodeFragment, ys: BytecodeFragment[]): BytecodeFragment[];
139
- declare function elemsec(segs: BytecodeFragment[]): (number | BytecodeFragment)[];
140
- declare function memarg(align: number, offset: number): number[][];
141
- export { blocktype, BytecodeFragment, code, codesec, data, datasec, elem, elemsec, elemtype, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, global, globalsec, globaltype, i32, import_, importdesc, importsec, instr, limits, locals, memarg, memsec, memtype, module, mut, name, section, start, startsec, table, tableidx, tablesec, tabletype, typeidx, typesec, u32, valtype, vec, };
package/dist/index.js DELETED
@@ -1,309 +0,0 @@
1
- const SECTION_ID_TYPE = 1;
2
- const SECTION_ID_IMPORT = 2;
3
- const SECTION_ID_FUNCTION = 3;
4
- const SECTION_ID_TABLE = 4;
5
- const SECTION_ID_MEMORY = 5;
6
- const SECTION_ID_GLOBAL = 6;
7
- const SECTION_ID_EXPORT = 7;
8
- const SECTION_ID_START = 8;
9
- const SECTION_ID_ELEMENT = 9;
10
- const SECTION_ID_CODE = 10;
11
- const SECTION_ID_DATA = 11;
12
- const TYPE_FUNCTION = 0x60;
13
- function stringToBytes(s) {
14
- const bytes = new TextEncoder().encode(s);
15
- return Array.from(bytes);
16
- }
17
- function int32ToBytes(v) {
18
- // prettier-ignore
19
- return [
20
- v & 0xff,
21
- (v >> 8) & 0xff,
22
- (v >> 16) & 0xff,
23
- (v >> 24) & 0xff,
24
- ];
25
- }
26
- function magic() {
27
- // [0x00, 0x61, 0x73, 0x6d]
28
- return stringToBytes("\0asm");
29
- }
30
- function version() {
31
- // [0x01, 0x00, 0x00, 0x00]
32
- return int32ToBytes(1);
33
- }
34
- var valtype;
35
- (function (valtype) {
36
- valtype[valtype["i32"] = 127] = "i32";
37
- valtype[valtype["i64"] = 126] = "i64";
38
- valtype[valtype["f32"] = 125] = "f32";
39
- valtype[valtype["f64"] = 124] = "f64";
40
- })(valtype || (valtype = {}));
41
- // t: valtype
42
- function blocktype(t) {
43
- return t ?? 0x40;
44
- }
45
- function vec(elements) {
46
- return [u32(elements.length), ...elements];
47
- }
48
- function section(id, contents) {
49
- const sizeInBytes = contents.flat(Infinity).length;
50
- return [id, u32(sizeInBytes), contents];
51
- }
52
- function functype(paramTypes, resultTypes) {
53
- return [TYPE_FUNCTION, vec(paramTypes), vec(resultTypes)];
54
- }
55
- function typesec(functypes) {
56
- return section(SECTION_ID_TYPE, vec(functypes));
57
- }
58
- const typeidx = u32;
59
- function funcsec(typeidxs) {
60
- return section(SECTION_ID_FUNCTION, vec(typeidxs));
61
- }
62
- function code(func) {
63
- const sizeInBytes = func.flat(Infinity).length;
64
- return [u32(sizeInBytes), func];
65
- }
66
- function func(locals, body) {
67
- return [vec(locals), body];
68
- }
69
- function codesec(codes) {
70
- return section(SECTION_ID_CODE, vec(codes));
71
- }
72
- function name(s) {
73
- return vec(stringToBytes(s));
74
- }
75
- function export_(nm, exportdesc) {
76
- return [name(nm), exportdesc];
77
- }
78
- function exportsec(exports) {
79
- return section(SECTION_ID_EXPORT, vec(exports));
80
- }
81
- const funcidx = u32;
82
- const exportdesc = {
83
- func(idx) {
84
- return [0x00, funcidx(idx)];
85
- },
86
- table(idx) {
87
- return [0x01, tableidx(idx)];
88
- },
89
- mem(idx) {
90
- return [0x02, memidx(idx)];
91
- },
92
- global(idx) {
93
- return [0x03, globalidx(idx)];
94
- },
95
- };
96
- function module(sections) {
97
- return [magic(), version(), sections];
98
- }
99
- const instr = {
100
- unreachable: 0x00,
101
- nop: 0x01,
102
- block: 0x02,
103
- loop: 0x03,
104
- if: 0x04,
105
- else: 0x05,
106
- end: 0x0b,
107
- br: 0x0c,
108
- br_if: 0x0d,
109
- br_table: 0x0e,
110
- return: 0x0f,
111
- call: 0x10,
112
- call_indirect: 0x11,
113
- drop: 0x1a,
114
- select: 0x1b,
115
- local: {
116
- get: 0x20,
117
- set: 0x21,
118
- tee: 0x22,
119
- },
120
- global: {
121
- get: 0x23,
122
- set: 0x24,
123
- tee: 0x25,
124
- },
125
- memory: {
126
- size: 0x3f,
127
- grow: 0x40,
128
- },
129
- i32: {
130
- load: 0x28,
131
- const: 0x41,
132
- eqz: 0x45,
133
- eq: 0x46,
134
- ne: 0x47,
135
- lt_s: 0x48,
136
- lt_u: 0x49,
137
- gt_s: 0x4a,
138
- gt_u: 0x4b,
139
- le_s: 0x4c,
140
- le_u: 0x4d,
141
- ge_s: 0x4e,
142
- ge_u: 0x4f,
143
- add: 0x6a,
144
- sub: 0x6b,
145
- mul: 0x6c,
146
- },
147
- i64: {
148
- store32: 0x3e,
149
- const: 0x42,
150
- add: 0x7c,
151
- sub: 0x7d,
152
- mul: 0x7e,
153
- },
154
- f32: {
155
- const: 0x43,
156
- add: 0x92,
157
- sub: 0x93,
158
- mul: 0x94,
159
- div: 0x95,
160
- },
161
- f64: {
162
- load: 0x2b,
163
- store: 0x39,
164
- const: 0x44,
165
- add: 0xa0,
166
- sub: 0xa1,
167
- mul: 0xa2,
168
- div: 0xa3,
169
- reinterpret_i64: 0xbf,
170
- },
171
- };
172
- const SEVEN_BIT_MASK_BIG_INT = 127n;
173
- const CONTINUATION_BIT = 0b10000000;
174
- function u32(v) {
175
- let val = BigInt(v);
176
- let more = true;
177
- const r = [];
178
- while (more) {
179
- const b = Number(val & SEVEN_BIT_MASK_BIG_INT);
180
- val = val >> 7n;
181
- more = val !== 0n;
182
- if (more) {
183
- r.push(b | CONTINUATION_BIT);
184
- }
185
- else {
186
- r.push(b);
187
- }
188
- }
189
- return r;
190
- }
191
- function i32(v) {
192
- let val = BigInt(v);
193
- const r = [];
194
- let more = true;
195
- while (more) {
196
- const b = Number(val & 127n);
197
- const signBitSet = !!(b & 0x40);
198
- val = val >> 7n;
199
- if ((val === 0n && !signBitSet) || (val === -1n && signBitSet)) {
200
- more = false;
201
- r.push(b);
202
- }
203
- else {
204
- r.push(b | CONTINUATION_BIT);
205
- }
206
- }
207
- return r;
208
- }
209
- function f64(v) {
210
- var buf = new ArrayBuffer(8);
211
- new Float64Array(buf)[0] = v;
212
- return Array.from(new Uint8Array(buf));
213
- }
214
- function locals(n, type) {
215
- return [u32(n), type];
216
- }
217
- // mod:name nm:name d:importdesc
218
- function import_(mod, nm, d) {
219
- return [name(mod), name(nm), d];
220
- }
221
- // im*:vec(import)
222
- function importsec(ims) {
223
- return section(SECTION_ID_IMPORT, vec(ims));
224
- }
225
- const importdesc = {
226
- // x:typeidx
227
- func(x) {
228
- return [0x00, x];
229
- },
230
- // tt:tabletype
231
- table(tt) {
232
- return [0x01, tt];
233
- },
234
- // mt:memtype
235
- mem(mt) {
236
- return [0x02, mt];
237
- },
238
- // gt:globaltype
239
- global(gt) {
240
- return [0x03, gt];
241
- },
242
- };
243
- const memidx = u32;
244
- function memsec(mems) {
245
- return section(SECTION_ID_MEMORY, vec(mems));
246
- }
247
- // lim:limits
248
- function memtype(limits) {
249
- return limits;
250
- }
251
- const limits = {
252
- min(n) {
253
- return [0x00, u32(n)];
254
- },
255
- minmax(n, m) {
256
- return [0x01, u32(n), u32(m)];
257
- },
258
- };
259
- const globalidx = u32;
260
- const mut = {
261
- const: 0x00,
262
- var: 0x01,
263
- };
264
- // t:valtype m:mut
265
- function globaltype(t, m) {
266
- return [t, m];
267
- }
268
- // gt:globaltype e:expr
269
- function global(gt, e) {
270
- return [gt, e];
271
- }
272
- // glob*:vec(global)
273
- function globalsec(globs) {
274
- return section(SECTION_ID_GLOBAL, vec(globs));
275
- }
276
- function tabletype(elemtype, limits) {
277
- return [elemtype, limits];
278
- }
279
- function table(tabletype) {
280
- return tabletype;
281
- }
282
- function tablesec(tables) {
283
- return section(SECTION_ID_TABLE, vec(tables));
284
- }
285
- const elemtype = { funcref: 0x70 };
286
- const tableidx = u32;
287
- const start = funcidx;
288
- // st:start
289
- function startsec(st) {
290
- return section(SECTION_ID_START, st);
291
- }
292
- // x:memidx e:expr b∗:vec(byte)
293
- function data(x, e, bs) {
294
- return [x, e, vec(bs)];
295
- }
296
- function datasec(segs) {
297
- return section(SECTION_ID_DATA, vec(segs));
298
- }
299
- // x:tableidx e:expr y∗:vec(funcidx)
300
- function elem(x, e, ys) {
301
- return [x, e, vec(ys)];
302
- }
303
- function elemsec(segs) {
304
- return section(SECTION_ID_ELEMENT, vec(segs));
305
- }
306
- function memarg(align, offset) {
307
- return [u32(align), u32(offset)];
308
- }
309
- export { blocktype, code, codesec, data, datasec, elem, elemsec, elemtype, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, global, globalsec, globaltype, i32, import_, importdesc, importsec, instr, limits, locals, memarg, memsec, memtype, module, mut, name, section, start, startsec, table, tableidx, tablesec, tabletype, typeidx, typesec, u32, valtype, vec, };
package/index.ts DELETED
@@ -1,432 +0,0 @@
1
- const SECTION_ID_TYPE = 1;
2
- const SECTION_ID_IMPORT = 2;
3
- const SECTION_ID_FUNCTION = 3;
4
- const SECTION_ID_TABLE = 4;
5
- const SECTION_ID_MEMORY = 5;
6
- const SECTION_ID_GLOBAL = 6;
7
- const SECTION_ID_EXPORT = 7;
8
- const SECTION_ID_START = 8;
9
- const SECTION_ID_ELEMENT = 9;
10
- const SECTION_ID_CODE = 10;
11
- const SECTION_ID_DATA = 11;
12
-
13
- const TYPE_FUNCTION = 0x60;
14
-
15
- type BytecodeFragment = (number | BytecodeFragment)[];
16
-
17
- function stringToBytes(s: string): number[] {
18
- const bytes = new TextEncoder().encode(s);
19
- return Array.from(bytes);
20
- }
21
-
22
- function int32ToBytes(v: number): number[] {
23
- // prettier-ignore
24
- return [
25
- v & 0xff,
26
- (v >> 8) & 0xff,
27
- (v >> 16) & 0xff,
28
- (v >> 24) & 0xff,
29
- ];
30
- }
31
-
32
- function magic(): number[] {
33
- // [0x00, 0x61, 0x73, 0x6d]
34
- return stringToBytes("\0asm");
35
- }
36
-
37
- function version(): number[] {
38
- // [0x01, 0x00, 0x00, 0x00]
39
- return int32ToBytes(1);
40
- }
41
-
42
- enum valtype {
43
- i32 = 0x7f,
44
- i64 = 0x7e,
45
- f32 = 0x7d,
46
- f64 = 0x7c,
47
- }
48
-
49
- // t: valtype
50
- function blocktype(t?: valtype): number {
51
- return t ?? 0x40;
52
- }
53
-
54
- function vec<T extends BytecodeFragment>(elements: T): BytecodeFragment {
55
- return [u32(elements.length), ...elements];
56
- }
57
-
58
- function section(id: number, contents: BytecodeFragment) {
59
- const sizeInBytes = (contents as any[]).flat(Infinity).length;
60
- return [id, u32(sizeInBytes), contents];
61
- }
62
-
63
- function functype(
64
- paramTypes: valtype[],
65
- resultTypes: valtype[],
66
- ): BytecodeFragment {
67
- return [TYPE_FUNCTION, vec(paramTypes), vec(resultTypes)];
68
- }
69
-
70
- function typesec(functypes: BytecodeFragment): BytecodeFragment {
71
- return section(SECTION_ID_TYPE, vec(functypes));
72
- }
73
-
74
- const typeidx = u32;
75
-
76
- function funcsec(typeidxs: BytecodeFragment): BytecodeFragment {
77
- return section(SECTION_ID_FUNCTION, vec(typeidxs));
78
- }
79
-
80
- function code(func: BytecodeFragment): BytecodeFragment {
81
- const sizeInBytes = (func as any[]).flat(Infinity).length;
82
- return [u32(sizeInBytes), func];
83
- }
84
-
85
- function func(
86
- locals: BytecodeFragment,
87
- body: BytecodeFragment,
88
- ): BytecodeFragment {
89
- return [vec(locals), body];
90
- }
91
-
92
- function codesec(codes: BytecodeFragment): BytecodeFragment {
93
- return section(SECTION_ID_CODE, vec(codes));
94
- }
95
-
96
- function name(s: string): BytecodeFragment {
97
- return vec(stringToBytes(s));
98
- }
99
-
100
- function export_(nm: string, exportdesc: BytecodeFragment): BytecodeFragment {
101
- return [name(nm), exportdesc];
102
- }
103
-
104
- function exportsec(exports: BytecodeFragment): BytecodeFragment {
105
- return section(SECTION_ID_EXPORT, vec(exports));
106
- }
107
-
108
- const funcidx = u32;
109
-
110
- const exportdesc = {
111
- func(idx: number): BytecodeFragment {
112
- return [0x00, funcidx(idx)];
113
- },
114
- table(idx: number): BytecodeFragment {
115
- return [0x01, tableidx(idx)];
116
- },
117
- mem(idx: number): BytecodeFragment {
118
- return [0x02, memidx(idx)];
119
- },
120
- global(idx: number): BytecodeFragment {
121
- return [0x03, globalidx(idx)];
122
- },
123
- };
124
-
125
- function module(sections): BytecodeFragment {
126
- return [magic(), version(), sections];
127
- }
128
-
129
- const instr = {
130
- unreachable: 0x00,
131
- nop: 0x01,
132
- block: 0x02,
133
- loop: 0x03,
134
- if: 0x04,
135
- else: 0x05,
136
- end: 0x0b,
137
- br: 0x0c,
138
- br_if: 0x0d,
139
- br_table: 0x0e,
140
- return: 0x0f,
141
- call: 0x10,
142
- call_indirect: 0x11,
143
- drop: 0x1a,
144
- select: 0x1b,
145
-
146
- local: {
147
- get: 0x20,
148
- set: 0x21,
149
- tee: 0x22,
150
- },
151
- global: {
152
- get: 0x23,
153
- set: 0x24,
154
- tee: 0x25,
155
- },
156
- memory: {
157
- size: 0x3f,
158
- grow: 0x40,
159
- },
160
-
161
- i32: {
162
- load: 0x28,
163
- const: 0x41,
164
- eqz: 0x45,
165
- eq: 0x46,
166
- ne: 0x47,
167
- lt_s: 0x48,
168
- lt_u: 0x49,
169
- gt_s: 0x4a,
170
- gt_u: 0x4b,
171
- le_s: 0x4c,
172
- le_u: 0x4d,
173
- ge_s: 0x4e,
174
- ge_u: 0x4f,
175
- add: 0x6a,
176
- sub: 0x6b,
177
- mul: 0x6c,
178
- },
179
- i64: {
180
- store32: 0x3e,
181
- const: 0x42,
182
- add: 0x7c,
183
- sub: 0x7d,
184
- mul: 0x7e,
185
- },
186
- f32: {
187
- const: 0x43,
188
- add: 0x92,
189
- sub: 0x93,
190
- mul: 0x94,
191
- div: 0x95,
192
- },
193
- f64: {
194
- load: 0x2b,
195
- store: 0x39,
196
- const: 0x44,
197
- add: 0xa0,
198
- sub: 0xa1,
199
- mul: 0xa2,
200
- div: 0xa3,
201
- reinterpret_i64: 0xbf,
202
- },
203
- };
204
-
205
- const SEVEN_BIT_MASK_BIG_INT = 0b01111111n;
206
- const CONTINUATION_BIT = 0b10000000;
207
-
208
- function u32(v: number | bigint): number[] {
209
- let val = BigInt(v);
210
- let more = true;
211
- const r = [];
212
-
213
- while (more) {
214
- const b = Number(val & SEVEN_BIT_MASK_BIG_INT);
215
- val = val >> 7n;
216
- more = val !== 0n;
217
- if (more) {
218
- r.push(b | CONTINUATION_BIT);
219
- } else {
220
- r.push(b);
221
- }
222
- }
223
- return r;
224
- }
225
-
226
- function i32(v: number | bigint): number[] {
227
- let val = BigInt(v);
228
- const r = [];
229
-
230
- let more = true;
231
- while (more) {
232
- const b = Number(val & 0b01111111n);
233
- const signBitSet = !!(b & 0x40);
234
-
235
- val = val >> 7n;
236
-
237
- if ((val === 0n && !signBitSet) || (val === -1n && signBitSet)) {
238
- more = false;
239
- r.push(b);
240
- } else {
241
- r.push(b | CONTINUATION_BIT);
242
- }
243
- }
244
-
245
- return r;
246
- }
247
-
248
- function f64(v: number): number[] {
249
- var buf = new ArrayBuffer(8);
250
- new Float64Array(buf)[0] = v;
251
- return Array.from(new Uint8Array(buf));
252
- }
253
-
254
- function locals(n: number, type: valtype): BytecodeFragment {
255
- return [u32(n), type];
256
- }
257
-
258
- // mod:name nm:name d:importdesc
259
- function import_(
260
- mod: string,
261
- nm: string,
262
- d: BytecodeFragment,
263
- ): BytecodeFragment {
264
- return [name(mod), name(nm), d];
265
- }
266
-
267
- // im*:vec(import)
268
- function importsec(ims: BytecodeFragment): BytecodeFragment {
269
- return section(SECTION_ID_IMPORT, vec(ims));
270
- }
271
-
272
- const importdesc = {
273
- // x:typeidx
274
- func(x: BytecodeFragment): BytecodeFragment {
275
- return [0x00, x];
276
- },
277
- // tt:tabletype
278
- table(tt: BytecodeFragment): BytecodeFragment {
279
- return [0x01, tt];
280
- },
281
- // mt:memtype
282
- mem(mt: BytecodeFragment): BytecodeFragment {
283
- return [0x02, mt];
284
- },
285
- // gt:globaltype
286
- global(gt: BytecodeFragment): BytecodeFragment {
287
- return [0x03, gt];
288
- },
289
- };
290
-
291
- const memidx = u32;
292
-
293
- function memsec(mems: BytecodeFragment[]) {
294
- return section(SECTION_ID_MEMORY, vec(mems));
295
- }
296
-
297
- // lim:limits
298
- function memtype(limits: BytecodeFragment) {
299
- return limits;
300
- }
301
-
302
- const limits = {
303
- min(n: number) {
304
- return [0x00, u32(n)];
305
- },
306
- minmax(n: number, m: number) {
307
- return [0x01, u32(n), u32(m)];
308
- },
309
- };
310
-
311
- const globalidx = u32;
312
-
313
- const mut = {
314
- const: 0x00,
315
- var: 0x01,
316
- };
317
-
318
- // t:valtype m:mut
319
- function globaltype(t, m) {
320
- return [t, m];
321
- }
322
-
323
- // gt:globaltype e:expr
324
- function global(gt, e) {
325
- return [gt, e];
326
- }
327
-
328
- // glob*:vec(global)
329
- function globalsec(globs: BytecodeFragment[]) {
330
- return section(SECTION_ID_GLOBAL, vec(globs));
331
- }
332
-
333
- function tabletype(elemtype: number, limits: BytecodeFragment) {
334
- return [elemtype, limits];
335
- }
336
-
337
- function table(tabletype: BytecodeFragment) {
338
- return tabletype;
339
- }
340
-
341
- function tablesec(tables: BytecodeFragment[]) {
342
- return section(SECTION_ID_TABLE, vec(tables));
343
- }
344
-
345
- const elemtype = { funcref: 0x70 };
346
-
347
- const tableidx = u32;
348
-
349
- const start = funcidx;
350
-
351
- // st:start
352
- function startsec(st: BytecodeFragment) {
353
- return section(SECTION_ID_START, st);
354
- }
355
-
356
- // x:memidx e:expr b∗:vec(byte)
357
- function data(
358
- x: BytecodeFragment,
359
- e: BytecodeFragment,
360
- bs: BytecodeFragment[],
361
- ) {
362
- return [x, e, vec(bs)];
363
- }
364
-
365
- function datasec(segs: BytecodeFragment[]) {
366
- return section(SECTION_ID_DATA, vec(segs));
367
- }
368
-
369
- // x:tableidx e:expr y∗:vec(funcidx)
370
- function elem(
371
- x: BytecodeFragment,
372
- e: BytecodeFragment,
373
- ys: BytecodeFragment[],
374
- ) {
375
- return [x, e, vec(ys)];
376
- }
377
-
378
- function elemsec(segs: BytecodeFragment[]) {
379
- return section(SECTION_ID_ELEMENT, vec(segs));
380
- }
381
-
382
- function memarg(align: number, offset: number) {
383
- return [u32(align), u32(offset)];
384
- }
385
-
386
- export {
387
- blocktype,
388
- BytecodeFragment,
389
- code,
390
- codesec,
391
- data,
392
- datasec,
393
- elem,
394
- elemsec,
395
- elemtype,
396
- export_,
397
- exportdesc,
398
- exportsec,
399
- f64,
400
- func,
401
- funcidx,
402
- funcsec,
403
- functype,
404
- global,
405
- globalsec,
406
- globaltype,
407
- i32,
408
- import_,
409
- importdesc,
410
- importsec,
411
- instr,
412
- limits,
413
- locals,
414
- memarg,
415
- memsec,
416
- memtype,
417
- module,
418
- mut,
419
- name,
420
- section,
421
- start,
422
- startsec,
423
- table,
424
- tableidx,
425
- tablesec,
426
- tabletype,
427
- typeidx,
428
- typesec,
429
- u32,
430
- valtype,
431
- vec,
432
- };
package/tsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "files": ["index.ts"],
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "target": "es2020",
6
- "declaration": true
7
- }
8
- }
Binary file