porffor 0.60.20 → 0.60.22

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.
@@ -611,8 +611,8 @@ const lookup = (scope, name, failEarly = false) => {
611
611
  return wasm.slice();
612
612
  }
613
613
 
614
- if (!(name in funcIndex) && name in builtinFuncs) {
615
- includeBuiltin(scope, name);
614
+ if (name in builtinFuncs) {
615
+ if (!(name in funcIndex)) includeBuiltin(scope, name);
616
616
  } else if (name in internalConstrs) {
617
617
  // todo: return an actual something
618
618
  return [ number(1) ];
@@ -882,7 +882,7 @@ const generateReturn = (scope, decl) => {
882
882
  };
883
883
 
884
884
  const localTmp = (scope, name, type = valtypeBinary) => {
885
- if (scope.locals[name]) return scope.locals[name].idx;
885
+ if (name in scope.locals) return scope.locals[name].idx;
886
886
 
887
887
  let idx = scope.localInd++;
888
888
  scope.locals[name] = { idx, type };
@@ -3015,6 +3015,34 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
3015
3015
  return typeof def === 'function' ? def() : def;
3016
3016
  }
3017
3017
 
3018
+ if (bc.length === 2 && (bc[0][0] === 'default' || bc[1][0] === 'default')) {
3019
+ let trueCase, falseCase;
3020
+ if (bc[0][0] === 'default') {
3021
+ trueCase = bc[1];
3022
+ falseCase = bc[0];
3023
+ } else {
3024
+ trueCase = bc[0];
3025
+ falseCase = bc[1];
3026
+ }
3027
+
3028
+ if (!Array.isArray(trueCase[0])) {
3029
+ depth.push('if');
3030
+ const out = [
3031
+ ...type,
3032
+ number(trueCase[0], Valtype.i32),
3033
+ [ Opcodes.i32_eq ],
3034
+ [ Opcodes.if, returns ],
3035
+ ...typeof trueCase[1] === 'function' ? trueCase[1]() : trueCase[1],
3036
+ [ Opcodes.else ],
3037
+ ...typeof falseCase[1] === 'function' ? falseCase[1]() : falseCase[1],
3038
+ [ Opcodes.end ],
3039
+ ];
3040
+ depth.pop();
3041
+
3042
+ return out;
3043
+ }
3044
+ }
3045
+
3018
3046
  if (Prefs.typeswitchBrtable) {
3019
3047
  if (fallthrough) throw new Error(`Fallthrough is not currently supported with --typeswitch-brtable`);
3020
3048
  return brTable(type, bc, returns);
@@ -3131,7 +3159,7 @@ const typeIsNotOneOf = (type, types, valtype = Valtype.i32) => {
3131
3159
  return out;
3132
3160
  };
3133
3161
 
3134
- const allocVar = (scope, name, global = false, type = true, redecl = false, i32 = false) => {
3162
+ const allocVar = (scope, name, global = false, type = true, i32 = false, redecl = false) => {
3135
3163
  const target = global ? globals : scope.locals;
3136
3164
 
3137
3165
  // already declared
@@ -6457,7 +6485,7 @@ const generateClass = (scope, decl) => {
6457
6485
  // define in construction instead
6458
6486
  if (computed) {
6459
6487
  // compute key now, reference in construction
6460
- const computedTmp = allocVar(scope, `#class_computed_prop${uniqId()}`, true, true, false, true);
6488
+ const computedTmp = allocVar(scope, `#class_computed_prop${uniqId()}`, true, true, true);
6461
6489
 
6462
6490
  out.push(
6463
6491
  ...toPropertyKey(scope, generate(scope, key), getNodeType(scope, key), computed, true),
@@ -6847,7 +6875,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6847
6875
  const { name, def, destr, type } = args[i];
6848
6876
 
6849
6877
  func.localInd = i * 2;
6850
- allocVar(func, name, false, true, true);
6878
+ allocVar(func, name, false, true, false, true);
6851
6879
 
6852
6880
  func.localInd = localInd;
6853
6881
  if (type) {
@@ -7186,8 +7214,7 @@ const internalConstrs = {
7186
7214
  }, global, name);
7187
7215
  },
7188
7216
  type: TYPES.array,
7189
- notConstr: true,
7190
- length: 0
7217
+ notConstr: true
7191
7218
  },
7192
7219
 
7193
7220
  __Porffor_fastOr: {
@@ -7246,8 +7273,7 @@ const internalConstrs = {
7246
7273
  return out;
7247
7274
  },
7248
7275
  type: TYPES.number,
7249
- notConstr: true,
7250
- length: 2
7276
+ notConstr: true
7251
7277
  },
7252
7278
 
7253
7279
  __Math_min: {
@@ -7266,8 +7292,7 @@ const internalConstrs = {
7266
7292
  return out;
7267
7293
  },
7268
7294
  type: TYPES.number,
7269
- notConstr: true,
7270
- length: 2
7295
+ notConstr: true
7271
7296
  },
7272
7297
 
7273
7298
  __Porffor_printStatic: {
@@ -7278,8 +7303,7 @@ const internalConstrs = {
7278
7303
  return out;
7279
7304
  },
7280
7305
  type: TYPES.undefined,
7281
- notConstr: true,
7282
- length: 1
7306
+ notConstr: true
7283
7307
  },
7284
7308
 
7285
7309
  __Porffor_type: {
@@ -7288,15 +7312,13 @@ const internalConstrs = {
7288
7312
  Opcodes.i32_from_u
7289
7313
  ],
7290
7314
  type: TYPES.number,
7291
- notConstr: true,
7292
- length: 1
7315
+ notConstr: true
7293
7316
  },
7294
7317
 
7295
7318
  __Porffor_compileType: {
7296
7319
  generate: (scope, decl) => makeString(scope, TYPE_NAMES[knownType(scope, getNodeType(scope, decl.arguments[0]))] ?? 'unknown'),
7297
7320
  type: TYPES.bytestring,
7298
- notConstr: true,
7299
- length: 1
7321
+ notConstr: true
7300
7322
  },
7301
7323
 
7302
7324
  __Porffor_call: {
@@ -7319,8 +7341,7 @@ const internalConstrs = {
7319
7341
  _new: decl.arguments[3].value !== null,
7320
7342
  _forceCreateThis: true
7321
7343
  }),
7322
- notConstr: true,
7323
- length: 1
7344
+ notConstr: true
7324
7345
  },
7325
7346
 
7326
7347
  __console_log: {
@@ -7359,8 +7380,7 @@ const internalConstrs = {
7359
7380
  return fast('__Porffor_consolePrint');
7360
7381
  },
7361
7382
  type: TYPES.undefined,
7362
- notConstr: true,
7363
- length: 0
7383
+ notConstr: true
7364
7384
  }
7365
7385
  };
7366
7386
 
@@ -19,12 +19,16 @@ const f64ToI32Op = {
19
19
  // const inv = (obj, keyMap = x => x) => Object.keys(obj).reduce((acc, x) => { acc[keyMap(obj[x])] = x; return acc; }, {});
20
20
  // const invOpcodes = inv(Opcodes);
21
21
 
22
- export default ({ name, wasm, locals: _locals, params }) => {
22
+ export default ({ name, wasm, locals: _locals, params }, _globals) => {
23
23
  let locals = Object.values(_locals);
24
- const localNames = Object.keys(_locals);
24
+ // const localNames = Object.keys(_locals);
25
25
  const localValtypes = locals.map(x => x.type);
26
26
  const localNeeded = new Array(locals.length).fill(0);
27
27
 
28
+ let globals = Object.values(_globals);
29
+ const globalValtypes = globals.map(x => x.type);
30
+ // const globalNeeded = new Array(globals.length).fill(0);
31
+
28
32
  // every pass does the same initial low level things
29
33
  // each subsequent pass does it again and does more high-level things
30
34
  const passes = [
@@ -42,6 +46,7 @@ export default ({ name, wasm, locals: _locals, params }) => {
42
46
 
43
47
  const reset = () => {
44
48
  locals = new Array(locals.length).fill(false);
49
+ globals = new Array(globals.length).fill(false);
45
50
  empty();
46
51
  };
47
52
 
@@ -467,7 +472,7 @@ export default ({ name, wasm, locals: _locals, params }) => {
467
472
  break;
468
473
  }
469
474
 
470
- case Opcodes.f64_copysign: { // ?
475
+ case Opcodes.f64_copysign: { // todo: check behavior
471
476
  if (stack.length < 2) { empty(); break; };
472
477
  const [ b, a ] = pop2();
473
478
  const v = Math.abs(a) * (b > 0 ? 1 : -1);
@@ -567,6 +572,29 @@ export default ({ name, wasm, locals: _locals, params }) => {
567
572
  break;
568
573
  }
569
574
 
575
+ case Opcodes.global_get: {
576
+ const x = globals[op[1]];
577
+ if (x === false) {
578
+ empty();
579
+ } else {
580
+ replaceVal(x, globalValtypes[op[1]]);
581
+ push(x);
582
+ }
583
+ break;
584
+ }
585
+
586
+ case Opcodes.global_set: {
587
+ if (stack.length < 1) {
588
+ globals[op[1]] = false;
589
+ empty();
590
+ break;
591
+ }
592
+
593
+ const x = peek();
594
+ globals[op[1]] = x;
595
+ break;
596
+ }
597
+
570
598
  case Opcodes.block:
571
599
  case Opcodes.loop:
572
600
  case Opcodes.try:
package/compiler/index.js CHANGED
@@ -135,7 +135,7 @@ export default (code, module = Prefs.module) => {
135
135
 
136
136
  for (const x of funcs) {
137
137
  const preOps = x.wasm.length;
138
- cyclone(x);
138
+ cyclone(x, globals);
139
139
 
140
140
  if (preOps !== x.wasm.length) console.log(`${x.name}: ${preOps} -> ${x.wasm.length} ops`);
141
141
  }
@@ -147,7 +147,7 @@ export default (code, module = Prefs.module) => {
147
147
  console.log(`cyclone size diff: ${oldSize - newSize} bytes (${oldSize} -> ${newSize})\n`);
148
148
  } else {
149
149
  for (const x of funcs) {
150
- cyclone(x);
150
+ cyclone(x, globals);
151
151
  }
152
152
  }
153
153
  }
@@ -212,46 +212,18 @@ export default (code, module = Prefs.module) => {
212
212
  console.log([...pages.keys()].map(x => `\x1B[36m - ${x}\x1B[0m`).join('\n') + '\n');
213
213
  }
214
214
 
215
- if (Prefs.emscripten) {
216
- const tmpFile = 'porffor_tmp.wasm';
217
- const cO = Prefs._cO ?? 'Oz';
215
+ if (Prefs.wasmOpt) {
216
+ if (logProgress) progressStart('wasm-opt...');
218
217
 
219
- const args = [
220
- 'emcc',
221
- '-xc', '-', // use stdin as c source in
222
- '-s', 'STANDALONE_WASM=1',
223
- '-s', 'NO_FILESYSTEM=1',
224
- '-s', 'EXPORTED_FUNCTIONS=\'["_m"]\'',
225
- '-nostartfiles',
226
- '-Wl,--no-entry',
227
- '-o', tmpFile,
228
- '-' + cO,
229
- Prefs.d ? '-g' : ''
230
- ];
231
-
232
- if (Prefs.clangFast) args.push('-flto=thin', '-march=native', '-ffast-math', '-fno-asynchronous-unwind-tables');
233
-
234
- if (Prefs.s) args.push('-s');
235
-
236
- Prefs['2cWasmImports'] = true;
237
- const c = toc(out)
238
- .replace(`int main()`, `
239
- void __wasi_proc_exit(int code) {
240
- __builtin_trap();
241
- }
242
-
243
- int m()`);
244
- Prefs['2cWasmImports'] = false;
245
-
246
- // obvious command escape is obvious
247
- execSync(args.join(' '), {
248
- stdio: [ 'pipe', 'inherit', 'inherit' ],
249
- input: c,
250
- encoding: 'utf8'
218
+ const t4 = performance.now();
219
+ const newWasm = execSync(`wasm-opt -all -O4 -o -`, {
220
+ stdio: [ 'pipe', 'pipe', 'pipe' ],
221
+ input: wasm,
222
+ encoding: null
251
223
  });
224
+ wasm = out.wasm = new Uint8Array(newWasm);
252
225
 
253
- out.wasm = wasm = fs.readFileSync(tmpFile, null);
254
- fs.unlinkSync(tmpFile);
226
+ if (logProgress) progressDone('wasm-opt', t4);
255
227
  }
256
228
 
257
229
  if (target === 'wasm' && outFile) {
package/foo.js ADDED
@@ -0,0 +1 @@
1
+ (typeof console === 'undefined' ? print : console.log)('lol');
package/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honk/porffor",
3
- "version": "0.60.20",
3
+ "version": "0.60.22",
4
4
  "exports": "./compiler/wrap.js",
5
5
  "publish": {
6
6
  "exclude": [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.60.20",
4
+ "version": "0.60.22",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.60.20';
3
+ globalThis.version = '0.60.22';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {