porffor 0.16.0-e5b6b94c8 โ 0.16.0-f9dde1759
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 +4 -3
- package/compiler/2c.js +53 -65
- package/compiler/assemble.js +5 -4
- package/compiler/builtins/console.ts +1 -1
- package/compiler/builtins/porffor.d.ts +11 -0
- package/compiler/builtins/set.ts +3 -2
- package/compiler/builtins/symbol.ts +6 -6
- package/compiler/builtins.js +25 -5
- package/compiler/codegen.js +20 -42
- package/compiler/cyclone.js +535 -0
- package/compiler/decompile.js +3 -1
- package/compiler/generated_builtins.js +1 -1
- package/compiler/havoc.js +93 -0
- package/compiler/index.js +89 -6
- package/compiler/opt.js +3 -39
- package/compiler/parse.js +2 -2
- package/compiler/pgo.js +207 -0
- package/compiler/precompile.js +3 -1
- package/compiler/prefs.js +6 -1
- package/compiler/wrap.js +53 -12
- package/no_pgo.txt +923 -0
- package/package.json +3 -5
- package/pgo.txt +916 -0
- package/runner/index.js +21 -11
- /package/runner/{profiler.js โ profile.js} +0 -0
package/CONTRIBUTING.md
CHANGED
@@ -26,7 +26,7 @@ You can also swap out `node` in the alias to use another runtime like Deno (`den
|
|
26
26
|
|
27
27
|
### Precompile
|
28
28
|
|
29
|
-
**If you update any file inside `compiler/builtins` you will need to do this for it to update inside Porffor otherwise your changes will have no effect.** Run
|
29
|
+
**If you update any file inside `compiler/builtins` you will need to do this for it to update inside Porffor otherwise your changes will have no effect.** Run `./porf precompile` to precompile. It may error during this, if so, you might have an error in your code or there could be a compiler error with Porffor (feel free to ask for help as soon as you encounter any errors with it).
|
30
30
|
|
31
31
|
<br>
|
32
32
|
|
@@ -206,6 +206,7 @@ Store the character code into the `out` pointer variable, and increment it.
|
|
206
206
|
- You cannot use other functions in the file not exported, or variables not inside the current function.
|
207
207
|
- `if (...)` uses a fast truthy implementation which is not spec-compliant as most conditions should be strictly checked. To use spec-compliant behavior, use `if (Boolean(...))`.
|
208
208
|
- For object (string/array/etc) literals, you must use a variable eg `const out: bytestring = 'foobar'; console.log(out);` instead of `console.log('foobar')` due to precompile's allocator constraints.
|
209
|
+
- Generally prefer/use non-strict equality ops (`==`/`!=`).
|
209
210
|
|
210
211
|
<br>
|
211
212
|
|
@@ -232,7 +233,7 @@ builtins/tostring_number: impl radix
|
|
232
233
|
|
233
234
|
## Test262
|
234
235
|
|
235
|
-
|
236
|
+
For the first time, ensure you run `./test262/setup.sh`.
|
236
237
|
|
237
238
|
Run `node test262` to run all the tests and get an output of total overall test results.
|
238
239
|
|
@@ -246,7 +247,7 @@ The main thing you want to pay attention to is the emoji summary (lol):
|
|
246
247
|
To break this down:
|
247
248
|
๐งช total ๐ค pass โ fail ๐ runtime error ๐ todo (error) โฐ timeout ๐๏ธ wasm compile error ๐ฅ compile error
|
248
249
|
|
249
|
-
The diff compared to the last commit (with test262 data) is shown in brackets. Basically, you
|
250
|
+
The diff compared to the last commit (with test262 data) is shown in brackets. Basically, you want passes ๐ค up, and errors ๐๐๐๐ฅ down. It is fine if some errors change balance/etc, as long as they are not new failures.
|
250
251
|
|
251
252
|
It will also log new passes/fails. Be careful as sometimes the overall passes can increase, but other files have also regressed into failures which you might miss. Also keep in mind some tests may have been false positives before, but we can investigate the diff together :)
|
252
253
|
|
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/assemble.js
CHANGED
@@ -21,7 +21,7 @@ const chHint = (topTier, baselineTier, strategy) => {
|
|
21
21
|
return (strategy | (baselineTier << 2) | (topTier << 4));
|
22
22
|
};
|
23
23
|
|
24
|
-
export default (funcs, globals, tags, pages, data, flags) => {
|
24
|
+
export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) => {
|
25
25
|
const types = [], typeCache = {};
|
26
26
|
|
27
27
|
const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
|
@@ -44,7 +44,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
44
44
|
|
45
45
|
let importFuncs = [];
|
46
46
|
|
47
|
-
if (optLevel < 1 || !Prefs.treeshakeWasmImports) {
|
47
|
+
if (optLevel < 1 || !Prefs.treeshakeWasmImports || noTreeshake) {
|
48
48
|
importFuncs = importedFuncs;
|
49
49
|
} else {
|
50
50
|
let imports = new Map();
|
@@ -94,7 +94,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
94
94
|
|
95
95
|
const importSection = importFuncs.length === 0 ? [] : createSection(
|
96
96
|
Section.import,
|
97
|
-
encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(
|
97
|
+
encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(typeof x.params === 'object' ? x.params : new Array(x.params).fill(valtypeBinary), new Array(x.returns).fill(valtypeBinary)) ]))
|
98
98
|
);
|
99
99
|
|
100
100
|
const funcSection = createSection(
|
@@ -116,7 +116,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
116
116
|
] ])
|
117
117
|
);
|
118
118
|
|
119
|
-
if (pages.has('func argc lut')) {
|
119
|
+
if (pages.has('func argc lut') && !data.addedFuncArgcLut) {
|
120
120
|
// generate func argc lut data
|
121
121
|
const bytes = [];
|
122
122
|
for (let i = 0; i < funcs.length; i++) {
|
@@ -128,6 +128,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
128
128
|
offset: pages.get('func argc lut').ind * pageSize,
|
129
129
|
bytes
|
130
130
|
});
|
131
|
+
data.addedFuncArgcLut = true;
|
131
132
|
}
|
132
133
|
|
133
134
|
// const t0 = performance.now();
|
@@ -22,6 +22,14 @@ type PorfforGlobal = {
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
|
25
|
+
allocate(): any;
|
26
|
+
set: {
|
27
|
+
read(_this: any, index: number): i32;
|
28
|
+
write(_this: any, index: number, value: any): boolean;
|
29
|
+
}
|
30
|
+
|
31
|
+
print(x: any): i32;
|
32
|
+
|
25
33
|
randomByte(): i32;
|
26
34
|
|
27
35
|
type(x: any): bytestring;
|
@@ -48,6 +56,9 @@ type PorfforGlobal = {
|
|
48
56
|
|
49
57
|
s(...args: any): string;
|
50
58
|
bs(...args: any): bytestring;
|
59
|
+
|
60
|
+
readArgv(index: i32, out: bytestring): i32;
|
61
|
+
readFile(path: bytestring, out: bytestring): i32;
|
51
62
|
};
|
52
63
|
|
53
64
|
declare global {
|
package/compiler/builtins/set.ts
CHANGED
@@ -189,9 +189,10 @@ export const Set$constructor = (iterable: any): Set => {
|
|
189
189
|
|
190
190
|
export const __Set_prototype_union = (_this: Set, other: any) => {
|
191
191
|
if (Porffor.rawType(other) != Porffor.TYPES.set) {
|
192
|
-
throw new TypeError("Set.union
|
192
|
+
throw new TypeError("Set.prototype.union\'s \'other\' argument must be a Set");
|
193
193
|
}
|
194
|
-
|
194
|
+
|
195
|
+
const out: Set = Set$constructor(_this);
|
195
196
|
for (const x of other) {
|
196
197
|
out.add(x);
|
197
198
|
}
|
@@ -8,10 +8,10 @@ export const __Porffor_symbol_descStore = (op: boolean, value: any): any => {
|
|
8
8
|
Porffor.wasm.i32.store(ptr, size + 1, 0, 0)
|
9
9
|
|
10
10
|
// reuse set internals to store description
|
11
|
-
|
11
|
+
Porffor.set.write(ptr, size, value);
|
12
12
|
return size;
|
13
13
|
} else { // read
|
14
|
-
return
|
14
|
+
return Porffor.set.read(ptr, value);
|
15
15
|
}
|
16
16
|
};
|
17
17
|
|
@@ -21,8 +21,8 @@ export const Symbol = (description: any): Symbol => {
|
|
21
21
|
};
|
22
22
|
|
23
23
|
export const __Symbol_prototype_description$get = (_this: Symbol) => {
|
24
|
-
const description: bytestring =
|
25
|
-
Porffor.wasm`local.get ${_this}` - 1);
|
24
|
+
const description: bytestring =
|
25
|
+
__Porffor_symbol_descStore(false, Porffor.wasm`local.get ${_this}` - 1);
|
26
26
|
return description;
|
27
27
|
};
|
28
28
|
|
@@ -38,8 +38,8 @@ export const __Symbol_prototype_toString = (_this: Symbol) => {
|
|
38
38
|
Porffor.wasm.i32.store8(out, 108, 0, 9);
|
39
39
|
Porffor.wasm.i32.store8(out, 40, 0, 10);
|
40
40
|
|
41
|
-
const description: bytestring =
|
42
|
-
Porffor.wasm`local.get ${_this}` - 1);
|
41
|
+
const description: bytestring =
|
42
|
+
__Porffor_symbol_descStore(false, Porffor.wasm`local.get ${_this}` - 1);
|
43
43
|
|
44
44
|
const descLen: i32 = description.length;
|
45
45
|
let outPtr: i32 = Porffor.wasm`local.get ${out}` + 7;
|
package/compiler/builtins.js
CHANGED
@@ -32,26 +32,26 @@ export const importedFuncs = [
|
|
32
32
|
{
|
33
33
|
name: 'profile1',
|
34
34
|
import: 'y',
|
35
|
-
params:
|
35
|
+
params: [ Valtype.i32 ],
|
36
36
|
returns: 0
|
37
37
|
},
|
38
38
|
{
|
39
39
|
name: 'profile2',
|
40
40
|
import: 'z',
|
41
|
-
params:
|
41
|
+
params: [ Valtype.i32 ],
|
42
42
|
returns: 0
|
43
43
|
},
|
44
44
|
{
|
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
|