porffor 0.16.0-ec15a329e → 0.16.0-fe07da0f4

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/CONTRIBUTING.md CHANGED
@@ -233,7 +233,7 @@ builtins/tostring_number: impl radix
233
233
 
234
234
  ## Test262
235
235
 
236
- For the first time, ensure you run `./test262/setup.sh`.
236
+ Make sure you have Test262 cloned already **inside of `test262/`** (`git clone https://github.com/tc39/test262.git test262/test262`) and run `npm install` inside `test262/` too.
237
237
 
238
238
  Run `node test262` to run all the tests and get an output of total overall test results.
239
239
 
package/compiler/2c.js CHANGED
@@ -29,8 +29,8 @@ typedef double f64;
29
29
  f64 NAN = 0e+0/0e+0;
30
30
 
31
31
  struct ReturnValue {
32
- f64 value;
33
- i32 type;
32
+ ${CValtype.f64} value;
33
+ ${CValtype.i32} type;
34
34
  };\n\n`;
35
35
 
36
36
  // todo: is memcpy/etc safe with host endianness?
@@ -41,60 +41,60 @@ const CMemFuncs = {
41
41
  [Opcodes.i32_store]: {
42
42
  c: `memcpy(_memory + offset + pointer, &value, sizeof(value));`,
43
43
  args: ['pointer', 'value'],
44
- argTypes: ['i32', 'i32'],
44
+ argTypes: [CValtype.i32, CValtype.i32],
45
45
  returns: false
46
46
  },
47
47
  [Opcodes.i32_store16]: {
48
48
  c: `memcpy(_memory + offset + pointer, &value, sizeof(value));`,
49
49
  args: ['pointer', 'value'],
50
- argTypes: ['i32', 'i16'],
50
+ argTypes: [CValtype.i32, CValtype.i16],
51
51
  returns: false
52
52
  },
53
53
  [Opcodes.i32_store8]: {
54
54
  c: `memcpy(_memory + offset + pointer, &value, sizeof(value));`,
55
55
  args: ['pointer', 'value'],
56
- argTypes: ['i32', 'i8'],
56
+ argTypes: [CValtype.i32, CValtype.i8],
57
57
  returns: false
58
58
  },
59
59
 
60
60
  [Opcodes.i32_load]: {
61
- c: `i32 out;
61
+ c: `${CValtype.i32} out;
62
62
  memcpy(&out, _memory + offset + pointer, sizeof(out));
63
63
  return out;`,
64
64
  args: ['pointer'],
65
- argTypes: ['i32'],
66
- returns: 'i32'
65
+ argTypes: [CValtype.i32],
66
+ returns: CValtype.i32
67
67
  },
68
68
  [Opcodes.i32_load16_u]: {
69
- c: `i16 out;
69
+ c: `${CValtype.i16} out;
70
70
  memcpy(&out, _memory + offset + pointer, sizeof(out));
71
71
  return out;`,
72
72
  args: ['pointer'],
73
- argTypes: ['i32'],
74
- returns: 'i32'
73
+ argTypes: [CValtype.i32],
74
+ returns: CValtype.i32
75
75
  },
76
76
  [Opcodes.i32_load8_u]: {
77
- c: `i8 out;
77
+ c: `${CValtype.i8} out;
78
78
  memcpy(&out, _memory + offset + pointer, sizeof(out));
79
79
  return out;`,
80
80
  args: ['pointer'],
81
- argTypes: ['i32'],
82
- returns: 'i32'
81
+ argTypes: [CValtype.i32],
82
+ returns: CValtype.i32
83
83
  },
84
84
 
85
85
  [Opcodes.f64_store]: {
86
86
  c: `memcpy(_memory + offset + pointer, &value, sizeof(value));`,
87
87
  args: ['pointer', 'value'],
88
- argTypes: ['i32', 'f64'],
88
+ argTypes: [CValtype.i32, CValtype.f64],
89
89
  returns: false
90
90
  },
91
91
  [Opcodes.f64_load]: {
92
- c: `f64 out;
92
+ c: `${CValtype.f64} out;
93
93
  memcpy(&out, _memory + offset + pointer, sizeof(out));
94
94
  return out;`,
95
95
  args: ['pointer'],
96
- argTypes: ['i32'],
97
- returns: 'f64'
96
+ argTypes: [CValtype.i32],
97
+ returns: CValtype.f64
98
98
  },
99
99
  };
100
100
 
@@ -108,7 +108,7 @@ for (const x in CValtype) {
108
108
 
109
109
  const removeBrackets = str => {
110
110
  // return str;
111
- // if (str.startsWith('(i32)(u32)')) return '(i32)(u32)(' + removeBrackets(str.slice(22, -1)) + ')';
111
+ // if (str.startsWith(`(${CValtype.i32})(${CValtype.u32})`)) return `(${CValtype.i32})(${CValtype.u32})(` + removeBrackets(str.slice(22, -1)) + ')';
112
112
 
113
113
  for (const x in CValtype) {
114
114
  const p = `(${x})`;
@@ -156,7 +156,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
156
156
  }
157
157
 
158
158
  if (data.length > 0) {
159
- prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n '));
159
+ prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n'));
160
160
  }
161
161
 
162
162
  if (importFuncs.find(x => x.name === '__Porffor_readArgv')) {
@@ -168,10 +168,10 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
168
168
 
169
169
  let depth = 1;
170
170
  let brDepth = 0;
171
- const line = (str, semi = true) => out += `${' '.repeat((depth + brDepth) * 2)}${str}${semi ? ';' : ''}\n`;
171
+ const line = (str, semi = true) => out += `${' '.repeat(depth * 2 + brDepth * 2)}${str}${semi ? ';' : ''}\n`;
172
172
  const lines = lines => {
173
173
  for (const x of lines) {
174
- out += `${' '.repeat((depth + brDepth) * 2)}${x}\n`;
174
+ out += `${' '.repeat(depth * 2)}${x}\n`;
175
175
  }
176
176
  };
177
177
 
@@ -219,10 +219,10 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
219
219
 
220
220
  const shouldInline = false; // f.internal;
221
221
  if (f.name === 'main') out += `int main(${prependMain.has('argv') ? 'int argc, char* argv[]' : ''}) {\n`;
222
- else out += `${f.internal ? (returns ? 'f64' : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
222
+ else out += `${f.internal ? (returns ? CValtype.f64 : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
223
223
 
224
224
  if (f.name === 'main') {
225
- out += ' ' + [...prependMain.values()].join('\n ');
225
+ out += [...prependMain.values()].join('\n');
226
226
  if (prependMain.size > 0) out += '\n\n';
227
227
  }
228
228
 
@@ -283,12 +283,12 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
283
283
  switch (i[1]) {
284
284
  // i32_trunc_sat_f64_s
285
285
  case 0x02:
286
- vals.push(`(i32)(${vals.pop()})`);
286
+ vals.push(`(${CValtype.i32})(${vals.pop()})`);
287
287
  break;
288
288
 
289
289
  // i32_trunc_sat_f64_u
290
290
  case 0x03:
291
- vals.push(`(u32)(${vals.pop()})`);
291
+ vals.push(`(${CValtype.u32})(${vals.pop()})`);
292
292
  break;
293
293
  }
294
294
 
@@ -337,7 +337,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
337
337
 
338
338
  case Opcodes.f64_trunc:
339
339
  // vals.push(`trunc(${vals.pop()})`);
340
- vals.push(`(i32)(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
340
+ vals.push(`(${CValtype.i32})(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
341
341
  break;
342
342
 
343
343
  case Opcodes.f64_convert_i32_u:
@@ -345,7 +345,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
345
345
  case Opcodes.f64_convert_i64_u:
346
346
  case Opcodes.f64_convert_i64_s:
347
347
  // int to f64
348
- vals.push(`(f64)(${removeBrackets(vals.pop())})`);
348
+ vals.push(`(${CValtype.f64})(${removeBrackets(vals.pop())})`);
349
349
  break;
350
350
 
351
351
  case Opcodes.i32_eqz:
@@ -353,7 +353,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
353
353
  vals.push(`!(${removeBrackets(vals.pop())})`);
354
354
  } else {
355
355
  let cond = '(' + removeBrackets(vals.pop());
356
- if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} == 0e+0`;
356
+ if (cond.startsWith(`(${CValtype.i32})`)) cond = `${cond.slice(`(${CValtype.i32})`.length)}) == 0e+0`;
357
357
  else cond += ') == 0';
358
358
  vals.push(cond);
359
359
  }
@@ -368,7 +368,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
368
368
  case Opcodes.if: {
369
369
  let cond = removeBrackets(vals.pop());
370
370
  if (!lastCond) {
371
- if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
371
+ if (cond.startsWith(`(${CValtype.i32})`)) cond = `(${cond.slice(`(${CValtype.i32})`.length)}) != 0e+0`;
372
372
  else cond = `(${cond}) != 0`;
373
373
  }
374
374
 
@@ -434,16 +434,28 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
434
434
  const importFunc = importFuncs[i[1]];
435
435
  switch (importFunc.name) {
436
436
  case 'print':
437
+ // line(`printf("%f\\n", ${vals.pop()})`);
437
438
  line(`printf("${valtype === 'f64' ? '%g' : '%i'}\\n", ${vals.pop()})`);
438
439
  includes.set('stdio.h', true);
439
440
  break;
440
441
  case 'printChar':
441
- line(`putchar((int)(${vals.pop()}))`);
442
+ line(`printf("%c", (int)(${vals.pop()}))`);
442
443
  includes.set('stdio.h', true);
443
444
  break;
444
445
 
445
446
  case 'time':
446
447
  line(`double _time_out`);
448
+ /* platformSpecific(
449
+ `FILETIME _time_filetime;
450
+ GetSystemTimeAsFileTime(&_time_filetime);
451
+
452
+ ULARGE_INTEGER _time_ularge;
453
+ _time_ularge.LowPart = _time_filetime.dwLowDateTime;
454
+ _time_ularge.HighPart = _time_filetime.dwHighDateTime;
455
+ _time_out = (_time_ularge.QuadPart - 116444736000000000i64) / 10000.;`,
456
+ `struct timespec _time;
457
+ clock_gettime(CLOCK_MONOTONIC, &_time);
458
+ _time_out = _time.tv_nsec / 1000000.;`); */
447
459
  platformSpecific(
448
460
  `LARGE_INTEGER _time_freq, _time_t;
449
461
  QueryPerformanceFrequency(&_time_freq);
@@ -458,11 +470,14 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
458
470
  winIncludes.set('windows.h', true);
459
471
  break;
460
472
 
461
- case '__Porffor_readArgv': {
473
+ case '__Porffor_readArgv':
474
+ includes.set('stdlib.h', true);
475
+
462
476
  prepend.set('__Porffor_readArgv',
463
- `i32 __Porffor_readArgv(u32 index, u32 outPtr) {
477
+ `void __Porffor_readArgv(u32 index, u32 outPtr) {
464
478
  if (index >= _argc) {
465
- return -1;
479
+ printf("expected %d arguments\\n", index);
480
+ exit(1);
466
481
  }
467
482
 
468
483
  char* arg = _argv[index];
@@ -475,24 +490,23 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
475
490
  }
476
491
 
477
492
  memcpy(_memory + outPtr, &read, sizeof(read));
478
- return read;
479
493
  }`);
480
494
 
481
- const outPtr = vals.pop();
482
- const index = vals.pop();
483
- vals.push(`(f64)__Porffor_readArgv((u32)(${index}), (u32)(${outPtr}))`);
495
+ line(`__Porffor_readArgv((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
496
+ vals.pop();
484
497
  break;
485
- }
486
498
 
487
- case '__Porffor_readFile': {
499
+ case '__Porffor_readFile':
488
500
  includes.set('stdio.h', true);
501
+ includes.set('stdlib.h', true);
489
502
 
490
503
  prepend.set('__Porffor_readFile',
491
- `i32 __Porffor_readFile(u32 pathPtr, u32 outPtr) {
504
+ `void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
492
505
  char* path = _memory + pathPtr + 4;
493
506
  FILE* fp = fopen(path, "r");
494
507
  if (fp == NULL) {
495
- return -1;
508
+ printf("failed to open file: %s\\n", path);
509
+ exit(1);
496
510
  }
497
511
 
498
512
  u32 read = 0;
@@ -505,13 +519,10 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
505
519
  fclose(fp);
506
520
 
507
521
  memcpy(_memory + outPtr, &read, sizeof(read));
508
- return read;
509
522
  }`);
510
- const outPtr = vals.pop();
511
- const pathPtr = vals.pop();
512
- vals.push(`(f64)__Porffor_readFile((u32)(${pathPtr}), (u32)(${outPtr}))`);
523
+ line(`__Porffor_readFile((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
524
+ vals.pop();
513
525
  break;
514
- }
515
526
 
516
527
  default:
517
528
  log.warning('2c', `unimplemented import: ${importFunc.name}`);
@@ -528,10 +539,9 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
528
539
  if (func.internal) {
529
540
  vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
530
541
  } else {
531
- const id = retTmpId++;
532
- line(`const struct ReturnValue _${id} = ${sanitize(func.name)}(${args.join(', ')})`);
533
- vals.push(`_${id}.value`);
534
- vals.push(`_${id}.type`);
542
+ line(`const struct ReturnValue _${retTmpId++} = ${sanitize(func.name)}(${args.join(', ')})`);
543
+ vals.push(`_.value`);
544
+ vals.push(`_.type`);
535
545
  }
536
546
  } else line(`${sanitize(func.name)}(${args.join(', ')})`);
537
547
 
@@ -561,7 +571,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
561
571
 
562
572
  let cond = removeBrackets(vals.pop());
563
573
  if (!lastCond) {
564
- if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
574
+ if (cond.startsWith(`(${CValtype.i32})`)) cond = `(${cond.slice(`(${CValtype.i32})`.length)}) != 0e+0`;
565
575
  else cond = `(${cond}) != 0`;
566
576
  }
567
577
 
@@ -591,7 +601,8 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
591
601
  const name = invOpcodes[i[0]];
592
602
  const func = CMemFuncs[i[0]];
593
603
  if (!prepend.has(name)) {
594
- prepend.set(name, `${func.returns || 'void'} ${name}(i32 align, i32 offset, ${func.args.map((x, i) => `${func.argTypes[i]} ${x}`).join(', ')}) {\n ${func.c.replaceAll('\n', '\n ')}\n}\n`);
604
+ prepend.set(name, `${func.returns || 'void'} ${name}(${CValtype.i32} align, ${CValtype.i32} offset, ${func.args.map((x, i) => `${func.argTypes[i]} ${x}`).join(', ')}) {\n ${func.c.replaceAll('\n', '\n ')}\n}\n`);
605
+ // generate func c and prepend
595
606
  }
596
607
 
597
608
  const immediates = [ i[1], read_unsignedLEB128(i.slice(2)) ];
@@ -626,6 +637,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
626
637
  depth = 0;
627
638
 
628
639
  const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');
640
+
629
641
  out = platformSpecific(makeIncludes(winIncludes), makeIncludes(unixIncludes), false) + '\n' + makeIncludes(includes) + '\n' + alwaysPreface + [...prepend.values()].join('\n') + '\n\n' + out;
630
642
 
631
643
  return out.trim();
@@ -56,9 +56,6 @@ type PorfforGlobal = {
56
56
 
57
57
  s(...args: any): string;
58
58
  bs(...args: any): bytestring;
59
-
60
- readArgv(index: i32, out: bytestring): i32;
61
- readFile(path: bytestring, out: bytestring): i32;
62
59
  };
63
60
 
64
61
  declare global {
@@ -45,13 +45,13 @@ export const importedFuncs = [
45
45
  name: '__Porffor_readArgv',
46
46
  import: 'w',
47
47
  params: 2,
48
- returns: 1
48
+ returns: 0
49
49
  },
50
50
  {
51
51
  name: '__Porffor_readFile',
52
52
  import: 'q',
53
53
  params: 2,
54
- returns: 1
54
+ returns: 0
55
55
  }
56
56
  ];
57
57
 
package/compiler/parse.js CHANGED
@@ -10,7 +10,7 @@ if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
10
10
  const file = process.argv.slice(2).find(x => x[0] !== '-' && !['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(x));
11
11
 
12
12
  // should we try to support types (while parsing)
13
- const types = Prefs.parseTypes || Prefs.t || file?.endsWith('.ts');
13
+ const types = Prefs.parseTypes || file?.endsWith('.ts');
14
14
  globalThis.typedInput = types && Prefs.optTypes;
15
15
 
16
16
  // todo: review which to use by default
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.16.0-ec15a329e",
4
+ "version": "0.16.0-fe07da0f4",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {