@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 +16 -1
- package/dist/index.js +32 -1
- package/index.test.ts +102 -5
- package/index.ts +43 -0
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|