porffor 0.2.0-6aff0fa → 0.2.0-6bc63ef

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 (54) hide show
  1. package/CONTRIBUTING.md +256 -0
  2. package/LICENSE +20 -20
  3. package/README.md +115 -82
  4. package/asur/index.js +624 -340
  5. package/byg/index.js +216 -0
  6. package/compiler/2c.js +2 -53
  7. package/compiler/{sections.js → assemble.js} +60 -14
  8. package/compiler/builtins/annexb_string.js +72 -0
  9. package/compiler/builtins/annexb_string.ts +18 -0
  10. package/compiler/builtins/array.ts +145 -0
  11. package/compiler/builtins/base64.ts +7 -84
  12. package/compiler/builtins/boolean.ts +18 -0
  13. package/compiler/builtins/crypto.ts +120 -0
  14. package/compiler/builtins/date.ts +2067 -0
  15. package/compiler/builtins/escape.ts +141 -0
  16. package/compiler/builtins/function.ts +5 -0
  17. package/compiler/builtins/int.ts +145 -0
  18. package/compiler/builtins/number.ts +529 -0
  19. package/compiler/builtins/object.ts +4 -0
  20. package/compiler/builtins/porffor.d.ts +44 -7
  21. package/compiler/builtins/set.ts +187 -0
  22. package/compiler/builtins/string.ts +1080 -0
  23. package/compiler/builtins.js +400 -120
  24. package/compiler/{codeGen.js → codegen.js} +850 -402
  25. package/compiler/decompile.js +2 -3
  26. package/compiler/embedding.js +22 -22
  27. package/compiler/encoding.js +94 -10
  28. package/compiler/expression.js +1 -1
  29. package/compiler/generated_builtins.js +1613 -3
  30. package/compiler/index.js +16 -16
  31. package/compiler/log.js +2 -2
  32. package/compiler/opt.js +28 -27
  33. package/compiler/parse.js +36 -30
  34. package/compiler/precompile.js +37 -46
  35. package/compiler/prefs.js +7 -6
  36. package/compiler/prototype.js +20 -36
  37. package/compiler/types.js +38 -0
  38. package/compiler/wasmSpec.js +14 -1
  39. package/compiler/wrap.js +79 -69
  40. package/package.json +9 -5
  41. package/porf +2 -0
  42. package/rhemyn/compile.js +44 -26
  43. package/rhemyn/parse.js +322 -320
  44. package/rhemyn/test/parse.js +58 -58
  45. package/runner/compare.js +33 -34
  46. package/runner/debug.js +117 -0
  47. package/runner/index.js +69 -12
  48. package/runner/profiler.js +22 -30
  49. package/runner/repl.js +40 -13
  50. package/runner/sizes.js +37 -37
  51. package/runner/version.js +3 -3
  52. package/runner/info.js +0 -89
  53. package/runner/transform.js +0 -15
  54. package/util/enum.js +0 -20
@@ -1,7 +1,8 @@
1
- import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
2
- import { number, i32x4 } from "./embedding.js";
3
- import Prefs from './prefs.js';
4
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';
5
6
 
6
7
  export const importedFuncs = [
7
8
  {
@@ -23,20 +24,30 @@ export const importedFuncs = [
23
24
  returns: 1
24
25
  },
25
26
  {
26
- name: 'profile',
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',
27
40
  import: 'z',
28
41
  params: 1,
29
42
  returns: 0
30
43
  }
31
- ].filter(x => x);
44
+ ];
32
45
 
33
46
  for (let i = 0; i < importedFuncs.length; i++) {
34
47
  const f = importedFuncs[i];
35
48
  importedFuncs[f.name] = i;
36
49
  }
37
50
 
38
- const char = c => number(c.charCodeAt(0));
39
-
40
51
  const printStaticStr = str => {
41
52
  const out = [];
42
53
 
@@ -58,10 +69,10 @@ export const NULL = 0;
58
69
 
59
70
  export const BuiltinVars = function() {
60
71
  this.undefined = number(UNDEFINED);
61
- this.undefined.type = 'undefined';
72
+ this.undefined.type = TYPES.undefined;
62
73
 
63
74
  this.null = number(NULL);
64
- this.null.type = 'object';
75
+ this.null.type = TYPES.object;
65
76
 
66
77
  this.NaN = number(NaN);
67
78
  this.NaN.floatOnly = true;
@@ -128,7 +139,15 @@ export const BuiltinVars = function() {
128
139
 
129
140
  // wintercg(tm)
130
141
  this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.2.0`, false, '__navigator_userAgent');
131
- this.__navigator_userAgent.type = Prefs.bytestring ? '_bytestring' : 'string';
142
+ this.__navigator_userAgent.type = Prefs.bytestring ? TYPES.bytestring : TYPES.string;
143
+
144
+ for (const x in TYPES) {
145
+ this['__Porffor_TYPES_' + x] = number(TYPES[x]);
146
+ }
147
+
148
+ this.__performance_timeOrigin = [
149
+ [ Opcodes.call, importedFuncs.timeOrigin ]
150
+ ];
132
151
  };
133
152
 
134
153
  export const BuiltinFuncs = function() {
@@ -187,19 +206,20 @@ export const BuiltinFuncs = function() {
187
206
  params: [ valtypeBinary ],
188
207
  locals: [],
189
208
  returns: [ valtypeBinary ],
190
- returnType: 'object',
209
+ returnType: TYPES.object,
191
210
  wasm: [
192
- [ Opcodes.local_get, 0 ]
211
+ // [ Opcodes.local_get, 0 ]
212
+ ...number(1)
193
213
  ]
194
214
  };
195
215
 
196
216
 
197
- this.__console_log = {
217
+ this.__Porffor_print = {
198
218
  params: [ valtypeBinary, Valtype.i32 ],
199
219
  typedParams: true,
200
220
  locals: [ Valtype.i32, Valtype.i32 ],
201
221
  returns: [],
202
- wasm: (scope, { TYPES, typeSwitch }) => [
222
+ wasm: (scope, { typeSwitch }) => [
203
223
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
204
224
  [TYPES.number]: [
205
225
  [ Opcodes.local_get, 0 ],
@@ -251,7 +271,7 @@ export const BuiltinFuncs = function() {
251
271
 
252
272
  [ Opcodes.end ]
253
273
  ],
254
- [TYPES._bytestring]: [
274
+ [TYPES.bytestring]: [
255
275
  // simply print a (byte)string :))
256
276
  // cache input pointer as i32
257
277
  [ Opcodes.local_get, 0 ],
@@ -285,7 +305,7 @@ export const BuiltinFuncs = function() {
285
305
 
286
306
  [ Opcodes.end ]
287
307
  ],
288
- [TYPES._array]: [
308
+ [TYPES.array]: [
289
309
  ...printStaticStr('[ '),
290
310
 
291
311
  // cache input pointer as i32
@@ -346,10 +366,7 @@ export const BuiltinFuncs = function() {
346
366
  [ Opcodes.local_get, 0 ],
347
367
  [ Opcodes.call, importedFuncs.print ],
348
368
  ]
349
- }, Blocktype.void),
350
-
351
- ...char('\n'),
352
- [ Opcodes.call, importedFuncs.printChar ]
369
+ }, Blocktype.void)
353
370
  ]
354
371
  };
355
372
 
@@ -361,7 +378,7 @@ export const BuiltinFuncs = function() {
361
378
  params: [ valtypeBinary ],
362
379
  locals: [],
363
380
  returns: [ valtypeBinary ],
364
- returnType: 'boolean',
381
+ returnType: TYPES.boolean,
365
382
  wasm: [
366
383
  [ Opcodes.local_get, 0 ],
367
384
  [ Opcodes.local_get, 0 ],
@@ -376,7 +393,7 @@ export const BuiltinFuncs = function() {
376
393
  params: [ valtypeBinary ],
377
394
  locals: [ valtypeBinary ],
378
395
  returns: [ valtypeBinary ],
379
- returnType: 'boolean',
396
+ returnType: TYPES.boolean,
380
397
  wasm: [
381
398
  [ Opcodes.local_get, 0 ],
382
399
  [ Opcodes.local_get, 0 ],
@@ -395,7 +412,7 @@ export const BuiltinFuncs = function() {
395
412
  params: [ valtypeBinary ],
396
413
  locals: [],
397
414
  returns: [ valtypeBinary ],
398
- returnType: 'boolean',
415
+ returnType: TYPES.boolean,
399
416
  wasm: [
400
417
  [ Opcodes.local_get, 0 ],
401
418
  [ Opcodes.local_get, 0 ],
@@ -410,7 +427,7 @@ export const BuiltinFuncs = function() {
410
427
  params: [ valtypeBinary ],
411
428
  locals: [],
412
429
  returns: [ valtypeBinary ],
413
- returnType: 'boolean',
430
+ returnType: TYPES.boolean,
414
431
  wasm: [
415
432
  [ Opcodes.local_get, 0 ],
416
433
  [ Opcodes.local_get, 0 ],
@@ -550,61 +567,313 @@ export const BuiltinFuncs = function() {
550
567
 
551
568
  // this is an implementation of xorshift128+ (in wasm bytecode)
552
569
  // fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
553
- const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
570
+ const prngSeed0 = (Math.random() * (2 ** 30)) | 0, prngSeed1 = (Math.random() * (2 ** 30)) | 0;
571
+
572
+ const prng = ({
573
+ 'lcg32_glibc': {
574
+ globals: [ Valtype.i32 ],
575
+ locals: [],
576
+ returns: Valtype.i32,
577
+ wasm: [
578
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
579
+ // MULTIPLIER * state0
580
+ [ Opcodes.global_get, 0 ],
581
+ ...number(1103515245, Valtype.i32),
582
+ [ Opcodes.i32_mul ],
583
+
584
+ // + INCREMENT
585
+ ...number(12345, Valtype.i32),
586
+ [ Opcodes.i32_add ],
587
+
588
+ // % MODULUS
589
+ ...number(2 ** 31, Valtype.i32),
590
+ [ Opcodes.i32_rem_s ],
591
+
592
+ // state0 =
593
+ [ Opcodes.global_set, 0 ],
594
+
595
+ // state0
596
+ [ Opcodes.global_get, 0 ],
597
+ ],
598
+ },
599
+ 'lcg32_minstd': {
600
+ globals: [ Valtype.i32 ],
601
+ locals: [],
602
+ returns: Valtype.i32,
603
+ wasm: [
604
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
605
+ // MULTIPLIER * state0
606
+ [ Opcodes.global_get, 0 ],
607
+ ...number(48271, Valtype.i32),
608
+ [ Opcodes.i32_mul ],
609
+
610
+ // % MODULUS
611
+ ...number((2 ** 31) - 1, Valtype.i32),
612
+ [ Opcodes.i32_rem_s ],
613
+
614
+ // state0 =
615
+ [ Opcodes.global_set, 0 ],
616
+
617
+ // state0
618
+ [ Opcodes.global_get, 0 ],
619
+ ],
620
+ },
621
+ 'lcg64_musl': 0, // todo
622
+
623
+ 'xorshift32+': {
624
+ globals: [ Valtype.i32 ],
625
+ locals: [ Valtype.i32 ],
626
+ returns: Valtype.i32,
627
+ wasm: [
628
+ // setup: s1 = state0
629
+ [ Opcodes.global_get, 0 ], // state0
630
+ [ Opcodes.local_tee, 0 ], // s1
631
+
632
+ // s1 ^= s1 << 13
633
+ [ Opcodes.local_get, 0 ], // s1
634
+ [ Opcodes.i32_const, 13 ],
635
+ [ Opcodes.i32_shl ], // <<
636
+ [ Opcodes.i32_xor ], // ^
637
+ [ Opcodes.local_tee, 0 ], // s1
638
+
639
+ // s1 ^= s1 >> 17
640
+ [ Opcodes.local_get, 0 ], // s1
641
+ [ Opcodes.i32_const, 17 ],
642
+ [ Opcodes.i32_shr_s ], // >>
643
+ [ Opcodes.i32_xor ], // ^
644
+ [ Opcodes.local_tee, 0 ], // s1
645
+
646
+ // s1 ^= s1 << 5
647
+ [ Opcodes.local_get, 0 ], // s1
648
+ [ Opcodes.i32_const, 5 ],
649
+ [ Opcodes.i32_shl ], // <<
650
+ [ Opcodes.i32_xor ], // ^
651
+ [ Opcodes.local_tee, 0 ], // s1
652
+
653
+ // state0 = s1
654
+ [ Opcodes.global_set, 0 ],
655
+
656
+ // s1
657
+ [ Opcodes.local_get, 0 ],
658
+ ],
659
+ },
660
+
661
+ 'xorshift64+': {
662
+ globals: [ Valtype.i64 ],
663
+ locals: [ Valtype.i64 ],
664
+ returns: Valtype.i64,
665
+ wasm: [
666
+ // setup: s1 = state0
667
+ [ Opcodes.global_get, 0 ], // state0
668
+ [ Opcodes.local_tee, 0 ], // s1
669
+
670
+ // s1 ^= s1 >> 12
671
+ [ Opcodes.local_get, 0 ], // s1
672
+ [ Opcodes.i64_const, 12 ],
673
+ [ Opcodes.i64_shr_s ], // >>
674
+ [ Opcodes.i64_xor ], // ^
675
+ [ Opcodes.local_tee, 0 ], // s1
676
+
677
+ // s1 ^= s1 << 25
678
+ [ Opcodes.local_get, 0 ], // s1
679
+ [ Opcodes.i64_const, 25 ],
680
+ [ Opcodes.i64_shl ], // <<
681
+ [ Opcodes.i64_xor ], // ^
682
+ [ Opcodes.local_tee, 0 ], // s1
683
+
684
+ // s1 ^= s1 >> 27
685
+ [ Opcodes.local_get, 0 ], // s1
686
+ [ Opcodes.i64_const, 27 ],
687
+ [ Opcodes.i64_shr_s ], // >>
688
+ [ Opcodes.i64_xor ], // ^
689
+ [ Opcodes.local_tee, 0 ], // s1
690
+
691
+ // state0 = s1
692
+ [ Opcodes.global_set, 0 ],
693
+
694
+ // // s1 * 0x2545F4914F6CDD1D
695
+ // [ Opcodes.local_get, 0 ],
696
+ // [ Opcodes.i64_const, 0x9d, 0xba, 0xb3, 0xfb, 0x94, 0x92, 0xfd, 0xa2, 0x25 ],
697
+ // [ Opcodes.i64_mul ]
698
+
699
+ // s1
700
+ [ Opcodes.local_get, 0 ],
701
+ ],
702
+ },
703
+
704
+ 'xorshift128+': {
705
+ globals: [ Valtype.i64, Valtype.i64 ],
706
+ locals: [ Valtype.i64, Valtype.i64 ],
707
+ returns: Valtype.i64,
708
+ wasm: [
709
+ // setup: s1 = state0, s0 = state1, state0 = s0
710
+ [ Opcodes.global_get, 0 ], // state0
711
+ [ Opcodes.local_tee, 0 ], // s1
712
+ [ Opcodes.global_get, 1 ], // state1
713
+ [ Opcodes.local_tee, 1, ], // s0
714
+ [ Opcodes.global_set, 0 ], // state0
715
+
716
+ // s1 ^= s1 << 23
717
+ // [ Opcodes.local_get, 0 ], // s1
718
+ [ Opcodes.local_get, 0 ], // s1
719
+ [ Opcodes.i64_const, 23 ],
720
+ [ Opcodes.i64_shl ], // <<
721
+ [ Opcodes.i64_xor ], // ^
722
+ [ Opcodes.local_set, 0 ], // s1
723
+
724
+ // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
725
+ // s1 ^ s0
726
+ [ Opcodes.local_get, 0 ], // s1
727
+ [ Opcodes.local_get, 1 ], // s0
728
+ [ Opcodes.i64_xor ], // ^
729
+
730
+ // ^ (s1 >> 17)
731
+ [ Opcodes.local_get, 0 ], // s1
732
+ [ Opcodes.i64_const, 17 ],
733
+ [ Opcodes.i64_shr_u ], // >>
734
+ [ Opcodes.i64_xor ], // ^
735
+
736
+ // ^ (s0 >> 26)
737
+ [ Opcodes.local_get, 1 ], // s0
738
+ [ Opcodes.i64_const, 26 ],
739
+ [ Opcodes.i64_shr_u ], // >>
740
+ [ Opcodes.i64_xor ], // ^
741
+
742
+ // state1 =
743
+ [ Opcodes.global_set, 1 ],
744
+
745
+ // state1 + s0
746
+ [ Opcodes.global_get, 1 ], // state1
747
+ [ Opcodes.local_get, 1 ], // s0
748
+ [ Opcodes.i64_add ]
749
+ ]
750
+ },
751
+
752
+ 'xoroshiro128+': {
753
+ globals: [ Valtype.i64, Valtype.i64 ],
754
+ locals: [ Valtype.i64, Valtype.i64, Valtype.i64 ],
755
+ returns: Valtype.i64,
756
+ wasm: [
757
+ // setup: s1 = state1, s0 = state0
758
+ [ Opcodes.global_get, 1 ], // state0
759
+ [ Opcodes.local_tee, 0 ], // s1
760
+ [ Opcodes.global_get, 0 ], // state1
761
+ [ Opcodes.local_tee, 1, ], // s0
762
+
763
+ // result = s0 + s1
764
+ [ Opcodes.i64_add ],
765
+ [ Opcodes.local_set, 2 ], // result
766
+
767
+ // s1 ^= s0
768
+ [ Opcodes.local_get, 0 ], // s1
769
+ [ Opcodes.local_get, 1 ], // s0
770
+ [ Opcodes.i64_xor ],
771
+ [ Opcodes.local_set, 0 ], // s1
772
+
773
+ // state0 = rotl(s0, 24) ^ s1 ^ (s1 << 16)
774
+
775
+ // rotl(s0, 24) ^ s1
776
+ [ Opcodes.local_get, 1 ], // s0
777
+ ...number(24, Valtype.i64),
778
+ [ Opcodes.i64_rotl ],
779
+ [ Opcodes.local_get, 0 ], // s1
780
+ [ Opcodes.i64_xor ],
781
+
782
+ // ^ (s1 << 16)
783
+ [ Opcodes.local_get, 0 ], // s1
784
+ ...number(16, Valtype.i64),
785
+ [ Opcodes.i64_shl ],
786
+ [ Opcodes.i64_xor ],
787
+
788
+ // state0 =
789
+ [ Opcodes.global_set, 0 ], // state0
790
+
791
+ // state1 = rotl(s1, 37)
792
+ [ Opcodes.local_get, 0 ], // s1
793
+ ...number(37, Valtype.i64),
794
+ [ Opcodes.i64_rotl ],
795
+ [ Opcodes.global_set, 1 ], // state1
796
+
797
+ // result
798
+ [ Opcodes.local_get, 2 ],
799
+ ]
800
+ },
801
+
802
+ 'xoshiro128+': {
803
+ globals: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
804
+ locals: [ Valtype.i32, Valtype.i32 ],
805
+ returns: Valtype.i32,
806
+ wasm: [
807
+ // result = state0 + state3
808
+ [ Opcodes.global_get, 0 ], // state0
809
+ [ Opcodes.global_get, 3 ], // state0
810
+ [ Opcodes.i32_add ],
811
+ [ Opcodes.local_set, 0 ], // result
812
+
813
+ // t = state1 << 9
814
+ [ Opcodes.global_get, 1 ], // state1
815
+ ...number(9, Valtype.i32),
816
+ [ Opcodes.i32_shl ],
817
+ [ Opcodes.local_set, 1 ], // t
818
+
819
+ // state2 ^= state0
820
+ [ Opcodes.global_get, 2 ], // state2
821
+ [ Opcodes.global_get, 0 ], // state0
822
+ [ Opcodes.i32_xor ],
823
+ [ Opcodes.global_set, 2 ], // state2
824
+
825
+ // state3 ^= state1
826
+ [ Opcodes.global_get, 3 ], // state3
827
+ [ Opcodes.global_get, 1 ], // state1
828
+ [ Opcodes.i32_xor ],
829
+ [ Opcodes.global_set, 3 ], // state3
830
+
831
+ // state1 ^= state2
832
+ [ Opcodes.global_get, 1 ], // state1
833
+ [ Opcodes.global_get, 2 ], // state2
834
+ [ Opcodes.i32_xor ],
835
+ [ Opcodes.global_set, 1 ], // state1
836
+
837
+ // state0 ^= state3
838
+ [ Opcodes.global_get, 0 ], // state2
839
+ [ Opcodes.global_get, 3 ], // state0
840
+ [ Opcodes.i32_xor ],
841
+ [ Opcodes.global_set, 0 ], // state2
842
+
843
+ // state2 ^= t
844
+ [ Opcodes.global_get, 2 ], // state2
845
+ [ Opcodes.local_get, 1 ], // t
846
+ [ Opcodes.i32_xor ],
847
+ [ Opcodes.global_set, 2 ], // state2
848
+
849
+ // state3 = rotl(state3, 11)
850
+ [ Opcodes.global_get, 3 ], // state3
851
+ ...number(11, Valtype.i32),
852
+ [ Opcodes.i32_rotl ],
853
+ [ Opcodes.global_set, 3 ], // state3
854
+
855
+ // result
856
+ [ Opcodes.local_get, 0 ],
857
+ ]
858
+ }
859
+ })[Prefs.prng ?? 'xorshift128+'];
860
+
861
+ if (!prng) throw new Error(`unknown prng algo: ${Prefs.prng}`);
554
862
 
555
863
  this.__Math_random = {
556
864
  floatOnly: true,
557
865
  params: [],
558
- locals: [ Valtype.i64, Valtype.i64 ],
866
+ locals: prng.locals,
559
867
  localNames: [ 's1', 's0' ],
560
- globals: [ Valtype.i64, Valtype.i64 ],
868
+ globals: prng.globals,
561
869
  globalNames: [ 'state0', 'state1' ],
562
870
  globalInits: [ prngSeed0, prngSeed1 ],
563
871
  returns: [ Valtype.f64 ],
564
872
  wasm: [
565
- // setup: s1 = state0, s0 = state1, state0 = s0
566
- [ Opcodes.global_get, 0 ], // state0
567
- [ Opcodes.local_tee, 0 ], // s1
568
- [ Opcodes.global_get, 1 ], // state1
569
- [ Opcodes.local_tee, 1, ], // s0
570
- [ Opcodes.global_set, 0 ], // state0
571
-
572
- // s1 ^= s1 << 23
573
- // [ Opcodes.local_get, 0 ], // s1
574
- [ Opcodes.local_get, 0 ], // s1
575
- [ Opcodes.i64_const, 23 ],
576
- [ Opcodes.i64_shl ], // <<
577
- [ Opcodes.i64_xor ], // ^
578
- [ Opcodes.local_set, 0 ], // s1
579
-
580
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
581
- // s1 ^ s0
582
- [ Opcodes.local_get, 0 ], // s1
583
- [ Opcodes.local_get, 1 ], // s0
584
- [ Opcodes.i64_xor ], // ^
585
-
586
- // ^ (s1 >> 17)
587
- [ Opcodes.local_get, 0 ], // s1
588
- [ Opcodes.i64_const, 17 ],
589
- [ Opcodes.i64_shr_u ], // >>
590
- [ Opcodes.i64_xor ], // ^
591
-
592
- // ^ (s0 >> 26)
593
- [ Opcodes.local_get, 1 ], // s0
594
- [ Opcodes.i64_const, 26 ],
595
- [ Opcodes.i64_shr_u ], // >>
596
- [ Opcodes.i64_xor ], // ^
597
-
598
- // state1 =
599
- [ Opcodes.global_set, 1 ],
873
+ ...prng.wasm,
600
874
 
601
875
  // you thought it was over? now we need the result as a f64 between 0-1 :)
602
876
 
603
- // state1 + s0
604
- [ Opcodes.global_get, 1 ], // state1
605
- [ Opcodes.local_get, 1 ], // s0
606
- [ Opcodes.i64_add ],
607
-
608
877
  // should we >> 12 here?
609
878
  // it feels like it but it breaks values
610
879
 
@@ -619,15 +888,51 @@ export const BuiltinFuncs = function() {
619
888
  // ...number(1),
620
889
  // [ Opcodes.f64_sub ],
621
890
 
622
- ...number((1 << 53) - 1, Valtype.i64),
623
- [ Opcodes.i64_and ],
891
+ ...(prng.returns === Valtype.i64 ? [
892
+ ...number((1 << 53) - 1, Valtype.i64),
893
+ [ Opcodes.i64_and ],
624
894
 
625
- // double(mantissa)
626
- [ Opcodes.f64_convert_i64_u ],
895
+ // double(mantissa)
896
+ [ Opcodes.f64_convert_i64_u ],
627
897
 
628
- // / (1 << 53)
629
- ...number(1 << 53),
630
- [ Opcodes.f64_div ]
898
+ // / (1 << 53)
899
+ ...number(1 << 53),
900
+ [ Opcodes.f64_div ]
901
+ ] : [
902
+ ...number((1 << 21) - 1, Valtype.i32),
903
+ [ Opcodes.i32_and ],
904
+
905
+ // double(mantissa)
906
+ [ Opcodes.f64_convert_i32_u ],
907
+
908
+ // / (1 << 21)
909
+ ...number(1 << 21),
910
+ [ Opcodes.f64_div ]
911
+ ])
912
+ ]
913
+ };
914
+
915
+ this.__Porffor_randomByte = {
916
+ params: [],
917
+ locals: prng.locals,
918
+ localNames: [ 's1', 's0' ],
919
+ globals: prng.globals,
920
+ globalNames: [ 'state0', 'state1' ],
921
+ globalInits: [ prngSeed0, prngSeed1 ],
922
+ returns: [ Valtype.i32 ],
923
+ wasm: [
924
+ ...prng.wasm,
925
+
926
+ ...(prng.returns === Valtype.i64 ? [
927
+ // the lowest bits of the output generated by xorshift128+ have low quality
928
+ ...number(56, Valtype.i64),
929
+ [ Opcodes.i64_shr_u ],
930
+
931
+ [ Opcodes.i32_wrap_i64 ],
932
+ ] : []),
933
+
934
+ ...number(0xff, Valtype.i32),
935
+ [ Opcodes.i32_and ],
631
936
  ]
632
937
  };
633
938
 
@@ -706,7 +1011,7 @@ export const BuiltinFuncs = function() {
706
1011
  params: [ valtypeBinary ],
707
1012
  locals: [],
708
1013
  returns: [ valtypeBinary ],
709
- returnType: 'boolean',
1014
+ returnType: TYPES.boolean,
710
1015
  wasm: [
711
1016
  [ Opcodes.local_get, 0 ],
712
1017
  ...number(0),
@@ -731,7 +1036,7 @@ export const BuiltinFuncs = function() {
731
1036
  typedParams: true,
732
1037
  locals: [ Valtype.i32, Valtype.i32 ],
733
1038
  returns: [ valtypeBinary ],
734
- returnType: Prefs.bytestring ? '_bytestring' : 'string',
1039
+ returnType: Prefs.bytestring ? TYPES.bytestring : TYPES.string,
735
1040
  wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
736
1041
  const bc = {};
737
1042
  for (const x in TYPE_NAMES) {
@@ -742,60 +1047,35 @@ export const BuiltinFuncs = function() {
742
1047
  }
743
1048
  };
744
1049
 
745
- const localIsOneOf = (getter, arr, valtype = valtypeBinary) => {
746
- const out = [];
747
-
748
- for (let i = 0; i < arr.length; i++) {
749
- out.push(...getter, ...number(arr[i], valtype), valtype === Valtype.f64 ? [ Opcodes.f64_eq ] : [ Opcodes.i32_eq ]);
750
- if (i !== 0) out.push([ Opcodes.i32_or ]);
751
- }
752
-
753
- return out;
754
- };
755
-
756
- this.__Porffor_ptr = {
1050
+ this.__Porffor_rawType = {
757
1051
  params: [ valtypeBinary, Valtype.i32 ],
758
1052
  typedParams: true,
759
- locals: [ Valtype.i32, Valtype.i32 ],
1053
+ locals: [],
760
1054
  returns: [ valtypeBinary ],
761
- wasm: (scope, { TYPES }) => [
762
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
763
- [ Opcodes.if, valtypeBinary ],
764
- [ Opcodes.local_get, 0 ],
765
- [ Opcodes.else ],
766
- ...number(NaN),
767
- [ Opcodes.end ]
768
- ]
769
- };
770
-
771
- this.__Porffor_i32_ptr = {
772
- params: [ Valtype.i32, Valtype.i32 ],
773
- typedParams: true,
774
- locals: [ Valtype.i32, Valtype.i32 ],
775
- returns: [ Valtype.i32 ],
776
- wasm: (scope, { TYPES }) => [
777
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
778
- [ Opcodes.if, Valtype.i32 ],
779
- [ Opcodes.local_get, 0 ],
780
- [ Opcodes.else ],
781
- ...number(-1, Valtype.i32),
782
- [ Opcodes.end ]
1055
+ wasm: [
1056
+ [ Opcodes.local_get, 1 ],
1057
+ Opcodes.i32_from_u
783
1058
  ]
784
1059
  };
785
1060
 
786
- // unsafe: does not check type just ~casts to number
787
- this.__Porffor_i32_ptrUnsafe = {
788
- params: [ Valtype.i32 ],
1061
+ this.__Porffor_clone = {
1062
+ params: [ valtypeBinary, valtypeBinary ],
789
1063
  locals: [],
790
- returns: [ Valtype.i32 ],
1064
+ returns: [],
791
1065
  wasm: [
1066
+ // dst
1067
+ [ Opcodes.local_get, 1 ],
1068
+ Opcodes.i32_to_u,
1069
+
1070
+ // src
792
1071
  [ Opcodes.local_get, 0 ],
1072
+ Opcodes.i32_to_u,
1073
+
1074
+ // size = pageSize
1075
+ ...number(pageSize, Valtype.i32),
1076
+ [ ...Opcodes.memory_copy, 0x00, 0x00 ],
793
1077
  ]
794
1078
  };
795
1079
 
796
-
797
- const generated = new GeneratedBuiltins.BuiltinFuncs();
798
- for (const x in generated) {
799
- this[x] = generated[x];
800
- }
1080
+ GeneratedBuiltins.BuiltinFuncs.call(this);
801
1081
  };