porffor 0.16.0-fe07da0f4 → 0.17.0-05070e1f0

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.
@@ -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(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)) ]))
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();
@@ -239,7 +240,13 @@ export default (funcs, globals, tags, pages, data, flags) => {
239
240
 
240
241
  const dataSection = data.length === 0 ? [] : createSection(
241
242
  Section.data,
242
- 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
+ }))
243
250
  );
244
251
 
245
252
  const dataCountSection = data.length === 0 ? [] : createSection(
@@ -54,7 +54,7 @@ export const __Array_prototype_indexOf = (_this: any[], searchElement: any, posi
54
54
  } else position = 0;
55
55
 
56
56
  for (let i: i32 = position; i < len; i++) {
57
- if (_this[i] == searchElement) return i;
57
+ if (_this[i] === searchElement) return i;
58
58
  }
59
59
 
60
60
  return -1;
@@ -68,7 +68,7 @@ export const __Array_prototype_lastIndexOf = (_this: any[], searchElement: any,
68
68
  } else position = 0;
69
69
 
70
70
  for (let i: i32 = len - 1; i >= position; i--) {
71
- if (_this[i] == searchElement) return i;
71
+ if (_this[i] === searchElement) return i;
72
72
  }
73
73
 
74
74
  return -1;
@@ -82,7 +82,7 @@ export const __Array_prototype_includes = (_this: any[], searchElement: any, pos
82
82
  } else position = 0;
83
83
 
84
84
  for (let i: i32 = position; i < len; i++) {
85
- if (_this[i] == searchElement) return true;
85
+ if (_this[i] === searchElement) return true;
86
86
  }
87
87
 
88
88
  return false;
@@ -171,12 +171,13 @@ export const __Array_prototype_filter = (_this: any[], callbackFn: any) => {
171
171
  };
172
172
 
173
173
  export const __Array_prototype_map = (_this: any[], callbackFn: any) => {
174
+ const len: i32 = _this.length;
174
175
  const out: any[] = [];
176
+ out.length = len;
175
177
 
176
- const len: i32 = _this.length;
177
178
  let i: i32 = 0;
178
179
  while (i < len) {
179
- out.push(callbackFn(_this[i], i++, _this));
180
+ out[i] = callbackFn(_this[i], i++, _this);
180
181
  }
181
182
 
182
183
  return out;
@@ -222,4 +223,92 @@ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
222
223
  }
223
224
 
224
225
  return true;
226
+ };
227
+
228
+ export const __Array_prototype_some = (_this: any[], callbackFn: any) => {
229
+ const len: i32 = _this.length;
230
+ let i: i32 = 0;
231
+ while (i < len) {
232
+ if (Boolean(callbackFn(_this[i], i++, _this))) return true;
233
+ }
234
+
235
+ return false;
236
+ };
237
+
238
+ export const __Array_prototype_reduce = (_this: any[], callbackFn: any, initialValue: any) => {
239
+ let acc: any = initialValue ?? _this[0];
240
+
241
+ const len: i32 = _this.length;
242
+ let i: i32 = 0;
243
+ while (i < len) {
244
+ acc = callbackFn(acc, _this[i], i++, _this);
245
+ }
246
+
247
+ return acc;
248
+ };
249
+
250
+ export const __Array_prototype_reduceRight = (_this: any[], callbackFn: any, initialValue: any) => {
251
+ const len: i32 = _this.length;
252
+ let acc: any = initialValue ?? _this[len - 1];
253
+
254
+ let i: i32 = len;
255
+ while (i > 0) {
256
+ acc = callbackFn(acc, _this[--i], i, _this);
257
+ }
258
+
259
+ return acc;
260
+ };
261
+
262
+ export const __Array_prototype_toString = (_this: any[]) => {
263
+ // todo: this is bytestring only!
264
+
265
+ let out: bytestring = '';
266
+ out.length = 0;
267
+
268
+ const len: i32 = _this.length;
269
+ let i: i32 = 0;
270
+ while (i < len) {
271
+ if (i > 0) Porffor.bytestring.appendChar(out, 44);
272
+
273
+ const element: any = _this[i++];
274
+ const type: i32 = Porffor.rawType(element);
275
+ if (element != 0 || Porffor.fastAnd(
276
+ type != Porffor.TYPES.undefined, // undefined
277
+ type != Porffor.TYPES.object // null
278
+ )) {
279
+ Porffor.bytestring.appendStr(out, ecma262.ToString(element));
280
+ }
281
+ }
282
+
283
+ return out;
284
+ };
285
+
286
+ export const __Array_prototype_join = (_this: any[], _separator: any) => {
287
+ // todo: this is bytestring only!
288
+ // todo/perf: optimize single char separators
289
+ // todo/perf: optimize default separator (?)
290
+
291
+ let separator: bytestring = ',';
292
+ if (Porffor.rawType(_separator) != Porffor.TYPES.undefined)
293
+ separator = ecma262.ToString(_separator);
294
+
295
+ let out: bytestring = '';
296
+ out.length = 0;
297
+
298
+ const len: i32 = _this.length;
299
+ let i: i32 = 0;
300
+ while (i < len) {
301
+ if (i > 0) Porffor.bytestring.appendStr(out, separator);
302
+
303
+ const element: any = _this[i++];
304
+ const type: i32 = Porffor.rawType(element);
305
+ if (element != 0 || Porffor.fastAnd(
306
+ type != Porffor.TYPES.undefined, // undefined
307
+ type != Porffor.TYPES.object // null
308
+ )) {
309
+ Porffor.bytestring.appendStr(out, ecma262.ToString(element));
310
+ }
311
+ }
312
+
313
+ return out;
225
314
  };
@@ -2,17 +2,18 @@
2
2
  import type {} from './porffor.d.ts';
3
3
 
4
4
  export const btoa = (input: bytestring): bytestring => {
5
+ // todo: throw on invalid chars
6
+
5
7
  const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
6
8
  const keyStrPtr: i32 = Porffor.wasm`local.get ${keyStr}`;
7
9
 
8
10
  let len: i32 = input.length;
9
11
  let output: bytestring = '';
10
- output.length = 4 * (len / 3 + !!(len % 3));
11
12
 
12
13
  let i: i32 = Porffor.wasm`local.get ${input}`,
13
14
  j: i32 = Porffor.wasm`local.get ${output}`;
14
15
 
15
- // todo/perf: add some per 6 char variant using bitwise magic
16
+ // todo/perf: add some per 6 char variant using bitwise magic?
16
17
 
17
18
  const endPtr = i + len;
18
19
  while (i < endPtr) {
@@ -38,40 +39,43 @@ export const btoa = (input: bytestring): bytestring => {
38
39
  Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc4, 0, 4), 0, 4);
39
40
  }
40
41
 
42
+ output.length = j - Porffor.wasm`local.get ${output}`;
41
43
  return output;
42
44
  };
43
45
 
44
- // todo: impl atob by converting below to "porf ts"
45
- /* var atob = function (input) {
46
- const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
46
+ export const atob = (input: bytestring): bytestring => {
47
+ // todo: throw on non-base64 chars
48
+
49
+ const lut: bytestring = '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>@@@?456789:;<=@@@@@@@\x00\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0B\f\r\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19@@@@@@\x1A\x1B\x1C\x1D\x1E\x1F !"#$%&\'()*+,-./0123';
50
+ const lutPtr: i32 = Porffor.wasm`local.get ${lut}`;
51
+
52
+ let output: bytestring = '';
47
53
 
48
- let output = "";
49
- let chr1, chr2, chr3;
50
- let enc1, enc2, enc3, enc4;
51
- let i = 0;
54
+ let i: i32 = Porffor.wasm`local.get ${input}`,
55
+ j: i32 = Porffor.wasm`local.get ${output}`;
52
56
 
53
- while (i < input.length) {
54
- enc1 = keyStr.indexOf(input.charAt(i++));
55
- enc2 = keyStr.indexOf(input.charAt(i++));
56
- enc3 = keyStr.indexOf(input.charAt(i++));
57
- enc4 = keyStr.indexOf(input.charAt(i++));
57
+ const endPtr = i + input.length;
58
+ while (i < endPtr) {
59
+ const enc1: i32 = Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4);
60
+ const enc2: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
61
+ const enc3: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
62
+ const enc4: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(lutPtr + Porffor.wasm.i32.load8_u(i++, 0, 4), 0, 4) : -1;
58
63
 
59
- chr1 = (enc1 << 2) | (enc2 >> 4);
60
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
61
- chr3 = ((enc3 & 3) << 6) | enc4;
64
+ const chr1: i32 = (enc1 << 2) | (enc2 == -1 ? 0 : (enc2 >> 4));
65
+ const chr2: i32 = ((enc2 & 15) << 4) | (enc3 == -1 ? 0 : (enc3 >> 2));
66
+ const chr3: i32 = ((enc3 & 3) << 6) | (enc4 == -1 ? 0 : enc4);
62
67
 
63
- // output += String.fromCharCode(chr1);
64
- Porffor.bytestring.appendCharCode(output, chr1);
68
+ Porffor.wasm.i32.store8(j++, chr1, 0, 4);
65
69
 
66
70
  if (enc3 != 64) {
67
- // output += String.fromCharCode(chr2);
68
- Porffor.bytestring.appendCharCode(output, chr2);
71
+ Porffor.wasm.i32.store8(j++, chr2, 0, 4);
69
72
  }
73
+
70
74
  if (enc4 != 64) {
71
- // output += String.fromCharCode(chr3);
72
- Porffor.bytestring.appendCharCode(output, chr3);
75
+ Porffor.wasm.i32.store8(j++, chr3, 0, 4);
73
76
  }
74
77
  }
75
78
 
79
+ output.length = j - Porffor.wasm`local.get ${output}`;
76
80
  return output;
77
- }; */
81
+ };
@@ -253,29 +253,6 @@ export const __ecma262_UTC = (t: number): number => {
253
253
  return t;
254
254
  };
255
255
 
256
-
257
- // todo: move this somewhere generic?
258
- // 7.1.5 ToIntegerOrInfinity (argument)
259
- // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tointegerorinfinity
260
- export const __ecma262_ToIntegerOrInfinity = (argument: unknown): number => {
261
- // 1. Let number be ? ToNumber(argument).
262
- let number: number = Number(argument);
263
-
264
- // 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0.
265
- if (Number.isNaN(number)) return 0;
266
-
267
- // 3. If number is +∞𝔽, return +∞.
268
- // 4. If number is -∞𝔽, return -∞.
269
- if (!Number.isFinite(number)) return number;
270
-
271
- // 5. Return truncate(ℝ(number)).
272
- number = Math.trunc(number);
273
-
274
- // return 0 for -0
275
- if (number == 0) return 0;
276
- return number;
277
- };
278
-
279
256
  // 21.4.1.27 MakeTime (hour, min, sec, ms)
280
257
  // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-maketime
281
258
  export const __ecma262_MakeTime = (hour: number, min: number, sec: number, ms: number): number => {
@@ -722,12 +699,9 @@ export const __Porffor_date_allocate = (): Date => {
722
699
  const hack: bytestring = '';
723
700
 
724
701
  if (hack.length == 0) {
725
- hack.length = Porffor.wasm`i32.const 1
726
- memory.grow 0
727
- drop
728
- memory.size 0
702
+ hack.length = Porffor.wasm`
729
703
  i32.const 1
730
- i32.sub
704
+ memory.grow 0
731
705
  i32.const 65536
732
706
  i32.mul
733
707
  i32.from_u`;
@@ -1894,8 +1868,7 @@ export const __ecma262_ToDateString = (tv: number) => {
1894
1868
 
1895
1869
  // 1. If tv is NaN, return "Invalid Date".
1896
1870
  if (Number.isNaN(tv)) {
1897
- out = 'Invalid Date';
1898
- return out;
1871
+ return out = 'Invalid Date';
1899
1872
  }
1900
1873
 
1901
1874
  // 2. Let t be LocalTime(tv).
@@ -16,7 +16,7 @@ export const __Math_exp = (x: number): number => {
16
16
  return 1 / Math.exp(-x);
17
17
  }
18
18
 
19
- const k: number = Math.floor(x / Math.LN2);
19
+ let k: number = Math.floor(x / Math.LN2);
20
20
  const r: number = x - k * Math.LN2;
21
21
 
22
22
  // Taylor series via Horner's method
@@ -30,7 +30,11 @@ export const __Math_exp = (x: number): number => {
30
30
  i++;
31
31
  }
32
32
 
33
- return sum * (1 << k);
33
+ while (k-- > 0) {
34
+ sum *= 2;
35
+ }
36
+
37
+ return sum;
34
38
  };
35
39
 
36
40
  export const __Math_log2 = (y: number): number => {
@@ -6,11 +6,9 @@ export const __Number_prototype_toString = (_this: number, radix: number|any) =>
6
6
  let outPtr: i32 = Porffor.wasm`local.get ${out}`;
7
7
 
8
8
  if (!Number.isFinite(_this)) {
9
- if (Number.isNaN(_this)) out = 'NaN';
10
- else if (_this == Infinity) out = 'Infinity';
11
- else out = '-Infinity';
12
-
13
- return out;
9
+ if (Number.isNaN(_this)) return out = 'NaN';
10
+ if (_this == Infinity) return out = 'Infinity';
11
+ return out = '-Infinity';
14
12
  }
15
13
 
16
14
  if (Porffor.rawType(radix) != Porffor.TYPES.number) {
@@ -24,8 +22,7 @@ export const __Number_prototype_toString = (_this: number, radix: number|any) =>
24
22
  }
25
23
 
26
24
  if (_this == 0) {
27
- out = '0';
28
- return out;
25
+ return out = '0';
29
26
  }
30
27
 
31
28
  // if negative value
@@ -99,7 +96,6 @@ export const __Number_prototype_toString = (_this: number, radix: number|any) =>
99
96
  }
100
97
 
101
98
  out.length = outPtr - Porffor.wasm`local.get ${out}`;
102
-
103
99
  return out;
104
100
  }
105
101
 
@@ -235,7 +231,6 @@ export const __Number_prototype_toString = (_this: number, radix: number|any) =>
235
231
  }
236
232
 
237
233
  out.length = outPtr - Porffor.wasm`local.get ${out}`;
238
-
239
234
  return out;
240
235
  };
241
236
 
@@ -244,11 +239,9 @@ export const __Number_prototype_toFixed = (_this: number, fractionDigits: number
244
239
  let outPtr: i32 = Porffor.wasm`local.get ${out}`;
245
240
 
246
241
  if (!Number.isFinite(_this)) {
247
- if (Number.isNaN(_this)) out = 'NaN';
248
- else if (_this == Infinity) out = 'Infinity';
249
- else out = '-Infinity';
250
-
251
- return out;
242
+ if (Number.isNaN(_this)) return out = 'NaN';
243
+ if (_this == Infinity) return out = 'Infinity';
244
+ return out = '-Infinity';
252
245
  }
253
246
 
254
247
  fractionDigits |= 0;
@@ -324,7 +317,6 @@ export const __Number_prototype_toFixed = (_this: number, fractionDigits: number
324
317
  }
325
318
 
326
319
  out.length = outPtr - Porffor.wasm`local.get ${out}`;
327
-
328
320
  return out;
329
321
  };
330
322
 
@@ -334,11 +326,9 @@ export const __Number_prototype_toExponential = (_this: number, fractionDigits:
334
326
  let outPtr: i32 = Porffor.wasm`local.get ${out}`;
335
327
 
336
328
  if (!Number.isFinite(_this)) {
337
- if (Number.isNaN(_this)) out = 'NaN';
338
- else if (_this == Infinity) out = 'Infinity';
339
- else out = '-Infinity';
340
-
341
- return out;
329
+ if (Number.isNaN(_this)) return out = 'NaN';
330
+ if (_this == Infinity) return out = 'Infinity';
331
+ return out = '-Infinity';
342
332
  }
343
333
 
344
334
  if (Porffor.rawType(fractionDigits) != Porffor.TYPES.number) {
@@ -519,7 +509,6 @@ export const __Number_prototype_toExponential = (_this: number, fractionDigits:
519
509
  }
520
510
 
521
511
  out.length = outPtr - Porffor.wasm`local.get ${out}`;
522
-
523
512
  return out;
524
513
  };
525
514
 
@@ -28,6 +28,13 @@ type PorfforGlobal = {
28
28
  write(_this: any, index: number, value: any): boolean;
29
29
  }
30
30
 
31
+ bytestring: {
32
+ // defined in date.ts
33
+ appendStr(str: bytestring, appendage: bytestring): i32;
34
+ appendChar(str: bytestring, char: i32): i32;
35
+ appendPadNum(str: bytestring, num: number, len: number): i32;
36
+ }
37
+
31
38
  print(x: any): i32;
32
39
 
33
40
  randomByte(): i32;
@@ -56,6 +63,9 @@ type PorfforGlobal = {
56
63
 
57
64
  s(...args: any): string;
58
65
  bs(...args: any): bytestring;
66
+
67
+ readArgv(index: i32, out: bytestring): i32;
68
+ readFile(path: bytestring, out: bytestring): i32;
59
69
  };
60
70
 
61
71
  declare global {
@@ -2,12 +2,9 @@ import type {} from './porffor.d.ts';
2
2
 
3
3
  // dark wasm magic for dealing with memory, sorry.
4
4
  export const __Porffor_allocate = (): number => {
5
- Porffor.wasm`i32.const 1
6
- memory.grow 0
7
- drop
8
- memory.size 0
5
+ Porffor.wasm`
9
6
  i32.const 1
10
- i32.sub
7
+ memory.grow 0
11
8
  i32.const 65536
12
9
  i32.mul
13
10
  i32.from_u
@@ -173,15 +170,8 @@ export const Set = () => {
173
170
  export const Set$constructor = (iterable: any): Set => {
174
171
  const out: Set = __Porffor_allocate();
175
172
 
176
- const type: number = Porffor.rawType(iterable);
177
- if (Porffor.fastOr(
178
- type == Porffor.TYPES.array,
179
- type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
180
- type == Porffor.TYPES.set
181
- )) {
182
- for (const x of iterable) {
183
- __Set_prototype_add(out, x);
184
- }
173
+ if (Porffor.rawType(iterable) != Porffor.TYPES.undefined) for (const x of iterable) {
174
+ __Set_prototype_add(out, x);
185
175
  }
186
176
 
187
177
  return out;
@@ -198,3 +188,8 @@ export const __Set_prototype_union = (_this: Set, other: any) => {
198
188
  }
199
189
  return out;
200
190
  };
191
+
192
+ export const __Set_prototype_toString = (_this: Set) => {
193
+ const out: bytestring = '[object Set]';
194
+ return out;
195
+ };
@@ -0,0 +1,10 @@
1
+ // todo: support non-bytestring properly
2
+ export const String = (value: any): bytestring => {
3
+ if (Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
4
+ return __ecma262_ToString(value);
5
+ };
6
+
7
+ // todo: support constructor/string objects properly
8
+ export const String$constructor = (value: any): bytestring => {
9
+ return __ecma262_ToString(value);
10
+ };
@@ -0,0 +1,42 @@
1
+ export default () => {
2
+ let out = '';
3
+
4
+ const constr = name => out += `export const ${name} = () => {
5
+ throw new TypeError("Constructor ${name} requires 'new'");
6
+ };
7
+
8
+ export const ${name}$constructor = (arg: any): ${name} => {
9
+ const out: ${name} = Porffor.allocate();
10
+ let len: i32 = 0;
11
+
12
+ const type: i32 = Porffor.rawType(arg);
13
+ if (Porffor.fastOr(
14
+ type == Porffor.TYPES.array,
15
+ type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
16
+ type == Porffor.TYPES.set
17
+ )) {
18
+ let i: i32 = 0;
19
+ for (const x of arg) {
20
+ out[i++] = x;
21
+ }
22
+ len = i;
23
+ } else if (type == Porffor.TYPES.number) {
24
+ len = arg;
25
+ }
26
+
27
+ out.length = len;
28
+ return out;
29
+ };`;
30
+
31
+ constr('Uint8Array');
32
+ constr('Int8Array');
33
+ constr('Uint8ClampedArray');
34
+ constr('Uint16Array');
35
+ constr('Int16Array');
36
+ constr('Uint32Array');
37
+ constr('Int32Array');
38
+ constr('Float32Array');
39
+ constr('Float64Array');
40
+
41
+ return out;
42
+ };
@@ -0,0 +1,62 @@
1
+ // general widely used ecma262/spec functions
2
+
3
+ // 7.1.5 ToIntegerOrInfinity (argument)
4
+ // https://tc39.es/ecma262/#sec-tointegerorinfinity
5
+ export const __ecma262_ToIntegerOrInfinity = (argument: unknown): number => {
6
+ // 1. Let number be ? ToNumber(argument).
7
+ let number: number = Number(argument);
8
+
9
+ // 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0.
10
+ if (Number.isNaN(number)) return 0;
11
+
12
+ // 3. If number is +∞𝔽, return +∞.
13
+ // 4. If number is -∞𝔽, return -∞.
14
+ if (!Number.isFinite(number)) return number;
15
+
16
+ // 5. Return truncate(ℝ(number)).
17
+ number = Math.trunc(number);
18
+
19
+ // return 0 for -0
20
+ if (number == 0) return 0;
21
+ return number;
22
+ };
23
+
24
+ // todo: support non-bytestring properly
25
+ // 7.1.17 ToString (argument)
26
+ // https://tc39.es/ecma262/#sec-tostring
27
+ export const __ecma262_ToString = (argument: unknown): bytestring => {
28
+ let out: bytestring = '';
29
+ const type: i32 = Porffor.rawType(argument);
30
+
31
+ // 1. If argument is a String, return argument.
32
+ if (Porffor.fastOr(
33
+ type == Porffor.TYPES.string,
34
+ type == Porffor.TYPES.bytestring)) return argument;
35
+
36
+ // 2. If argument is a Symbol, throw a TypeError exception.
37
+ if (type == Porffor.TYPES.symbol) throw new TypeError('Cannot convert a Symbol value to a string');
38
+
39
+ // 3. If argument is undefined, return "undefined".
40
+ if (type == Porffor.TYPES.undefined) return out = 'undefined';
41
+
42
+ // 4. If argument is null, return "null".
43
+ if (Porffor.fastAnd(
44
+ type == Porffor.TYPES.object,
45
+ argument == 0)) return out = 'null';
46
+
47
+ if (type == Porffor.TYPES.boolean) {
48
+ // 5. If argument is true, return "true".
49
+ if (argument == true) return out = 'true';
50
+
51
+ // 6. If argument is false, return "false".
52
+ return out = 'false';
53
+ }
54
+
55
+ // 7. If argument is a Number, return Number::toString(argument, 10).
56
+ // 8. If argument is a BigInt, return BigInt::toString(argument, 10).
57
+ // 9. Assert: argument is an Object.
58
+ // 10. Let primValue be ? ToPrimitive(argument, string).
59
+ // 11. Assert: primValue is not an Object.
60
+ // 12. Return ? ToString(primValue).
61
+ return argument.toString();
62
+ };