@wasmgroundup/emit 0.2.4 → 0.2.6

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/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ declare enum valtype {
5
5
  f32 = 125,
6
6
  f64 = 124
7
7
  }
8
+ declare function blocktype(t?: valtype): number;
8
9
  declare function vec<T extends BytecodeFragment>(elements: T): BytecodeFragment;
9
10
  declare function section(id: number, contents: BytecodeFragment): (number | BytecodeFragment)[];
10
11
  declare function functype(paramTypes: valtype[], resultTypes: valtype[]): BytecodeFragment;
@@ -20,10 +21,13 @@ declare function exportsec(exports: BytecodeFragment): BytecodeFragment;
20
21
  declare const funcidx: typeof u32;
21
22
  declare const exportdesc: {
22
23
  func(idx: number): BytecodeFragment;
24
+ global(idx: number): BytecodeFragment;
23
25
  };
24
26
  declare function module(sections: any): BytecodeFragment;
25
27
  declare const instr: {
26
28
  nop: number;
29
+ if: number;
30
+ else: number;
27
31
  end: number;
28
32
  call: number;
29
33
  local: {
@@ -31,6 +35,10 @@ declare const instr: {
31
35
  set: number;
32
36
  tee: number;
33
37
  };
38
+ global: {
39
+ get: number;
40
+ set: number;
41
+ };
34
42
  i32: {
35
43
  const: number;
36
44
  add: number;
@@ -67,4 +75,11 @@ declare function importsec(ims: BytecodeFragment): BytecodeFragment;
67
75
  declare const importdesc: {
68
76
  func(x: number): BytecodeFragment;
69
77
  };
70
- export { BytecodeFragment, code, codesec, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, i32, import_, importdesc, importsec, instr, locals, module, name, section, typeidx, typesec, valtype, vec, };
78
+ declare const mut: {
79
+ const: number;
80
+ var: number;
81
+ };
82
+ declare function globaltype(t: any, m: any): any[];
83
+ declare function global(gt: any, e: any): any[];
84
+ declare function globalsec(globs: any): (number | BytecodeFragment)[];
85
+ export { blocktype, BytecodeFragment, code, codesec, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, global, globalsec, globaltype, i32, import_, importdesc, importsec, instr, locals, module, mut, name, section, typeidx, typesec, valtype, vec, };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const SECTION_ID_TYPE = 1;
2
2
  const SECTION_ID_IMPORT = 2;
3
3
  const SECTION_ID_FUNCTION = 3;
4
+ const SECTION_ID_GLOBAL = 6;
4
5
  const SECTION_ID_EXPORT = 7;
5
6
  const SECTION_ID_CODE = 10;
6
7
  const TYPE_FUNCTION = 0x60;
@@ -32,6 +33,10 @@ var valtype;
32
33
  valtype[valtype["f32"] = 125] = "f32";
33
34
  valtype[valtype["f64"] = 124] = "f64";
34
35
  })(valtype || (valtype = {}));
36
+ // t: valtype
37
+ function blocktype(t) {
38
+ return t ?? 0x40;
39
+ }
35
40
  function vec(elements) {
36
41
  return [u32(elements.length), ...elements];
37
42
  }
@@ -73,6 +78,9 @@ const exportdesc = {
73
78
  func(idx) {
74
79
  return [0x00, funcidx(idx)];
75
80
  },
81
+ global(idx) {
82
+ return [0x03, globalidx(idx)];
83
+ },
76
84
  };
77
85
  function module(sections) {
78
86
  return [magic(), version(), sections];
@@ -83,6 +91,8 @@ var numtype;
83
91
  })(numtype || (numtype = {}));
