porffor 0.2.0-fdf0fc5 → 0.14.0-0d97d1e6a
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/README.md +9 -2
- package/byg/index.js +3 -24
- package/compiler/2c.js +2 -53
- package/compiler/assemble.js +37 -11
- package/compiler/builtins/annexb_string.js +10 -10
- package/compiler/builtins/annexb_string.ts +3 -3
- package/compiler/builtins/array.ts +2 -6
- package/compiler/builtins/base64.ts +1 -1
- package/compiler/builtins/boolean.ts +1 -3
- package/compiler/builtins/crypto.ts +1 -1
- package/compiler/builtins/date.ts +1 -4
- package/compiler/builtins/escape.ts +1 -1
- package/compiler/builtins/function.ts +0 -2
- package/compiler/builtins/int.ts +0 -2
- package/compiler/builtins/number.ts +3 -8
- package/compiler/builtins/object.ts +0 -2
- package/compiler/builtins/porffor.d.ts +9 -8
- package/compiler/builtins/set.ts +184 -2
- package/compiler/builtins/string.ts +1 -1
- package/compiler/builtins/symbol.ts +61 -0
- package/compiler/builtins.js +8 -9
- package/compiler/codegen.js +121 -124
- package/compiler/decompile.js +3 -3
- package/compiler/embedding.js +2 -2
- package/compiler/encoding.js +0 -14
- package/compiler/expression.js +1 -1
- package/compiler/generated_builtins.js +348 -204
- package/compiler/index.js +3 -10
- package/compiler/opt.js +7 -7
- package/compiler/parse.js +1 -3
- package/compiler/precompile.js +17 -25
- package/compiler/prefs.js +6 -2
- package/compiler/prototype.js +5 -5
- package/compiler/wasmSpec.js +5 -0
- package/compiler/wrap.js +88 -57
- package/package.json +1 -1
- package/runner/compare.js +0 -1
- package/runner/debug.js +1 -6
- package/runner/profiler.js +15 -42
- package/runner/repl.js +3 -9
- package/runner/sizes.js +2 -2
- package/runner/version.js +10 -8
package/README.md
CHANGED
@@ -13,7 +13,7 @@ Porffor is primarily built from scratch, the only thing that is not is the parse
|
|
13
13
|
## Usage
|
14
14
|
Expect nothing to work! Only very limited JS is currently supported. See files in `bench` for examples.
|
15
15
|
|
16
|
-
###
|
16
|
+
### Install
|
17
17
|
**`npm install -g porffor`**. It's that easy (hopefully) :)
|
18
18
|
|
19
19
|
### Trying a REPL
|
@@ -189,6 +189,13 @@ These include some early (stage 1/0) and/or dead (last commit years ago) proposa
|
|
189
189
|
- Intrinsic functions (see below)
|
190
190
|
- Inlining wasm via ``asm`...``\` "macro"
|
191
191
|
|
192
|
+
## Versioning
|
193
|
+
Porffor uses a unique versioning system, here's an example: `0.14.0-15cb49f07`. Let's break it down:
|
194
|
+
1. `0` - major, always `0` as Porffor is not ready yet
|
195
|
+
2. `14` - minor, total Test262 pass percentage (floored to nearest int)
|
196
|
+
3. `0` - micro, always `0` as unused
|
197
|
+
4. `15cb49f07` - commit hash
|
198
|
+
|
192
199
|
## Performance
|
193
200
|
*For the features it supports most of the time*, Porffor is *blazingly fast* compared to most interpreters and common engines running without JIT. For those with JIT, it is usually slower by default, but can catch up with compiler arguments and typed input, even more so when compiling to native binaries.
|
194
201
|
|
@@ -220,7 +227,7 @@ Mostly for reducing size. I do not really care about compiler perf/time as long
|
|
220
227
|
- No tags if unused/optimized out
|
221
228
|
|
222
229
|
## Test262
|
223
|
-
Porffor can run Test262 via some hacks/transforms which remove unsupported features whilst still doing the same asserts (eg simpler error messages using literals only). It currently passes >
|
230
|
+
Porffor can run Test262 via some hacks/transforms which remove unsupported features whilst still doing the same asserts (eg simpler error messages using literals only). It currently passes >14% (see latest commit desc for latest and details). Use `node test262` to test, it will also show a difference of overall results between the last commit and current results.
|
224
231
|
|
225
232
|
## Codebase
|
226
233
|
- `compiler`: contains the compiler itself
|
package/byg/index.js
CHANGED
@@ -2,7 +2,6 @@ import fs from 'node:fs';
|
|
2
2
|
|
3
3
|
const noAnsi = s => s.replace(/\u001b\[[0-9]+m/g, '');
|
4
4
|
const printLine = (line, number, breakpoint = false, current = false, selected = false) => {
|
5
|
-
// console.log(`\x1b[${breakpoint ? (selected ? '106' : '46') : (selected ? '47' : '100')}m\x1b[${selected ? '30' : '97'}m${number.toFixed(0).padStart(4, ' ')}\x1b[${breakpoint ? (selected ? '96' : '36') : (selected ? '37' : '90')}m\x1b[${current ? '47' : '40'}m▌ \x1b[${current ? '47' : '40'}m\x1b[${current ? '30' : '37'}m${current ? noAnsi(line) : line}\x1b[0K`);
|
6
5
|
console.log(`\x1b[${breakpoint ? (selected ? '43' : '103') : (selected ? '47' : '100')}m\x1b[${selected || breakpoint ? '30' : '97'}m${number.toFixed(0).padStart(4, ' ')}\x1b[${breakpoint ? (selected ? '33' : '93') : (selected ? '37' : '90')}m\x1b[${current ? '47' : '40'}m▌ \x1b[${current ? '47' : '40'}m\x1b[${current ? '30' : '37'}m${current ? noAnsi(line) : line}\x1b[0K`);
|
7
6
|
};
|
8
7
|
|
@@ -13,13 +12,10 @@ const box = (x, y, width, height, title = '', content = [], color = ['90', '100'
|
|
13
12
|
|
14
13
|
// top
|
15
14
|
process.stdout.write(`\x1b[48m\x1b[${y + 1};${x + 1}H\x1b[${color[0]}m` + '▄'.repeat(width));
|
16
|
-
|
17
15
|
// bottom
|
18
16
|
process.stdout.write(`\x1b[${y + height + 1};${x + 1}H▝` + '▀'.repeat(width - 1) + '▘');
|
19
|
-
|
20
17
|
// left
|
21
18
|
process.stdout.write(`\x1b[${y + 1};${x + 1}H▗` + '\x1b[1B\x1b[1D▐'.repeat(height - 1));
|
22
|
-
|
23
19
|
// right
|
24
20
|
process.stdout.write(`\x1b[${y + 1};${x + width + 1}H▖` + '\x1b[1B\x1b[1D▌'.repeat(height - 1));
|
25
21
|
|
@@ -33,8 +29,6 @@ const box = (x, y, width, height, title = '', content = [], color = ['90', '100'
|
|
33
29
|
process.stdout.write(`\x1b[${y + 1};${x + 1}H\x1b[${color[1]}m` + ' '.repeat(width) + (`\x1b[1B\x1b[${width}D` + ' '.repeat(width)).repeat(Math.max(0, height - 1)));
|
34
30
|
|
35
31
|
// title
|
36
|
-
// if (title) process.stdout.write(`\x1b[${y + 1};${x + ((width - title.length) / 2 | 0) + 1}H\x1b[${color[1]}m\x1b[${color[2]}m\x1b[1m${title}\x1b[22m`);
|
37
|
-
// if (title) process.stdout.write(`\x1b[${y};${x}H\x1b[${color[3]}▗\x1b[${color[4]}m\x1b[${color[2]}m\x1b[1m${' '.repeat((width - title.length) / 2 | 0)}${title}${' '.repeat(width - (((width - title.length) / 2 | 0)) - title.length)}\x1b[0m\x1b[${color[4]}m▖`);
|
38
32
|
if (title) process.stdout.write(`\x1b[${y};${x}H\x1b[0m\x1b[${color[3]}m▐\x1b[${color[4]}m\x1b[${color[2]}m\x1b[1m${' '.repeat((width - title.length) / 2 | 0)}${title}${' '.repeat(width - (((width - title.length) / 2 | 0)) - title.length)}\x1b[0m\x1b[${color[3]}m▌`);
|
39
33
|
|
40
34
|
// content
|
@@ -66,8 +60,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
66
60
|
process.exit();
|
67
61
|
}
|
68
62
|
|
69
|
-
// process.stdout.write(s);
|
70
|
-
|
71
63
|
if (!paused) pause();
|
72
64
|
});
|
73
65
|
|
@@ -83,7 +75,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
83
75
|
|
84
76
|
process.on('exit', () => {
|
85
77
|
process.stdout.write('\x1b[0m');
|
86
|
-
// console.clear();
|
87
78
|
});
|
88
79
|
|
89
80
|
console.clear();
|
@@ -130,18 +121,9 @@ export default ({ lines, pause, breakpoint }) => {
|
|
130
121
|
|
131
122
|
for (const x of boxes) {
|
132
123
|
const y = x.y({ currentLinePos });
|
133
|
-
const height = x.height;
|
134
124
|
if (y < 0 || y >= termHeight) continue;
|
135
125
|
|
136
|
-
|
137
|
-
// if (y + height >= termHeight) {
|
138
|
-
// const excess = y + height - termHeight;
|
139
|
-
// height -= excess;
|
140
|
-
|
141
|
-
// content = content.slice(0, height - 2);
|
142
|
-
// }
|
143
|
-
|
144
|
-
box(x.x, y, x.width, height, x.title, x.content);
|
126
|
+
box(x.x, y, x.width, x.height, x.title, x.content);
|
145
127
|
}
|
146
128
|
|
147
129
|
// text += ` | rss: ${(process.memoryUsage.rss() / 1024 / 1024).toFixed(2)}mb`;
|
@@ -179,7 +161,8 @@ export default ({ lines, pause, breakpoint }) => {
|
|
179
161
|
}
|
180
162
|
|
181
163
|
case 'b': {
|
182
|
-
if (!lastSpecial) {
|
164
|
+
if (!lastSpecial) {
|
165
|
+
// b pressed normally
|
183
166
|
breakpoints[currentLine + scrollOffset] = !breakpoints[currentLine + scrollOffset];
|
184
167
|
draw();
|
185
168
|
|
@@ -188,7 +171,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
188
171
|
}
|
189
172
|
|
190
173
|
// arrow down
|
191
|
-
// if (screenOffset + termHeight <= lines.length) scrollOffset++;
|
192
174
|
if (scrollOffset < lines.length - currentLine - 1) scrollOffset++;
|
193
175
|
draw();
|
194
176
|
break;
|
@@ -198,7 +180,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
198
180
|
if (!lastSpecial) break;
|
199
181
|
|
200
182
|
// arrow up
|
201
|
-
// if (screenOffset > 0) scrollOffset--;
|
202
183
|
if (scrollOffset > -currentLine) scrollOffset--;
|
203
184
|
draw();
|
204
185
|
|
@@ -209,7 +190,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
209
190
|
if (!lastSpecial) break;
|
210
191
|
|
211
192
|
// page up
|
212
|
-
// scrollOffset -= Math.min(screenOffset, termHeight - 1);
|
213
193
|
scrollOffset -= Math.min(scrollOffset + currentLine, termHeight - 1);
|
214
194
|
draw();
|
215
195
|
break;
|
@@ -219,7 +199,6 @@ export default ({ lines, pause, breakpoint }) => {
|
|
219
199
|
if (!lastSpecial) break;
|
220
200
|
|
221
201
|
// page down
|
222
|
-
// scrollOffset += Math.min((lines.length + 1) - (screenOffset + termHeight), termHeight - 1);
|
223
202
|
scrollOffset += Math.min(lines.length - (scrollOffset + currentLine) - 1, termHeight - 1);
|
224
203
|
draw();
|
225
204
|
break;
|
package/compiler/2c.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { read_ieee754_binary64, read_signedLEB128, read_unsignedLEB128 } from './encoding.js';
|
2
2
|
import { Blocktype, Opcodes, Valtype } from './wasmSpec.js';
|
3
3
|
import { operatorOpcode } from './expression.js';
|
4
|
-
import { log } from
|
4
|
+
import { log } from './log.js';
|
5
5
|
|
6
6
|
const CValtype = {
|
7
7
|
i8: 'i8',
|
@@ -106,17 +106,6 @@ for (const x in CValtype) {
|
|
106
106
|
if (Valtype[x]) CValtype[Valtype[x]] = CValtype[x];
|
107
107
|
}
|
108
108
|
|
109
|
-
const todo = msg => {
|
110
|
-
class TodoError extends Error {
|
111
|
-
constructor(message) {
|
112
|
-
super(message);
|
113
|
-
this.name = 'TodoError';
|
114
|
-
}
|
115
|
-
}
|
116
|
-
|
117
|
-
throw new TodoError(msg);
|
118
|
-
};
|
119
|
-
|
120
109
|
const removeBrackets = str => {
|
121
110
|
// return str;
|
122
111
|
// if (str.startsWith(`(${CValtype.i32})(${CValtype.u32})`)) return `(${CValtype.i32})(${CValtype.u32})(` + removeBrackets(str.slice(22, -1)) + ')';
|
@@ -167,11 +156,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
167
156
|
prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n'));
|
168
157
|
}
|
169
158
|
|
170
|
-
// for (const [ x, p ] of pages) {
|
171
|
-
// out += `${CValtype[p.type]} ${x.replace(': ', '_').replace(/[^0-9a-zA-Z_]/g, '')}[100]`;
|
172
|
-
// out += ';\n';
|
173
|
-
// }
|
174
|
-
|
175
159
|
if (out) out += '\n';
|
176
160
|
|
177
161
|
let depth = 1;
|
@@ -213,9 +197,9 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
213
197
|
|
214
198
|
for (const f of funcs) {
|
215
199
|
depth = 1;
|
200
|
+
brDepth = 0;
|
216
201
|
|
217
202
|
const invLocals = inv(f.locals, x => x.idx);
|
218
|
-
// if (f.returns.length > 1) todo('funcs returning >1 value unsupported');
|
219
203
|
|
220
204
|
for (const x in invLocals) {
|
221
205
|
invLocals[x] = sanitize(invLocals[x]);
|
@@ -247,12 +231,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
247
231
|
const brs = [];
|
248
232
|
let lastCond = false;
|
249
233
|
|
250
|
-
// let brDepth = 0;
|
251
|
-
|
252
234
|
const blockStart = (i, loop) => {
|
253
|
-
// reset "stack"
|
254
|
-
// vals = [];
|
255
|
-
|
256
235
|
rets.push(i[1]);
|
257
236
|
|
258
237
|
const br = brId++;
|
@@ -269,25 +248,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
269
248
|
brDepth++;
|
270
249
|
};
|
271
250
|
|
272
|
-
const highlight = i => {
|
273
|
-
const surrounding = 6;
|
274
|
-
|
275
|
-
const decomp = decompile(f.wasm.slice(i - surrounding, i + surrounding + 1), '', 0, f.locals, f.params, f.returns, funcs, globals, exceptions).slice(0, -1).split('\n');
|
276
|
-
|
277
|
-
const noAnsi = s => s.replace(/\u001b\[[0-9]+m/g, '');
|
278
|
-
let longest = 0;
|
279
|
-
for (let j = 0; j < decomp.length; j++) {
|
280
|
-
longest = Math.max(longest, noAnsi(decomp[j]).length);
|
281
|
-
}
|
282
|
-
|
283
|
-
const middle = Math.floor(decomp.length / 2);
|
284
|
-
decomp[middle] = `\x1B[47m\x1B[30m${noAnsi(decomp[middle])}${'\u00a0'.repeat(longest - noAnsi(decomp[middle]).length)}\x1B[0m`;
|
285
|
-
|
286
|
-
console.log('\x1B[90m...\x1B[0m');
|
287
|
-
console.log(decomp.join('\n'));
|
288
|
-
console.log('\x1B[90m...\x1B[0m\n');
|
289
|
-
};
|
290
|
-
|
291
251
|
for (let _ = 0; _ < f.wasm.length; _++) {
|
292
252
|
const i = f.wasm[_];
|
293
253
|
if (!i || !i[0]) continue;
|
@@ -415,8 +375,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
415
375
|
const br = brs.at(-1);
|
416
376
|
const ret = rets.at(-1);
|
417
377
|
if (ret && ret !== Blocktype.void) {
|
418
|
-
// console.log(vals, ret);
|
419
|
-
// console.log(decompile(f.wasm.slice(_ - 5, _ + 1)));
|
420
378
|
if (vals.length > 0) line(`_r${br} = ${removeBrackets(vals.pop())}`);
|
421
379
|
// vals.push(`_r${br}`);
|
422
380
|
}
|
@@ -425,8 +383,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
425
383
|
line(`} else {`, false);
|
426
384
|
depth++;
|
427
385
|
|
428
|
-
// reset "stack"
|
429
|
-
// vals = [];
|
430
386
|
break;
|
431
387
|
}
|
432
388
|
|
@@ -441,8 +397,6 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
441
397
|
const br = brs.pop();
|
442
398
|
const ret = rets.pop();
|
443
399
|
if (ret && ret !== Blocktype.void) {
|
444
|
-
// console.log(vals, ret);
|
445
|
-
// console.log(decompile(f.wasm.slice(_ - 5, _ + 1)));
|
446
400
|
if (vals.length > 0) line(`_r${br} = ${removeBrackets(vals.pop())}`);
|
447
401
|
vals.push(`_r${br}`);
|
448
402
|
}
|
@@ -541,18 +495,14 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
541
495
|
|
542
496
|
case Opcodes.br: {
|
543
497
|
const ret = rets[brDepth - i[1] - 1];
|
544
|
-
// console.log(rets, brDepth, i[1], brDepth - i[1] - 1, ret, vals);
|
545
498
|
if (ret !== Blocktype.void) line(`_r${brs[brDepth - i[1] - 1]} = ${removeBrackets(vals.pop())}`);
|
546
499
|
line(`goto j${brs[brDepth - i[1] - 1]}`);
|
547
500
|
|
548
|
-
// // reset "stack"
|
549
|
-
// vals = [];
|
550
501
|
break;
|
551
502
|
}
|
552
503
|
|
553
504
|
case Opcodes.br_if: {
|
554
505
|
const ret = rets[brDepth - i[1] - 1];
|
555
|
-
// console.log(rets, brDepth, i[1], brDepth - i[1] - 1, ret, vals);
|
556
506
|
|
557
507
|
let cond = removeBrackets(vals.pop());
|
558
508
|
if (!lastCond) {
|
@@ -602,7 +552,6 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
602
552
|
}
|
603
553
|
|
604
554
|
log.warning('2c', `unimplemented op: ${invOpcodes[i[0]]}`);
|
605
|
-
// todo(`unimplemented op: ${invOpcodes[i[0]]}`);
|
606
555
|
}
|
607
556
|
|
608
557
|
lastCond = false;
|
package/compiler/assemble.js
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
import { Valtype, FuncType,
|
2
|
-
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128,
|
3
|
-
// import { number } from './embedding.js';
|
1
|
+
import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize, Reftype } from './wasmSpec.js';
|
2
|
+
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64_into } from './encoding.js';
|
4
3
|
import { importedFuncs } from './builtins.js';
|
5
|
-
import { log } from
|
4
|
+
import { log } from './log.js';
|
6
5
|
import Prefs from './prefs.js';
|
7
6
|
|
8
7
|
const createSection = (type, data) => [
|
@@ -66,6 +65,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
66
65
|
importFuncs = [...imports.values()];
|
67
66
|
|
68
67
|
// fix call indexes for non-imports
|
68
|
+
// also fix call_indirect types
|
69
69
|
const delta = importedFuncs.length - importFuncs.length;
|
70
70
|
for (const f of funcs) {
|
71
71
|
f.originalIndex = f.index;
|
@@ -75,6 +75,16 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
75
75
|
if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] >= importedFuncs.length) {
|
76
76
|
inst[1] -= delta;
|
77
77
|
}
|
78
|
+
|
79
|
+
if (inst[0] === Opcodes.call_indirect) {
|
80
|
+
const params = [];
|
81
|
+
for (let i = 0; i < inst[1]; i++) {
|
82
|
+
params.push(valtypeBinary, Valtype.i32);
|
83
|
+
}
|
84
|
+
|
85
|
+
const returns = [ valtypeBinary, Valtype.i32 ];
|
86
|
+
inst[1] = getType(params, returns);
|
87
|
+
}
|
78
88
|
}
|
79
89
|
}
|
80
90
|
}
|
@@ -92,17 +102,23 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
92
102
|
encodeVector(funcs.map(x => getType(x.params, x.returns))) // type indexes
|
93
103
|
);
|
94
104
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
105
|
+
const tableSection = !funcs.table ? [] : createSection(
|
106
|
+
Section.table,
|
107
|
+
encodeVector([ [ Reftype.funcref, 0x00, funcs.length ] ])
|
108
|
+
);
|
109
|
+
|
110
|
+
const elementSection = !funcs.table ? [] : createSection(
|
111
|
+
Section.element,
|
112
|
+
encodeVector([ [
|
113
|
+
0x00,
|
114
|
+
Opcodes.i32_const, 0, Opcodes.end,
|
115
|
+
...encodeVector(funcs.map(x => x.index))
|
116
|
+
] ])
|
101
117
|
);
|
102
118
|
|
103
119
|
// const t0 = performance.now();
|
104
120
|
|
105
|
-
// specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection(
|
121
|
+
// specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
|
106
122
|
const globalsValues = Object.values(globals);
|
107
123
|
|
108
124
|
let globalSection = [];
|
@@ -227,6 +243,14 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
227
243
|
dataSection: dataSection.map(x => x.toString(16)),
|
228
244
|
});
|
229
245
|
|
246
|
+
// compilation hints section - unspecd, v8 only
|
247
|
+
// https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
|
248
|
+
const chSection = !compileHints ? [] : customSection(
|
249
|
+
'compilationHints',
|
250
|
+
// for now just do everything as optimize eager
|
251
|
+
encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
|
252
|
+
);
|
253
|
+
|
230
254
|
return Uint8Array.from([
|
231
255
|
...Magic,
|
232
256
|
...ModuleVersion,
|
@@ -234,10 +258,12 @@ export default (funcs, globals, tags, pages, data, flags) => {
|
|
234
258
|
...importSection,
|
235
259
|
...funcSection,
|
236
260
|
...chSection,
|
261
|
+
...tableSection,
|
237
262
|
...memorySection,
|
238
263
|
...tagSection,
|
239
264
|
...globalSection,
|
240
265
|
...exportSection,
|
266
|
+
...elementSection,
|
241
267
|
...dataCountSection,
|
242
268
|
...codeSection,
|
243
269
|
...dataSection
|
@@ -2,7 +2,7 @@ export default () => {
|
|
2
2
|
let out = `// @porf --funsafe-no-unlikely-proto-checks --valtype=i32
|
3
3
|
`;
|
4
4
|
|
5
|
-
const
|
5
|
+
const noArgs = (a0, a1) => out += `
|
6
6
|
export const __String_prototype_${a0} = (_this: string) => {
|
7
7
|
let out: string = Porffor.s\`<${a1}>\`;
|
8
8
|
|
@@ -58,15 +58,15 @@ ${[...a1].map((x, i) => ` Porffor.wasm.i32.store8(outPtr, ${x.charCodeAt(0)}, 0
|
|
58
58
|
};
|
59
59
|
`;
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
noArgs('big', 'big');
|
62
|
+
noArgs('blink', 'blink');
|
63
|
+
noArgs('bold', 'b');
|
64
|
+
noArgs('fixed', 'tt');
|
65
|
+
noArgs('italics', 'i');
|
66
|
+
noArgs('small', 'small');
|
67
|
+
noArgs('strike', 'strike');
|
68
|
+
noArgs('sub', 'sub');
|
69
|
+
noArgs('sup', 'sup');
|
70
70
|
|
71
71
|
return out;
|
72
72
|
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// @porf --
|
1
|
+
// @porf --valtype=i32
|
2
2
|
|
3
3
|
export const __String_prototype_trimLeft = (_this: string) => {
|
4
4
|
return __String_prototype_trimStart(_this);
|
@@ -13,6 +13,6 @@ export const __String_prototype_trimRight = (_this: string) => {
|
|
13
13
|
return __String_prototype_trimEnd(_this);
|
14
14
|
};
|
15
15
|
|
16
|
-
export const
|
17
|
-
return
|
16
|
+
export const __ByteString_prototype_trimRight = (_this: string) => {
|
17
|
+
return __ByteString_prototype_trimEnd(_this);
|
18
18
|
};
|
@@ -1,5 +1,3 @@
|
|
1
|
-
// @porf --funsafe-no-unlikely-proto-checks
|
2
|
-
|
3
1
|
export const __Array_isArray = (x: unknown): boolean =>
|
4
2
|
// Porffor.wasm`local.get ${x+1}` == Porffor.TYPES.array;
|
5
3
|
Porffor.rawType(x) == Porffor.TYPES.array;
|
@@ -91,14 +89,12 @@ export const __Array_prototype_with = (_this: any[], index: number, value: any)
|
|
91
89
|
if (index < 0) {
|
92
90
|
index = len + index;
|
93
91
|
if (index < 0) {
|
94
|
-
|
95
|
-
return null;
|
92
|
+
throw new RangeError('Invalid index');
|
96
93
|
}
|
97
94
|
}
|
98
95
|
|
99
96
|
if (index > len) {
|
100
|
-
|
101
|
-
return null;
|
97
|
+
throw new RangeError('Invalid index');
|
102
98
|
}
|
103
99
|
|
104
100
|
// todo: allocator is bad here?
|
@@ -1,5 +1,3 @@
|
|
1
|
-
// @porf --funsafe-no-unlikely-proto-checks
|
2
|
-
|
3
1
|
// 20.3.3.2 Boolean.prototype.toString ()
|
4
2
|
// https://tc39.es/ecma262/#sec-boolean.prototype.tostring
|
5
3
|
export const __Boolean_prototype_toString = (_this: boolean) => {
|
@@ -17,4 +15,4 @@ export const __Boolean_prototype_toString = (_this: boolean) => {
|
|
17
15
|
export const __Boolean_prototype_valueOf = (_this: boolean) => {
|
18
16
|
// 1. Return ? ThisBooleanValue(this value).
|
19
17
|
return _this;
|
20
|
-
};
|
18
|
+
};
|
@@ -1,5 +1,3 @@
|
|
1
|
-
// @porf --funsafe-no-unlikely-proto-checks
|
2
|
-
|
3
1
|
// 21.4.1.3 Day (t)
|
4
2
|
// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-day
|
5
3
|
// 1. Return 𝔽(floor(ℝ(t / msPerDay))).
|
@@ -1774,8 +1772,7 @@ export const __Date_prototype_toISOString = (_this: Date) => {
|
|
1774
1772
|
|
1775
1773
|
// 4. If tv is NaN, throw a RangeError exception.
|
1776
1774
|
if (Number.isNaN(tv)) {
|
1777
|
-
|
1778
|
-
return;
|
1775
|
+
throw new RangeError('Invalid time value');
|
1779
1776
|
}
|
1780
1777
|
|
1781
1778
|
// 5. Assert: tv is an integral Number.
|
package/compiler/builtins/int.ts
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
// @porf --funsafe-no-unlikely-proto-checks
|
2
|
-
|
3
1
|
// radix: number|any for rawType check
|
4
2
|
export const __Number_prototype_toString = (_this: number, radix: number|any) => {
|
5
3
|
let out: bytestring = '';
|
@@ -20,8 +18,7 @@ export const __Number_prototype_toString = (_this: number, radix: number|any) =>
|
|
20
18
|
|
21
19
|
radix |= 0;
|
22
20
|
if (radix < 2 || radix > 36) {
|
23
|
-
|
24
|
-
return out;
|
21
|
+
throw new RangeError('toString() radix argument must be between 2 and 36');
|
25
22
|
}
|
26
23
|
|
27
24
|
if (_this == 0) {
|
@@ -254,8 +251,7 @@ export const __Number_prototype_toFixed = (_this: number, fractionDigits: number
|
|
254
251
|
|
255
252
|
fractionDigits |= 0;
|
256
253
|
if (fractionDigits < 0 || fractionDigits > 100) {
|
257
|
-
|
258
|
-
return out;
|
254
|
+
throw new RangeError('toFixed() fractionDigits argument must be between 0 and 100');
|
259
255
|
}
|
260
256
|
|
261
257
|
// if negative value
|
@@ -349,8 +345,7 @@ export const __Number_prototype_toExponential = (_this: number, fractionDigits:
|
|
349
345
|
} else {
|
350
346
|
fractionDigits |= 0;
|
351
347
|
if (fractionDigits < 0 || fractionDigits > 100) {
|
352
|
-
|
353
|
-
return out;
|
348
|
+
throw new RangeError('toExponential() fractionDigits argument must be between 0 and 100');
|
354
349
|
}
|
355
350
|
}
|
356
351
|
|
@@ -7,18 +7,18 @@ type PorfforGlobal = {
|
|
7
7
|
wasm: {
|
8
8
|
(...args: any[]): any;
|
9
9
|
i32: {
|
10
|
-
load(pointer:
|
11
|
-
store(pointer:
|
12
|
-
load8_u(pointer:
|
13
|
-
store8(pointer:
|
14
|
-
load16_u(pointer:
|
15
|
-
store16(pointer:
|
10
|
+
load(pointer: any, align: i32, offset: i32): i32;
|
11
|
+
store(pointer: any, value: i32, align: i32, offset: i32): i32;
|
12
|
+
load8_u(pointer: any, align: i32, offset: i32): i32;
|
13
|
+
store8(pointer: any, value: i32, align: i32, offset: i32): i32;
|
14
|
+
load16_u(pointer: any, align: i32, offset: i32): i32;
|
15
|
+
store16(pointer: any, value: i32, align: i32, offset: i32): i32;
|
16
16
|
const(value: i32): i32;
|
17
17
|
}
|
18
18
|
|
19
19
|
f64: {
|
20
|
-
load(pointer:
|
21
|
-
store(pointer:
|
20
|
+
load(pointer: any, align: i32, offset: i32): i32;
|
21
|
+
store(pointer: any, value: f64, align: i32, offset: i32): f64;
|
22
22
|
}
|
23
23
|
}
|
24
24
|
|
@@ -40,6 +40,7 @@ type PorfforGlobal = {
|
|
40
40
|
regexp: i32;
|
41
41
|
bytestring: i32;
|
42
42
|
date: i32;
|
43
|
+
set: i32;
|
43
44
|
}
|
44
45
|
|
45
46
|
fastOr(...args: any): boolean;
|