porffor 0.2.0-4b72c49 → 0.2.0-4d189b5

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 (53) hide show
  1. package/CONTRIBUTING.md +248 -0
  2. package/LICENSE +20 -20
  3. package/README.md +129 -84
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +237 -0
  7. package/compiler/2c.js +1 -1
  8. package/compiler/{sections.js → assemble.js} +59 -12
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +18 -0
  11. package/compiler/builtins/array.ts +145 -0
  12. package/compiler/builtins/base64.ts +7 -84
  13. package/compiler/builtins/crypto.ts +120 -0
  14. package/compiler/builtins/date.ts +2071 -0
  15. package/compiler/builtins/escape.ts +141 -0
  16. package/compiler/builtins/int.ts +147 -0
  17. package/compiler/builtins/number.ts +527 -0
  18. package/compiler/builtins/porffor.d.ts +43 -7
  19. package/compiler/builtins/string.ts +1055 -0
  20. package/compiler/builtins/tostring.ts +45 -0
  21. package/compiler/builtins.js +403 -110
  22. package/compiler/{codeGen.js → codegen.js} +820 -309
  23. package/compiler/decompile.js +0 -1
  24. package/compiler/embedding.js +22 -22
  25. package/compiler/encoding.js +108 -10
  26. package/compiler/generated_builtins.js +1470 -4
  27. package/compiler/index.js +16 -14
  28. package/compiler/log.js +6 -3
  29. package/compiler/opt.js +23 -22
  30. package/compiler/parse.js +30 -22
  31. package/compiler/precompile.js +25 -26
  32. package/compiler/prefs.js +7 -6
  33. package/compiler/prototype.js +2 -18
  34. package/compiler/types.js +37 -0
  35. package/compiler/wasmSpec.js +18 -6
  36. package/compiler/wrap.js +51 -47
  37. package/package.json +9 -5
  38. package/porf +2 -0
  39. package/rhemyn/compile.js +44 -26
  40. package/rhemyn/parse.js +322 -320
  41. package/rhemyn/test/parse.js +58 -58
  42. package/runner/compare.js +34 -34
  43. package/runner/debug.js +122 -0
  44. package/runner/index.js +74 -11
  45. package/runner/profiler.js +102 -0
  46. package/runner/repl.js +42 -9
  47. package/runner/sizes.js +37 -37
  48. package/demo.js +0 -15
  49. package/runner/info.js +0 -89
  50. package/runner/profile.js +0 -46
  51. package/runner/results.json +0 -1
  52. package/runner/transform.js +0 -15
  53. package/util/enum.js +0 -20
@@ -0,0 +1,45 @@
1
+ // // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
+
3
+ export const __Boolean_prototype_toString = (_this: boolean) => {
4
+ let out: bytestring = '';
5
+ if (_this) out = 'true';
6
+ else out = 'false';
7
+
8
+ return out;
9
+ };
10
+
11
+ export const __String_prototype_toString = (_this: string) => {
12
+ let out: string = Porffor.s``;
13
+ Porffor.clone(_this, out);
14
+ return out;
15
+ };
16
+
17
+ export const ___bytestring_prototype_toString = (_this: bytestring) => {
18
+ let out: bytestring = Porffor.bs``;
19
+ Porffor.clone(_this, out);
20
+ return out;
21
+ };
22
+
23
+ // // export const __undefined_prototype_toString = (_this: number) => {
24
+
25
+ // // };
26
+
27
+ export const __Object_prototype_toString = (_this: object) => {
28
+ let out: bytestring = '[object Object]';
29
+ return out;
30
+ };
31
+
32
+ export const __Function_prototype_toString = (_this: Function) => {
33
+ // todo: actually use source
34
+ let out: bytestring = 'function () {}';
35
+ return out;
36
+ };
37
+
38
+
39
+ // // export const ___array_prototype_toString = (_this: any[]) => {
40
+ // // return _this.join();
41
+ // // };
42
+
43
+ // // export const ___regexp_prototype_toString = (_this: number) => {
44
+
45
+ // // };
@@ -2,6 +2,7 @@ import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
2
2
  import { number, i32x4 } from "./embedding.js";
