porffor 0.50.19 → 0.50.21

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/README.md CHANGED
@@ -175,9 +175,6 @@ No particular order and no guarantees, just what could happen soon™
175
175
  - PGO
176
176
  - Self hosted testing?
177
177
 
178
- ## VSCode extension
179
- There is a vscode extension in `vscode-ext` which tweaks JS syntax highlighting to be nicer with porffor features (eg highlighting wasm inside of inline asm).
180
-
181
178
  ## Wasm proposals used
182
179
  Porffor intentionally does not use Wasm proposals which are not commonly implemented yet (eg GC) so it can be used in as many places as possible.
183
180
 
@@ -1,5 +1,5 @@
1
1
  import { Valtype, FuncType, ExportDesc, Section, Magic, Opcodes, PageSize, Reftype } from './wasmSpec.js';
2
- import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into } from './encoding.js';
2
+ import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into, unsignedLEB128_length } from './encoding.js';
3
3
  import { importedFuncs } from './builtins.js';
4
4
  import { log } from './log.js';
5
5
  import './prefs.js';
@@ -250,9 +250,7 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
250
250
  let codeSection = [];
251
251
  for (let i = 0; i < funcs.length; i++) {
252
252
  const x = funcs[i];
253
- // time(x.name);
254
253
  const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx);
255
- // time(' locals gen');
256
254
 
257
255
  const paramCount = x.params.length;
258
256
  let localDecl = [], typeCount = 0, lastType, declCount = 0;
@@ -269,77 +267,131 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
269
267
  lastType = local?.type;
270
268
  }
271
269
 
272
- // time(' localDecl gen');
273
-
274
- const makeAssembled = Prefs.d;
275
270
  let wasm = [], wasmNonFlat = [];
276
- for (let i = 0; i < x.wasm.length; i++) {
277
- let o = x.wasm[i];
278
-
279
- // encode local/global ops as unsigned leb128 from raw number
280
- if (
281
- (o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
282
- o[1] > 127
283
- ) {
284
- const n = o[1];
285
- o = [ o[0] ];
286
- unsignedLEB128_into(n, o);
287
- }
271
+ if (Prefs.d) {
272
+ for (let i = 0; i < x.wasm.length; i++) {
273
+ let o = x.wasm[i];
274
+
275
+ // encode local/global ops as unsigned leb128 from raw number
276
+ if (
277
+ (o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
278
+ o[1] > 127
279
+ ) {
280
+ const n = o[1];
281
+ o = [ o[0] ];
282
+ unsignedLEB128_into(n, o);
283
+ }
288
284
 
289
- // encode f64.const ops as ieee754 from raw number
290
- if (o[0] === Opcodes.f64_const) {
291
- const n = o[1];
292
- o = ieee754_binary64(n);
293
- if (o.length === 8) o.unshift(Opcodes.f64_const);
294
- }
285
+ // encode f64.const ops as ieee754 from raw number
286
+ if (o[0] === Opcodes.f64_const) {
287
+ const n = o[1];
288
+ o = ieee754_binary64(n);
289
+ if (o.length === 8) o.unshift(Opcodes.f64_const);
290
+ }
295
291
 
296
- // encode call ops as unsigned leb128 from raw number
297
- if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
298
- const n = o[1] - importDelta;
299
- o = [ Opcodes.call ];
300
- unsignedLEB128_into(n, o);
301
- }
292
+ // encode call ops as unsigned leb128 from raw number
293
+ if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
294
+ const n = o[1] - importDelta;
295
+ o = [ Opcodes.call ];
296
+ unsignedLEB128_into(n, o);
297
+ }
302
298
 
303
- // encode call indirect ops as types from info
304
- if (o[0] === Opcodes.call_indirect) {
305
- o = [...o];
306
- const params = [];
307
- for (let i = 0; i < o[1]; i++) {
308
- params.push(valtypeBinary, Valtype.i32);
299
+ // encode call indirect ops as types from info
300
+ if (o[0] === Opcodes.call_indirect) {
301
+ o = [...o];
302
+ const params = [];
303
+ for (let i = 0; i < o[1]; i++) {
304
+ params.push(valtypeBinary, Valtype.i32);
305
+ }
306
+
307
+ let returns = [ valtypeBinary, Valtype.i32 ];
308
+ if (o.at(-1) === 'no_type_return') {
309
+ o.pop();
310
+ returns = [ valtypeBinary ];
311
+ }
312
+
313
+ o[1] = getType(params, returns);
309
314
  }
310
315
 
311
- let returns = [ valtypeBinary, Valtype.i32 ];
312
- if (o.at(-1) === 'no_type_return') {
313
- o.pop();
314
- returns = [ valtypeBinary ];
316
+ for (let j = 0; j < o.length; j++) {
317
+ const x = o[j];
318
+ if (x == null || !(x <= 0xff)) continue;
319
+ wasm.push(x);
315
320
  }
316
321
 
317
- o[1] = getType(params, returns);
322
+ wasmNonFlat.push(o);
318
323
  }
319
324
 
320
- for (let j = 0; j < o.length; j++) {
321
- const x = o[j];
322
- if (x == null || !(x <= 0xff)) continue;
323
- wasm.push(x);
324
- }
325
+ x.assembled = { localDecl, wasm, wasmNonFlat };
326
+ } else {
327
+ for (let i = 0; i < x.wasm.length; i++) {
328
+ let o = x.wasm[i];
329
+ const op = o[0];
330
+
331
+ // encode local/global ops as unsigned leb128 from raw number
332
+ if (
333
+ (op >= Opcodes.local_get && op <= Opcodes.global_set) &&
334
+ o[1] > 127
335
+ ) {
336
+ wasm.push(op);
337
+ unsignedLEB128_into(o[1], wasm);
338
+ continue;
339
+ }
325
340
 
326
- if (makeAssembled) wasmNonFlat.push(o);
327
- }
328
- // time(' wasm transform');
341
+ // encode f64.const ops as ieee754 from raw number
342
+ if (op === Opcodes.f64_const) {
343
+ wasm.push(op);
344
+ ieee754_binary64_into(o[1], wasm);
345
+ continue;
346
+ }
329
347
 
330
- if (makeAssembled) {
331
- x.assembled = { localDecl, wasm, wasmNonFlat };
332
- }
348
+ // encode call ops as unsigned leb128 from raw number
349
+ if ((op === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
350
+ wasm.push(op);
351
+ unsignedLEB128_into(o[1] - importDelta, wasm);
352
+ continue;
353
+ }
354
+
355
+ // encode call indirect ops as types from info
356
+ if (op === Opcodes.call_indirect) {
357
+ const params = [];
358
+ for (let i = 0; i < o[1]; i++) {
359
+ params.push(valtypeBinary, Valtype.i32);
360
+ }
333
361
 
334
- let out = unsignedLEB128(declCount)
335
- .concat(localDecl, wasm, Opcodes.end);
362
+ let returns = [ valtypeBinary, Valtype.i32 ];
363
+ if (o.at(-1) === 'no_type_return') {
364
+ returns = [ valtypeBinary ];
365
+ }
366
+
367
+ wasm.push(op, getType(params, returns), o[2]);
368
+ continue;
369
+ }
336
370
 
337
- codeSection.push(
338
- ...unsignedLEB128(out.length),
339
- ...out
340
- );
371
+ for (let j = 0; j < o.length; j++) {
372
+ const x = o[j];
373
+ if (x == null || !(x <= 0xff)) continue;
374
+ wasm.push(x);
375
+ }
376
+ }
377
+ }
341
378
 
342
- // time(' finish');
379
+ if (wasm.length > 100000) {
380
+ // slow path for handling large arrays which break v8 due to running out of stack size
381
+ const out = unsignedLEB128(declCount)
382
+ .concat(localDecl, wasm, Opcodes.end);
383
+ codeSection = codeSection.concat(unsignedLEB128(out.length), out);
384
+ } else {
385
+ codeSection.push(
386
+ ...unsignedLEB128(unsignedLEB128_length(declCount) + localDecl.length + wasm.length + 1),
387
+ ...unsignedLEB128(declCount),
388
+ ...localDecl,
389
+ ...wasm,
390
+ Opcodes.end
391
+ );
392
+ }
393
+
394
+ // globalThis.progress?.(`${i}/${funcs.length}`);
343
395
  }
344
396
 
345
397
  codeSection.unshift(...unsignedLEB128(funcs.length, codeSection));
@@ -368,10 +420,14 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
368
420
  dataSection.push(0x01);
369
421
  }
370
422
 
371
- dataSection.push(
372
- ...unsignedLEB128(x.bytes.length),
373
- ...x.bytes
374
- );
423
+ if (x.bytes.length > 100000) {
424
+ codeSection = codeSection.concat(unsignedLEB128(x.bytes.length), x.bytes);
425
+ } else {
426
+ dataSection.push(
427
+ ...unsignedLEB128(x.bytes.length),
428
+ ...x.bytes
429
+ );
430
+ }
375
431
  }
376
432
 
377
433
  dataSection.unshift(...unsignedLEB128(data.length, dataSection));
@@ -367,7 +367,6 @@ export const __Array_prototype_with = (_this: any[], _index: any, value: any) =>
367
367
  }
368
368
 
369
369
  let out: any[] = Porffor.allocate();
370
-
371
370
  Porffor.clone(_this, out);
372
371
 
373
372
  out[index] = value;
@@ -54,12 +54,6 @@ export const importedFuncs = [
54
54
  import: 'q',
55
55
  params: 2,
56
56
  returns: 1
57
- },
58
- {
59
- name: 'debugger',
60
- import: 'b',
61
- params: 0,
62
- returns: 0,
63
57
  }
64
58
  ];
65
59