porffor 0.2.0-fdf0fc5 → 0.14.0-4e46400a9

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.
Files changed (40) hide show
  1. package/README.md +9 -2
  2. package/byg/index.js +3 -24
  3. package/compiler/2c.js +2 -53
  4. package/compiler/assemble.js +26 -11
  5. package/compiler/builtins/annexb_string.js +10 -10
  6. package/compiler/builtins/annexb_string.ts +3 -3
  7. package/compiler/builtins/array.ts +2 -6
  8. package/compiler/builtins/base64.ts +1 -1
  9. package/compiler/builtins/boolean.ts +0 -2
  10. package/compiler/builtins/crypto.ts +1 -1
  11. package/compiler/builtins/date.ts +1 -4
  12. package/compiler/builtins/escape.ts +1 -1
  13. package/compiler/builtins/function.ts +0 -2
  14. package/compiler/builtins/int.ts +0 -2
  15. package/compiler/builtins/number.ts +3 -8
  16. package/compiler/builtins/object.ts +0 -2
  17. package/compiler/builtins/porffor.d.ts +9 -8
  18. package/compiler/builtins/set.ts +184 -2
  19. package/compiler/builtins/string.ts +1 -1
  20. package/compiler/builtins.js +4 -7
  21. package/compiler/codegen.js +78 -121
  22. package/compiler/decompile.js +2 -2
  23. package/compiler/embedding.js +2 -2
  24. package/compiler/encoding.js +0 -14
  25. package/compiler/expression.js +1 -1
  26. package/compiler/generated_builtins.js +303 -204
  27. package/compiler/index.js +0 -2
  28. package/compiler/opt.js +7 -7
  29. package/compiler/parse.js +1 -3
  30. package/compiler/precompile.js +17 -25
  31. package/compiler/prototype.js +5 -5
  32. package/compiler/wasmSpec.js +5 -0
  33. package/compiler/wrap.js +75 -57
  34. package/package.json +1 -1
  35. package/runner/compare.js +0 -1
  36. package/runner/debug.js +1 -6
  37. package/runner/profiler.js +15 -42
  38. package/runner/repl.js +3 -9
  39. package/runner/sizes.js +2 -2
  40. 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
- ### Setup
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 >10% (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.
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
- // crop box if > termHeight
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) { // b pressed normally
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 "./log.js";
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;
@@ -1,8 +1,7 @@
1
- import { Valtype, FuncType, Empty, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize } from './wasmSpec.js';
2
- import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, ieee754_binary64, unsignedLEB128_into, signedLEB128_into, ieee754_binary64_into } from './encoding.js';
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 "./log.js";
4
+ import { log } from './log.js';
6
5
  import Prefs from './prefs.js';
7
6
 
