porffor 0.2.0-09999e8 → 0.2.0-15592d6

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.
@@ -15,7 +15,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
15
15
  if (name) out += `${makeSignature(params, returns)} ;; $${name} (${ind})\n`;
16
16
 
17
17
  const justLocals = Object.values(locals).sort((a, b) => a.idx - b.idx).slice(params.length);
18
- if (justLocals.length > 0) out += ` local ${justLocals.map(x => invValtype[x.type]).join(' ')}\n`;
18
+ if (name && justLocals.length > 0) out += ` local ${justLocals.map(x => invValtype[x.type]).join(' ')}\n`;
19
19
 
20
20
  let i = -1, lastInst;
21
21
  let byte = 0;
@@ -32,7 +32,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
32
32
  inst = [ [ inst[0], inst[1] ], ...inst.slice(2) ];
33
33
  }
34
34
 
35
- if (inst[0] === Opcodes.end || inst[0] === Opcodes.else || inst[0] === Opcodes.catch_all) depth--;
35
+ if (depth > 0 && (inst[0] === Opcodes.end || inst[0] === Opcodes.else || inst[0] === Opcodes.catch_all)) depth--;
36
36
 
37
37
  out += ' '.repeat(Math.max(0, depth * 2));
38
38
 
@@ -119,7 +119,7 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
119
119
  export const highlightAsm = asm => asm
120
120
  .replace(/(local|global|memory)\.[^\s]*/g, _ => `\x1B[31m${_}\x1B[0m`)
121
121
  .replace(/(i(8|16|32|64)x[0-9]+|v128)(\.[^\s]*)?/g, _ => `\x1B[34m${_}\x1B[0m`)
122
- .replace(/[^m](i32|i64|f32|f64|drop)(\.[^\s]*)?/g, _ => `${_[0]}\x1B[36m${_.slice(1)}\x1B[0m`)
122
+ .replace(/(i32|i64|f32|f64|drop)(\.[^\s]*)?/g, _ => `\x1B[36m${_}\x1B[0m`)
123
123
  .replace(/(return_call|call|br_if|br|return|rethrow|throw)/g, _ => `\x1B[35m${_}\x1B[0m`)
124
124
  .replace(/(block|loop|if|end|else|try|catch_all|catch|delegate)/g, _ => `\x1B[95m${_}\x1B[0m`)
125
125
  .replace(/unreachable/g, _ => `\x1B[91m${_}\x1B[0m`)
@@ -0,0 +1,3 @@
1
+
2
+ export const BuiltinFuncs = function() {
3
+ };
package/compiler/index.js CHANGED
@@ -4,7 +4,6 @@ import codeGen from './codeGen.js';
4
4
  import opt from './opt.js';
5
5
  import produceSections from './sections.js';
6
6
  import decompile from './decompile.js';
7
- import { BuiltinPreludes } from './builtins.js';
8
7
  import toc from './2c.js';
9
8
 
10
9
  globalThis.decompile = decompile;
