porffor 0.16.0-594397507 → 0.16.0-ab08df866

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
@@ -29,8 +29,8 @@ typedef double f64;
29
29
  f64 NAN = 0e+0/0e+0;
30
30
 
31
31
  struct ReturnValue {
32
- ${CValtype.f64} value;
33
- ${CValtype.i32} type;
32
+ f64 value;
33
+ 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: [CValtype.i32, CValtype.i32],
44
+ argTypes: ['i32', '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: [CValtype.i32, CValtype.i16],
50
+ argTypes: ['i32', '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: [CValtype.i32, CValtype.i8],
56
+ argTypes: ['i32', 'i8'],
57
57
  returns: false
58
58
  },
59
59
 
60
60
  [Opcodes.i32_load]: {
61
- c: `${CValtype.i32} out;
61
+ c: `i32 out;
62
62
  memcpy(&out, _memory + offset + pointer, sizeof(out));
63
63
  return out;`,
64
64
  args: ['pointer'],
65
- argTypes: [CValtype.i32],
66
- returns: CValtype.i32
65
+ argTypes: ['i32'],
66
+ returns: 'i32'
67
67
  },
68
68
  [Opcodes.i32_load16_u]: {
69
- c: `${CValtype.i16} out;
69
+ c: `i16 out;
70
70
  memcpy(&out, _memory + offset + pointer, sizeof(out));
71
71
  return out;`,
72
72
  args: ['pointer'],
73
- argTypes: [CValtype.i32],
74
- returns: CValtype.i32
73
+ argTypes: ['i32'],
74
+ returns: 'i32'
75
75
  },
76
76
  [Opcodes.i32_load8_u]: {
77
- c: `${CValtype.i8} out;
77
+ c: `i8 out;
78
78
  memcpy(&out, _memory + offset + pointer, sizeof(out));
79
79
  return out;`,
80
80
  args: ['pointer'],
81
- argTypes: [CValtype.i32],
82
- returns: CValtype.i32
81
+ argTypes: ['i32'],
82
+ returns: '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: [CValtype.i32, CValtype.f64],
88
+ argTypes: ['i32', 'f64'],
89
89
  returns: false
90
90
  },
91
91
  [Opcodes.f64_load]: {
92
- c: `${CValtype.f64} out;
92
+ c: `f64 out;
93
93
  memcpy(&out, _memory + offset + pointer, sizeof(out));
94
94
  return out;`,
95
95
  args: ['pointer'],
96
- argTypes: [CValtype.i32],
97
- returns: CValtype.f64
96
+ argTypes: ['i32'],
97
+ returns: '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(`(${CValtype.i32})(${CValtype.u32})`)) return `(${CValtype.i32})(${CValtype.u32})(` + removeBrackets(str.slice(22, -1)) + ')';
111
+ // if (str.startsWith('(i32)(u32)')) return '(i32)(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 * 2 + brDepth * 2)}${str}${semi ? ';' : ''}\n`;
171
+ const line = (str, semi = true) => out += `${' '.repeat((depth + brDepth) * 2)}${str}${semi ? ';' : ''}\n`;
172
172
  const lines = lines => {
173
173
  for (const x of lines) {
174
- out += `${' '.repeat(depth * 2)}${x}\n`;
174
+ out += `${' '.repeat((depth + brDepth) * 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 ? CValtype.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 ? '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(`(${CValtype.i32})(${vals.pop()})`);
286
+ vals.push(`(i32)(${vals.pop()})`);
287
287
  break;
288
288
 
289
289
  // i32_trunc_sat_f64_u
290
290
  case 0x03:
291
- vals.push(`(${CValtype.u32})(${vals.pop()})`);
291
+ vals.push(`(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(`(${CValtype.i32})(${removeBrackets(vals.pop())})`); // this is ~10x faster with clang??
340
+ vals.push(`(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(`(${CValtype.f64})(${removeBrackets(vals.pop())})`);
348
+ vals.push(`(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(`(${CValtype.i32})`)) cond = `${cond.slice(`(${CValtype.i32})`.length)}) == 0e+0`;
356
+ if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} == 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(`(${CValtype.i32})`)) cond = `(${cond.slice(`(${CValtype.i32})`.length)}) != 0e+0`;
371
+ if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
372
372
  else cond = `(${cond}) != 0`;
373
373
  }
374
374
 
@@ -434,28 +434,16 @@ 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()})`);
438
437
  line(`printf("${valtype === 'f64' ? '%g' : '%i'}\\n", ${vals.pop()})`);
439
438
  includes.set('stdio.h', true);
440
439
  break;
441
440
  case 'printChar':
442
- line(`printf("%c", (int)(${vals.pop()}))`);
441
+ line(`putchar((int)(${vals.pop()}))`);
443
442
  includes.set('stdio.h', true);
444
443
  break;
445
444
 
446
445
  case 'time':
447
446
  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.;`); */
459
447
  platformSpecific(
460
448
  `LARGE_INTEGER _time_freq, _time_t;
461
449
  QueryPerformanceFrequency(&_time_freq);
@@ -470,14 +458,11 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
470
458
  winIncludes.set('windows.h', true);
471
459
  break;
472
460
 
473
- case '__Porffor_readArgv':
474
- includes.set('stdlib.h', true);
475
-
461
+ case '__Porffor_readArgv': {
476
462
  prepend.set('__Porffor_readArgv',
477
- `void __Porffor_readArgv(u32 index, u32 outPtr) {
463
+ `i32 __Porffor_readArgv(u32 index, u32 outPtr) {
478
464
  if (index >= _argc) {
479
- printf("expected %d arguments\\n", index);
480
- exit(1);
465
+ return -1;
481
466
  }
482
467
 
483
468
  char* arg = _argv[index];
@@ -490,23 +475,24 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
490
475
  }
491
476
 
492
477
  memcpy(_memory + outPtr, &read, sizeof(read));
478
+ return read;
493
479
  }`);
494
480
 
495
- line(`__Porffor_readArgv((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
496
- vals.pop();
481
+ const outPtr = vals.pop();
482
+ const index = vals.pop();
483
+ vals.push(`(f64)__Porffor_readArgv((u32)(${index}), (u32)(${outPtr}))`);
497
484
  break;
485
+ }
498
486
 
499
- case '__Porffor_readFile':
487
+ case '__Porffor_readFile': {
500
488
  includes.set('stdio.h', true);
501
- includes.set('stdlib.h', true);
502
489
 
503
490
  prepend.set('__Porffor_readFile',
504
- `void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
491
+ `i32 __Porffor_readFile(u32 pathPtr, u32 outPtr) {
505
492
  char* path = _memory + pathPtr + 4;
506
493
  FILE* fp = fopen(path, "r");
507
494
  if (fp == NULL) {
508
- printf("failed to open file: %s\\n", path);
509
- exit(1);
495
+ return -1;
510
496
  }
511
497
 
512
498
  u32 read = 0;
@@ -519,10 +505,13 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
519
505
  fclose(fp);
520
506
 
521
507
  memcpy(_memory + outPtr, &read, sizeof(read));
508
+ return read;
522
509
  }`);
523
- line(`__Porffor_readFile((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
524
- vals.pop();
510
+ const outPtr = vals.pop();
511
+ const pathPtr = vals.pop();
512
+ vals.push(`(f64)__Porffor_readFile((u32)(${pathPtr}), (u32)(${outPtr}))`);
525
513
  break;
514
+ }
526
515
 
527
516
  default:
528
517
  log.warning('2c', `unimplemented import: ${importFunc.name}`);
@@ -539,9 +528,10 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
539
528
  if (func.internal) {
540
529
  vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
541
530
  } else {
542
- line(`const struct ReturnValue _${retTmpId++} = ${sanitize(func.name)}(${args.join(', ')})`);
543
- vals.push(`_.value`);
544
- vals.push(`_.type`);
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`);
545
535
  }
546
536
  } else line(`${sanitize(func.name)}(${args.join(', ')})`);
547
537
 
@@ -571,7 +561,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
571
561
 
572
562
  let cond = removeBrackets(vals.pop());
573
563
  if (!lastCond) {
574
- if (cond.startsWith(`(${CValtype.i32})`)) cond = `(${cond.slice(`(${CValtype.i32})`.length)}) != 0e+0`;
564
+ if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
575
565
  else cond = `(${cond}) != 0`;
576
566
  }
577
567
 
@@ -601,8 +591,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
601
591
  const name = invOpcodes[i[0]];
602
592
  const func = CMemFuncs[i[0]];
