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 +53 -65
- package/compiler/builtins/porffor.d.ts +3 -0
- package/compiler/builtins.js +23 -3
- package/compiler/codegen.js +8 -16
- package/compiler/generated_builtins.js +1 -1
- package/compiler/opt.js +2 -2
- package/package.json +1 -1
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
|
-
|
33
|
-
|
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: [
|
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: [
|
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: [
|
56
|
+
argTypes: ['i32', 'i8'],
|
57
57
|
returns: false
|
58
58
|
},
|
59
59
|
|
60
60
|
[Opcodes.i32_load]: {
|
61
|
-
c:
|
61
|
+
c: `i32 out;
|
62
62
|
memcpy(&out, _memory + offset + pointer, sizeof(out));
|
63
63
|
return out;`,
|
64
64
|
args: ['pointer'],
|
65
|
-
argTypes: [
|
66
|
-
returns:
|
65
|
+
argTypes: ['i32'],
|
66
|
+
returns: 'i32'
|
67
67
|
},
|
68
68
|
[Opcodes.i32_load16_u]: {
|
69
|
-
c:
|
69
|
+
c: `i16 out;
|
70
70
|
memcpy(&out, _memory + offset + pointer, sizeof(out));
|
71
71
|
return out;`,
|
72
72
|
args: ['pointer'],
|
73
|
-
argTypes: [
|
74
|
-
returns:
|
73
|
+
argTypes: ['i32'],
|
74
|
+
returns: 'i32'
|
75
75
|
},
|
76
76
|
[Opcodes.i32_load8_u]: {
|
77
|
-
c:
|
77
|
+
c: `i8 out;
|
78
78
|
memcpy(&out, _memory + offset + pointer, sizeof(out));
|
79
79
|
return out;`,
|
80
80
|
args: ['pointer'],
|
81
|
-
argTypes: [
|
82
|
-
returns:
|
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: [
|
88
|
+
argTypes: ['i32', 'f64'],
|
89
89
|
returns: false
|
90
90
|
},
|
91
91
|
[Opcodes.f64_load]: {
|
92
|
-
c:
|
92
|
+
c: `f64 out;
|
93
93
|
memcpy(&out, _memory + offset + pointer, sizeof(out));
|
94
94
|
return out;`,
|
95
95
|
args: ['pointer'],
|
96
|
-
argTypes: [
|
97
|
-
returns:
|
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(
|
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
|
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 ?
|
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(`(
|
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(`(
|
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(`(
|
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(`(
|
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(`(
|
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(`(
|
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(`
|
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
|
-
`
|
463
|
+
`i32 __Porffor_readArgv(u32 index, u32 outPtr) {
|
478
464
|
if (index >= _argc) {
|
479
|
-
|
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
|
-
|
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
|
-
`
|
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
|
-
|
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
|
-
|
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
|
-
|
543
|
-
|
544
|
-
vals.push(`_.
|
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(`(
|
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}(
|
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();
|
package/compiler/builtins.js
CHANGED
@@ -45,13 +45,13 @@ export const importedFuncs = [
|
|
45
45
|
name: '__Porffor_readArgv',
|
46
46
|
import: 'w',
|
47
47
|
params: 2,
|
48
|
-
returns:
|
48
|
+
returns: 1
|
49
49
|
},
|
50
50
|
{
|
51
51
|
name: '__Porffor_readFile',
|
52
52
|
import: 'q',
|
53
53
|
params: 2,
|
54
|
-
returns:
|
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
|
package/compiler/codegen.js
CHANGED
@@ -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
|
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 = (
|
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
|
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,
|
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
|
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
|
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