porffor 0.34.8 → 0.34.9

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.
@@ -1,5 +1,5 @@
1
1
  import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize, Reftype } from './wasmSpec.js';
2
- import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64_into } from './encoding.js';
2
+ import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into } from './encoding.js';
3
3
  import { importedFuncs } from './builtins.js';
4
4
  import { log } from './log.js';
5
5
  import {} from './prefs.js';
@@ -72,6 +72,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
72
72
  return typeCache[hash] = idx;
73
73
  };
74
74
 
75
+ let t = performance.now();
76
+ const time = msg => {
77
+ if (!Prefs.profileAssemble) return;
78
+
79
+ console.log(`${' '.repeat(50)}\r[${(performance.now() - t).toFixed(2)}ms] ${msg}`);
80
+ t = performance.now();
81
+ };
82
+
75
83
  let importFuncs = [], importDelta = 0;
76
84
  if (optLevel < 1 || !Prefs.treeshakeWasmImports || noTreeshake) {
77
85
  importFuncs = importedFuncs;
@@ -81,7 +89,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
81
89
  // tree shake imports
82
90
  for (const f of funcs) {
83
91
  for (const inst of f.wasm) {
84
- if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] < importedFuncs.length) {
92
+ if ((inst[0] === Opcodes.call /* || inst[0] === Opcodes.return_call */) && inst[1] < importedFuncs.length) {
85
93
  const idx = inst[1];
86
94
  const func = importedFuncs[idx];
87
95
 
@@ -102,17 +110,21 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
102
110
  f.asmIndex = f.index - importDelta;
103
111
  }
104
112
 
113
+ time('treeshake import funcs');
114
+
105
115
  if (Prefs.optLog) log('assemble', `treeshake: using ${importFuncs.length}/${importedFuncs.length} imports`);
106
116
 
107
117
  const importSection = importFuncs.length === 0 ? [] : createSection(
108
118
  Section.import,
109
119
  encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(typeof x.params === 'object' ? x.params : new Array(x.params).fill(valtypeBinary), new Array(x.returns).fill(valtypeBinary)) ]))
110
120
  );
121
+ time('import section');
111
122
 
112
123
  const funcSection = createSection(
113
124
  Section.func,
114
125
  encodeVector(funcs.map(x => getType(x.params, x.returns))) // type indexes
115
126
  );
127
+ time('func section');
116
128
 
117
129
  const nameSection = Prefs.d ? customSection('name', encodeNames(funcs)) : [];
118
130
 
@@ -120,6 +132,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
120
132
  Section.table,
121
133
  encodeVector([ [ Reftype.funcref, 0x00, ...unsignedLEB128(funcs.length) ] ])
122
134
  );
135
+ time('table section');
123
136
 
124
137
  const elementSection = !funcs.table ? [] : createSection(
125
138
  Section.element,
@@ -129,6 +142,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
129
142
  ...encodeVector(funcs.map(x => unsignedLEB128(x.asmIndex)))
130
143
  ] ])
131
144
  );
145
+ time('element section');
132
146
 
133
147
  if (pages.has('func lut')) {
134
148
  const offset = pages.get('func lut').ind * pageSize;
@@ -181,8 +195,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
181
195
  });
182
196
  data.addedFuncArgcLut = true;
183
197
  }
184
-
185
- // const t0 = performance.now();
198
+ time('func lut');
186
199
 
187
200
  // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
188
201
  const globalsValues = Object.values(globals);
@@ -224,17 +237,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
224
237
  unsignedLEB128_into(data.length, globalSection);
225
238
  globalSection = globalSection.concat(data);
226
239
  }
227
-
228
- // if (Prefs.profileCompiler) {
229
- // const log = console.log;
230
- // console.log = function () {
231
- // log.apply(this, arguments);
232
- // console.log = log;
233
- // console.log(` a. assembled global section in ${(performance.now() - t0).toFixed(2)}ms\n`);
234
- // };
235
- // }
236
-
237
- const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
240
+ time('global section');
238
241
 
239
242
  if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
240
243
  if (optLevel === 0) pages.set('O0 precaution', 0);
@@ -244,9 +247,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
244
247
  Section.memory,
245
248
  encodeVector([ [ 0x00, ...unsignedLEB128(Math.ceil((pages.size * pageSize) / PageSize)) ] ])
246
249
  );
