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 +1 -1
- package/compiler/2c.js +65 -53
- package/compiler/builtins/porffor.d.ts +0 -3
- package/compiler/builtins.js +2 -2
- package/compiler/parse.js +1 -1
- package/package.json +1 -1
package/CONTRIBUTING.md
CHANGED
@@ -233,7 +233,7 @@ builtins/tostring_number: impl radix
|
|
233
233
|
|
234
234
|
## Test262
|
235
235
|
|
236
|
-
|
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: [
|
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: [
|
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: [
|
56
|
+
argTypes: [CValtype.i32, CValtype.i8],
|
57
57
|
returns: false
|
58
58
|
},
|
59
59
|
|
60
60
|
[Opcodes.i32_load]: {
|
61
|
-
c:
|
61
|
+
c: `${CValtype.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: [CValtype.i32],
|
66
|
+
returns: CValtype.i32
|
67
67
|
},
|
68
68
|
[Opcodes.i32_load16_u]: {
|
69
|
-
c:
|
69
|
+
c: `${CValtype.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: [CValtype.i32],
|
74
|
+
returns: CValtype.i32
|
75
75
|
},
|
76
76
|
[Opcodes.i32_load8_u]: {
|
77
|
-
c:
|
77
|
+
c: `${CValtype.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: [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: [
|
88
|
+
argTypes: [CValtype.i32, CValtype.f64],
|
89
89
|
returns: false
|
90
90
|
},
|
91
91
|
[Opcodes.f64_load]: {
|
92
|
-
c:
|
92
|
+
c: `${CValtype.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: [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(
|
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(
|
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(
|
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 ?
|
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 +=
|
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(
|
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 =
|
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(`
|
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
|
-
`
|
477
|
+
`void __Porffor_readArgv(u32 index, u32 outPtr) {
|
464
478
|
if (index >= _argc) {
|
465
|
-
|
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
|
-
|
482
|
-
|
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
|
-
`
|
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
|
-
|
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
|
-
|
511
|
-
|
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
|
532
|
-
|
533
|
-
vals.push(`_
|
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 =
|
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();
|
package/compiler/builtins.js
CHANGED
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 ||
|
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