603
593
  if (!prepend.has(name)) {
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
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`);
606
595
  }
607
596
 
608
597
  const immediates = [ i[1], read_unsignedLEB128(i.slice(2)) ];
@@ -637,7 +626,6 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
637
626
  depth = 0;
638
627
 
639
628
  const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');
640
-
641
629
  out = platformSpecific(makeIncludes(winIncludes), makeIncludes(unixIncludes), false) + '\n' + makeIncludes(includes) + '\n' + alwaysPreface + [...prepend.values()].join('\n') + '\n\n' + out;
642
630
 
643
631
  return out.trim();
@@ -56,6 +56,9 @@ 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;
59
62
  };
60
63
 
61
64
  declare global {
@@ -45,13 +45,13 @@ export const importedFuncs = [
45
45
  name: '__Porffor_readArgv',
46
46
  import: 'w',
47
47
  params: 2,
48
- returns: 0
48
+ returns: 1
49
49
  },
50
50
  {
51
51
  name: '__Porffor_readFile',
52
52
  import: 'q',
53
53
  params: 2,
54
- returns: 0
54
+ returns: 1
55
55
  }
56
56
  ];
57
57
 
@@ -167,6 +167,7 @@ export const BuiltinFuncs = function() {
167
167
  params: [ valtypeBinary, valtypeBinary ],
168
168
  locals: [],
169
169
  returns: [ valtypeBinary ],
170
+ returnType: TYPES.number,
170
171
  wasm: [ // x - truncf(x / y) * y
171
172
  [ Opcodes.local_get, 0 ], // x
172
173
 
@@ -189,6 +190,7 @@ export const BuiltinFuncs = function() {
189
190
  params: [ valtypeBinary, valtypeBinary ],
190
191
  locals: [],
191
192
  returns: [ valtypeBinary ],
193
+ returnType: TYPES.number,
192
194
  wasm: [
193
195
  [ Opcodes.local_get, 0 ],
194
196
  Opcodes.i32_to,
@@ -208,6 +210,7 @@ export const BuiltinFuncs = function() {
208
210
  params: [ valtypeBinary ],
209
211
  locals: [],
210
212
  returns: [ valtypeBinary ],
213
+ returnType: TYPES.number,
211
214
  wasm: [
212
215
  [ Opcodes.local_get, 0 ]
213
216
  ],
@@ -469,6 +472,7 @@ export const BuiltinFuncs = function() {
469
472
  params: [ valtypeBinary ],
470
473
  locals: [],
471
474
  returns: [ valtypeBinary ],
475
+ returnType: TYPES.number,
472
476
  wasm: [
473
477
  [ Opcodes.local_get, 0 ],
474
478
  [ Opcodes.f64_sqrt ]
@@ -480,6 +484,7 @@ export const BuiltinFuncs = function() {
480
484
  params: [ valtypeBinary ],
481
485
  locals: [],
482
486
  returns: [ valtypeBinary ],
487
+ returnType: TYPES.number,
483
488
  wasm: [
484
489
  [ Opcodes.local_get, 0 ],
485
490
  [ Opcodes.f64_abs ]
@@ -491,6 +496,7 @@ export const BuiltinFuncs = function() {
491
496
  params: [ valtypeBinary ],
492
497
  locals: [],
493
498
  returns: [ valtypeBinary ],
499
+ returnType: TYPES.number,
494
500
  wasm: [
495
501
  ...number(1),
496
502
  [ Opcodes.local_get, 0 ],
@@ -503,6 +509,7 @@ export const BuiltinFuncs = function() {
503
509
  params: [ valtypeBinary ],
504
510
  locals: [],
505
511
  returns: [ valtypeBinary ],
512
+ returnType: TYPES.number,
506
513
  wasm: [
507
514
  [ Opcodes.local_get, 0 ],
508
515
  [ Opcodes.f64_floor ]
@@ -514,6 +521,7 @@ export const BuiltinFuncs = function() {
514
521
  params: [ valtypeBinary ],
515
522
  locals: [],
516
523
  returns: [ valtypeBinary ],
524
+ returnType: TYPES.number,
517
525
  wasm: [
518
526
  [ Opcodes.local_get, 0 ],
519
527
  [ Opcodes.f64_ceil ]
@@ -525,6 +533,7 @@ export const BuiltinFuncs = function() {
525
533
  params: [ valtypeBinary ],
526
534
  locals: [],
527
535
  returns: [ valtypeBinary ],
536
+ returnType: TYPES.number,
528
537
  wasm: [
529
538
  [ Opcodes.local_get, 0 ],
530
539
  [ Opcodes.f64_nearest ]
@@ -536,6 +545,7 @@ export const BuiltinFuncs = function() {
536
545
  params: [ valtypeBinary ],
537
546
  locals: [],
538
547
  returns: [ valtypeBinary ],
548
+ returnType: TYPES.number,
539
549
  wasm: [
540
550
  [ Opcodes.local_get, 0 ],
541
551
  [ Opcodes.f64_trunc ]
@@ -547,6 +557,7 @@ export const BuiltinFuncs = function() {
547
557
  params: [ valtypeBinary ],
548
558
  locals: [],
549
559
  returns: [ valtypeBinary ],
560
+ returnType: TYPES.number,
550
561
  wasm: [
551
562
  [ Opcodes.local_get, 0 ],
552
563
  Opcodes.i32_trunc_sat_f64_u,
@@ -560,6 +571,7 @@ export const BuiltinFuncs = function() {
560
571
  params: [ valtypeBinary ],
561
572
  locals: [],
562
573
  returns: [ valtypeBinary ],
574
+ returnType: TYPES.number,
563
575
  wasm: [
564
576
  [ Opcodes.local_get, 0 ],
565
577
  [ Opcodes.f32_demote_f64 ],
@@ -573,6 +585,7 @@ export const BuiltinFuncs = function() {
573
585
  params: [ valtypeBinary, valtypeBinary ],
574
586
  locals: [],
575
587
  returns: [ valtypeBinary ],
588
+ returnType: TYPES.number,
576
589
  wasm: [
577
590
  [ Opcodes.local_get, 0 ],
578
591
  Opcodes.i32_trunc_sat_f64_s,
@@ -887,6 +900,7 @@ export const BuiltinFuncs = function() {
887
900
  globalNames: [ 'state0', 'state1' ],
888
901
  globalInits: [ prngSeed0, prngSeed1 ],
889
902
  returns: [ Valtype.f64 ],
903
+ returnType: TYPES.number,
890
904
  wasm: [
891
905
  ...prng.wasm,
892
906
 
@@ -938,6 +952,7 @@ export const BuiltinFuncs = function() {
938
952
  globalNames: [ 'state0', 'state1' ],
939
953
  globalInits: [ prngSeed0, prngSeed1 ],
940
954
  returns: [ Valtype.i32 ],
955
+ returnType: TYPES.number,
941
956
  wasm: [
942
957
  ...prng.wasm,
943
958
 
@@ -959,6 +974,7 @@ export const BuiltinFuncs = function() {
959
974
  params: [ valtypeBinary ],
960
975
  locals: [],
961
976
  returns: [ valtypeBinary ],
977
+ returnType: TYPES.number,
962
978
  wasm: [
963
979
  [ Opcodes.local_get, 0 ],
964
980
  ...number(Math.PI / 180),
@@ -971,6 +987,7 @@ export const BuiltinFuncs = function() {
971
987
  params: [ valtypeBinary ],
972
988
  locals: [],
973
989
  returns: [ valtypeBinary ],
990
+ returnType: TYPES.number,
974
991
  wasm: [
975
992
  [ Opcodes.local_get, 0 ],
976
993
  ...number(180 / Math.PI),
@@ -984,6 +1001,7 @@ export const BuiltinFuncs = function() {
984
1001
  locals: [],
985
1002
  localNames: [ 'x', 'lower', 'upper' ],
986
1003
  returns: [ valtypeBinary ],
1004
+ returnType: TYPES.number,
987
1005
  wasm: [
988
1006
  [ Opcodes.local_get, 0 ],
989
1007
  [ Opcodes.local_get, 1 ],
@@ -999,9 +1017,9 @@ export const BuiltinFuncs = function() {
999
1017
  locals: [],
1000
1018
  localNames: [ 'x', 'inLow', 'inHigh', 'outLow', 'outHigh' ],
1001
1019
  returns: [ valtypeBinary ],
1020
+ returnType: TYPES.number,
1002
1021
  wasm: [
1003
1022
  // (x − inLow) * (outHigh − outLow) / (inHigh - inLow) + outLow
1004
-
1005
1023
  [ Opcodes.local_get, 0 ],
1006
1024
  [ Opcodes.local_get, 1 ],
1007
1025
  [ Opcodes.f64_sub ],
@@ -1043,6 +1061,7 @@ export const BuiltinFuncs = function() {
1043
1061
  params: [],
1044
1062
  locals: [],
1045
1063
  returns: [ valtypeBinary ],
1064
+ returnType: TYPES.number,
1046
1065
  wasm: [
1047
1066
  [ Opcodes.call, importedFuncs.time ]
1048
1067
  ]
@@ -1070,6 +1089,7 @@ export const BuiltinFuncs = function() {
1070
1089
  typedParams: true,
1071
1090
  locals: [],
1072
1091
  returns: [ valtypeBinary ],
1092
+ returnType: TYPES.number,
1073
1093
  wasm: [
1074
1094
  [ Opcodes.local_get, 1 ],
1075
1095
  Opcodes.i32_from_u
@@ -1078,7 +1078,7 @@ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes
1078
1078
  locals,
1079
1079
  localInd: allLocals.length,
1080
1080
  returns,
1081
- returnType: returnType ?? TYPES.number,
1081
+ returnType,
1082
1082
  internal: true,
1083
1083
  index: currentFuncIndex++,
1084
1084
  table
@@ -1254,7 +1254,7 @@ const getNodeType = (scope, node) => {
1254
1254
  const func = funcs.find(x => x.name === name);
1255
1255
 
1256
1256
  if (func) {
1257
- if (func.returnType) return func.returnType;
1257
+ if (func.returnType != null) return func.returnType;
1258
1258
  }
1259
1259
 
1260
1260
  if (builtinFuncs[name] && !builtinFuncs[name].typedReturns) return builtinFuncs[name].returnType ?? TYPES.number;
@@ -1270,15 +1270,7 @@ const getNodeType = (scope, node) => {
1270
1270
  const func = spl[spl.length - 1];
1271
1271
  const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES.bytestring && prototypeFuncs[x][func] != null);
1272
1272
  if (protoFuncs.length === 1) {
1273
- if (protoFuncs[0].returnType) return protoFuncs[0].returnType;
1274
- }
1275
-
1276
- if (protoFuncs.length > 0) {
1277
- if (scope.locals['#last_type']) return getLastType(scope);
1278
-
1279
- // presume
1280
- // todo: warn here?
1281
- return TYPES.number;
1273
+ if (protoFuncs[0].returnType != null) return protoFuncs[0].returnType;
1282
1274
  }
1283
1275
  }
1284
1276
 
@@ -1978,7 +1970,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
1978
1970
  const func = funcs[idx - importedFuncs.length]; // idx === scope.index ? scope : funcs.find(x => x.index === idx);
1979
1971
  const userFunc = func && !func.internal;
1980
1972
  const typedParams = userFunc || builtinFuncs[name]?.typedParams;
1981
- const typedReturns = (func && func.returnType == null) || builtinFuncs[name]?.typedReturns;
1973
+ const typedReturns = (userFunc && func.returnType == null) || builtinFuncs[name]?.typedReturns;
1982
1974
  const paramCount = func && (typedParams ? func.params.length / 2 : func.params.length);
1983
1975
 
1984
1976
  let args = decl.arguments;
@@ -2571,7 +2563,7 @@ const generateUnary = (scope, decl) => {
2571
2563
  // * -1
2572
2564
 
2573
2565
  if (decl.prefix && decl.argument.type === 'Literal' && typeof decl.argument.value === 'number') {
2574
- // if -<N>, just return that
2566
+ // if -n, just return that as a const
2575
2567
  return number(-1 * decl.argument.value);
2576
2568
  }
2577
2569
 
@@ -2583,14 +2575,14 @@ const generateUnary = (scope, decl) => {
2583
2575
  case '!':
2584
2576
  const arg = decl.argument;
2585
2577
  if (arg.type === 'UnaryExpression' && arg.operator === '!') {
2586
- // !!x -> is x truthy
2578
+ // opt: !!x -> is x truthy
2587
2579
  return truthy(scope, generate(scope, arg.argument), getNodeType(scope, arg.argument), false, false);
2588
2580
  }
2581
+
2589
2582
  // !=
2590
- return falsy(scope, generate(scope, decl.argument), getNodeType(scope, decl.argument), false, false);
2583
+ return falsy(scope, generate(scope, arg), getNodeType(scope, arg), false, false);
2591
2584
 
2592
2585
  case '~':
2593
- // todo: does not handle Infinity properly (should convert to 0) (but opt const converting saves us sometimes)
2594
2586
  return [
2595
2587
  ...generate(scope, decl.argument),
2596
2588
  Opcodes.i32_to,
@@ -1748,7 +1748,7 @@ export const BuiltinFuncs = function() {
1748
1748
  localNames: ["iterable","iterable#type","out","type","forof_base_pointer","forof_length","forof_counter","x","x#type","#last_type","#typeswitch_tmp"],
1749
1749
  };
1750
1750
  this.__Set_prototype_union = {
1751
- wasm: (scope, {builtin,internalThrow,}) => [[32,2],[32,3],[16, builtin('__Porffor_rawType')],[68,0,0,0,0,0,0,52,64],[98],[4,64],...internalThrow(scope, 'TypeError', `Set.union requires 'Set'`),[11],[32,0],[65,20],[16, builtin('Set$constructor')],[33,4],[32,2],[252,3],[33,5],[65,0],[33,7],[32,5],[40,1,0],[33,6],[32,3],[33,11],[2,64],[32,11],[65,2],[70],[4,64,"TYPESWITCH|String"],[65,2],[33,9],[3,64],[65,0],[32,5],[47,0,4],[59,0,3],[68,0,0,0,0,0,0,240,191],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,2],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,16],[70],[4,64,"TYPESWITCH|Array"],[3,64],[32,5],[43,0,4],[32,5],[45,0,12],[33,9],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,9],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,18],[70],[4,64,"TYPESWITCH|ByteString"],[65,18],[33,9],[3,64],[65,0],[32,5],[32,7],[106],[45,0,4],[58,0,3],[68,0,0,0,0,0,0,240,191],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,20],[70],[4,64,"TYPESWITCH|Set"],[3,64],[32,5],[43,0,4],[32,5],[45,0,12],[33,9],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,9],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],...internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`),[11,"TYPESWITCH_end"],[32,4],[65,20],[15]],
1751
+ wasm: (scope, {builtin,internalThrow,}) => [[32,2],[32,3],[16, builtin('__Porffor_rawType')],[68,0,0,0,0,0,0,52,64],[98],[4,64],...internalThrow(scope, 'TypeError', `Set.prototype.union's 'other' argument must be a Set`),[11],[32,0],[65,20],[16, builtin('Set$constructor')],[33,4],[32,2],[252,3],[33,5],[65,0],[33,7],[32,5],[40,1,0],[33,6],[32,3],[33,11],[2,64],[32,11],[65,2],[70],[4,64,"TYPESWITCH|String"],[65,2],[33,9],[3,64],[65,0],[32,5],[47,0,4],[59,0,3],[68,0,0,0,0,0,0,240,191],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,2],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,16],[70],[4,64,"TYPESWITCH|Array"],[3,64],[32,5],[43,0,4],[32,5],[45,0,12],[33,9],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,9],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,18],[70],[4,64,"TYPESWITCH|ByteString"],[65,18],[33,9],[3,64],[65,0],[32,5],[32,7],[106],[45,0,4],[58,0,3],[68,0,0,0,0,0,0,240,191],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],[32,11],[65,20],[70],[4,64,"TYPESWITCH|Set"],[3,64],[32,5],[43,0,4],[32,5],[45,0,12],[33,9],[33,8],[2,64],[32,4],[65,20],[32,8],[32,9],[16, builtin('__Set_prototype_add')],[26],[26],[32,5],[65,9],[106],[33,5],[32,7],[65,1],[106],[34,7],[32,6],[71],[13,1],[11],[11],[12,1],[11],...internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`),[11,"TYPESWITCH_end"],[32,4],[65,20],[15]],
1752
1752
  params: [124,127,124,127],
1753
1753
  typedParams: true,
1754
1754
  returns: [124,127],
package/compiler/opt.js CHANGED
@@ -108,7 +108,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
108
108
  for (const f of funcs) {
109
109
  const wasm = f.wasm;
110
110
 
111
- const lastType = f.locals['#last_type'];
111
+ const lastType = f.locals['#last_type']?.idx;
112
112
 
113
113
  let runs = (+Prefs.optWasmRuns) || 2; // todo: how many by default?
114
114
  while (runs > 0) {
@@ -248,7 +248,7 @@ export default (funcs, globals, pages, tags, exceptions) => {
248
248
  }
249
249
 
250
250
  // remove setting last type if it is never gotten
251
- if (!f.gotLastType && inst[0] === Opcodes.local_set && inst[1] === lastType?.idx) {
251
+ if (!f.gotLastType && inst[0] === Opcodes.local_set && inst[1] === lastType) {
252
252
  // replace this inst with drop
253
253
  wasm.splice(i, 1, [ Opcodes.drop ]); // remove this and last inst
254
254
  if (i > 0) i--;
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-594397507",
4
+ "version": "0.16.0-ab08df866",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {