porffor 0.14.0-f67c123a1 → 0.16.0-08983b6b1

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 (45) hide show
  1. package/CONTRIBUTING.md +16 -10
  2. package/README.md +14 -30
  3. package/asur/index.js +1 -1
  4. package/compiler/2c.js +172 -59
  5. package/compiler/allocators.js +128 -0
  6. package/compiler/assemble.js +37 -5
  7. package/compiler/builtins/annexb_string.ts +1 -0
  8. package/compiler/builtins/array.ts +154 -7
  9. package/compiler/builtins/base64.ts +1 -0
  10. package/compiler/builtins/boolean.ts +3 -1
  11. package/compiler/builtins/console.ts +6 -0
  12. package/compiler/builtins/crypto.ts +1 -0
  13. package/compiler/builtins/date.ts +5 -30
  14. package/compiler/builtins/error.js +22 -0
  15. package/compiler/builtins/escape.ts +1 -2
  16. package/compiler/builtins/function.ts +2 -0
  17. package/compiler/builtins/int.ts +2 -0
  18. package/compiler/builtins/math.ts +410 -0
  19. package/compiler/builtins/number.ts +12 -21
  20. package/compiler/builtins/object.ts +2 -0
  21. package/compiler/builtins/porffor.d.ts +18 -0
  22. package/compiler/builtins/set.ts +22 -12
  23. package/compiler/builtins/string.ts +1 -0
  24. package/compiler/builtins/string_f64.ts +10 -0
  25. package/compiler/builtins/symbol.ts +62 -0
  26. package/compiler/builtins/z_ecma262.ts +62 -0
  27. package/compiler/builtins.js +50 -12
  28. package/compiler/codegen.js +826 -552
  29. package/compiler/cyclone.js +535 -0
  30. package/compiler/decompile.js +7 -1
  31. package/compiler/generated_builtins.js +635 -84
  32. package/compiler/havoc.js +93 -0
  33. package/compiler/index.js +108 -15
  34. package/compiler/opt.js +10 -44
  35. package/compiler/parse.js +3 -9
  36. package/compiler/pgo.js +212 -0
  37. package/compiler/precompile.js +17 -11
  38. package/compiler/prefs.js +13 -5
  39. package/compiler/prototype.js +200 -186
  40. package/compiler/wasmSpec.js +2 -2
  41. package/compiler/wrap.js +128 -44
  42. package/package.json +3 -5
  43. package/runner/index.js +31 -15
  44. package/runner/repl.js +18 -2
  45. /package/runner/{profiler.js → profile.js} +0 -0
@@ -0,0 +1,128 @@
1
+ import { Opcodes, PageSize, Valtype } from './wasmSpec.js';
2
+ import { number } from './embedding.js';
3
+ import Prefs from './prefs.js';
4
+
5
+ // we currently have 3 allocators:
6
+ // - static (default): a static/compile-time allocator. fast (no grow/run-time alloc needed) but can break some code
7
+ // - grow: perform a memory.grow every allocation. simple but maybe slow?
8
+ // - chunk: perform large memory.grow's in chunks when needed. needs investigation
9
+
10
+ export default name => {
11
+ switch (name) {
12
+ case 'static': return new StaticAllocator();
13
+ case 'grow': return new GrowAllocator();
14
+ case 'chunk': return new ChunkAllocator();
15
+ default: throw new Error(`unknown allocator: ${name}`);
16
+ }
17
+ };
18
+
19
+ export class StaticAllocator {
20
+ constructor() {
21
+ }
22
+
23
+ allocType(itemType) {
24
+ switch (itemType) {
25
+ case 'i8': return 'bytestring';
26
+ case 'i16': return 'string';
27
+
28
+ default: return 'array';
29
+ }
30
+ }
31
+
32
+ ptr(ind) {
33
+ if (ind === 0) return 4;
34
+ return ind * PageSize;
35
+ }
36
+
37
+ alloc({ scope, pages }, name, { itemType }) {
38
+ const reason = `${this.allocType(itemType)}: ${Prefs.scopedPageNames ? (scope.name + '/') : ''}${name}`;
39
+
40
+ if (pages.has(reason)) return number(this.ptr(pages.get(reason).ind), Valtype.i32);
41
+
42
+ if (reason.startsWith('array:')) pages.hasArray = true;
43
+ if (reason.startsWith('string:')) pages.hasString = true;
44
+ if (reason.startsWith('bytestring:')) pages.hasByteString = true;
45
+ if (reason.includes('string:')) pages.hasAnyString = true;
46
+
47
+ let ind = pages.size;
48
+ pages.set(reason, { ind, type: itemType });
49
+
50
+ scope.pages ??= new Map();
51
+ scope.pages.set(reason, { ind, type: itemType });
52
+
53
+ return number(this.ptr(ind), Valtype.i32);
54
+ }
55
+ }
56
+
57
+ export class GrowAllocator {
58
+ constructor() {
59
+ Prefs.rmUnusedTypes = false;
60
+ }
61
+
62
+ alloc() {
63
+ return [
64
+ // grow by 1 page
65
+ [ Opcodes.i32_const, 1 ],
66
+ [ Opcodes.memory_grow, 0 ], // returns old page count
67
+
68
+ // get ptr (page count * page size)
69
+ number(65536, Valtype.i32)[0],
70
+ [ Opcodes.i32_mul ]
71
+ ];
72
+ }
73
+ }
74
+
75
+ export class ChunkAllocator {
76
+ constructor(chunkSize) {
77
+ Prefs.rmUnusedTypes = false;
78
+
79
+ // 64KiB * chunk size each growth
80
+ // 16: 1MiB chunks
81
+ this.chunkSize = chunkSize ?? Prefs.chunkAllocatorSize ?? 16;
82
+ }
83
+
84
+ alloc({ asmFunc, funcIndex }) {
85
+ const func = funcIndex['#chunkallocator_alloc'] ?? asmFunc('#chunkallocator_alloc', {
86
+ wasm: [
87
+ [ Opcodes.global_get, 0 ],
88
+ [ Opcodes.global_get, 1 ],
89
+ [ Opcodes.i32_ge_s ],
90
+ [ Opcodes.if, Valtype.i32 ], // ptr >= next
91
+ // grow by chunk size pages
92
+ [ Opcodes.i32_const, this.chunkSize ],
93
+ [ Opcodes.memory_grow, 0 ],
94
+
95
+ // ptr = prev memory size * PageSize
96
+ number(65536, Valtype.i32)[0],
97
+ [ Opcodes.i32_mul ],
98
+ [ Opcodes.global_set, 0 ],
99
+
100
+ // next = ptr + ((chunkSize - 1) * PageSize)
101
+ [ Opcodes.global_get, 0 ],
102
+ number(65536 * (this.chunkSize - 1), Valtype.i32)[0],
103
+ [ Opcodes.i32_add ],
104
+ [ Opcodes.global_set, 1 ],
105
+
106
+ // return ptr
107
+ [ Opcodes.global_get, 0 ],
108
+ [ Opcodes.else ],
109
+ // return ptr = ptr + PageSize
110
+ [ Opcodes.global_get, 0 ],
111
+ number(65536, Valtype.i32)[0],
112
+ [ Opcodes.i32_add ],
113
+ [ Opcodes.global_set, 0 ],
114
+ [ Opcodes.global_get, 0 ],
115
+ [ Opcodes.end ],
116
+ ],
117
+ params: [],
118
+ locals: [],
119
+ globals: [ Valtype.i32, Valtype.i32 ],
120
+ globalNames: ['#chunkallocator_ptr', '#chunkallocator_next'],
121
+ returns: [ Valtype.i32 ],
122
+ }).index;
123
+
124
+ return [
125
+ [ Opcodes.call, func ]
126
+ ];
127
+ }
128
+ }
@@ -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();
@@ -65,6 +65,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
65
65
  importFuncs = [...imports.values()];
66
66
 
67
67
  // fix call indexes for non-imports
68
+ // also fix call_indirect types
68
69
  const delta = importedFuncs.length - importFuncs.length;
69
70
  for (const f of funcs) {
70
71
  f.originalIndex = f.index;
@@ -74,6 +75,16 @@ export default (funcs, globals, tags, pages, data, flags) => {
74
75
  if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] >= importedFuncs.length) {
75
76
  inst[1] -= delta;
76
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
+ }
77
88
  }
78
89
  }
79
90
  }
@@ -83,7 +94,7 @@ export default (funcs, globals, tags, pages, data, flags) => {
83
94
 
84
95
  const importSection = importFuncs.length === 0 ? [] : createSection(
85
96
  Section.import,
86
- encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(new Array(x.params).fill(x.name.startsWith('profile') ? Valtype.i32 : valtypeBinary), new Array(x.returns).fill(valtypeBinary)) ]))
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)) ]))
87
98
  );
88
99
 
89
100
  const funcSection = createSection(
@@ -101,10 +112,25 @@ export default (funcs, globals, tags, pages, data, flags) => {
101
112
  encodeVector([ [
102
113
  0x00,
103
114
  Opcodes.i32_const, 0, Opcodes.end,
104
- encodeVector(funcs.map(x => x.index))
115
+ ...encodeVector(funcs.map(x => x.index))
105
116
  ] ])
106
117
  );
107
118
 
119
+ if (pages.has('func argc lut') && !data.addedFuncArgcLut) {
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
+ data.addedFuncArgcLut = true;
132
+ }
133
+
108
134
  // const t0 = performance.now();
109
135
 
110
136
  // specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
@@ -214,7 +240,13 @@ export default (funcs, globals, tags, pages, data, flags) => {
214
240
 
215
241
  const dataSection = data.length === 0 ? [] : createSection(
216
242
  Section.data,
217
- encodeVector(data.map(x => [ 0x00, Opcodes.i32_const, ...signedLEB128(x.offset), Opcodes.end, ...encodeVector(x.bytes) ]))
243
+ encodeVector(data.map(x => {
244
+ // type: active
245
+ if (x.offset != null) return [ 0x00, Opcodes.i32_const, ...signedLEB128(x.offset), Opcodes.end, ...encodeVector(x.bytes) ];
246
+
247
+ // type: passive
248
+ return [ 0x01, ...encodeVector(x.bytes) ];
249
+ }))
218
250
  );
219
251
 
220
252
  const dataCountSection = data.length === 0 ? [] : createSection(
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const __String_prototype_trimLeft = (_this: string) => {
4
5
  return __String_prototype_trimStart(_this);
@@ -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 * 8;
32
+ const thisPtrEnd: i32 = thisPtr + end * 9;
31
33
 
32
- thisPtr += start * 8;
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 += 8;
37
- outPtr += 8;
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;
@@ -50,7 +54,7 @@ export const __Array_prototype_indexOf = (_this: any[], searchElement: any, posi
50
54
  } else position = 0;
51
55
 
52
56
  for (let i: i32 = position; i < len; i++) {
53
- if (_this[i] == searchElement) return i;
57
+ if (_this[i] === searchElement) return i;
54
58
  }
55
59
 
56
60
  return -1;
@@ -64,7 +68,7 @@ export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any,
64
68
  } else position = 0;
65
69
 
66
70
  for (let i: i32 = len - 1; i >= position; i--) {
67
- if (_this[i] == searchElement) return i;
71
+ if (_this[i] === searchElement) return i;
68
72
  }
69
73
 
70
74
  return -1;
@@ -78,7 +82,7 @@ export const __Array_prototype_includes = (_this: any[], searchElement: any, pos
78
82
  } else position = 0;
79
83
 
80
84
  for (let i: i32 = position; i < len; i++) {
81
- if (_this[i] == searchElement) return true;
85
+ if (_this[i] === searchElement) return true;
82
86
  }
83
87
 
84
88
  return false;
@@ -142,4 +146,147 @@ 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 len: i32 = _this.length;
175
+ const out: any[] = [];
176
+ out.length = len;
177
+
178
+ let i: i32 = 0;
179
+ while (i < len) {
180
+ out[i] = callbackFn(_this[i], i++, _this);
181
+ }
182
+
183
+ return out;
184
+ };
185
+
186
+ export const __Array_prototype_find = (_this: any[], callbackFn: any) => {
187
+ const len: i32 = _this.length;
188
+ let i: i32 = 0;
189
+ while (i < len) {
190
+ const el: any = _this[i];
191
+ if (Boolean(callbackFn(el, i++, _this))) return el;
192
+ }
193
+ };
194
+
195
+ export const __Array_prototype_findLast = (_this: any[], callbackFn: any) => {
196
+ let i: i32 = _this.length;
197
+ while (i > 0) {
198
+ const el: any = _this[--i];
199
+ if (Boolean(callbackFn(el, i, _this))) return el;
200
+ }
201
+ };
202
+
203
+ export const __Array_prototype_findIndex = (_this: any[], callbackFn: any) => {
204
+ const len: i32 = _this.length;
205
+ let i: i32 = 0;
206
+ while (i < len) {
207
+ if (Boolean(callbackFn(_this[i], i++, _this))) return i;
208
+ }
209
+ };
210
+
211
+ export const __Array_prototype_findLastIndex = (_this: any[], callbackFn: any) => {
212
+ let i: i32 = _this.length;
213
+ while (i > 0) {
214
+ if (Boolean(callbackFn(_this[--i], i, _this))) return i;
215
+ }
216
+ };
217
+
218
+ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
219
+ const len: i32 = _this.length;
220
+ let i: i32 = 0;
221
+ while (i < len) {
222
+ if (!Boolean(callbackFn(_this[i], i++, _this))) return false;
223
+ }
224
+
225
+ return true;
226
+ };
227
+
228
+ export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialValue: any) => {
229
+ let acc: any = initialValue ?? _this[0];
230
+
231
+ const len: i32 = _this.length;
232
+ let i: i32 = 0;
233
+ while (i < len) {
234
+ acc = callbackFn(acc, _this[i], i++, _this);
235
+ }
236
+
237
+ return acc;
238
+ };
239
+
240
+ export const __Array_prototype_toString = (_this: any[]) => {
241
+ // todo: this is bytestring only!
242
+
243
+ let out: bytestring = '';
244
+ out.length = 0;
245
+
246
+ const len: i32 = _this.length;
247
+ let i: i32 = 0;
248
+ while (i < len) {
249
+ if (i > 0) Porffor.bytestring.appendChar(out, 44);
250
+
251
+ const element: any = _this[i++];
252
+ const type: i32 = Porffor.rawType(element);
253
+ if (element != 0 || Porffor.fastAnd(
254
+ type != Porffor.TYPES.undefined, // undefined
255
+ type != Porffor.TYPES.object // null
256
+ )) {
257
+ Porffor.bytestring.appendStr(out, ecma262.ToString(element));
258
+ }
259
+ }
260
+
261
+ return out;
262
+ };
263
+
264
+ export const __Array_prototype_join = (_this: any[], _separator: any) => {
265
+ // todo: this is bytestring only!
266
+ // todo/perf: optimize single char separators
267
+ // todo/perf: optimize default separator (?)
268
+
269
+ let separator: bytestring = ',';
270
+ if (Porffor.rawType(_separator) != Porffor.TYPES.undefined)
271
+ separator = ecma262.ToString(_separator);
272
+
273
+ let out: bytestring = '';
274
+ out.length = 0;
275
+
276
+ const len: i32 = _this.length;
277
+ let i: i32 = 0;
278
+ while (i < len) {
279
+ if (i > 0) Porffor.bytestring.appendStr(out, separator);
280
+
281
+ const element: any = _this[i++];
282
+ const type: i32 = Porffor.rawType(element);
283
+ if (element != 0 || Porffor.fastAnd(
284
+ type != Porffor.TYPES.undefined, // undefined
285
+ type != Porffor.TYPES.object // null
286
+ )) {
287
+ Porffor.bytestring.appendStr(out, ecma262.ToString(element));
288
+ }
289
+ }
290
+
291
+ return out;
145
292
  };
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const btoa = (input: bytestring): bytestring => {
4
5
  const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // 20.3.3.2 Boolean.prototype.toString ()
2
4
  // https://tc39.es/ecma262/#sec-boolean.prototype.tostring
3
5
  export const __Boolean_prototype_toString = (_this: boolean) => {
@@ -15,4 +17,4 @@ export const __Boolean_prototype_toString = (_this: boolean) => {
15
17
  export const __Boolean_prototype_valueOf = (_this: boolean) => {
16
18
  // 1. Return ? ThisBooleanValue(this value).
17
19
  return _this;
18
- };
20
+ };
@@ -0,0 +1,6 @@
1
+ import type {} from './porffor.d.ts';
2
+
3
+ export const __console_clear = () => {
4
+ const clear: bytestring = '\x1b[1;1H\x1b[J';
5
+ Porffor.print(clear);
6
+ };
@@ -1,4 +1,5 @@
1
1
  // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
2
3
 
3
4
  export const __crypto_randomUUID = (): bytestring => {
4
5
  let bytes: bytestring = '................';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // 21.4.1.3 Day (t)
2
4
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-day
3
5
  // 1. Return 𝔽(floor(ℝ(t / msPerDay))).
@@ -251,29 +253,6 @@ export const __ecma262_UTC = (t: number): number => {
251
253
  return t;
252
254
  };
253
255
 
254
-
255
- // todo: move this somewhere generic?
256
- // 7.1.5 ToIntegerOrInfinity (argument)
257
- // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tointegerorinfinity
258
- export const __ecma262_ToIntegerOrInfinity = (argument: unknown): number => {
259
- // 1. Let number be ? ToNumber(argument).
260
- let number: number = Number(argument);
261
-
262
- // 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0.
263
- if (Number.isNaN(number)) return 0;
264
-
265
- // 3. If number is +∞𝔽, return +∞.
266
- // 4. If number is -∞𝔽, return -∞.
267
- if (!Number.isFinite(number)) return number;
268
-
269
- // 5. Return truncate(ℝ(number)).
270
- number = Math.trunc(number);
271
-
272
- // return 0 for -0
273
- if (number == 0) return 0;
274
- return number;
275
- };
276
-
277
256
  // 21.4.1.27 MakeTime (hour, min, sec, ms)
278
257
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-maketime
279
258
  export const __ecma262_MakeTime = (hour: number, min: number, sec: number, ms: number): number => {
@@ -720,12 +699,9 @@ export const __Porffor_date_allocate = (): Date => {
720
699
  const hack: bytestring = '';
721
700
 
722
701
  if (hack.length == 0) {
723
- hack.length = Porffor.wasm`i32.const 1
724
- memory.grow 0
725
- drop
726
- memory.size 0
702
+ hack.length = Porffor.wasm`
727
703
  i32.const 1
728
- i32.sub
704
+ memory.grow 0
729
705
  i32.const 65536
730
706
  i32.mul
731
707
  i32.from_u`;
@@ -1892,8 +1868,7 @@ export const __ecma262_ToDateString = (tv: number) => {
1892
1868
 
1893
1869
  // 1. If tv is NaN, return "Invalid Date".
1894
1870
  if (Number.isNaN(tv)) {
1895
- out = 'Invalid Date';
1896
- return out;
1871
+ return out = 'Invalid Date';
1897
1872
  }
1898
1873
 
1899
1874
  // 2. Let t be LocalTime(tv).
@@ -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
+ };
@@ -1,6 +1,5 @@
1
1
  // @porf --valtype=i32
2
-
3
- import type {} from './porffor';
2
+ import type {} from './porffor.d.ts';
4
3
 
5
4
  export const escape = (input: string|bytestring): bytestring => {
6
5
  // we have no byte array yet so use bytestring with 0x00 and 0x01 via escape characters
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  export const __Function_prototype_toString = (_this: Function) => {
2
4
  // todo: actually use source
3
5
  let out: bytestring = 'function () {}';
@@ -1,3 +1,5 @@
1
+ import type {} from './porffor.d.ts';
2
+
1
3
  // radix: number|any for rawType check
2
4
  // export const parseInt = (input: string|bytestring, radix: number|any): f64 => {
3
5
  export const parseInt = (input: string|bytestring, radix: number): f64 => {