@@ -37,10 +36,6 @@ export default (code, flags) => {
37
36
  globalThis.allocLog = process.argv.includes('-alloc-log');
38
37
  globalThis.regexLog = process.argv.includes('-regex-log');
39
38
 
40
- for (const x in BuiltinPreludes) {
41
- if (code.indexOf(x + '(') !== -1) code = BuiltinPreludes[x] + code;
42
- }
43
-
44
39
  const t0 = performance.now();
45
40
  const program = parse(code, flags);
46
41
  if (flags.includes('info')) console.log(`1. parsed in ${(performance.now() - t0).toFixed(2)}ms`);
@@ -52,7 +47,7 @@ export default (code, flags) => {
52
47
  if (process.argv.includes('-funcs')) logFuncs(funcs, globals, exceptions);
53
48
 
54
49
  const t2 = performance.now();
55
- opt(funcs, globals, pages);
50
+ opt(funcs, globals, pages, tags, exceptions);
56
51
  if (flags.includes('info')) console.log(`3. optimized code in ${(performance.now() - t2).toFixed(2)}ms`);
57
52
 
58
53
  if (process.argv.includes('-opt-funcs')) logFuncs(funcs, globals, exceptions);
@@ -68,11 +63,17 @@ export default (code, flags) => {
68
63
  console.log([...pages.keys()].map(x => `\x1B[36m - ${x}\x1B[0m`).join('\n') + '\n');
69
64
  }
70
65
 
71
- const out = { wasm: sections, funcs, globals, tags, exceptions, pages };
66
+ const out = { wasm: sections, funcs, globals, tags, exceptions, pages, data };
72
67
 
73
68
  const target = getArg('target') ?? getArg('t') ?? 'wasm';
74
69
  const outFile = getArg('o');
75
70
 
71
+ if (target === 'wasm' && outFile) {
72
+ writeFileSync(outFile, Buffer.from(sections));
73
+
74
+ if (process.version) process.exit();
75
+ }
76
+
76
77
  if (target === 'c') {
77
78
  const c = toc(out);
78
79
  out.c = c;
@@ -87,11 +88,16 @@ export default (code, flags) => {
87
88
  }
88
89
 
89
90
  if (target === 'native') {
90
- const compiler = getArg('compiler') ?? 'clang';
91
+ let compiler = getArg('compiler') ?? 'clang';
91
92
  const cO = getArg('cO') ?? 'Ofast';
92
93
 
94
+ if (compiler === 'zig') compiler = [ 'zig', 'cc' ];
95
+ else compiler = [ compiler ];
96
+
93
97
  const tmpfile = 'tmp.c';
94
- const args = [ compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native' ];
98
+ // const args = [ compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-ffunction-sections', '-fdata-sections', '-Wl', '-fno-ident', '-fno-exceptions', '-ffast-math' ];
99
+ // const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-ffast-math', '-fno-exceptions', '-target', 'x86_64-linux' ];
100
+ const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO, '-march=native', '-s', '-ffast-math', '-fno-exceptions' ];
95
101
 
96
102
  const c = toc(out);
97
103
  writeFileSync(tmpfile, c);
package/compiler/opt.js CHANGED
@@ -11,7 +11,7 @@ const performWasmOp = (op, a, b) => {
11
11
  }
12
12
  };
13
13
 
14
- export default (funcs, globals, pages) => {
14
+ export default (funcs, globals, pages, tags, exceptions) => {
15
15
  const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
16
16
  if (optLevel === 0) return;
17
17
 
@@ -99,6 +99,9 @@ export default (funcs, globals, pages) => {
99
99
 
100
100
  if (process.argv.includes('-opt-inline-only')) return;
101
101
 
102
+ const tagUse = tags.reduce((acc, x) => { acc[x.idx] = 0; return acc; }, {});
103
+ const exceptionUse = exceptions.reduce((acc, _, i) => { acc[i] = 0; return acc; }, {});
104
+
102
105
  // wasm transform pass
103
106
  for (const f of funcs) {
104
107
  const wasm = f.wasm;
@@ -127,6 +130,13 @@ export default (funcs, globals, pages) => {
127
130
  if (inst[0] === Opcodes.local_get) getCount[inst[1]]++;
128
131
  if (inst[0] === Opcodes.local_set || inst[0] === Opcodes.local_tee) setCount[inst[1]]++;
129
132
 
133
+ if (inst[0] === Opcodes.throw) {
134
+ tagUse[inst[1]]++;
135
+
136
+ const exceptId = read_signedLEB128(wasm[i - 1].slice(1));
137
+ exceptionUse[exceptId]++;
138
+ }
139
+
130
140
  if (inst[0] === Opcodes.block) {
131
141
  // remove unneeded blocks (no brs inside)
132
142
  // block
@@ -143,7 +153,7 @@ export default (funcs, globals, pages) => {
143
153
  depth--;
144
154
  if (depth <= 0) break;
145
155
  }
146
- if (op === Opcodes.br || op === Opcodes.br_if) {
156
+ if (op === Opcodes.br || op === Opcodes.br_if || op === Opcodes.br_table) {
147
157
  hasBranch = true;
148
158
  break;
149
159
  }
@@ -188,6 +198,7 @@ export default (funcs, globals, pages) => {
188
198
  let missing = false;
189
199
  if (type === 'Array') missing = !pages.hasArray;
190
200
  if (type === 'String') missing = !pages.hasString;
201
+ if (type === 'ByteString') missing = !pages.hasByteString;
191
202
 
192
203
  if (missing) {
193
204
  let j = i, depth = 0;
@@ -235,7 +246,7 @@ export default (funcs, globals, pages) => {
235
246
  }
236
247
 
237
248
  // remove setting last type if it is never gotten
238
- if (!f.gotLastType && inst[0] === Opcodes.local_set && inst[1] === lastType.idx) {
249
+ if (!f.gotLastType && inst[0] === Opcodes.local_set && inst[1] === lastType?.idx) {
239
250
  // replace this inst with drop
240
251
  wasm.splice(i, 1, [ Opcodes.drop ]); // remove this and last inst
241
252
  if (i > 0) i--;
@@ -541,5 +552,18 @@ export default (funcs, globals, pages) => {
541
552
  }
542
553
  }
543
554
 
555
+ for (const x in tagUse) {
556
+ if (tagUse[x] === 0) {
557
+ const el = tags.find(y => y.idx === x);
558
+ tags.splice(tags.indexOf(el), 1);
559
+ }
560
+ }
561
+
562
+ for (const x of Object.keys(exceptionUse).sort((a, b) => b - a)) {
563
+ if (exceptionUse[x] === 0) {
564
+ exceptions.splice(+x, 1);
565
+ }
566
+ }
567
+
544
568
  // return funcs;
545
569
  };
@@ -0,0 +1,79 @@
1
+ import fs from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
6
+
7
+ // import porfParse from './parse.js';
8
+ // import porfCodegen from './codeGen.js';
9
+
10
+ const argv = process.argv.slice();
11
+
12
+ const compile = async (file, [ _funcs, _globals ]) => {
13
+ const source = fs.readFileSync(file, 'utf8');
14
+ const first = source.slice(0, source.indexOf('\n'));
15
+
16
+ let args = ['-bytestring'];
17
+ if (file.endsWith('.ts')) args.push('-parse-types', '-opt-types');
18
+ if (first.startsWith('// @porf')) {
19
+ args = args.concat(first.slice('// @porf '.length).split(' '));
20
+ }
21
+ process.argv = argv.concat(args);
22
+
23
+ // globalThis.optLog = process.argv.includes('-opt-log');
24
+ // globalThis.codeLog = process.argv.includes('-code-log');
25
+ // globalThis.allocLog = process.argv.includes('-alloc-log');
26
+ // globalThis.regexLog = process.argv.includes('-regex-log');
27
+
28
+ // const porfParse = (await import(`./parse.js?_=${Date.now()}`)).default;
29
+ // const porfCodegen = (await import(`./codeGen.js?_=${Date.now()}`)).default;
30
+
31
+ // let { funcs, globals, data } = porfCodegen(porfParse(source, ['module']));
32
+
33
+ const porfCompile = (await import(`./index.js?_=${Date.now()}`)).default;
34
+
35
+ let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
36
+
37
+ funcs = funcs.filter(x => x.export);
38
+ for (const x of funcs) {
39
+ if (x.data) x.data = x.data.map(x => data[x]);
40
+ if (x.exceptions) x.exceptions = x.exceptions.map(x => {
41
+ const obj = exceptions[x];
42
+ if (obj) obj.exceptId = x;
43
+ return obj;
44
+ }).filter(x => x);
45
+ }
46
+
47
+ _funcs.push(...funcs);
48
+ _globals.push(...Object.values(globals));
49
+ };
50
+
51
+ const precompile = async () => {
52
+ const dir = join(__dirname, 'builtins');
53
+
54
+ let funcs = [], globals = [];
55
+ for (const file of fs.readdirSync(dir)) {
56
+ if (file.endsWith('.d.ts')) continue;
57
+ await compile(join(dir, file), [ funcs, globals ]);
58
+ }
59
+
60
+ // todo: globals, exceptions, pages per func
61
+
62
+ return `// autogenerated by precompile.js
63
+
64
+ export const BuiltinFuncs = function() {
65
+ ${funcs.map(x => ` this.${x.name} = {
66
+ wasm: ${JSON.stringify(x.wasm)},
67
+ params: ${JSON.stringify(x.params)},
68
+ typedParams: true,
69
+ returns: ${JSON.stringify(x.returns)},
70
+ typedReturns: true,
71
+ locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length * 2).map(x => x.type))},
72
+ ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
73
+ ${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)},` : ''}
74
+ ${x.exceptions && x.exceptions.length > 0 ? ` exceptions: ${JSON.stringify(x.exceptions)},` : ''}
75
+ };`.replaceAll('\n\n', '\n')).join('\n')}
76
+ }`;
77
+ };
78
+
79
+ console.log(await precompile());
@@ -16,7 +16,8 @@ const TYPES = {
16
16
 
17
17
  // these are not "typeof" types but tracked internally
18
18
  _array: 0x10,
19
- _regexp: 0x11
19
+ _regexp: 0x11,
20
+ _bytestring: 0x12
20
21
  };
21
22
 
22
23
  // todo: turn these into built-ins once arrays and these become less hacky
@@ -71,7 +72,7 @@ export const PrototypeFuncs = function() {
71
72
  ],
72
73
 
73
74
  // todo: only for 1 argument
74
- push: (pointer, length, wNewMember) => [
75
+ push: (pointer, length, wNewMember, _1, _2, _3, unusedValue) => [
75
76
  // get memory offset of array at last index (length)
76
77
  ...length.getCachedI32(),
77
78
  ...number(ValtypeSize[valtype], Valtype.i32),
@@ -92,22 +93,28 @@ export const PrototypeFuncs = function() {
92
93
  ...number(1, Valtype.i32),
93
94
  [ Opcodes.i32_add ],
94
95
 
95
- ...length.setCachedI32(),
96
- ...length.getCachedI32(),
96
+ ...(unusedValue() ? [] : [
97
+ ...length.setCachedI32(),
98
+ ...length.getCachedI32(),
99
+ ])
97
100
  ]),
98
101
 
99
- ...length.getCachedI32(),
100
- Opcodes.i32_from_u
102
+ ...(unusedValue() ? [] : [
103
+ ...length.getCachedI32(),
104
+ Opcodes.i32_from_u
105
+ ])
101
106
 
102
107
  // ...length.get()
103
108
  ],
104
109
 
105
- pop: (pointer, length) => [
110
+ pop: (pointer, length, _1, _2, _3, _4, unusedValue) => [
106
111
  // if length == 0, noop
107
112
  ...length.getCachedI32(),
108
113
  [ Opcodes.i32_eqz ],
109
114
  [ Opcodes.if, Blocktype.void ],
110
- ...number(UNDEFINED),
115
+ ...(unusedValue() ? [] : [
116
+ ...number(UNDEFINED),
117
+ ]),
111
118
  [ Opcodes.br, 1 ],
112
119
  [ Opcodes.end ],
113
120
 
@@ -119,19 +126,23 @@ export const PrototypeFuncs = function() {
119
126
  ...number(1, Valtype.i32),
120
127
  [ Opcodes.i32_sub ],
121
128
 
122
- ...length.setCachedI32(),
123
- ...length.getCachedI32(),
129
+ ...(unusedValue() ? [] : [
130
+ ...length.setCachedI32(),
131
+ ...length.getCachedI32(),
132
+ ])
124
133
  ]),
125
134
 
126
135
  // load last element
127
- ...length.getCachedI32(),
128
- ...number(ValtypeSize[valtype], Valtype.i32),
129
- [ Opcodes.i32_mul ],
136
+ ...(unusedValue() ? [] : [
137
+ ...length.getCachedI32(),
138
+ ...number(ValtypeSize[valtype], Valtype.i32),
139
+ [ Opcodes.i32_mul ],
130
140
 
131
- ...pointer,
132
- [ Opcodes.i32_add ],
141
+ ...pointer,
142
+ [ Opcodes.i32_add ],
133
143
 
134
- [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
144
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ]
145
+ ])
135
146
  ],
136
147
 
137
148
  shift: (pointer, length) => [
@@ -331,8 +342,8 @@ export const PrototypeFuncs = function() {
331
342
  ...number(0, Valtype.i32), // base 0 for store later
332
343
 
333
344
  ...wIndex,
334
-
335
345
  Opcodes.i32_to,
346
+
336
347
  ...number(ValtypeSize.i16, Valtype.i32),
337
348
  [ Opcodes.i32_mul ],
338
349
 
@@ -472,8 +483,151 @@ export const PrototypeFuncs = function() {
472
483
  this[TYPES.string].at.returnType = TYPES.string;
473
484
  this[TYPES.string].charAt.returnType = TYPES.string;
474
485
  this[TYPES.string].charCodeAt.local = Valtype.i32;
486
+ this[TYPES.string].charCodeAt.noPointerCache = zeroChecks.charcodeat;
475
487
 
476
488
  this[TYPES.string].isWellFormed.local = Valtype.i32;
477
489
  this[TYPES.string].isWellFormed.local2 = Valtype.i32;
478
490
  this[TYPES.string].isWellFormed.returnType = TYPES.boolean;
491
+
492
+ if (process.argv.includes('-bytestring')) {
493
+ this[TYPES._bytestring] = {
494
+ at: (pointer, length, wIndex, iTmp, _, arrayShell) => {
495
+ const [ newOut, newPointer ] = arrayShell(1, 'i16');
496
+
497
+ return [
498
+ // setup new/out array
499
+ ...newOut,
500
+ [ Opcodes.drop ],
501
+
502
+ ...number(0, Valtype.i32), // base 0 for store later
503
+
504
+ ...wIndex,
505
+ Opcodes.i32_to_u,
506
+ [ Opcodes.local_tee, iTmp ],
507
+
508
+ // if index < 0: access index + array length
509
+ ...number(0, Valtype.i32),
510
+ [ Opcodes.i32_lt_s ],
511
+ [ Opcodes.if, Blocktype.void ],
512
+ [ Opcodes.local_get, iTmp ],
513
+ ...length.getCachedI32(),
514
+ [ Opcodes.i32_add ],
515
+ [ Opcodes.local_set, iTmp ],
516
+ [ Opcodes.end ],
517
+
518
+ // if still < 0 or >= length: return undefined
519
+ [ Opcodes.local_get, iTmp ],
520
+ ...number(0, Valtype.i32),
521
+ [ Opcodes.i32_lt_s ],
522
+
523
+ [ Opcodes.local_get, iTmp ],
524
+ ...length.getCachedI32(),
525
+ [ Opcodes.i32_ge_s ],
526
+ [ Opcodes.i32_or ],
527
+
528
+ [ Opcodes.if, Blocktype.void ],
529
+ ...number(UNDEFINED),
530
+ [ Opcodes.br, 1 ],
531
+ [ Opcodes.end ],
532
+
533
+ [ Opcodes.local_get, iTmp ],
534
+
535
+ ...pointer,
536
+ [ Opcodes.i32_add ],
537
+
538
+ // load current string ind {arg}
539
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
540
+
541
+ // store to new string ind 0
542
+ [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
543
+
544
+ // return new string (pointer)
545
+ ...number(newPointer)
546
+ ];
547
+ },
548
+
549
+ // todo: out of bounds properly
550
+ charAt: (pointer, length, wIndex, _1, _2, arrayShell) => {
551
+ const [ newOut, newPointer ] = arrayShell(1, 'i16');
552
+
553
+ return [
554
+ // setup new/out array
555
+ ...newOut,
556
+ [ Opcodes.drop ],
557
+
558
+ ...number(0, Valtype.i32), // base 0 for store later
559
+
560
+ ...wIndex,
561
+ Opcodes.i32_to,
562
+
563
+ ...pointer,
564
+ [ Opcodes.i32_add ],
565
+
566
+ // load current string ind {arg}
567
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
568
+
569
+ // store to new string ind 0
570
+ [ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
571
+
572
+ // return new string (page)
573
+ ...number(newPointer)
574
+ ];
575
+ },
576
+
577
+ charCodeAt: (pointer, length, wIndex, iTmp) => {
578
+ return [
579
+ ...wIndex,
580
+ Opcodes.i32_to,
581
+
582
+ ...(zeroChecks.charcodeat ? [] : [
583
+ [ Opcodes.local_set, iTmp ],
584
+
585
+ // index < 0
586
+ ...(noUnlikelyChecks ? [] : [
587
+ [ Opcodes.local_get, iTmp ],
588
+ ...number(0, Valtype.i32),
589
+ [ Opcodes.i32_lt_s ],
590
+ ]),
591
+
592
+ // index >= length
593
+ [ Opcodes.local_get, iTmp ],
594
+ ...length.getCachedI32(),
595
+ [ Opcodes.i32_ge_s ],
596
+
597
+ ...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
598
+ [ Opcodes.if, Blocktype.void ],
599
+ ...number(NaN),
600
+ [ Opcodes.br, 1 ],
601
+ [ Opcodes.end ],
602
+
603
+ [ Opcodes.local_get, iTmp ],
604
+ ]),
605
+
606
+ ...pointer,
607
+ [ Opcodes.i32_add ],
608
+
609
+ // load current string ind {arg}
610
+ [ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
611
+ Opcodes.i32_from_u
612
+ ];
613
+ },
614
+
615
+ isWellFormed: () => {
616
+ return [
617
+ // we know it must be true as it is a bytestring lol
618
+ ...number(1)
619
+ ]
620
+ }
621
+ };
622
+
623
+ this[TYPES._bytestring].at.local = Valtype.i32;
624
+ this[TYPES._bytestring].at.returnType = TYPES._bytestring;
625
+ this[TYPES._bytestring].charAt.returnType = TYPES._bytestring;
626
+ this[TYPES._bytestring].charCodeAt.local = Valtype.i32;
627
+ this[TYPES._bytestring].charCodeAt.noPointerCache = zeroChecks.charcodeat;
628
+
629
+ this[TYPES._bytestring].isWellFormed.local = Valtype.i32;
630
+ this[TYPES._bytestring].isWellFormed.local2 = Valtype.i32;
631
+ this[TYPES._bytestring].isWellFormed.returnType = TYPES.boolean;
632
+ }
479
633
  };
@@ -95,7 +95,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
95
95
  // https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
96
96
  const chSection = !compileHints ? [] : customSection(
97
97
  'compilationHints',
98
- // for now just do everything as optimise eager
98
+ // for now just do everything as optimize eager
99
99
  encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
100
100
  );
101
101
 
@@ -150,7 +150,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
150
150
 
151
151
  if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
152
152
 
153
- return encodeVector([ ...encodeVector(localDecl), ...x.wasm.flat().filter(x => x <= 0xff), Opcodes.end ]);
153
+ return encodeVector([ ...encodeVector(localDecl), ...x.wasm.flat().filter(x => x != null && x <= 0xff), Opcodes.end ]);
154
154
  }))
155
155
  );
156
156
 
@@ -32,8 +32,6 @@ export const Opcodes = {
32
32
  throw: 0x08,
33
33
  rethrow: 0x09,
34
34
 
35
- return: 0x0F,
36
-
37
35
  call: 0x10,
38
36
  call_indirect: 0x11,
39
37
  return_call: 0x12,
@@ -42,7 +40,10 @@ export const Opcodes = {
42
40
  end: 0x0b,
43
41
  br: 0x0c,
44
42
  br_if: 0x0d,
43
+ br_table: 0x0e,
44
+ return: 0x0f,
45
45
  call: 0x10,
46
+
46
47
  drop: 0x1a,
47
48
 
48
49
  local_get: 0x20,
@@ -56,9 +57,12 @@ export const Opcodes = {
56
57
  i64_load: 0x29,
57
58
  f64_load: 0x2b,
58
59
 
60
+ i32_load8_s: 0x2c,
61
+ i32_load8_u: 0x2d,
59
62
  i32_load16_s: 0x2e,
60
63
  i32_load16_u: 0x2f,
61
64
 
65
+ i32_store8: 0x3a,
62
66
  i32_store16: 0x3b,
63
67
 
64
68
  i32_store: 0x36,