8
7
  const createSection = (type, data) => [
@@ -92,17 +91,23 @@ export default (funcs, globals, tags, pages, data, flags) => {
92
91
  encodeVector(funcs.map(x => getType(x.params, x.returns))) // type indexes
93
92
  );
94
93
 
95
- // compilation hints section - unspecd, v8 only
96
- // https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
97
- const chSection = !compileHints ? [] : customSection(
98
- 'compilationHints',
99
- // for now just do everything as optimize eager
100
- encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
94
+ const tableSection = !funcs.table ? [] : createSection(
95
+ Section.table,
96
+ encodeVector([ [ Reftype.funcref, 0x00, funcs.length ] ])
97
+ );
98
+
99
+ const elementSection = !funcs.table ? [] : createSection(
100
+ Section.element,
101
+ encodeVector([ [
102
+ 0x00,
103
+ Opcodes.i32_const, 0, Opcodes.end,
104
+ encodeVector(funcs.map(x => x.index))
105
+ ] ])
101
106
  );
102
107
 
103
108
  // const t0 = performance.now();
104
109
 
105
- // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection(...)
110
+ // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
106
111
  const globalsValues = Object.values(globals);
107
112
 
108
113
  let globalSection = [];
@@ -227,6 +232,14 @@ export default (funcs, globals, tags, pages, data, flags) => {
227
232
  dataSection: dataSection.map(x => x.toString(16)),
228
233
  });
229
234
 
235
+ // compilation hints section - unspecd, v8 only
236
+ // https://github.com/WebAssembly/design/issues/1473#issuecomment-1431274746
237
+ const chSection = !compileHints ? [] : customSection(
238
+ 'compilationHints',
239
+ // for now just do everything as optimize eager
240
+ encodeVector(funcs.map(_ => chHint(0x02, 0x02, 0x02)))
241
+ );
242
+
230
243
  return Uint8Array.from([
231
244
  ...Magic,
232
245
  ...ModuleVersion,
@@ -234,10 +247,12 @@ export default (funcs, globals, tags, pages, data, flags) => {
234
247
  ...importSection,
235
248
  ...funcSection,
236
249
  ...chSection,
250
+ ...tableSection,
237
251
  ...memorySection,
238
252
  ...tagSection,
239
253
  ...globalSection,
240
254
  ...exportSection,
255
+ ...elementSection,
241
256
  ...dataCountSection,
242
257
  ...codeSection,
243
258
  ...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 annexB_noArgs = (a0, a1) => out += `
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
- annexB_noArgs('big', 'big');
62
- annexB_noArgs('blink', 'blink');
63
- annexB_noArgs('bold', 'b');
64
- annexB_noArgs('fixed', 'tt');
65
- annexB_noArgs('italics', 'i');
66
- annexB_noArgs('small', 'small');
67
- annexB_noArgs('strike', 'strike');
68
- annexB_noArgs('sub', 'sub');
69
- annexB_noArgs('sup', 'sup');
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 --funsafe-no-unlikely-proto-checks --valtype=i32
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 __ByteString_prototype_trimEnd = (_this: string) => {
17
- return __ByteString_prototype_trimRight(_this);
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
- // todo: throw RangeError: Invalid index
95
- return null;
92
+ throw new RangeError('Invalid index');
96
93
  }
97
94
  }
98
95
 
99
96
  if (index > len) {
100
- // todo: throw RangeError: Invalid index
101
- return null;
97
+ throw new RangeError('Invalid index');
102
98
  }
103
99
 
104
100
  // todo: allocator is bad here?
@@ -1,4 +1,4 @@
1
- // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
1
+ // @porf --valtype=i32
2
2
 
3
3
  export const btoa = (input: bytestring): bytestring => {
4
4
  const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -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) => {
@@ -1,4 +1,4 @@
1
- // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
1
+ // @porf --valtype=i32
2
2
 
3
3
  export const __crypto_randomUUID = (): bytestring => {
4
4
  let bytes: bytestring = '................';
@@ -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
- // todo throw
1778
- return;
1775
+ throw new RangeError('Invalid time value');
1779
1776
  }
1780
1777
 
1781
1778
  // 5. Assert: tv is an integral Number.
@@ -1,4 +1,4 @@
1
- // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
1
+ // @porf --valtype=i32
2
2
 
3
3
  import type {} from './porffor';
4
4
 
@@ -1,5 +1,3 @@
1
- // // @porf --funsafe-no-unlikely-proto-checks
2
-
3
1
  export const __Function_prototype_toString = (_this: Function) => {
4
2
  // todo: actually use source
5
3
  let out: bytestring = 'function () {}';
@@ -1,5 +1,3 @@
1
- // @porf --funsafe-no-unlikely-proto-checks
2
-
3
1
  // radix: number|any for rawType check
4
2
  // export const parseInt = (input: string|bytestring, radix: number|any): f64 => {
5
3
  export const parseInt = (input: string|bytestring, radix: number): f64 => {
@@ -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
- // todo: throw RangeError: toString() radix argument must be between 2 and 36
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
- // todo: throw RangeError: toFixed() digits argument must be between 0 and 100
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
- // todo: throw RangeError: toExponential() digits argument must be between 0 and 100
353
- return out;
348
+ throw new RangeError('toExponential() fractionDigits argument must be between 0 and 100');
354
349
  }
355
350
  }
356
351
 
@@ -1,5 +1,3 @@
1
- // // @porf --funsafe-no-unlikely-proto-checks
2
-
3
1
  export const __Object_prototype_toString = (_this: object) => {
4
2
  let out: bytestring = '[object Object]';
5
3
  return out;
@@ -7,18 +7,18 @@ type PorfforGlobal = {
7
7
  wasm: {
8
8
  (...args: any[]): any;
9
9
  i32: {
10
- load(pointer: i32, align: i32, offset: i32): i32;
11
- store(pointer: i32, value: i32, align: i32, offset: i32): i32;
12
- load8_u(pointer: i32, align: i32, offset: i32): i32;
13
- store8(pointer: i32, value: i32, align: i32, offset: i32): i32;
14
- load16_u(pointer: i32, align: i32, offset: i32): i32;
15
- store16(pointer: i32, value: i32, align: i32, offset: i32): i32;
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: i32, align: i32, offset: i32): i32;
21
- store(pointer: i32, value: f64, align: i32, offset: i32): f64;
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;