84
92
  const instr = {
85
93
  nop: 0x01,
94
+ if: 0x04,
95
+ else: 0x05,
86
96
  end: 0x0b,
87
97
  call: 0x10,
88
98
  local: {
@@ -90,6 +100,10 @@ const instr = {
90
100
  set: 0x21,
91
101
  tee: 0x22,
92
102
  },
103
+ global: {
104
+ get: 0x23,
105
+ set: 0x24,
106
+ },
93
107
  i32: {
94
108
  const: 0x41,
95
109
  add: 0x6a,
@@ -176,4 +190,21 @@ const importdesc = {
176
190
  return [0x00, funcidx(x)];
177
191
  },
178
192
  };
179
- export { code, codesec, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, i32, import_, importdesc, importsec, instr, locals, module, name, section, typeidx, typesec, valtype, vec, };
193
+ const globalidx = u32;
194
+ const mut = {
195
+ const: 0x00,
196
+ var: 0x01,
197
+ };
198
+ // t:valtype m:mut
199
+ function globaltype(t, m) {
200
+ return [t, m];
201
+ }
202
+ // gt:globaltype e:expr
203
+ function global(gt, e) {
204
+ return [gt, e];
205
+ }
206
+ // glob*:vec(global)
207
+ function globalsec(globs) {
208
+ return section(SECTION_ID_GLOBAL, vec(globs));
209
+ }
210
+ export { blocktype, code, codesec, export_, exportdesc, exportsec, f64, func, funcidx, funcsec, functype, global, globalsec, globaltype, i32, import_, importdesc, importsec, instr, locals, module, mut, name, section, typeidx, typesec, valtype, vec, };
package/index.test.ts CHANGED
@@ -2,6 +2,7 @@ import { expect, test } from "bun:test";
2
2
 
3
3
  import {
4
4
  BytecodeFragment,
5
+ blocktype,
5
6
  code,
6
7
  codesec,
7
8
  export_,
@@ -12,16 +13,27 @@ import {
12
13
  funcidx,
13
14
  funcsec,
14
15
  functype,
16
+ global,
17
+ globalsec,
18
+ globaltype,
19
+ i32,
15
20
  import_,
16
21
  importdesc,
17
22
  importsec,
18
23
  instr,
19
24
  module,
25
+ mut,
20
26
  typeidx,
21
27
  typesec,
22
28
  valtype,
23
29
  } from "./index";
24
30
 
31
+ const PI = 3.141592653589793115997963468544185161590576171875;
32
+
33
+ function fragmentToUInt8Array(frag: BytecodeFragment): Uint8Array {
34
+ return Uint8Array.from((frag as any).flat(Infinity));
35
+ }
36
+
25
37
  test("simple modules", async () => {
26
38
  const makeModule = (paramTypes, resultTypes, body) => {
27
39
  const mod = module([
@@ -30,7 +42,7 @@ test("simple modules", async () => {
30
42
  exportsec([export_("main", exportdesc.func(0))]),
31
43
  codesec([code(func([], body))]),
32
44
  ]);
33
- return Uint8Array.from(mod.flat(Infinity));
45
+ return fragmentToUInt8Array(mod);
34
46
  };
35
47
  const runMain = async (bytes, args) => {
36
48
  const { instance } = await WebAssembly.instantiate(bytes);
@@ -74,7 +86,7 @@ test("imports", async () => {
74
86
  code(func([], [instr.local.get, 0, instr.call, funcidx(0), instr.end])),
75
87
  ]),
76
88
  ]);
77
- return Uint8Array.from(mod.flat(Infinity));
89
+ return fragmentToUInt8Array(mod);
78
90
  };
79
91
 
80
92
  const { instance } = await WebAssembly.instantiate(makeModule(), {
@@ -90,23 +102,108 @@ test("imports", async () => {
90
102
  });
91
103
 
92
104
  test("f64", async () => {
93
- const PI = 3.141592653589793115997963468544185161590576171875;
94
105
  const makeModule = () => {
95
106
  const mod = module([
96
107
  typesec([functype([], [valtype.f64])]),
97
- funcsec([typeidx(0), typeidx(0)]),
108
+ funcsec([typeidx(0), typeidx(0), typeidx(0)]),
98
109
  exportsec([
99
110
  export_("pi", exportdesc.func(0)),
100
111
  export_("nan", exportdesc.func(1)),
112
+ export_("one", exportdesc.func(2)),
101
113
  ]),
102
114
  codesec([
103
115
  code(func([], [instr.f64.const, f64(PI), instr.end])),
104
116
  code(func([], [instr.f64.const, f64(Number.NaN), instr.end])),
117
+ code(func([], [instr.f64.const, f64(1), instr.end])),
105
118
  ]),
106
119
  ]);
107
- return Uint8Array.from(mod.flat(Infinity));
120
+ return fragmentToUInt8Array(mod);
108
121
  };
109
122
  const { instance } = await WebAssembly.instantiate(makeModule());
110
123
  expect(instance.exports.pi()).toBe(PI);
111
124
  expect(instance.exports.nan()).toBe(Number.NaN);
125
+ expect(instance.exports.one()).toBe(1);
126
+ });
127
+
128
+ test("globals", async () => {
129
+ const makeModule = () => {
130
+ const mod = module([
131
+ typesec([
132
+ functype([], [valtype.f64]), // pi
133
+ functype([], [valtype.i32]), // getVar
134
+ functype([], []), // incVar
135
+ ]),
136
+ funcsec([typeidx(0), typeidx(1), typeidx(2)]),
137
+ globalsec([
138
+ global(globaltype(valtype.f64, mut.const), [
139
+ instr.f64.const,
140
+ f64(PI),
141
+ instr.end,
142
+ ]),
143
+ global(globaltype(valtype.i32, mut.var), [
144
+ instr.i32.const,
145
+ i32(0),
146
+ instr.end,
147
+ ]),
148
+ ]),
149
+ exportsec([
150
+ export_("pi", exportdesc.func(0)),
151
+ export_("getVar", exportdesc.func(1)),
152
+ export_("incVar", exportdesc.func(2)),
153
+ ]),
154
+ codesec([
155
+ code(func([], [instr.global.get, 0, instr.end])), // pi
156
+ code(func([], [instr.global.get, 1, instr.end])), // getVar
157
+ code(
158
+ // prettier-ignore
159
+ func([], [
160
+ instr.global.get, 1,
161
+ instr.i32.const, 1,
162
+ instr.i32.add,
163
+ instr.global.set, 1,
164
+ instr.end,
165
+ ],
166
+ ),
167
+ ), // incVar
168
+ ]),
169
+ ]);
170
+ return fragmentToUInt8Array(mod);
171
+ };
172
+
173
+ const { exports } = (await WebAssembly.instantiate(makeModule())).instance;
174
+ expect(exports.pi()).toBe(PI);
175
+ expect(exports.getVar()).toBe(0);
176
+ exports.incVar();
177
+ expect(exports.getVar()).toBe(1);
178
+ });
179
+
180
+ test("if", async () => {
181
+ const makeModule = () => {
182
+ const mod = module([
183
+ typesec([functype([valtype.i32], [valtype.f64])]),
184
+ funcsec([typeidx(0)]),
185
+ exportsec([export_("maybePi", exportdesc.func(0))]),
186
+ codesec([
187
+ code(
188
+ func(
189
+ [],
190
+ // prettier-ignore
191
+ [
192
+ instr.local.get, 0,
193
+ instr.if, blocktype(valtype.f64),
194
+ instr.f64.const, f64(PI),
195
+ instr.else,
196
+ instr.f64.const, f64(0),
197
+ instr.end,
198
+ instr.end,
199
+ ],
200
+ ),
201
+ ),
202
+ ]),
203
+ ]);
204
+ return fragmentToUInt8Array(mod);
205
+ };
206
+ const { exports } = (await WebAssembly.instantiate(makeModule())).instance;
207
+ expect(exports.maybePi(1)).toBe(PI);
208
+ expect(exports.maybePi(0)).toBe(0);
112
209
  });
package/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  const SECTION_ID_TYPE = 1;
2
2
  const SECTION_ID_IMPORT = 2;
3
3
  const SECTION_ID_FUNCTION = 3;
4
+ const SECTION_ID_GLOBAL = 6;
4
5
  const SECTION_ID_EXPORT = 7;
5
6
  const SECTION_ID_CODE = 10;
6
7
 
@@ -40,6 +41,11 @@ enum valtype {
40
41
  f64 = 0x7c,
41
42
  }
42
43
 
44
+ // t: valtype
45
+ function blocktype(t?: valtype): number {
46
+ return t ?? 0x40;
47
+ }
48
+
43
49
  function vec<T extends BytecodeFragment>(elements: T): BytecodeFragment {
44
50
  return [u32(elements.length), ...elements];
45
51
  }
@@ -100,6 +106,9 @@ const exportdesc = {
100
106
  func(idx: number): BytecodeFragment {
101
107
  return [0x00, funcidx(idx)];
102
108
  },
109
+ global(idx: number): BytecodeFragment {
110
+ return [0x03, globalidx(idx)];
111
+ },
103
112
  };
104
113
 
105
114
  function module(sections): BytecodeFragment {
@@ -112,6 +121,8 @@ enum numtype {
112
121
 
113
122
  const instr = {
114
123
  nop: 0x01,
124
+ if: 0x04,
125
+ else: 0x05,
115
126
  end: 0x0b,
116
127
  call: 0x10,
117
128
 
@@ -120,6 +131,11 @@ const instr = {
120
131
  set: 0x21,
121
132
  tee: 0x22,
122
133
  },
134
+ global: {
135
+ get: 0x23,
136
+ set: 0x24,
137
+ },
138
+
123
139
  i32: {
124
140
  const: 0x41,
125
141
  add: 0x6a,
@@ -222,7 +238,30 @@ const importdesc = {
222
238
  },
223
239
  };
224
240
 
241
+ const globalidx = u32;
242
+
243
+ const mut = {
244
+ const: 0x00,
245
+ var: 0x01,
246
+ };
247
+
248
+ // t:valtype m:mut
249
+ function globaltype(t, m) {
250
+ return [t, m];
251
+ }
252
+
253
+ // gt:globaltype e:expr
254
+ function global(gt, e) {
255
+ return [gt, e];
256
+ }
257
+
258
+ // glob*:vec(global)
259
+ function globalsec(globs) {
260
+ return section(SECTION_ID_GLOBAL, vec(globs));
261
+ }
262
+
225
263
  export {
264
+ blocktype,
226
265
  BytecodeFragment,
227
266
  code,
228
267
  codesec,
@@ -234,6 +273,9 @@ export {
234
273
  funcidx,
235
274
  funcsec,
236
275
  functype,
276
+ global,
277
+ globalsec,
278
+ globaltype,
237
279
  i32,
238
280
  import_,
239
281
  importdesc,
@@ -241,6 +283,7 @@ export {
241
283
  instr,
242
284
  locals,
243
285
  module,
286
+ mut,
244
287
  name,
245
288
  section,
246
289
  typeidx,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wasmgroundup/emit",
3
3
  "description": "A library for creating binary-encoded WebAssembly modules",
4
- "version": "0.2.4",
4
+ "version": "0.2.6",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "repository": {