porffor 0.14.0-cdebd5442 โ 0.14.0-d6c141d91
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 +9 -3
- package/asur/index.js +1 -1
- package/bf_bun +0 -0
- package/bf_deno +0 -0
- package/bf_porf +0 -0
- package/bf_porf_fast +0 -0
- package/bf_porf_lto +0 -0
- package/compiler/2c.js +65 -2
- package/compiler/assemble.js +14 -0
- package/compiler/builtins/annexb_string.ts +1 -0
- package/compiler/builtins/array.ts +84 -4
- package/compiler/builtins/base64.ts +1 -0
- package/compiler/builtins/boolean.ts +2 -0
- package/compiler/builtins/crypto.ts +1 -0
- package/compiler/builtins/date.ts +2 -0
- package/compiler/builtins/error.js +22 -0
- package/compiler/builtins/escape.ts +1 -2
- package/compiler/builtins/function.ts +2 -0
- package/compiler/builtins/int.ts +2 -0
- package/compiler/builtins/math.ts +410 -0
- package/compiler/builtins/number.ts +2 -0
- package/compiler/builtins/object.ts +2 -0
- package/compiler/builtins/set.ts +7 -6
- package/compiler/builtins/string.ts +1 -0
- package/compiler/builtins/symbol.ts +3 -1
- package/compiler/builtins.js +33 -6
- package/compiler/codegen.js +502 -256
- package/compiler/generated_builtins.js +491 -60
- package/compiler/index.js +1 -1
- package/compiler/parse.js +1 -1
- package/compiler/precompile.js +5 -4
- package/compiler/prefs.js +1 -1
- package/compiler/prototype.js +180 -157
- package/compiler/wrap.js +66 -37
- package/package.json +1 -1
- package/runner/index.js +5 -4
- package/runner/repl.js +18 -2
- package/w.js +1 -0
package/CONTRIBUTING.md
CHANGED
@@ -198,11 +198,13 @@ Store the character code into the `out` pointer variable, and increment it.
|
|
198
198
|
|
199
199
|
## Porffor-specific TS notes
|
200
200
|
|
201
|
-
- For declaring variables, you must use explicit type annotations currently (eg `let a: number = 1`, not `let a = 1`)
|
201
|
+
- For declaring variables, you must use explicit type annotations currently (eg `let a: number = 1`, not `let a = 1`).
|
202
202
|
- You might spot `Porffor.fastOr`/`Porffor.fastAnd`, these are non-short circuiting versions of `||`/`&&`, taking any number of conditions as arguments. You shouldn't don't need to use or worry about these.
|
203
|
-
- **There are ~no objects, you cannot use them
|
203
|
+
- **There are ~no objects, you cannot use them.**
|
204
204
|
- Attempt to avoid string/array-heavy code and use more variables instead if possible, easier on memory and CPU/perf.
|
205
205
|
- Do not set a return type for prototype methods, it can cause errors/unexpected results.
|
206
|
+
- You cannot use other functions in the file not exported, or variables not inside the current function.
|
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(...))`.
|
206
208
|
|
207
209
|
<br>
|
208
210
|
|
@@ -231,7 +233,11 @@ builtins/tostring_number: impl radix
|
|
231
233
|
|
232
234
|
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.
|
233
235
|
|
234
|
-
Run `node test262` to run all the tests and get an output of total overall test results.
|
236
|
+
Run `node test262` to run all the tests and get an output of total overall test results.
|
237
|
+
|
238
|
+
Warning: this will consume 1-6GB of memory and ~90% of all CPU cores while running (depending on thread count), it should take 15-120s depending on machine. You can specify how many threads with `--threads=N`, it will use the number of CPU threads by default.
|
239
|
+
|
240
|
+
The main thing you want to pay attention to is the emoji summary (lol):
|
235
241
|
```
|
236
242
|
๐งช 50005 | ๐ค 7007 (-89) | โ 1914 (-32) | ๐ 13904 (-61) | ๐ 23477 (-120) | โฐ 2 | ๐ 2073 (+302) | ๐ฅ 1628
|
237
243
|
```
|
package/asur/index.js
CHANGED
@@ -1155,7 +1155,7 @@ if (bc.porfFunc && paused && op) {
|
|
1155
1155
|
switch (byg(
|
1156
1156
|
paused,
|
1157
1157
|
funcLines[currentFunc] + currentLine,
|
1158
|
-
'\x1b[1masur\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
|
1158
|
+
'\x1b[1masur debugger\x1b[22m: ' + callStack.join(' -> ') + (parents.length > 1 ? \` | \${parents.slice(1).map(x => invOpcodes[x.opcode]).join(' -> ')}\` : ''),
|
1159
1159
|
[
|
1160
1160
|
{
|
1161
1161
|
x: termWidth - 1 - width - 6,
|
package/bf_bun
ADDED
Binary file
|
package/bf_deno
ADDED
Binary file
|
package/bf_porf
ADDED
Binary file
|
package/bf_porf_fast
ADDED
Binary file
|
package/bf_porf_lto
ADDED
Binary file
|
package/compiler/2c.js
CHANGED
@@ -119,6 +119,9 @@ const removeBrackets = str => {
|
|
119
119
|
};
|
120
120
|
|
121
121
|
export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
122
|
+
// fix declaring order for c
|
123
|
+
funcs.reverse();
|
124
|
+
|
122
125
|
const invOperatorOpcode = Object.values(operatorOpcode).reduce((acc, x) => {
|
123
126
|
for (const k in x) {
|
124
127
|
acc[x[k]] = k;
|
@@ -156,6 +159,11 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
156
159
|
prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n'));
|
157
160
|
}
|
158
161
|
|
162
|
+
if (importFuncs.find(x => x.name === '__Porffor_readArgv')) {
|
163
|
+
prepend.set('argv', `int _argc; char** _argv;`);
|
164
|
+
prependMain.set('argv', `_argc = argc; _argv = argv;`);
|
165
|
+
}
|
166
|
+
|
159
167
|
if (out) out += '\n';
|
160
168
|
|
161
169
|
let depth = 1;
|
@@ -207,8 +215,9 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
207
215
|
|
208
216
|
const returns = f.returns.length > 0;
|
209
217
|
|
210
|
-
const shouldInline = f.internal;
|
211
|
-
|
218
|
+
const shouldInline = false; // f.internal;
|
219
|
+
if (f.name === 'main') out += `int main(${prependMain.has('argv') ? 'int argc, char* argv[]' : ''}) {\n`;
|
220
|
+
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`;
|
212
221
|
|
213
222
|
if (f.name === 'main') {
|
214
223
|
out += [...prependMain.values()].join('\n');
|
@@ -459,6 +468,60 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
459
468
|
winIncludes.set('windows.h', true);
|
460
469
|
break;
|
461
470
|
|
471
|
+
case '__Porffor_readArgv':
|
472
|
+
includes.set('stdlib.h', true);
|
473
|
+
|
474
|
+
prepend.set('__Porffor_readArgv',
|
475
|
+
`void __Porffor_readArgv(u32 index, u32 outPtr) {
|
476
|
+
if (index >= _argc) {
|
477
|
+
printf("expected %d arguments\\n", index);
|
478
|
+
exit(1);
|
479
|
+
}
|
480
|
+
|
481
|
+
char* arg = _argv[index];
|
482
|
+
|
483
|
+
u32 read = 0;
|
484
|
+
char* out = _memory + outPtr + 4;
|
485
|
+
char ch;
|
486
|
+
while ((ch = *(arg++)) != 0) {
|
487
|
+
out[read++] = ch;
|
488
|
+
}
|
489
|
+
|
490
|
+
memcpy(_memory + outPtr, &read, sizeof(read));
|
491
|
+
}`);
|
492
|
+
|
493
|
+
line(`__Porffor_readArgv((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
|
494
|
+
vals.pop();
|
495
|
+
break;
|
496
|
+
|
497
|
+
case '__Porffor_readFile':
|
498
|
+
includes.set('stdio.h', true);
|
499
|
+
includes.set('stdlib.h', true);
|
500
|
+
|
501
|
+
prepend.set('__Porffor_readFile',
|
502
|
+
`void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
|
503
|
+
char* path = _memory + pathPtr + 4;
|
504
|
+
FILE* fp = fopen(path, "r");
|
505
|
+
if (fp == NULL) {
|
506
|
+
printf("failed to open file: %s\\n", path);
|
507
|
+
exit(1);
|
508
|
+
}
|
509
|
+
|
510
|
+
u32 read = 0;
|
511
|
+
char* out = _memory + outPtr + 4;
|
512
|
+
char ch;
|
513
|
+
while ((ch = fgetc(fp)) != EOF) {
|
514
|
+
out[read++] = ch;
|
515
|
+
}
|
516
|
+
|
517
|
+
fclose(fp);
|
518
|
+
|
519
|
+
memcpy(_memory + outPtr, &read, sizeof(read));
|
520
|
+
}`);
|
521
|
+
line(`__Porffor_readFile((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
|
522
|
+
vals.pop();
|
523
|
+
break;
|
524
|
+
|
462
525
|
default:
|
463
526
|
log.warning('2c', `unimplemented import: ${importFunc.name}`);
|
464
527
|
break;
|
package/compiler/assemble.js
CHANGED
@@ -116,6 +116,20 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
116
116
|
] ])
|
117
117
|
);
|
118
118
|
|
119
|
+
if (pages.has('func argc lut')) {
|
120
|
+
// generate func argc lut data
|
121
|
+
const bytes = [];
|
122
|
+
for (let i = 0; i < funcs.length; i++) {
|
123
|
+
const argc = Math.floor(funcs[i].params.length / 2);
|
124
|
+
bytes.push(argc % 256, (argc / 256 | 0) % 256);
|
125
|
+
}
|
126
|
+
|
127
|
+
data.push({
|
128
|
+
offset: pages.get('func argc lut').ind * pageSize,
|
129
|
+
bytes
|
130
|
+
});
|
131
|
+
}
|
132
|
+
|
119
133
|
// const t0 = performance.now();
|
120
134
|
|
121
135
|
// specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import type {} from './porffor.d.ts';
|
2
|
+
|
1
3
|
export const __Array_isArray = (x: unknown): boolean =>
|
2
4
|
// Porffor.wasm`local.get ${x+1}` == Porffor.TYPES.array;
|
3
5
|
Porffor.rawType(x) == Porffor.TYPES.array;
|
@@ -27,14 +29,16 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
|
|
27
29
|
let outPtr: i32 = Porffor.wasm`local.get ${out}`;
|
28
30
|
let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
|
29
31
|
|
30
|
-
const thisPtrEnd: i32 = thisPtr + end *
|
32
|
+
const thisPtrEnd: i32 = thisPtr + end * 9;
|
31
33
|
|
32
|
-
thisPtr += start *
|
34
|
+
thisPtr += start * 9;
|
33
35
|
|
34
36
|
while (thisPtr < thisPtrEnd) {
|
35
37
|
Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
|
36
|
-
thisPtr
|
37
|
-
|
38
|
+
Porffor.wasm.i32.store8(outPtr + 8, Porffor.wasm.i32.load8_u(thisPtr + 8, 0, 4), 0, 4);
|
39
|
+
|
40
|
+
thisPtr += 9;
|
41
|
+
outPtr += 9;
|
38
42
|
}
|
39
43
|
|
40
44
|
out.length = end - start;
|
@@ -142,4 +146,80 @@ export const __Array_prototype_toReversed = (_this: any[]) => {
|
|
142
146
|
|
143
147
|
export const __Array_prototype_valueOf = (_this: any[]) => {
|
144
148
|
return _this;
|
149
|
+
};
|
150
|
+
|
151
|
+
|
152
|
+
export const __Array_prototype_forEach = (_this: any[], callbackFn: any) => {
|
153
|
+
const len: i32 = _this.length;
|
154
|
+
let i: i32 = 0;
|
155
|
+
while (i < len) {
|
156
|
+
callbackFn(_this[i], i++, _this);
|
157
|
+
}
|
158
|
+
};
|
159
|
+
|
160
|
+
export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
|
161
|
+
const out: any[] = [];
|
162
|
+
|
163
|
+
const len: i32 = _this.length;
|
164
|
+
let i: i32 = 0;
|
165
|
+
while (i < len) {
|
166
|
+
const el: any = _this[i];
|
167
|
+
if (Boolean(callbackFn(el, i++, _this))) out.push(el);
|
168
|
+
}
|
169
|
+
|
170
|
+
return out;
|
171
|
+
};
|
172
|
+
|
173
|
+
export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
|
174
|
+
const out: any[] = [];
|
175
|
+
|
176
|
+
const len: i32 = _this.length;
|
177
|
+
let i: i32 = 0;
|
178
|
+
while (i < len) {
|
179
|
+
out.push(callbackFn(_this[i], i++, _this));
|
180
|
+
}
|
181
|
+
|
182
|
+
return out;
|
183
|
+
};
|
184
|
+
|
185
|
+
export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
|
186
|
+
const len: i32 = _this.length;
|
187
|
+
let i: i32 = 0;
|
188
|
+
while (i < len) {
|
189
|
+
const el: any = _this[i];
|
190
|
+
if (Boolean(callbackFn(el, i++, _this))) return el;
|
191
|
+
}
|
192
|
+
};
|
193
|
+
|
194
|
+
export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
|
195
|
+
let i: i32 = _this.length;
|
196
|
+
while (i > 0) {
|
197
|
+
const el: any = _this[--i];
|
198
|
+
if (Boolean(callbackFn(el, i, _this))) return el;
|
199
|
+
}
|
200
|
+
};
|
201
|
+
|
202
|
+
export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
|
203
|
+
const len: i32 = _this.length;
|
204
|
+
let i: i32 = 0;
|
205
|
+
while (i < len) {
|
206
|
+
if (Boolean(callbackFn(_this[i], i++, _this))) return i;
|
207
|
+
}
|
208
|
+
};
|
209
|
+
|
210
|
+
export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
|
211
|
+
let i: i32 = _this.length;
|
212
|
+
while (i > 0) {
|
213
|
+
if (Boolean(callbackFn(_this[--i], i, _this))) return i;
|
214
|
+
}
|
215
|
+
};
|
216
|
+
|
217
|
+
export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
|
218
|
+
const len: i32 = _this.length;
|
219
|
+
let i: i32 = 0;
|
220
|
+
while (i < len) {
|
221
|
+
if (!Boolean(callbackFn(_this[i], i++, _this))) return false;
|
222
|
+
}
|
223
|
+
|
224
|
+
return true;
|
145
225
|
};
|
@@ -0,0 +1,22 @@
|
|
1
|
+
export default () => {
|
2
|
+
let out = '';
|
3
|
+
|
4
|
+
const error = name => out += `export const ${name} = (message: bytestring) => {
|
5
|
+
return {};
|
6
|
+
};
|
7
|
+
|
8
|
+
export const ${name}$constructor = (message: bytestring) => {
|
9
|
+
return {};
|
10
|
+
};`;
|
11
|
+
|
12
|
+
error('Error');
|
13
|
+
error('AggregateError');
|
14
|
+
error('TypeError');
|
15
|
+
error('ReferenceError');
|
16
|
+
error('SyntaxError');
|
17
|
+
error('RangeError');
|
18
|
+
error('EvalError');
|
19
|
+
error('URIError');
|
20
|
+
|
21
|
+
return out;
|
22
|
+
};
|
package/compiler/builtins/int.ts
CHANGED