porffor 0.20.0 → 0.20.2

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/compiler/2c.js CHANGED
@@ -27,7 +27,8 @@ typedef uint64_t u64;
27
27
  typedef float f32;
28
28
  typedef double f64;
29
29
 
30
- f64 NAN = 0e+0/0e+0;
30
+ const f64 NaN = 0e+0/0e+0;
31
+ const f64 Infinity = 1e+0/0e+0;
31
32
 
32
33
  struct ReturnValue {
33
34
  f64 value;
@@ -187,7 +188,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
187
188
  }
188
189
  return out;
189
190
  };
190
- const sanitize = str => str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
191
+ const sanitize = str => {
192
+ if (str === 'char') return '_' + str;
193
+
194
+ return str.replace(/[^0-9a-zA-Z_]/g, _ => codeToSanitizedStr(_.charCodeAt(0)));
195
+ };
191
196
 
192
197
  for (const x in invGlobals) {
193
198
  invGlobals[x] = sanitize(invGlobals[x]);
@@ -226,6 +231,20 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
226
231
  prependMain.set('argv', `_argc = argc; _argv = argv;`);
227
232
  }
228
233
 
234
+ prepend.set('func decls', funcs.filter(x => x.name !== 'main').map(f => {
235
+ const returns = f.returns.length > 0;
236
+ const typedReturns = f.returnType == null;
237
+
238
+ const invLocals = inv(f.locals, x => x.idx);
239
+ for (const x in invLocals) {
240
+ invLocals[x] = sanitize(invLocals[x]);
241
+ }
242
+
243
+ const shouldInline = false;
244
+
245
+ return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
246
+ }).join('\n'));
247
+
229
248
  if (out) out += '\n';
230
249
 
231
250
  const line = (str, semi = true) => out += `${str}${semi ? ';' : ''}\n`;
@@ -304,11 +323,26 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
304
323
  let tmpId = 0;
305
324
 
306
325
  const invLocals = inv(f.locals, x => x.idx);
307
-
326
+ const invLocalTypes = {};
308
327
  for (const x in invLocals) {
328
+ invLocalTypes[x] = CValtype[f.locals[invLocals[x]].type];
309
329
  invLocals[x] = sanitize(invLocals[x]);
310
330
  }
311
331
 
332
+ let localTmpId = 0;
333
+ const localGet = idx => {
334
+ if (Prefs['2cDirectLocalGet']) {
335
+ // this just does local.get via the variable name
336
+ // nice but does not get the value at this moment
337
+ // so breaks some wasm principles :(
338
+ vals.push(`${invLocals[i[1]]}`);
339
+ } else {
340
+ const id = localTmpId++;
341
+ line(`const ${invLocalTypes[idx]} _get${id} = ${invLocals[idx]}`);
342
+ vals.push(`_get${id}`);
343
+ }
344
+ };
345
+
312
346
  const returns = f.returns.length > 0;
313
347
  const typedReturns = f.returnType == null;
314
348
 
@@ -394,33 +428,31 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
394
428
  switch (i[0]) {
395
429
  case Opcodes.i32_const:
396
430
  case Opcodes.i64_const:
397
- // vals.push(read_signedLEB128(i.slice(1)).toString());
398
- vals.push(new String(read_signedLEB128(i.slice(1)).toString()));
399
- vals.at(-1).offset = _;
431
+ vals.push(read_signedLEB128(i.slice(1)).toString());
400
432
  break;
401
433
 
402
434
  case Opcodes.f64_const: {
403
- // const val = read_ieee754_binary64(i.slice(1)).toExponential();
404
- const val = new String(read_ieee754_binary64(i.slice(1)).toExponential());
405
- // vals.push(val == 'NaN' ? 'NAN' : val);
406
- vals.push(val == 'NaN' ? new String('NAN') : val);
407
- vals.at(-1).offset = _;
435
+ const val = read_ieee754_binary64(i.slice(1)).toExponential();
436
+ vals.push(val);
408
437
  break;
409
438
  }
410
439
 
411
- case Opcodes.local_get:
412
- vals.push(`${invLocals[i[1]]}`);
440
+ case Opcodes.local_get: {
441
+ localGet(i[1]);
413
442
  break;
443
+ }
414
444
 
415
445
  case Opcodes.local_set:
416
446
  line(`${invLocals[i[1]]} = ${removeBrackets(vals.pop())}`);
417
447
  break;
418
448
 
419
- case Opcodes.local_tee:
449
+ case Opcodes.local_tee: {
420
450
  line(`${invLocals[i[1]]} = ${removeBrackets(vals.pop())}`);
421
- vals.push(`${invLocals[i[1]]}`);
451
+ localGet(i[1]);
452
+
422
453
  // vals.push(`((${invLocals[i[1]]} = ${vals.pop()}))`);
423
454
  break;
455
+ }
424
456
 
425
457
  case Opcodes.global_get:
426
458
  vals.push(`${invGlobals[i[1]]}`);
@@ -430,11 +462,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
430
462
  line(`${invGlobals[i[1]]} = ${removeBrackets(vals.pop())}`);
431
463
  break;
432
464
 
433
- case Opcodes.f64_trunc:
434
- // vals.push(`trunc(${vals.pop()})`);
435
- vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
436
- break;
437
-
438
465
  case Opcodes.f64_convert_i32_u:
439
466
  case Opcodes.f64_convert_i32_s:
440
467
  case Opcodes.f64_convert_i64_u:
@@ -686,6 +713,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
686
713
  break;
687
714
  }
688
715
 
716
+ case Opcodes.select: {
717
+ const cond = vals.pop();
718
+ const b = vals.pop();
719
+ const a = vals.pop();
720
+
721
+ vals.push(`(${cond} ? ${a} : ${b})`);
722
+ break;
723
+ }
724
+
689
725
  case Opcodes.throw: {
690
726
  const id = vals.pop();
691
727
 
@@ -697,29 +733,6 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
697
733
  break;
698
734
  }
699
735
 
700
- case Opcodes.f64_abs: {
701
- break;
702
- }
703
- case Opcodes.f64_neg: {
704
- break;
705
- }
706
-
707
- case Opcodes.f64_ceil: {
708
- break;
709
- }
710
- case Opcodes.f64_floor: {
711
- break;
712
- }
713
- case Opcodes.f64_trunc: {
714
- break;
715
- }
716
- case Opcodes.f64_nearest: {
717
- break;
718
- }
719
-
720
- case Opcodes.f64_sqrt: {
721
- break;
722
- }
723
736
  case Opcodes.f64_min: {
724
737
  const b = vals.pop();
725
738
  const a = vals.pop();
@@ -740,10 +753,45 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
740
753
  vals.push(`(_tmp${id}a > _tmp${id}b ? _tmp${id}a : _tmp${id}b)`);
741
754
  break;
742
755
  }
743
- case Opcodes.f64_copysign: {
756
+
757
+ case Opcodes.f64_abs: {
758
+ const id = tmpId++;
759
+ line(`const f64 _tmp${id} = ${vals.pop()}`);
760
+ vals.push(`(_tmp${id} < 0 ? -_tmp${id} : _tmp${id})`);
761
+ break;
762
+ }
763
+ case Opcodes.f64_neg: {
764
+ vals.push(`(-${vals.pop()})`);
744
765
  break;
745
766
  }
746
767
 
768
+ case Opcodes.f64_ceil:
769
+ vals.push(`ceil(${vals.pop()})`);
770
+ includes.set('math.h', true);
771
+ break;
772
+ case Opcodes.f64_floor:
773
+ vals.push(`floor(${vals.pop()})`);
774
+ includes.set('math.h', true);
775
+ break;
776
+ case Opcodes.f64_trunc:
777
+ // vals.push(`trunc(${vals.pop()})`);
778
+ // includes.set('math.h', true);
779
+
780
+ vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
781
+ break;
782
+ case Opcodes.f64_nearest:
783
+ vals.push(`round(${vals.pop()})`);
784
+ includes.set('math.h', true);
785
+ break;
786
+
787
+ // case Opcodes.f64_sqrt: {
788
+ // break;
789
+ // }
790
+
791
+ // case Opcodes.f64_copysign: {
792
+ // break;
793
+ // }
794
+
747
795
  default:
748
796
  if (CMemFuncs[i[0]]) {
749
797
  const name = invOpcodes[i[0]];
@@ -763,7 +811,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
763
811
  break;
764
812
  }
765
813
 
766
- log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]}`);
814
+ log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]} \x1b[90m(${f.name})`);
767
815
  }
768
816
 
769
817
  lastCond = false;
@@ -4,7 +4,7 @@ import type {} from './porffor.d.ts';
4
4
  // todo: support constructor/string objects properly
5
5
  export const String = function (value: any): bytestring {
6
6
  if (!new.target && Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
7
- return __ecma262_ToString(value);
7
+ return ecma262.ToString(value);
8
8
  };
9
9
 
10
10
  export const __String_fromCharCode = (...codes: any[]): bytestring|string => {
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.20.0+221fc85ef",
4
+ "version": "0.20.2+fe061341a",
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.20.0+221fc85ef';
3
+ globalThis.version = '0.20.2+fe061341a';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {