porffor 0.2.0-fde989a → 0.14.0-032e4ad08

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 (64) hide show
  1. package/CONTRIBUTING.md +262 -0
  2. package/LICENSE +20 -20
  3. package/README.md +135 -94
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +216 -0
  7. package/compiler/2c.js +66 -54
  8. package/compiler/{sections.js → assemble.js} +109 -21
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +19 -0
  11. package/compiler/builtins/array.ts +225 -0
  12. package/compiler/builtins/base64.ts +77 -0
  13. package/compiler/builtins/boolean.ts +20 -0
  14. package/compiler/builtins/crypto.ts +121 -0
  15. package/compiler/builtins/date.ts +2069 -0
  16. package/compiler/builtins/error.js +22 -0
  17. package/compiler/builtins/escape.ts +140 -0
  18. package/compiler/builtins/function.ts +7 -0
  19. package/compiler/builtins/int.ts +147 -0
  20. package/compiler/builtins/math.ts +410 -0
  21. package/compiler/builtins/number.ts +531 -0
  22. package/compiler/builtins/object.ts +6 -0
  23. package/compiler/builtins/porffor.d.ts +60 -0
  24. package/compiler/builtins/set.ts +199 -0
  25. package/compiler/builtins/string.ts +1081 -0
  26. package/compiler/builtins/symbol.ts +62 -0
  27. package/compiler/builtins.js +466 -284
  28. package/compiler/{codeGen.js → codegen.js} +1573 -656
  29. package/compiler/decompile.js +3 -4
  30. package/compiler/embedding.js +22 -22
  31. package/compiler/encoding.js +94 -10
  32. package/compiler/expression.js +1 -1
  33. package/compiler/generated_builtins.js +2110 -0
  34. package/compiler/index.js +29 -44
  35. package/compiler/log.js +6 -3
  36. package/compiler/opt.js +55 -41
  37. package/compiler/parse.js +38 -30
  38. package/compiler/precompile.js +121 -0
  39. package/compiler/prefs.js +31 -0
  40. package/compiler/prototype.js +209 -201
  41. package/compiler/types.js +38 -0
  42. package/compiler/wasmSpec.js +33 -8
  43. package/compiler/wrap.js +154 -89
  44. package/package.json +9 -5
  45. package/porf +2 -0
  46. package/porffor_tmp.c +202 -0
  47. package/rhemyn/compile.js +46 -27
  48. package/rhemyn/parse.js +322 -320
  49. package/rhemyn/test/parse.js +58 -58
  50. package/runner/compare.js +33 -34
  51. package/runner/debug.js +117 -0
  52. package/runner/index.js +80 -12
  53. package/runner/profiler.js +75 -0
  54. package/runner/repl.js +58 -15
  55. package/runner/sizes.js +37 -37
  56. package/runner/version.js +10 -8
  57. package/compiler/builtins/base64.js +0 -92
  58. package/filesize.cmd +0 -2
  59. package/runner/info.js +0 -89
  60. package/runner/profile.js +0 -46
  61. package/runner/results.json +0 -1
  62. package/runner/transform.js +0 -15
  63. package/tmp.c +0 -661
  64. package/util/enum.js +0 -20
@@ -1,5 +1,8 @@
1
- import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
2
- import { number, i32x4 } from "./embedding.js";
1
+ import * as GeneratedBuiltins from './generated_builtins.js';
2
+ import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
3
+ import { number } from './embedding.js';
4
+ import { TYPES } from './types.js';
5
+ import Prefs from './prefs.js';
3
6
 
4
7
  export const importedFuncs = [
5
8
  {
@@ -19,6 +22,36 @@ export const importedFuncs = [
19
22
  import: 't',
20
23
  params: 0,
21
24
  returns: 1
25
+ },
26
+ {
27
+ name: 'timeOrigin',
28
+ import: 'u',
29
+ params: 0,
30
+ returns: 1
31
+ },
32
+ {
33
+ name: 'profile1',
34
+ import: 'y',
35
+ params: 1,
36
+ returns: 0
37
+ },
38
+ {
39
+ name: 'profile2',
40
+ import: 'z',
41
+ params: 1,
42
+ returns: 0
43
+ },
44
+ {
45
+ name: '__Porffor_readArgv',
46
+ import: 'w',
47
+ params: 2,
48
+ returns: 0
49
+ },
50
+ {
51
+ name: '__Porffor_readFile',
52
+ import: 'q',
53
+ params: 2,
54
+ returns: 0
22
55
  }
23
56
  ];
24
57
 
@@ -27,8 +60,6 @@ for (let i = 0; i < importedFuncs.length; i++) {
27
60
  importedFuncs[f.name] = i;
28
61
  }
29
62
 
30
- const char = c => number(c.charCodeAt(0));
31
-
32
63
  const printStaticStr = str => {
33
64
  const out = [];
34
65
 
@@ -50,10 +81,10 @@ export const NULL = 0;
50
81
 
51
82
  export const BuiltinVars = function() {
52
83
  this.undefined = number(UNDEFINED);
53
- this.undefined.type = 'undefined';
84
+ this.undefined.type = TYPES.undefined;
54
85
 
55
86
  this.null = number(NULL);
56
- this.null.type = 'object';
87
+ this.null.type = TYPES.object;
57
88
 
58
89
  this.NaN = number(NaN);
59
90
  this.NaN.floatOnly = true;
@@ -117,6 +148,18 @@ export const BuiltinVars = function() {
117
148
 
118
149
  // stubs just so that parent objects exist
119
150
  this.Math = number(1);
151
+
152
+ // wintercg(tm)
153
+ this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.14.0`, false, '__navigator_userAgent');
154
+ this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.bytestring : TYPES.string;
155
+
156
+ for (const x in TYPES) {
157
+ this['__Porffor_TYPES_' + x] = number(TYPES[x]);
158
+ }
159
+
160
+ this.__performance_timeOrigin = [
161
+ [ Opcodes.call, importedFuncs.timeOrigin ]
162
+ ];
120
163
  };
121
164
 
122
165
  export const BuiltinFuncs = function() {
@@ -167,7 +210,8 @@ export const BuiltinFuncs = function() {
167
210
  returns: [ valtypeBinary ],
168
211
  wasm: [
169
212
  [ Opcodes.local_get, 0 ]
170
- ]
213
+ ],
214
+ constr: true
171
215
  };
172
216
 
173
217
  // just return given (default 0) for (new) Object() as we somewhat supports object just not constructor
@@ -175,19 +219,21 @@ export const BuiltinFuncs = function() {
175
219
  params: [ valtypeBinary ],
176
220
  locals: [],
177
221
  returns: [ valtypeBinary ],
178
- returnType: 'object',
222
+ returnType: TYPES.object,
179
223
  wasm: [
180
- [ Opcodes.local_get, 0 ]
181
- ]
224
+ // [ Opcodes.local_get, 0 ]
225
+ ...number(1)
226
+ ],
227
+ constr: true
182
228
  };
183
229
 
184
230
 
185
- this.__console_log = {
231
+ this.__Porffor_print = {
186
232
  params: [ valtypeBinary, Valtype.i32 ],
187
233
  typedParams: true,
188
234
  locals: [ Valtype.i32, Valtype.i32 ],
189
235
  returns: [],
190
- wasm: (scope, { TYPES, typeSwitch }) => [
236
+ wasm: (scope, { typeSwitch, builtin }) => [
191
237
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
192
238
  [TYPES.number]: [
193
239
  [ Opcodes.local_get, 0 ],
@@ -239,7 +285,41 @@ export const BuiltinFuncs = function() {
239
285
 
240
286
  [ Opcodes.end ]
241
287
  ],
242
- [TYPES._array]: [
288
+ [TYPES.bytestring]: [
289
+ // simply print a (byte)string :))
290
+ // cache input pointer as i32
291
+ [ Opcodes.local_get, 0 ],
292
+ Opcodes.i32_to_u,
293
+ [ Opcodes.local_tee, 2 ],
294
+
295
+ // make end pointer
296
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
297
+ [ Opcodes.local_get, 2 ],
298
+ [ Opcodes.i32_add ],
299
+ [ Opcodes.local_set, 3 ],
300
+
301
+ [ Opcodes.loop, Blocktype.void ],
302
+
303
+ // print current char
304
+ [ Opcodes.local_get, 2 ],
305
+ [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
306
+ Opcodes.i32_from_u,
307
+ [ Opcodes.call, importedFuncs.printChar ],
308
+
309
+ // increment pointer
310
+ [ Opcodes.local_get, 2 ],
311
+ [ Opcodes.i32_const, 1 ],
312
+ [ Opcodes.i32_add ],
313
+ [ Opcodes.local_tee, 2 ],
314
+
315
+ // if pointer != end pointer, loop
316
+ [ Opcodes.local_get, 3 ],
317
+ [ Opcodes.i32_ne ],
318
+ [ Opcodes.br_if, 0 ],
319
+
320
+ [ Opcodes.end ]
321
+ ],
322
+ [TYPES.array]: [
243
323
  ...printStaticStr('[ '),
244
324
 
245
325
  // cache input pointer as i32
@@ -249,7 +329,7 @@ export const BuiltinFuncs = function() {
249
329
 
250
330
  // make end pointer
251
331
  [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
252
- ...number(ValtypeSize[valtype], Valtype.i32),
332
+ ...number(ValtypeSize[valtype] + 1, Valtype.i32),
253
333
  [ Opcodes.i32_mul ],
254
334
 
255
335
  [ Opcodes.local_get, 2 ],
@@ -258,14 +338,18 @@ export const BuiltinFuncs = function() {
258
338
 
259
339
  [ Opcodes.loop, Blocktype.void ],
260
340
 
261
- // print current char
341
+ // print current array element
262
342
  [ Opcodes.local_get, 2 ],
263
- [ Opcodes.load, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
264
- [ Opcodes.call, importedFuncs.print ],
343
+ [ Opcodes.load, 0, ValtypeSize.i32 ],
344
+
345
+ [ Opcodes.local_get, 2 ],
346
+ [ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
347
+
348
+ [ Opcodes.call, builtin('__Porffor_print') ],
265
349
 
266
350
  // increment pointer by sizeof valtype
267
351
  [ Opcodes.local_get, 2 ],
268
- ...number(ValtypeSize[valtype], Valtype.i32),
352
+ ...number(ValtypeSize[valtype] + 1, Valtype.i32),
269
353
  [ Opcodes.i32_add ],
270
354
  [ Opcodes.local_tee, 2 ],
271
355
 
@@ -300,10 +384,7 @@ export const BuiltinFuncs = function() {
300
384
  [ Opcodes.local_get, 0 ],
301
385
  [ Opcodes.call, importedFuncs.print ],
302
386
  ]
303
- }, Blocktype.void),
304
-
305
- ...char('\n'),
306
- [ Opcodes.call, importedFuncs.printChar ]
387
+ }, Blocktype.void)
307
388
  ]
308
389
  };
309
390
 
@@ -315,7 +396,7 @@ export const BuiltinFuncs = function() {
315
396
  params: [ valtypeBinary ],
316
397
  locals: [],
317
398
  returns: [ valtypeBinary ],
318
- returnType: 'boolean',
399
+ returnType: TYPES.boolean,
319
400
  wasm: [
320
401
  [ Opcodes.local_get, 0 ],
321
402
  [ Opcodes.local_get, 0 ],
@@ -330,7 +411,7 @@ export const BuiltinFuncs = function() {
330
411
  params: [ valtypeBinary ],
331
412
  locals: [ valtypeBinary ],
332
413
  returns: [ valtypeBinary ],
333
- returnType: 'boolean',
414
+ returnType: TYPES.boolean,
334
415
  wasm: [
335
416
  [ Opcodes.local_get, 0 ],
336
417
  [ Opcodes.local_get, 0 ],
@@ -349,7 +430,7 @@ export const BuiltinFuncs = function() {
349
430
  params: [ valtypeBinary ],
350
431
  locals: [],
351
432
  returns: [ valtypeBinary ],
352
- returnType: 'boolean',
433
+ returnType: TYPES.boolean,
353
434
  wasm: [
354
435
  [ Opcodes.local_get, 0 ],
355
436
  [ Opcodes.local_get, 0 ],
@@ -364,7 +445,7 @@ export const BuiltinFuncs = function() {
364
445
  params: [ valtypeBinary ],
365
446
  locals: [],
366
447
  returns: [ valtypeBinary ],
367
- returnType: 'boolean',
448
+ returnType: TYPES.boolean,
368
449
  wasm: [
369
450
  [ Opcodes.local_get, 0 ],
370
451
  [ Opcodes.local_get, 0 ],
@@ -504,61 +585,313 @@ export const BuiltinFuncs = function() {
504
585
 
505
586
  // this is an implementation of xorshift128+ (in wasm bytecode)
506
587
  // fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
507
- const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
588
+ const prngSeed0 = (Math.random() * (2 ** 30)) | 0, prngSeed1 = (Math.random() * (2 ** 30)) | 0;
589
+
590
+ const prng = ({
591
+ 'lcg32_glibc': {
592
+ globals: [ Valtype.i32 ],
593
+ locals: [],
594
+ returns: Valtype.i32,
595
+ wasm: [
596
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
597
+ // MULTIPLIER * state0
598
+ [ Opcodes.global_get, 0 ],
599
+ ...number(1103515245, Valtype.i32),
600
+ [ Opcodes.i32_mul ],
601
+
602
+ // + INCREMENT
603
+ ...number(12345, Valtype.i32),
604
+ [ Opcodes.i32_add ],
605
+
606
+ // % MODULUS
607
+ ...number(2 ** 31, Valtype.i32),
608
+ [ Opcodes.i32_rem_s ],
609
+
610
+ // state0 =
611
+ [ Opcodes.global_set, 0 ],
612
+
613
+ // state0
614
+ [ Opcodes.global_get, 0 ],
615
+ ],
616
+ },
617
+ 'lcg32_minstd': {
618
+ globals: [ Valtype.i32 ],
619
+ locals: [],
620
+ returns: Valtype.i32,
621
+ wasm: [
622
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
623
+ // MULTIPLIER * state0
624
+ [ Opcodes.global_get, 0 ],
625
+ ...number(48271, Valtype.i32),
626
+ [ Opcodes.i32_mul ],
627
+
628
+ // % MODULUS
629
+ ...number((2 ** 31) - 1, Valtype.i32),
630
+ [ Opcodes.i32_rem_s ],
631
+
632
+ // state0 =
633
+ [ Opcodes.global_set, 0 ],
634
+
635
+ // state0
636
+ [ Opcodes.global_get, 0 ],
637
+ ],
638
+ },
639
+ 'lcg64_musl': 0, // todo
640
+
641
+ 'xorshift32+': {
642
+ globals: [ Valtype.i32 ],
643
+ locals: [ Valtype.i32 ],
644
+ returns: Valtype.i32,
645
+ wasm: [
646
+ // setup: s1 = state0
647
+ [ Opcodes.global_get, 0 ], // state0
648
+ [ Opcodes.local_tee, 0 ], // s1
649
+
650
+ // s1 ^= s1 << 13
651
+ [ Opcodes.local_get, 0 ], // s1
652
+ [ Opcodes.i32_const, 13 ],
653
+ [ Opcodes.i32_shl ], // <<
654
+ [ Opcodes.i32_xor ], // ^
655
+ [ Opcodes.local_tee, 0 ], // s1
656
+
657
+ // s1 ^= s1 >> 17
658
+ [ Opcodes.local_get, 0 ], // s1
659
+ [ Opcodes.i32_const, 17 ],
660
+ [ Opcodes.i32_shr_s ], // >>
661
+ [ Opcodes.i32_xor ], // ^
662
+ [ Opcodes.local_tee, 0 ], // s1
663
+
664
+ // s1 ^= s1 << 5
665
+ [ Opcodes.local_get, 0 ], // s1
666
+ [ Opcodes.i32_const, 5 ],
667
+ [ Opcodes.i32_shl ], // <<
668
+ [ Opcodes.i32_xor ], // ^
669
+ [ Opcodes.local_tee, 0 ], // s1
670
+
671
+ // state0 = s1
672
+ [ Opcodes.global_set, 0 ],
673
+
674
+ // s1
675
+ [ Opcodes.local_get, 0 ],
676
+ ],
677
+ },
678
+
679
+ 'xorshift64+': {
680
+ globals: [ Valtype.i64 ],
681
+ locals: [ Valtype.i64 ],
682
+ returns: Valtype.i64,
683
+ wasm: [
684
+ // setup: s1 = state0
685
+ [ Opcodes.global_get, 0 ], // state0
686
+ [ Opcodes.local_tee, 0 ], // s1
687
+
688
+ // s1 ^= s1 >> 12
689
+ [ Opcodes.local_get, 0 ], // s1
690
+ [ Opcodes.i64_const, 12 ],
691
+ [ Opcodes.i64_shr_s ], // >>
692
+ [ Opcodes.i64_xor ], // ^
693
+ [ Opcodes.local_tee, 0 ], // s1
694
+
695
+ // s1 ^= s1 << 25
696
+ [ Opcodes.local_get, 0 ], // s1
697
+ [ Opcodes.i64_const, 25 ],
698
+ [ Opcodes.i64_shl ], // <<
699
+ [ Opcodes.i64_xor ], // ^
700
+ [ Opcodes.local_tee, 0 ], // s1
701
+
702
+ // s1 ^= s1 >> 27
703
+ [ Opcodes.local_get, 0 ], // s1
704
+ [ Opcodes.i64_const, 27 ],
705
+ [ Opcodes.i64_shr_s ], // >>
706
+ [ Opcodes.i64_xor ], // ^
707
+ [ Opcodes.local_tee, 0 ], // s1
708
+
709
+ // state0 = s1
710
+ [ Opcodes.global_set, 0 ],
711
+
712
+ // // s1 * 0x2545F4914F6CDD1D
713
+ // [ Opcodes.local_get, 0 ],
714
+ // [ Opcodes.i64_const, 0x9d, 0xba, 0xb3, 0xfb, 0x94, 0x92, 0xfd, 0xa2, 0x25 ],
715
+ // [ Opcodes.i64_mul ]
716
+
717
+ // s1
718
+ [ Opcodes.local_get, 0 ],
719
+ ],
720
+ },
721
+
722
+ 'xorshift128+': {
723
+ globals: [ Valtype.i64, Valtype.i64 ],
724
+ locals: [ Valtype.i64, Valtype.i64 ],
725
+ returns: Valtype.i64,
726
+ wasm: [
727
+ // setup: s1 = state0, s0 = state1, state0 = s0
728
+ [ Opcodes.global_get, 0 ], // state0
729
+ [ Opcodes.local_tee, 0 ], // s1
730
+ [ Opcodes.global_get, 1 ], // state1
731
+ [ Opcodes.local_tee, 1, ], // s0
732
+ [ Opcodes.global_set, 0 ], // state0
733
+
734
+ // s1 ^= s1 << 23
735
+ // [ Opcodes.local_get, 0 ], // s1
736
+ [ Opcodes.local_get, 0 ], // s1
737
+ [ Opcodes.i64_const, 23 ],
738
+ [ Opcodes.i64_shl ], // <<
739
+ [ Opcodes.i64_xor ], // ^
740
+ [ Opcodes.local_set, 0 ], // s1
741
+
742
+ // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
743
+ // s1 ^ s0
744
+ [ Opcodes.local_get, 0 ], // s1
745
+ [ Opcodes.local_get, 1 ], // s0
746
+ [ Opcodes.i64_xor ], // ^
747
+
748
+ // ^ (s1 >> 17)
749
+ [ Opcodes.local_get, 0 ], // s1
750
+ [ Opcodes.i64_const, 17 ],
751
+ [ Opcodes.i64_shr_u ], // >>
752
+ [ Opcodes.i64_xor ], // ^
753
+
754
+ // ^ (s0 >> 26)
755
+ [ Opcodes.local_get, 1 ], // s0
756
+ [ Opcodes.i64_const, 26 ],
757
+ [ Opcodes.i64_shr_u ], // >>
758
+ [ Opcodes.i64_xor ], // ^
759
+
760
+ // state1 =
761
+ [ Opcodes.global_set, 1 ],
762
+
763
+ // state1 + s0
764
+ [ Opcodes.global_get, 1 ], // state1
765
+ [ Opcodes.local_get, 1 ], // s0
766
+ [ Opcodes.i64_add ]
767
+ ]
768
+ },
769
+
770
+ 'xoroshiro128+': {
771
+ globals: [ Valtype.i64, Valtype.i64 ],
772
+ locals: [ Valtype.i64, Valtype.i64, Valtype.i64 ],
773
+ returns: Valtype.i64,
774
+ wasm: [
775
+ // setup: s1 = state1, s0 = state0
776
+ [ Opcodes.global_get, 1 ], // state0
777
+ [ Opcodes.local_tee, 0 ], // s1
778
+ [ Opcodes.global_get, 0 ], // state1
779
+ [ Opcodes.local_tee, 1, ], // s0
780
+
781
+ // result = s0 + s1
782
+ [ Opcodes.i64_add ],
783
+ [ Opcodes.local_set, 2 ], // result
784
+
785
+ // s1 ^= s0
786
+ [ Opcodes.local_get, 0 ], // s1
787
+ [ Opcodes.local_get, 1 ], // s0
788
+ [ Opcodes.i64_xor ],
789
+ [ Opcodes.local_set, 0 ], // s1
790
+
791
+ // state0 = rotl(s0, 24) ^ s1 ^ (s1 << 16)
792
+
793
+ // rotl(s0, 24) ^ s1
794
+ [ Opcodes.local_get, 1 ], // s0
795
+ ...number(24, Valtype.i64),
796
+ [ Opcodes.i64_rotl ],
797
+ [ Opcodes.local_get, 0 ], // s1
798
+ [ Opcodes.i64_xor ],
799
+
800
+ // ^ (s1 << 16)
801
+ [ Opcodes.local_get, 0 ], // s1
802
+ ...number(16, Valtype.i64),
803
+ [ Opcodes.i64_shl ],
804
+ [ Opcodes.i64_xor ],
805
+
806
+ // state0 =
807
+ [ Opcodes.global_set, 0 ], // state0
808
+
809
+ // state1 = rotl(s1, 37)
810
+ [ Opcodes.local_get, 0 ], // s1
811
+ ...number(37, Valtype.i64),
812
+ [ Opcodes.i64_rotl ],
813
+ [ Opcodes.global_set, 1 ], // state1
814
+
815
+ // result
816
+ [ Opcodes.local_get, 2 ],
817
+ ]
818
+ },
819
+
820
+ 'xoshiro128+': {
821
+ globals: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
822
+ locals: [ Valtype.i32, Valtype.i32 ],
823
+ returns: Valtype.i32,
824
+ wasm: [
825
+ // result = state0 + state3
826
+ [ Opcodes.global_get, 0 ], // state0
827
+ [ Opcodes.global_get, 3 ], // state0
828
+ [ Opcodes.i32_add ],
829
+ [ Opcodes.local_set, 0 ], // result
830
+
831
+ // t = state1 << 9
832
+ [ Opcodes.global_get, 1 ], // state1
833
+ ...number(9, Valtype.i32),
834
+ [ Opcodes.i32_shl ],
835
+ [ Opcodes.local_set, 1 ], // t
836
+
837
+ // state2 ^= state0
838
+ [ Opcodes.global_get, 2 ], // state2
839
+ [ Opcodes.global_get, 0 ], // state0
840
+ [ Opcodes.i32_xor ],
841
+ [ Opcodes.global_set, 2 ], // state2
842
+
843
+ // state3 ^= state1
844
+ [ Opcodes.global_get, 3 ], // state3
845
+ [ Opcodes.global_get, 1 ], // state1
846
+ [ Opcodes.i32_xor ],
847
+ [ Opcodes.global_set, 3 ], // state3
848
+
849
+ // state1 ^= state2
850
+ [ Opcodes.global_get, 1 ], // state1
851
+ [ Opcodes.global_get, 2 ], // state2
852
+ [ Opcodes.i32_xor ],
853
+ [ Opcodes.global_set, 1 ], // state1
854
+
855
+ // state0 ^= state3
856
+ [ Opcodes.global_get, 0 ], // state2
857
+ [ Opcodes.global_get, 3 ], // state0
858
+ [ Opcodes.i32_xor ],
859
+ [ Opcodes.global_set, 0 ], // state2
860
+
861
+ // state2 ^= t
862
+ [ Opcodes.global_get, 2 ], // state2
863
+ [ Opcodes.local_get, 1 ], // t
864
+ [ Opcodes.i32_xor ],
865
+ [ Opcodes.global_set, 2 ], // state2
866
+
867
+ // state3 = rotl(state3, 11)
868
+ [ Opcodes.global_get, 3 ], // state3
869
+ ...number(11, Valtype.i32),
870
+ [ Opcodes.i32_rotl ],
871
+ [ Opcodes.global_set, 3 ], // state3
872
+
873
+ // result
874
+ [ Opcodes.local_get, 0 ],
875
+ ]
876
+ }
877
+ })[Prefs.prng ?? 'xorshift128+'];
878
+
879
+ if (!prng) throw new Error(`unknown prng algo: ${Prefs.prng}`);
508
880
 
509
881
  this.__Math_random = {
510
882
  floatOnly: true,
511
883
  params: [],
512
- locals: [ Valtype.i64, Valtype.i64 ],
884
+ locals: prng.locals,
513
885
  localNames: [ 's1', 's0' ],
514
- globals: [ Valtype.i64, Valtype.i64 ],
886
+ globals: prng.globals,
515
887
  globalNames: [ 'state0', 'state1' ],
516
888
  globalInits: [ prngSeed0, prngSeed1 ],
517
889
  returns: [ Valtype.f64 ],
518
890
  wasm: [
519
- // setup: s1 = state0, s0 = state1, state0 = s0
520
- [ Opcodes.global_get, 0 ], // state0
521
- [ Opcodes.local_tee, 0 ], // s1
522
- [ Opcodes.global_get, 1 ], // state1
523
- [ Opcodes.local_tee, 1, ], // s0
524
- [ Opcodes.global_set, 0 ], // state0
525
-
526
- // s1 ^= s1 << 23
527
- // [ Opcodes.local_get, 0 ], // s1
528
- [ Opcodes.local_get, 0 ], // s1
529
- [ Opcodes.i64_const, 23 ],
530
- [ Opcodes.i64_shl ], // <<
531
- [ Opcodes.i64_xor ], // ^
532
- [ Opcodes.local_set, 0 ], // s1
533
-
534
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
535
- // s1 ^ s0
536
- [ Opcodes.local_get, 0 ], // s1
537
- [ Opcodes.local_get, 1 ], // s0
538
- [ Opcodes.i64_xor ], // ^
539
-
540
- // ^ (s1 >> 17)
541
- [ Opcodes.local_get, 0 ], // s1
542
- [ Opcodes.i64_const, 17 ],
543
- [ Opcodes.i64_shr_u ], // >>
544
- [ Opcodes.i64_xor ], // ^
545
-
546
- // ^ (s0 >> 26)
547
- [ Opcodes.local_get, 1 ], // s0
548
- [ Opcodes.i64_const, 26 ],
549
- [ Opcodes.i64_shr_u ], // >>
550
- [ Opcodes.i64_xor ], // ^
551
-
552
- // state1 =
553
- [ Opcodes.global_set, 1 ],
891
+ ...prng.wasm,
554
892
 
555
893
  // you thought it was over? now we need the result as a f64 between 0-1 :)
556
894
 
557
- // state1 + s0
558
- [ Opcodes.global_get, 1 ], // state1
559
- [ Opcodes.local_get, 1 ], // s0
560
- [ Opcodes.i64_add ],
561
-
562
895
  // should we >> 12 here?
563
896
  // it feels like it but it breaks values
564
897
 
@@ -573,15 +906,51 @@ export const BuiltinFuncs = function() {
573
906
  // ...number(1),
574
907
  // [ Opcodes.f64_sub ],
575
908
 
576
- ...number((1 << 53) - 1, Valtype.i64),
577
- [ Opcodes.i64_and ],
909
+ ...(prng.returns === Valtype.i64 ? [
910
+ ...number((1 << 53) - 1, Valtype.i64),
911
+ [ Opcodes.i64_and ],
912
+
913
+ // double(mantissa)
914
+ [ Opcodes.f64_convert_i64_u ],
915
+
916
+ // / (1 << 53)
917
+ ...number(1 << 53),
918
+ [ Opcodes.f64_div ]
919
+ ] : [
920
+ ...number((1 << 21) - 1, Valtype.i32),
921
+ [ Opcodes.i32_and ],
922
+
923
+ // double(mantissa)
924
+ [ Opcodes.f64_convert_i32_u ],
925
+
926
+ // / (1 << 21)
927
+ ...number(1 << 21),
928
+ [ Opcodes.f64_div ]
929
+ ])
930
+ ]
931
+ };
932
+
933
+ this.__Porffor_randomByte = {
934
+ params: [],
935
+ locals: prng.locals,
936
+ localNames: [ 's1', 's0' ],
937
+ globals: prng.globals,
938
+ globalNames: [ 'state0', 'state1' ],
939
+ globalInits: [ prngSeed0, prngSeed1 ],
940
+ returns: [ Valtype.i32 ],
941
+ wasm: [
942
+ ...prng.wasm,
943
+
944
+ ...(prng.returns === Valtype.i64 ? [
945
+ // the lowest bits of the output generated by xorshift128+ have low quality
946
+ ...number(56, Valtype.i64),
947
+ [ Opcodes.i64_shr_u ],
578
948
 
579
- // double(mantissa)
580
- [ Opcodes.f64_convert_i64_u ],
949
+ [ Opcodes.i32_wrap_i64 ],
950
+ ] : []),
581
951
 
582
- // / (1 << 53)
583
- ...number(1 << 53),
584
- [ Opcodes.f64_div ]
952
+ ...number(0xff, Valtype.i32),
953
+ [ Opcodes.i32_and ],
585
954
  ]
586
955
  };
587
956
 
@@ -660,7 +1029,7 @@ export const BuiltinFuncs = function() {
660
1029
  params: [ valtypeBinary ],
661
1030
  locals: [],
662
1031
  returns: [ valtypeBinary ],
663
- returnType: 'boolean',
1032
+ returnType: TYPES.boolean,
664
1033
  wasm: [
665
1034
  [ Opcodes.local_get, 0 ],
666
1035
  ...number(0),
@@ -685,7 +1054,7 @@ export const BuiltinFuncs = function() {
685
1054
  typedParams: true,
686
1055
  locals: [ Valtype.i32, Valtype.i32 ],
687
1056
  returns: [ valtypeBinary ],
688
- returnType: process.argv.includes('-bytestring') ? '_bytestring' : 'string',
1057
+ returnType: Prefs.bytestring ? TYPES.bytestring : TYPES.string,
689
1058
  wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
690
1059
  const bc = {};
691
1060
  for (const x in TYPE_NAMES) {
@@ -696,233 +1065,46 @@ export const BuiltinFuncs = function() {
696
1065
  }
697
1066
  };
698
1067
 
699
- const localIsOneOf = (getter, arr, valtype = valtypeBinary) => {
700
- const out = [];
701
-
702
- for (let i = 0; i < arr.length; i++) {
703
- out.push(...getter, ...number(arr[i], valtype), valtype === Valtype.f64 ? [ Opcodes.f64_eq ] : [ Opcodes.i32_eq ]);
704
- if (i !== 0) out.push([ Opcodes.i32_or ]);
705
- }
706
-
707
- return out;
708
- };
709
-
710
- this.__Porffor_pointer = {
1068
+ this.__Porffor_rawType = {
711
1069
  params: [ valtypeBinary, Valtype.i32 ],
712
1070
  typedParams: true,
713
- locals: [ Valtype.i32, Valtype.i32 ],
714
- returns: [ valtypeBinary ],
715
- wasm: (scope, { TYPES }) => [
716
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
717
- [ Opcodes.if, valtypeBinary ],
718
- [ Opcodes.local_get, 0 ],
719
- [ Opcodes.else ],
720
- ...number(NaN),
721
- [ Opcodes.end ]
722
- ]
723
- };
724
-
725
-
726
- this.__SIMD_i32x4_load = {
727
- params: [ Valtype.i32 ],
728
- locals: [],
729
- returns: [ Valtype.v128 ],
730
- wasm: [
731
- [ Opcodes.local_get, 0 ],
732
- [ ...Opcodes.v128_load, 0, 0 ]
733
- ]
734
- };
735
-
736
- this.__SIMD_i32x4_splat = {
737
- params: [ Valtype.i32 ],
738
- locals: [],
739
- returns: [ Valtype.v128 ],
740
- wasm: [
741
- [ Opcodes.local_get, 0 ],
742
- [ ...Opcodes.i32x4_splat ],
743
- ]
744
- };
745
-
746
- this.__SIMD_i16x8_create = {
747
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
748
- locals: [],
749
- returns: [ Valtype.v128 ],
750
- wasm: [
751
- ...i32x4(0, 0, 0, 0),
752
- [ Opcodes.local_get, 0 ],
753
- [ ...Opcodes.i16x8_replace_lane, 0 ],
754
- [ Opcodes.local_get, 1 ],
755
- [ ...Opcodes.i16x8_replace_lane, 1 ],
756
- [ Opcodes.local_get, 2 ],
757
- [ ...Opcodes.i16x8_replace_lane, 2 ],
758
- [ Opcodes.local_get, 3 ],
759
- [ ...Opcodes.i16x8_replace_lane, 3 ],
760
- [ Opcodes.local_get, 4 ],
761
- [ ...Opcodes.i16x8_replace_lane, 4 ],
762
- [ Opcodes.local_get, 5 ],
763
- [ ...Opcodes.i16x8_replace_lane, 5 ],
764
- [ Opcodes.local_get, 6 ],
765
- [ ...Opcodes.i16x8_replace_lane, 6 ],
766
- [ Opcodes.local_get, 7 ],
767
- [ ...Opcodes.i16x8_replace_lane, 7 ],
768
- ]
769
- };
770
-
771
- this.__SIMD_i32x4_dot_i16x8 = {
772
- params: [ Valtype.v128, Valtype.v128 ],
773
1071
  locals: [],
774
- returns: [ Valtype.v128 ],
775
- wasm: [
776
- [ Opcodes.local_get, 0 ],
777
- [ Opcodes.local_get, 1 ],
778
- [ ...Opcodes.i32x4_dot_i16x8_s ]
779
- ]
780
- };
781
-
782
- this.__SIMD_i32x4_create = {
783
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
784
- locals: [],
785
- returns: [ Valtype.v128 ],
1072
+ returns: [ valtypeBinary ],
786
1073
  wasm: [
787
- ...i32x4(0, 0, 0, 0),
788
- [ Opcodes.local_get, 0 ],
789
- [ ...Opcodes.i32x4_replace_lane, 0 ],
790
1074
  [ Opcodes.local_get, 1 ],
791
- [ ...Opcodes.i32x4_replace_lane, 1 ],
792
- [ Opcodes.local_get, 2 ],
793
- [ ...Opcodes.i32x4_replace_lane, 2 ],
794
- [ Opcodes.local_get, 3 ],
795
- [ ...Opcodes.i32x4_replace_lane, 3 ],
1075
+ Opcodes.i32_from_u
796
1076
  ]
797
1077
  };
798
1078
 
799
- this.__SIMD_i32x4_add = {
800
- params: [ Valtype.v128, Valtype.v128 ],
1079
+ this.__Porffor_clone = {
1080
+ params: [ valtypeBinary, valtypeBinary ],
801
1081
  locals: [],
802
- returns: [ Valtype.v128 ],
1082
+ returns: [],
803
1083
  wasm: [
804
- [ Opcodes.local_get, 0 ],
1084
+ // dst
805
1085
  [ Opcodes.local_get, 1 ],
806
- [ ...Opcodes.i32x4_add ]
807
- ]
808
- };
1086
+ Opcodes.i32_to_u,
809
1087
 
810
- this.__SIMD_i32x4_sub = {
811
- params: [ Valtype.v128, Valtype.v128 ],
812
- locals: [],
813
- returns: [ Valtype.v128 ],
814
- wasm: [
1088
+ // src
815
1089
  [ Opcodes.local_get, 0 ],
816
- [ Opcodes.local_get, 1 ],
817
- [ ...Opcodes.i32x4_sub ]
818
- ]
819
- };
1090
+ Opcodes.i32_to_u,
820
1091
 
821
- this.__SIMD_i32x4_mul = {
822
- params: [ Valtype.v128, Valtype.v128 ],
823
- locals: [],
824
- returns: [ Valtype.v128 ],
825
- wasm: [
826
- [ Opcodes.local_get, 0 ],
827
- [ Opcodes.local_get, 1 ],
828
- [ ...Opcodes.i32x4_mul ]
1092
+ // size = pageSize
1093
+ ...number(pageSize, Valtype.i32),
1094
+ [ ...Opcodes.memory_copy, 0x00, 0x00 ],
829
1095
  ]
830
1096
  };
831
1097
 
832
- this.__SIMD_i32x4_get0 = {
833
- params: [ Valtype.v128 ],
834
- locals: [],
835
- returns: [ Valtype.i32 ],
836
- wasm: [
837
- [ Opcodes.local_get, 0 ],
838
- [ ...Opcodes.i32x4_extract_lane, 0 ],
839
- ],
840
- },
841
-
842
- this.__SIMD_i32x4_get1 = {
843
- params: [ Valtype.v128 ],
844
- locals: [],
845
- returns: [ Valtype.i32 ],
846
- wasm: [
847
- [ Opcodes.local_get, 0 ],
848
- [ ...Opcodes.i32x4_extract_lane, 1 ],
849
- ],
850
- };
851
-
852
- this.__SIMD_i32x4_get2 = {
853
- params: [ Valtype.v128 ],
854
- locals: [],
855
- returns: [ Valtype.i32 ],
856
- wasm: [
857
- [ Opcodes.local_get, 0 ],
858
- [ ...Opcodes.i32x4_extract_lane, 2 ],
859
- ],
860
- };
861
-
862
- this.__SIMD_i32x4_get3 = {
863
- params: [ Valtype.v128 ],
864
- locals: [],
865
- returns: [ Valtype.i32 ],
866
- wasm: [
867
- [ Opcodes.local_get, 0 ],
868
- [ ...Opcodes.i32x4_extract_lane, 3 ],
869
- ],
870
- };
871
1098
 
872
- this.__SIMD_i32x4_shuffle_000c = {
873
- params: [ Valtype.v128 ],
874
- locals: [],
875
- returns: [ Valtype.v128 ],
876
- wasm: [
877
- [ Opcodes.local_get, 0 ],
878
- ...i32x4(0, 0, 0, 0),
879
- [ ...Opcodes.i8x16_shuffle, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 9, 10, 11 ], // i32x4 (a, b, c, d) -> i32x4 (0, 0, 0, c)
880
- ]
881
- };
882
-
883
- this.__SIMD_i32x4_shuffle_00ab = {
884
- params: [ Valtype.v128 ],
1099
+ this.__fs_readFileSync = {
1100
+ params: [ valtypeBinary, valtypeBinary ],
885
1101
  locals: [],
886
- returns: [ Valtype.v128 ],
1102
+ returns: [ valtypeBinary ],
1103
+ returnType: TYPES.bytestring,
887
1104
  wasm: [
888
- [ Opcodes.local_get, 0 ],
889
- ...i32x4(0, 0, 0, 0),
890
- [ ...Opcodes.i8x16_shuffle, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7 ], // i32x4 (a, b, c, d) -> i32x4 (0, 0, a, b)
1105
+ [ Opcodes.call, importedFuncs.__Porffor_readFile ],
891
1106
  ]
892
1107
  };
893
- };
894
-
895
- export const BuiltinPreludes = {
896
- btoa: `var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
897
- var btoa = function (input) {
898
- // todo: throw invalid character for unicode
899
-
900
- let output = "";
901
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
902
- let i = 0;
903
-
904
- while (i < input.length) {
905
- chr1 = input.charCodeAt(i++);
906
- chr2 = input.charCodeAt(i++);
907
- chr3 = input.charCodeAt(i++);
908
-
909
- enc1 = chr1 >> 2;
910
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
911
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
912
- enc4 = chr3 & 63;
913
-
914
- if (isNaN(chr2)) {
915
- enc3 = enc4 = 64;
916
- } else if (isNaN(chr3)) {
917
- enc4 = 64;
918
- }
919
-
920
- output += keyStr.charAt(enc1);
921
- output += keyStr.charAt(enc2);
922
- output += keyStr.charAt(enc3);
923
- output += keyStr.charAt(enc4);
924
- }
925
1108
 
926
- return output;
927
- };`
1109
+ GeneratedBuiltins.BuiltinFuncs.call(this);
928
1110
  };