3
3
  import Prefs from './prefs.js';
4
4
  import * as GeneratedBuiltins from './generated_builtins.js';
5
+ import { TYPES } from './types.js';
5
6
 
6
7
  export const importedFuncs = [
7
8
  {
@@ -21,6 +22,24 @@ export const importedFuncs = [
21
22
  import: 't',
22
23
  params: 0,
23
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
24
43
  }
25
44
  ];
26
45
 
@@ -52,10 +71,10 @@ export const NULL = 0;
52
71
 
53
72
  export const BuiltinVars = function() {
54
73
  this.undefined = number(UNDEFINED);
55
- this.undefined.type = 'undefined';
74
+ this.undefined.type = TYPES.undefined;
56
75
 
57
76
  this.null = number(NULL);
58
- this.null.type = 'object';
77
+ this.null.type = TYPES.object;
59
78
 
60
79
  this.NaN = number(NaN);
61
80
  this.NaN.floatOnly = true;
@@ -119,6 +138,18 @@ export const BuiltinVars = function() {
119
138
 
120
139
  // stubs just so that parent objects exist
121
140
  this.Math = number(1);
141
+
142
+ // wintercg(tm)
143
+ this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.2.0`, false, '__navigator_userAgent');
144
+ this.__navigator_userAgent.type = Prefs.bytestring ? TYPES._bytestring : TYPES.string;
145
+
146
+ for (const x in TYPES) {
147
+ this['__Porffor_TYPES_' + x] = number(TYPES[x]);
148
+ }
149
+
150
+ this.__performance_timeOrigin = [
151
+ [ Opcodes.call, importedFuncs.timeOrigin ]
152
+ ];
122
153
  };
123
154
 
124
155
  export const BuiltinFuncs = function() {
@@ -177,19 +208,20 @@ export const BuiltinFuncs = function() {
177
208
  params: [ valtypeBinary ],
178
209
  locals: [],
179
210
  returns: [ valtypeBinary ],
180
- returnType: 'object',
211
+ returnType: TYPES.object,
181
212
  wasm: [
182
- [ Opcodes.local_get, 0 ]
213
+ // [ Opcodes.local_get, 0 ]
214
+ ...number(1)
183
215
  ]
184
216
  };
185
217
 
186
218
 
187
- this.__console_log = {
219
+ this.__Porffor_print = {
188
220
  params: [ valtypeBinary, Valtype.i32 ],
189
221
  typedParams: true,
190
222
  locals: [ Valtype.i32, Valtype.i32 ],
191
223
  returns: [],
192
- wasm: (scope, { TYPES, typeSwitch }) => [
224
+ wasm: (scope, { typeSwitch }) => [
193
225
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
194
226
  [TYPES.number]: [
195
227
  [ Opcodes.local_get, 0 ],
@@ -336,10 +368,7 @@ export const BuiltinFuncs = function() {
336
368
  [ Opcodes.local_get, 0 ],
337
369
  [ Opcodes.call, importedFuncs.print ],
338
370
  ]
339
- }, Blocktype.void),
340
-
341
- ...char('\n'),
342
- [ Opcodes.call, importedFuncs.printChar ]
371
+ }, Blocktype.void)
343
372
  ]
344
373
  };
345
374
 
@@ -351,7 +380,7 @@ export const BuiltinFuncs = function() {
351
380
  params: [ valtypeBinary ],
352
381
  locals: [],
353
382
  returns: [ valtypeBinary ],
354
- returnType: 'boolean',
383
+ returnType: TYPES.boolean,
355
384
  wasm: [
356
385
  [ Opcodes.local_get, 0 ],
357
386
  [ Opcodes.local_get, 0 ],
@@ -366,7 +395,7 @@ export const BuiltinFuncs = function() {
366
395
  params: [ valtypeBinary ],
367
396
  locals: [ valtypeBinary ],
368
397
  returns: [ valtypeBinary ],
369
- returnType: 'boolean',
398
+ returnType: TYPES.boolean,
370
399
  wasm: [
371
400
  [ Opcodes.local_get, 0 ],
372
401
  [ Opcodes.local_get, 0 ],
@@ -385,7 +414,7 @@ export const BuiltinFuncs = function() {
385
414
  params: [ valtypeBinary ],
386
415
  locals: [],
387
416
  returns: [ valtypeBinary ],
388
- returnType: 'boolean',
417
+ returnType: TYPES.boolean,
389
418
  wasm: [
390
419
  [ Opcodes.local_get, 0 ],
391
420
  [ Opcodes.local_get, 0 ],
@@ -400,7 +429,7 @@ export const BuiltinFuncs = function() {
400
429
  params: [ valtypeBinary ],
401
430
  locals: [],
402
431
  returns: [ valtypeBinary ],
403
- returnType: 'boolean',
432
+ returnType: TYPES.boolean,
404
433
  wasm: [
405
434
  [ Opcodes.local_get, 0 ],
406
435
  [ Opcodes.local_get, 0 ],
@@ -540,61 +569,314 @@ export const BuiltinFuncs = function() {
540
569
 
541
570
  // this is an implementation of xorshift128+ (in wasm bytecode)
542
571
  // fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
543
- const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
572
+ // const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
573
+ const prngSeed0 = (Math.random() * (2 ** 30)) | 0, prngSeed1 = (Math.random() * (2 ** 30)) | 0;
574
+
575
+ const prng = ({
576
+ 'lcg32_glibc': {
577
+ globals: [ Valtype.i32 ],
578
+ locals: [],
579
+ returns: Valtype.i32,
580
+ wasm: [
581
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
582
+ // MULTIPLIER * state0
583
+ [ Opcodes.global_get, 0 ],
584
+ ...number(1103515245, Valtype.i32),
585
+ [ Opcodes.i32_mul ],
586
+
587
+ // + INCREMENT
588
+ ...number(12345, Valtype.i32),
589
+ [ Opcodes.i32_add ],
590
+
591
+ // % MODULUS
592
+ ...number(2 ** 31, Valtype.i32),
593
+ [ Opcodes.i32_rem_s ],
594
+
595
+ // state0 =
596
+ [ Opcodes.global_set, 0 ],
597
+
598
+ // state0
599
+ [ Opcodes.global_get, 0 ],
600
+ ],
601
+ },
602
+ 'lcg32_minstd': {
603
+ globals: [ Valtype.i32 ],
604
+ locals: [],
605
+ returns: Valtype.i32,
606
+ wasm: [
607
+ // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
608
+ // MULTIPLIER * state0
609
+ [ Opcodes.global_get, 0 ],
610
+ ...number(48271, Valtype.i32),
611
+ [ Opcodes.i32_mul ],
612
+
613
+ // % MODULUS
614
+ ...number((2 ** 31) - 1, Valtype.i32),
615
+ [ Opcodes.i32_rem_s ],
616
+
617
+ // state0 =
618
+ [ Opcodes.global_set, 0 ],
619
+
620
+ // state0
621
+ [ Opcodes.global_get, 0 ],
622
+ ],
623
+ },
624
+ 'lcg64_musl': 0, // todo
625
+
626
+ 'xorshift32+': {
627
+ globals: [ Valtype.i32 ],
628
+ locals: [ Valtype.i32 ],
629
+ returns: Valtype.i32,
630
+ wasm: [
631
+ // setup: s1 = state0
632
+ [ Opcodes.global_get, 0 ], // state0
633
+ [ Opcodes.local_tee, 0 ], // s1
634
+
635
+ // s1 ^= s1 << 13
636
+ [ Opcodes.local_get, 0 ], // s1
637
+ [ Opcodes.i32_const, 13 ],
638
+ [ Opcodes.i32_shl ], // <<
639
+ [ Opcodes.i32_xor ], // ^
640
+ [ Opcodes.local_tee, 0 ], // s1
641
+
642
+ // s1 ^= s1 >> 17
643
+ [ Opcodes.local_get, 0 ], // s1
644
+ [ Opcodes.i32_const, 17 ],
645
+ [ Opcodes.i32_shr_s ], // >>
646
+ [ Opcodes.i32_xor ], // ^
647
+ [ Opcodes.local_tee, 0 ], // s1
648
+
649
+ // s1 ^= s1 << 5
650
+ [ Opcodes.local_get, 0 ], // s1
651
+ [ Opcodes.i32_const, 5 ],
652
+ [ Opcodes.i32_shl ], // <<
653
+ [ Opcodes.i32_xor ], // ^
654
+ [ Opcodes.local_tee, 0 ], // s1
655
+
656
+ // state0 = s1
657
+ [ Opcodes.global_set, 0 ],
658
+
659
+ // s1
660
+ [ Opcodes.local_get, 0 ],
661
+ ],
662
+ },
663
+
664
+ 'xorshift64+': {
665
+ globals: [ Valtype.i64 ],
666
+ locals: [ Valtype.i64 ],
667
+ returns: Valtype.i64,
668
+ wasm: [
669
+ // setup: s1 = state0
670
+ [ Opcodes.global_get, 0 ], // state0
671
+ [ Opcodes.local_tee, 0 ], // s1
672
+
673
+ // s1 ^= s1 >> 12
674
+ [ Opcodes.local_get, 0 ], // s1
675
+ [ Opcodes.i64_const, 12 ],
676
+ [ Opcodes.i64_shr_s ], // >>
677
+ [ Opcodes.i64_xor ], // ^
678
+ [ Opcodes.local_tee, 0 ], // s1
679
+
680
+ // s1 ^= s1 << 25
681
+ [ Opcodes.local_get, 0 ], // s1
682
+ [ Opcodes.i64_const, 25 ],
683
+ [ Opcodes.i64_shl ], // <<
684
+ [ Opcodes.i64_xor ], // ^
685
+ [ Opcodes.local_tee, 0 ], // s1
686
+
687
+ // s1 ^= s1 >> 27
688
+ [ Opcodes.local_get, 0 ], // s1
689
+ [ Opcodes.i64_const, 27 ],
690
+ [ Opcodes.i64_shr_s ], // >>
691
+ [ Opcodes.i64_xor ], // ^
692
+ [ Opcodes.local_tee, 0 ], // s1
693
+
694
+ // state0 = s1
695
+ [ Opcodes.global_set, 0 ],
696
+
697
+ // // s1 * 0x2545F4914F6CDD1D
698
+ // [ Opcodes.local_get, 0 ],
699
+ // [ Opcodes.i64_const, 0x9d, 0xba, 0xb3, 0xfb, 0x94, 0x92, 0xfd, 0xa2, 0x25 ],
700
+ // [ Opcodes.i64_mul ]
701
+
702
+ // s1
703
+ [ Opcodes.local_get, 0 ],
704
+ ],
705
+ },
706
+
707
+ 'xorshift128+': {
708
+ globals: [ Valtype.i64, Valtype.i64 ],
709
+ locals: [ Valtype.i64, Valtype.i64 ],
710
+ returns: Valtype.i64,
711
+ wasm: [
712
+ // setup: s1 = state0, s0 = state1, state0 = s0
713
+ [ Opcodes.global_get, 0 ], // state0
714
+ [ Opcodes.local_tee, 0 ], // s1
715
+ [ Opcodes.global_get, 1 ], // state1
716
+ [ Opcodes.local_tee, 1, ], // s0
717
+ [ Opcodes.global_set, 0 ], // state0
718
+
719
+ // s1 ^= s1 << 23
720
+ // [ Opcodes.local_get, 0 ], // s1
721
+ [ Opcodes.local_get, 0 ], // s1
722
+ [ Opcodes.i64_const, 23 ],
723
+ [ Opcodes.i64_shl ], // <<
724
+ [ Opcodes.i64_xor ], // ^
725
+ [ Opcodes.local_set, 0 ], // s1
726
+
727
+ // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
728
+ // s1 ^ s0
729
+ [ Opcodes.local_get, 0 ], // s1
730
+ [ Opcodes.local_get, 1 ], // s0
731
+ [ Opcodes.i64_xor ], // ^
732
+
733
+ // ^ (s1 >> 17)
734
+ [ Opcodes.local_get, 0 ], // s1
735
+ [ Opcodes.i64_const, 17 ],
736
+ [ Opcodes.i64_shr_u ], // >>
737
+ [ Opcodes.i64_xor ], // ^
738
+
739
+ // ^ (s0 >> 26)
740
+ [ Opcodes.local_get, 1 ], // s0
741
+ [ Opcodes.i64_const, 26 ],
742
+ [ Opcodes.i64_shr_u ], // >>
743
+ [ Opcodes.i64_xor ], // ^
744
+
745
+ // state1 =
746
+ [ Opcodes.global_set, 1 ],
747
+
748
+ // state1 + s0
749
+ [ Opcodes.global_get, 1 ], // state1
750
+ [ Opcodes.local_get, 1 ], // s0
751
+ [ Opcodes.i64_add ]
752
+ ]
753
+ },
754
+
755
+ 'xoroshiro128+': {
756
+ globals: [ Valtype.i64, Valtype.i64 ],
757
+ locals: [ Valtype.i64, Valtype.i64, Valtype.i64 ],
758
+ returns: Valtype.i64,
759
+ wasm: [
760
+ // setup: s1 = state1, s0 = state0
761
+ [ Opcodes.global_get, 1 ], // state0
762
+ [ Opcodes.local_tee, 0 ], // s1
763
+ [ Opcodes.global_get, 0 ], // state1
764
+ [ Opcodes.local_tee, 1, ], // s0
765
+
766
+ // result = s0 + s1
767
+ [ Opcodes.i64_add ],
768
+ [ Opcodes.local_set, 2 ], // result
769
+
770
+ // s1 ^= s0
771
+ [ Opcodes.local_get, 0 ], // s1
772
+ [ Opcodes.local_get, 1 ], // s0
773
+ [ Opcodes.i64_xor ],
774
+ [ Opcodes.local_set, 0 ], // s1
775
+
776
+ // state0 = rotl(s0, 24) ^ s1 ^ (s1 << 16)
777
+
778
+ // rotl(s0, 24) ^ s1
779
+ [ Opcodes.local_get, 1 ], // s0
780
+ ...number(24, Valtype.i64),
781
+ [ Opcodes.i64_rotl ],
782
+ [ Opcodes.local_get, 0 ], // s1
783
+ [ Opcodes.i64_xor ],
784
+
785
+ // ^ (s1 << 16)
786
+ [ Opcodes.local_get, 0 ], // s1
787
+ ...number(16, Valtype.i64),
788
+ [ Opcodes.i64_shl ],
789
+ [ Opcodes.i64_xor ],
790
+
791
+ // state0 =
792
+ [ Opcodes.global_set, 0 ], // state0
793
+
794
+ // state1 = rotl(s1, 37)
795
+ [ Opcodes.local_get, 0 ], // s1
796
+ ...number(37, Valtype.i64),
797
+ [ Opcodes.i64_rotl ],
798
+ [ Opcodes.global_set, 1 ], // state1
799
+
800
+ // result
801
+ [ Opcodes.local_get, 2 ],
802
+ ]
803
+ },
804
+
805
+ 'xoshiro128+': {
806
+ globals: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
807
+ locals: [ Valtype.i32, Valtype.i32 ],
808
+ returns: Valtype.i32,
809
+ wasm: [
810
+ // result = state0 + state3
811
+ [ Opcodes.global_get, 0 ], // state0
812
+ [ Opcodes.global_get, 3 ], // state0
813
+ [ Opcodes.i32_add ],
814
+ [ Opcodes.local_set, 0 ], // result
815
+
816
+ // t = state1 << 9
817
+ [ Opcodes.global_get, 1 ], // state1
818
+ ...number(9, Valtype.i32),
819
+ [ Opcodes.i32_shl ],
820
+ [ Opcodes.local_set, 1 ], // t
821
+
822
+ // state2 ^= state0
823
+ [ Opcodes.global_get, 2 ], // state2
824
+ [ Opcodes.global_get, 0 ], // state0
825
+ [ Opcodes.i32_xor ],
826
+ [ Opcodes.global_set, 2 ], // state2
827
+
828
+ // state3 ^= state1
829
+ [ Opcodes.global_get, 3 ], // state3
830
+ [ Opcodes.global_get, 1 ], // state1
831
+ [ Opcodes.i32_xor ],
832
+ [ Opcodes.global_set, 3 ], // state3
833
+
834
+ // state1 ^= state2
835
+ [ Opcodes.global_get, 1 ], // state1
836
+ [ Opcodes.global_get, 2 ], // state2
837
+ [ Opcodes.i32_xor ],
838
+ [ Opcodes.global_set, 1 ], // state1
839
+
840
+ // state0 ^= state3
841
+ [ Opcodes.global_get, 0 ], // state2
842
+ [ Opcodes.global_get, 3 ], // state0
843
+ [ Opcodes.i32_xor ],
844
+ [ Opcodes.global_set, 0 ], // state2
845
+
846
+ // state2 ^= t
847
+ [ Opcodes.global_get, 2 ], // state2
848
+ [ Opcodes.local_get, 1 ], // t
849
+ [ Opcodes.i32_xor ],
850
+ [ Opcodes.global_set, 2 ], // state2
851
+
852
+ // state3 = rotl(state3, 11)
853
+ [ Opcodes.global_get, 3 ], // state3
854
+ ...number(11, Valtype.i32),
855
+ [ Opcodes.i32_rotl ],
856
+ [ Opcodes.global_set, 3 ], // state3
857
+
858
+ // result
859
+ [ Opcodes.local_get, 0 ],
860
+ ]
861
+ }
862
+ })[Prefs.prng ?? 'xorshift128+'];
863
+
864
+ if (!prng) throw new Error(`unknown prng algo: ${Prefs.prng}`);
544
865
 
545
866
  this.__Math_random = {
546
867
  floatOnly: true,
547
868
  params: [],
548
- locals: [ Valtype.i64, Valtype.i64 ],
869
+ locals: prng.locals,
549
870
  localNames: [ 's1', 's0' ],
550
- globals: [ Valtype.i64, Valtype.i64 ],
871
+ globals: prng.globals,
551
872
  globalNames: [ 'state0', 'state1' ],
552
873
  globalInits: [ prngSeed0, prngSeed1 ],
553
874
  returns: [ Valtype.f64 ],
554
875
  wasm: [
555
- // setup: s1 = state0, s0 = state1, state0 = s0
556
- [ Opcodes.global_get, 0 ], // state0
557
- [ Opcodes.local_tee, 0 ], // s1
558
- [ Opcodes.global_get, 1 ], // state1
559
- [ Opcodes.local_tee, 1, ], // s0
560
- [ Opcodes.global_set, 0 ], // state0
561
-
562
- // s1 ^= s1 << 23
563
- // [ Opcodes.local_get, 0 ], // s1
564
- [ Opcodes.local_get, 0 ], // s1
565
- [ Opcodes.i64_const, 23 ],
566
- [ Opcodes.i64_shl ], // <<
567
- [ Opcodes.i64_xor ], // ^
568
- [ Opcodes.local_set, 0 ], // s1
569
-
570
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
571
- // s1 ^ s0
572
- [ Opcodes.local_get, 0 ], // s1
573
- [ Opcodes.local_get, 1 ], // s0
574
- [ Opcodes.i64_xor ], // ^
575
-
576
- // ^ (s1 >> 17)
577
- [ Opcodes.local_get, 0 ], // s1
578
- [ Opcodes.i64_const, 17 ],
579
- [ Opcodes.i64_shr_u ], // >>
580
- [ Opcodes.i64_xor ], // ^
581
-
582
- // ^ (s0 >> 26)
583
- [ Opcodes.local_get, 1 ], // s0
584
- [ Opcodes.i64_const, 26 ],
585
- [ Opcodes.i64_shr_u ], // >>
586
- [ Opcodes.i64_xor ], // ^
587
-
588
- // state1 =
589
- [ Opcodes.global_set, 1 ],
876
+ ...prng.wasm,
590
877
 
591
878
  // you thought it was over? now we need the result as a f64 between 0-1 :)
592
879
 
593
- // state1 + s0
594
- [ Opcodes.global_get, 1 ], // state1
595
- [ Opcodes.local_get, 1 ], // s0
596
- [ Opcodes.i64_add ],
597
-
598
880
  // should we >> 12 here?
599
881
  // it feels like it but it breaks values
600
882
 
@@ -609,15 +891,51 @@ export const BuiltinFuncs = function() {
609
891
  // ...number(1),
610
892
  // [ Opcodes.f64_sub ],
611
893
 
612
- ...number((1 << 53) - 1, Valtype.i64),
613
- [ Opcodes.i64_and ],
894
+ ...(prng.returns === Valtype.i64 ? [
895
+ ...number((1 << 53) - 1, Valtype.i64),
896
+ [ Opcodes.i64_and ],
897
+
898
+ // double(mantissa)
899
+ [ Opcodes.f64_convert_i64_u ],
900
+
901
+ // / (1 << 53)
902
+ ...number(1 << 53),
903
+ [ Opcodes.f64_div ]
904
+ ] : [
905
+ ...number((1 << 21) - 1, Valtype.i32),
906
+ [ Opcodes.i32_and ],
907
+
908
+ // double(mantissa)
909
+ [ Opcodes.f64_convert_i32_u ],
910
+
911
+ // / (1 << 21)
912
+ ...number(1 << 21),
913
+ [ Opcodes.f64_div ]
914
+ ])
915
+ ]
916
+ };
917
+
918
+ this.__Porffor_randomByte = {
919
+ params: [],
920
+ locals: prng.locals,
921
+ localNames: [ 's1', 's0' ],
922
+ globals: prng.globals,
923
+ globalNames: [ 'state0', 'state1' ],
924
+ globalInits: [ prngSeed0, prngSeed1 ],
925
+ returns: [ Valtype.i32 ],
926
+ wasm: [
927
+ ...prng.wasm,
928
+
929
+ ...(prng.returns === Valtype.i64 ? [
930
+ // the lowest bits of the output generated by xorshift128+ have low quality
931
+ ...number(56, Valtype.i64),
932
+ [ Opcodes.i64_shr_u ],
614
933
 
615
- // double(mantissa)
616
- [ Opcodes.f64_convert_i64_u ],
934
+ [ Opcodes.i32_wrap_i64 ],
935
+ ] : []),
617
936
 
618
- // / (1 << 53)
619
- ...number(1 << 53),
620
- [ Opcodes.f64_div ]
937
+ ...number(0xff, Valtype.i32),
938
+ [ Opcodes.i32_and ],
621
939
  ]
622
940
  };
623
941
 
@@ -696,7 +1014,7 @@ export const BuiltinFuncs = function() {
696
1014
  params: [ valtypeBinary ],
697
1015
  locals: [],
698
1016
  returns: [ valtypeBinary ],
699
- returnType: 'boolean',
1017
+ returnType: TYPES.boolean,
700
1018
  wasm: [
701
1019
  [ Opcodes.local_get, 0 ],
702
1020
  ...number(0),
@@ -721,7 +1039,7 @@ export const BuiltinFuncs = function() {
721
1039
  typedParams: true,
722
1040
  locals: [ Valtype.i32, Valtype.i32 ],
723
1041
  returns: [ valtypeBinary ],
724
- returnType: Prefs.bytestring ? '_bytestring' : 'string',
1042
+ returnType: Prefs.bytestring ? TYPES._bytestring : TYPES.string,
725
1043
  wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
726
1044
  const bc = {};
727
1045
  for (const x in TYPE_NAMES) {
@@ -732,60 +1050,35 @@ export const BuiltinFuncs = function() {
732
1050
  }
733
1051
  };
734
1052
 
735
- const localIsOneOf = (getter, arr, valtype = valtypeBinary) => {
736
- const out = [];
737
-
738
- for (let i = 0; i < arr.length; i++) {
739
- out.push(...getter, ...number(arr[i], valtype), valtype === Valtype.f64 ? [ Opcodes.f64_eq ] : [ Opcodes.i32_eq ]);
740
- if (i !== 0) out.push([ Opcodes.i32_or ]);
741
- }
742
-
743
- return out;
744
- };
745
-
746
- this.__Porffor_ptr = {
1053
+ this.__Porffor_rawType = {
747
1054
  params: [ valtypeBinary, Valtype.i32 ],
748
1055
  typedParams: true,
749
- locals: [ Valtype.i32, Valtype.i32 ],
1056
+ locals: [],
750
1057
  returns: [ valtypeBinary ],
751
- wasm: (scope, { TYPES }) => [
752
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
753
- [ Opcodes.if, valtypeBinary ],
754
- [ Opcodes.local_get, 0 ],
755
- [ Opcodes.else ],
756
- ...number(NaN),
757
- [ Opcodes.end ]
758
- ]
759
- };
760
-
761
- this.__Porffor_i32_ptr = {
762
- params: [ Valtype.i32, Valtype.i32 ],
763
- typedParams: true,
764
- locals: [ Valtype.i32, Valtype.i32 ],
765
- returns: [ Valtype.i32 ],
766
- wasm: (scope, { TYPES }) => [
767
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
768
- [ Opcodes.if, Valtype.i32 ],
769
- [ Opcodes.local_get, 0 ],
770
- [ Opcodes.else ],
771
- ...number(-1, Valtype.i32),
772
- [ Opcodes.end ]
1058
+ wasm: [
1059
+ [ Opcodes.local_get, 1 ],
1060
+ Opcodes.i32_from_u
773
1061
  ]
774
1062
  };
775
1063
 
776
- // unsafe: does not check type just ~casts to number
777
- this.__Porffor_i32_ptrUnsafe = {
778
- params: [ Valtype.i32 ],
1064
+ this.__Porffor_clone = {
1065
+ params: [ valtypeBinary, valtypeBinary ],
779
1066
  locals: [],
780
- returns: [ Valtype.i32 ],
1067
+ returns: [],
781
1068
  wasm: [
1069
+ // dst
1070
+ [ Opcodes.local_get, 1 ],
1071
+ Opcodes.i32_to_u,
1072
+
1073
+ // src
782
1074
  [ Opcodes.local_get, 0 ],
1075
+ Opcodes.i32_to_u,
1076
+
1077
+ // size = pageSize
1078
+ ...number(pageSize, Valtype.i32),
1079
+ [ ...Opcodes.memory_copy, 0x00, 0x00 ],
783
1080
  ]
784
1081
  };
785
1082
 
786
-
787
- const generated = new GeneratedBuiltins.BuiltinFuncs();
788
- for (const x in generated) {
789
- this[x] = generated[x];
790
- }
1083
+ GeneratedBuiltins.BuiltinFuncs.call(this);
791
1084
  };