porffor 0.16.0-fe07da0f4 → 0.17.0-93ba20045

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.
@@ -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,70 @@ export const __Array_prototype_every = (_this: any[], callbackFn: any) => {
222
223
  }
223
224
 
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;
225
292
  };
@@ -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).
@@ -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
@@ -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,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
+ };
@@ -32,26 +32,26 @@ export const importedFuncs = [
32
32
  {
33
33
  name: 'profile1',
34
34
  import: 'y',
35
- params: 1,
35
+ params: [ Valtype.i32 ],
36
36
  returns: 0
37
37
  },
38
38
  {
39
39
  name: 'profile2',
40
40
  import: 'z',
41
- params: 1,
41
+ params: [ Valtype.i32 ],
42
42
  returns: 0
43
43
  },
44
44
  {
45
45
  name: '__Porffor_readArgv',
46
46
  import: 'w',
47
47
  params: 2,
48
- returns: 0
48
+ returns: 1
49
49
  },
50
50
  {
51
51
  name: '__Porffor_readFile',
52
52
  import: 'q',
53
53
  params: 2,
54
- returns: 0
54
+ returns: 1
55
55
  }
56
56
  ];
57
57
 
@@ -150,7 +150,7 @@ export const BuiltinVars = function() {
150
150
  this.Math = number(1);
151
151
 
152
152
  // wintercg(tm)
153
- this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.16.0`, false, '__navigator_userAgent');
153
+ this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.17.0`, false, '__navigator_userAgent');
154
154
  this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.bytestring : TYPES.string;
155
155
 
156
156
  for (const x in TYPES) {
@@ -167,6 +167,7 @@ export const BuiltinFuncs = function() {
167
167
  params: [ valtypeBinary, valtypeBinary ],
168
168
  locals: [],
169
169
  returns: [ valtypeBinary ],
170
+ returnType: TYPES.number,
170
171
  wasm: [ // x - truncf(x / y) * y
171
172
  [ Opcodes.local_get, 0 ], // x
172
173
 
@@ -189,6 +190,7 @@ export const BuiltinFuncs = function() {
189
190
  params: [ valtypeBinary, valtypeBinary ],
190
191
  locals: [],
191
192
  returns: [ valtypeBinary ],
193
+ returnType: TYPES.number,
192
194
  wasm: [
193
195
  [ Opcodes.local_get, 0 ],
194
196
  Opcodes.i32_to,
@@ -208,6 +210,7 @@ export const BuiltinFuncs = function() {
208
210
  params: [ valtypeBinary ],
209
211
  locals: [],
210
212
  returns: [ valtypeBinary ],
213
+ returnType: TYPES.number,
211
214
  wasm: [
212
215
  [ Opcodes.local_get, 0 ]
213
216
  ],
@@ -469,6 +472,7 @@ export const BuiltinFuncs = function() {
469
472
  params: [ valtypeBinary ],
470
473
  locals: [],
471
474
  returns: [ valtypeBinary ],
475
+ returnType: TYPES.number,
472
476
  wasm: [
473
477
  [ Opcodes.local_get, 0 ],
474
478
  [ Opcodes.f64_sqrt ]
@@ -480,6 +484,7 @@ export const BuiltinFuncs = function() {
480
484
  params: [ valtypeBinary ],
481
485
  locals: [],
482
486
  returns: [ valtypeBinary ],
487
+ returnType: TYPES.number,
483
488
  wasm: [
484
489
  [ Opcodes.local_get, 0 ],
485
490
  [ Opcodes.f64_abs ]
@@ -491,6 +496,7 @@ export const BuiltinFuncs = function() {
491
496
  params: [ valtypeBinary ],
492
497
  locals: [],
493
498
  returns: [ valtypeBinary ],
499
+ returnType: TYPES.number,
494
500
  wasm: [
495
501
  ...number(1),
496
502
  [ Opcodes.local_get, 0 ],
@@ -503,6 +509,7 @@ export const BuiltinFuncs = function() {
503
509
  params: [ valtypeBinary ],
504
510
  locals: [],
505
511
  returns: [ valtypeBinary ],
512
+ returnType: TYPES.number,
506
513
  wasm: [
507
514
  [ Opcodes.local_get, 0 ],
508
515
  [ Opcodes.f64_floor ]
@@ -514,6 +521,7 @@ export const BuiltinFuncs = function() {
514
521
  params: [ valtypeBinary ],
515
522
  locals: [],
516
523
  returns: [ valtypeBinary ],
524
+ returnType: TYPES.number,
517
525
  wasm: [
518
526
  [ Opcodes.local_get, 0 ],
519
527
  [ Opcodes.f64_ceil ]
@@ -525,6 +533,7 @@ export const BuiltinFuncs = function() {
525
533
  params: [ valtypeBinary ],
526
534
  locals: [],
527
535
  returns: [ valtypeBinary ],
536
+ returnType: TYPES.number,
528
537
  wasm: [
529
538
  [ Opcodes.local_get, 0 ],
530
539
  [ Opcodes.f64_nearest ]
@@ -536,6 +545,7 @@ export const BuiltinFuncs = function() {
536
545
  params: [ valtypeBinary ],
537
546
  locals: [],
538
547
  returns: [ valtypeBinary ],
548
+ returnType: TYPES.number,
539
549
  wasm: [
540
550
  [ Opcodes.local_get, 0 ],
541
551
  [ Opcodes.f64_trunc ]
@@ -547,6 +557,7 @@ export const BuiltinFuncs = function() {
547
557
  params: [ valtypeBinary ],
548
558
  locals: [],
549
559
  returns: [ valtypeBinary ],
560
+ returnType: TYPES.number,
550
561
  wasm: [
551
562
  [ Opcodes.local_get, 0 ],
552
563
  Opcodes.i32_trunc_sat_f64_u,
@@ -560,6 +571,7 @@ export const BuiltinFuncs = function() {
560
571
  params: [ valtypeBinary ],
561
572
  locals: [],
562
573
  returns: [ valtypeBinary ],
574
+ returnType: TYPES.number,
563
575
  wasm: [
564
576
  [ Opcodes.local_get, 0 ],
565
577
  [ Opcodes.f32_demote_f64 ],
@@ -573,6 +585,7 @@ export const BuiltinFuncs = function() {
573
585
  params: [ valtypeBinary, valtypeBinary ],
574
586
  locals: [],
575
587
  returns: [ valtypeBinary ],
588
+ returnType: TYPES.number,
576
589
  wasm: [
577
590
  [ Opcodes.local_get, 0 ],
578
591
  Opcodes.i32_trunc_sat_f64_s,
@@ -887,6 +900,7 @@ export const BuiltinFuncs = function() {
887
900
  globalNames: [ 'state0', 'state1' ],
888
901
  globalInits: [ prngSeed0, prngSeed1 ],
889
902
  returns: [ Valtype.f64 ],
903
+ returnType: TYPES.number,
890
904
  wasm: [
891
905
  ...prng.wasm,
892
906
 
@@ -938,6 +952,7 @@ export const BuiltinFuncs = function() {
938
952
  globalNames: [ 'state0', 'state1' ],
939
953
  globalInits: [ prngSeed0, prngSeed1 ],
940
954
  returns: [ Valtype.i32 ],
955
+ returnType: TYPES.number,
941
956
  wasm: [
942
957
  ...prng.wasm,
943
958
 
@@ -959,6 +974,7 @@ export const BuiltinFuncs = function() {
959
974
  params: [ valtypeBinary ],
960
975
  locals: [],
961
976
  returns: [ valtypeBinary ],
977
+ returnType: TYPES.number,
962
978
  wasm: [
963
979
  [ Opcodes.local_get, 0 ],
964
980
  ...number(Math.PI / 180),
@@ -971,6 +987,7 @@ export const BuiltinFuncs = function() {
971
987
  params: [ valtypeBinary ],
972
988
  locals: [],
973
989
  returns: [ valtypeBinary ],
990
+ returnType: TYPES.number,
974
991
  wasm: [
975
992
  [ Opcodes.local_get, 0 ],
976
993
  ...number(180 / Math.PI),
@@ -984,6 +1001,7 @@ export const BuiltinFuncs = function() {
984
1001
  locals: [],
985
1002
  localNames: [ 'x', 'lower', 'upper' ],
986
1003
  returns: [ valtypeBinary ],
1004
+ returnType: TYPES.number,
987
1005
  wasm: [
988
1006
  [ Opcodes.local_get, 0 ],
989
1007
  [ Opcodes.local_get, 1 ],
@@ -999,9 +1017,9 @@ export const BuiltinFuncs = function() {
999
1017
  locals: [],
1000
1018
  localNames: [ 'x', 'inLow', 'inHigh', 'outLow', 'outHigh' ],
1001
1019
  returns: [ valtypeBinary ],
1020
+ returnType: TYPES.number,
1002
1021
  wasm: [
1003
1022
  // (x − inLow) * (outHigh − outLow) / (inHigh - inLow) + outLow
1004
-
1005
1023
  [ Opcodes.local_get, 0 ],
1006
1024
  [ Opcodes.local_get, 1 ],
1007
1025
  [ Opcodes.f64_sub ],
@@ -1043,6 +1061,7 @@ export const BuiltinFuncs = function() {
1043
1061
  params: [],
1044
1062
  locals: [],
1045
1063
  returns: [ valtypeBinary ],
1064
+ returnType: TYPES.number,
1046
1065
  wasm: [
1047
1066
  [ Opcodes.call, importedFuncs.time ]
1048
1067
  ]
@@ -1070,6 +1089,7 @@ export const BuiltinFuncs = function() {
1070
1089
  typedParams: true,
1071
1090
  locals: [],
1072
1091
  returns: [ valtypeBinary ],
1092
+ returnType: TYPES.number,
1073
1093
  wasm: [
1074
1094
  [ Opcodes.local_get, 1 ],
1075
1095
  Opcodes.i32_from_u