250
+ time('memory section');
251
+
252
+ const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
247
253
 
248
254
  // export memory if used
249
255
  if (usesMemory) exports.unshift([ ...encodeString('$'), ExportDesc.mem, 0x00 ]);
256
+ time('gen exports');
250
257
 
251
258
  const tagSection = tags.length === 0 ? [] : createSection(
252
259
  Section.tag,
@@ -255,16 +262,20 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
255
262
 
256
263
  // export first tag if used
257
264
  if (tags.length !== 0) exports.unshift([ ...encodeString('0'), ExportDesc.tag, 0x00 ]);
265
+ time('tag section');
258
266
 
259
267
  const exportSection = createSection(
260
268
  Section.export,
261
269
  encodeVector(exports)
262
270
  );
271
+ time('export section');
263
272
 
264
273
  const codeSection = createSection(
265
274
  Section.code,
266
275
  encodeVector(funcs.map(x => {
267
- const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length).sort((a, b) => a.idx - b.idx);
276
+ // time(x.name);
277
+ const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length);
278
+ // time(' locals gen');
268
279
 
269
280
  let localDecl = [], typeCount = 0, lastType;
270
281
  for (let i = 0; i < locals.length; i++) {
@@ -279,6 +290,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
279
290
  }
280
291
 
281
292
  if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
293
+ // time(' localDecl gen');
282
294
 
283
295
  const makeAssembled = Prefs.d;
284
296
  let wasm = [], wasmNonFlat = [];
@@ -287,7 +299,8 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
287
299
 
288
300
  // encode local/global ops as unsigned leb128 from raw number
289
301
  if (
290
- (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
302
+ // (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
303
+ (o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
291
304
  o[1] > 127
292
305
  ) {
293
306
  const n = o[1];
@@ -298,12 +311,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
298
311
  // encode f64.const ops as ieee754 from raw number
299
312
  if (o[0] === Opcodes.f64_const) {
300
313
  const n = o[1];
301
- o = [ o[0] ];
302
- ieee754_binary64_into(n, o);
314
+ // o = [ o[0] ];
315
+ // ieee754_binary64_into(n, o);
316
+ o = ieee754_binary64(n);
317
+ if (o.length === 8) o.unshift(Opcodes.f64_const);
303
318
  }
304
319
 
305
320
  // encode call ops as unsigned leb128 from raw number
306
- if ((o[0] === Opcodes.call || o[0] === Opcodes.return_call) && o[1] >= importedFuncs.length) {
321
+ if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
307
322
  const n = o[1] - importDelta;
308
323
  o = [ o[0] ];
309
324
  unsignedLEB128_into(n, o);
@@ -334,19 +349,28 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
334
349
 
335
350
  if (makeAssembled) wasmNonFlat.push(o);
336
351
  }
352
+ // time(' wasm transform');
337
353
 
338
354
  if (makeAssembled) {
339
355
  x.assembled = { localDecl, wasm, wasmNonFlat };
340
356
  }
341
357
 
342
- return encodeVector([ ...encodeVector(localDecl), ...wasm, Opcodes.end ]);
358
+ let out = unsignedLEB128(localDecl.length)
359
+ .concat(localDecl.flat(), wasm, Opcodes.end);
360
+
361
+ out.unshift(...unsignedLEB128(out.length));
362
+
363
+ // time(' finish');
364
+ return out;
343
365
  }))
344
366
  );
367
+ time('code section');
345
368
 
346
369
  const typeSection = createSection(
347
370
  Section.type,
348
371
  encodeVector(types)
349
372
  );
373
+ time('type section');
350
374
 
351
375
  const dataSection = data.length === 0 ? [] : createSection(
352
376
  Section.data,
@@ -368,11 +392,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
368
392
  return bytes;
369
393
  }))
370
394
  );
395
+ time('data section');
371
396
 
372
397
  const dataCountSection = data.length === 0 ? [] : createSection(
373
398
  Section.data_count,
374
399
  unsignedLEB128(data.length)
375
400
  );
401
+ time('datacount section');
376
402
 
377
403
  if (Prefs.sections) console.log({
378
404
  typeSection: typeSection.map(x => x.toString(16)),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.34.8+3c064d5f4",
4
+ "version": "0.34.9+9dbf4dfbb",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.34.8+3c064d5f4';
3
+ globalThis.version = '0.34.9+9dbf4dfbb';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {