porffor 0.2.0-6aff0fa → 0.2.0-75bc012

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 (50) 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 +237 -0
  6. package/compiler/2c.js +1 -1
  7. package/compiler/{sections.js → assemble.js} +59 -12
  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 +20 -0
  13. package/compiler/builtins/crypto.ts +120 -0
  14. package/compiler/builtins/date.ts +2070 -0
  15. package/compiler/builtins/escape.ts +141 -0
  16. package/compiler/builtins/int.ts +147 -0
  17. package/compiler/builtins/number.ts +534 -0
  18. package/compiler/builtins/porffor.d.ts +43 -7
  19. package/compiler/builtins/string.ts +1080 -0
  20. package/compiler/builtins/tostring.ts +25 -0
  21. package/compiler/builtins.js +398 -115
  22. package/compiler/{codeGen.js → codegen.js} +856 -323
  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 +1504 -2
  27. package/compiler/index.js +16 -14
  28. package/compiler/log.js +2 -2
  29. package/compiler/opt.js +23 -22
  30. package/compiler/parse.js +30 -22
  31. package/compiler/precompile.js +26 -27
  32. package/compiler/prefs.js +7 -6
  33. package/compiler/prototype.js +16 -32
  34. package/compiler/types.js +37 -0
  35. package/compiler/wasmSpec.js +14 -1
  36. package/compiler/wrap.js +41 -44
  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 +69 -12
  45. package/runner/profiler.js +45 -26
  46. package/runner/repl.js +42 -9
  47. package/runner/sizes.js +37 -37
  48. package/runner/info.js +0 -89
  49. package/runner/transform.js +0 -15
  50. package/util/enum.js +0 -20
@@ -0,0 +1,25 @@
1
+ // // @porf --funsafe-no-unlikely-proto-checks --valtype=i32
2
+
3
+ // // export const __undefined_prototype_toString = (_this: number) => {
4
+
5
+ // // };
6
+
7
+ export const __Object_prototype_toString = (_this: object) => {
8
+ let out: bytestring = '[object Object]';
9
+ return out;
10
+ };
11
+
12
+ export const __Function_prototype_toString = (_this: Function) => {
13
+ // todo: actually use source
14
+ let out: bytestring = 'function () {}';
15
+ return out;
16
+ };
17
+
18
+
19
+ // // export const __Array_prototype_toString = (_this: any[]) => {
20
+ // // return _this.join();
21
+ // // };
22
+
23
+ // // export const __RegExp_prototype_toString = (_this: number) => {
24
+
25
+ // // };
@@ -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
  {
@@ -23,12 +24,24 @@ 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];
@@ -58,10 +71,10 @@ export const NULL = 0;
58
71
 
59
72
  export const BuiltinVars = function() {
60
73
  this.undefined = number(UNDEFINED);
61
- this.undefined.type = 'undefined';
74
+ this.undefined.type = TYPES.undefined;
62
75
 
63
76
  this.null = number(NULL);
64
- this.null.type = 'object';
77
+ this.null.type = TYPES.object;
65
78
 
66
79
  this.NaN = number(NaN);
67
80
  this.NaN.floatOnly = true;
@@ -128,7 +141,15 @@ export const BuiltinVars = function() {
128
141
 
129
142
  // wintercg(tm)
130
143
  this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.2.0`, false, '__navigator_userAgent');
131
- this.__navigator_userAgent.type = Prefs.bytestring ? '_bytestring' : 'string';
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
+ ];
132
153
  };
133
154
 
134
155
  export const BuiltinFuncs = function() {
@@ -187,19 +208,20 @@ export const BuiltinFuncs = function() {
187
208
  params: [ valtypeBinary ],
188
209
  locals: [],
189
210
  returns: [ valtypeBinary ],
190
- returnType: 'object',
211
+ returnType: TYPES.object,
191
212
  wasm: [
192
- [ Opcodes.local_get, 0 ]
213
+ // [ Opcodes.local_get, 0 ]
214
+ ...number(1)
193
215
  ]
194
216
  };
195
217
 
196
218
 
197
- this.__console_log = {
219
+ this.__Porffor_print = {
198
220
  params: [ valtypeBinary, Valtype.i32 ],
199
221
  typedParams: true,
200
222
  locals: [ Valtype.i32, Valtype.i32 ],
201
223
  returns: [],
202
- wasm: (scope, { TYPES, typeSwitch }) => [
224
+ wasm: (scope, { typeSwitch }) => [
203
225
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
204
226
  [TYPES.number]: [
205
227
  [ Opcodes.local_get, 0 ],
@@ -251,7 +273,7 @@ export const BuiltinFuncs = function() {
251
273
 
252
274
  [ Opcodes.end ]
253
275
  ],
254
- [TYPES._bytestring]: [
276
+ [TYPES.bytestring]: [
255
277
  // simply print a (byte)string :))
256
278
  // cache input pointer as i32
257
279
  [ Opcodes.local_get, 0 ],
@@ -285,7 +307,7 @@ export const BuiltinFuncs = function() {
285
307
 
286
308
  [ Opcodes.end ]
287
309
  ],
288
- [TYPES._array]: [
310
+ [TYPES.array]: [
289
311
  ...printStaticStr('[ '),
290
312
 
291
313
  // cache input pointer as i32
@@ -346,10 +368,7 @@ export const BuiltinFuncs = function() {
346
368
  [ Opcodes.local_get, 0 ],
347
369
  [ Opcodes.call, importedFuncs.print ],
348
370
  ]
349
- }, Blocktype.void),
350
-
351
- ...char('\n'),
352
- [ Opcodes.call, importedFuncs.printChar ]
371
+ }, Blocktype.void)
353
372
  ]
354
373
  };
355
374
 
@@ -361,7 +380,7 @@ export const BuiltinFuncs = function() {
361
380
  params: [ valtypeBinary ],
362
381
  locals: [],
363
382
  returns: [ valtypeBinary ],
364
- returnType: 'boolean',
383
+ returnType: TYPES.boolean,
365
384
  wasm: [
366
385
  [ Opcodes.local_get, 0 ],
367
386
  [ Opcodes.local_get, 0 ],
@@ -376,7 +395,7 @@ export const BuiltinFuncs = function() {
376
395
  params: [ valtypeBinary ],
377
396
  locals: [ valtypeBinary ],
378
397
  returns: [ valtypeBinary ],
379
- returnType: 'boolean',
398
+ returnType: TYPES.boolean,
380
399
  wasm: [
381
400
  [ Opcodes.local_get, 0 ],
382
401
  [ Opcodes.local_get, 0 ],
@@ -395,7 +414,7 @@ export const BuiltinFuncs = function() {
395
414
  params: [ valtypeBinary ],
396
415
  locals: [],
397
416
  returns: [ valtypeBinary ],
398
- returnType: 'boolean',
417
+ returnType: TYPES.boolean,
399
418
  wasm: [
400
419
  [ Opcodes.local_get, 0 ],
401
420
  [ Opcodes.local_get, 0 ],
@@ -410,7 +429,7 @@ export const BuiltinFuncs = function() {
410
429
  params: [ valtypeBinary ],
411
430
  locals: [],
412
431
  returns: [ valtypeBinary ],
413
- returnType: 'boolean',
432
+ returnType: TYPES.boolean,
414
433
  wasm: [
415
434
  [ Opcodes.local_get, 0 ],
416
435
  [ Opcodes.local_get, 0 ],
@@ -550,61 +569,314 @@ export const BuiltinFuncs = function() {
550
569
 
551
570
  // this is an implementation of xorshift128+ (in wasm bytecode)
552
571
  // 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);
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}`);
554
865
 
555
866
  this.__Math_random = {
556
867
  floatOnly: true,
557
868
  params: [],
558
- locals: [ Valtype.i64, Valtype.i64 ],
869
+ locals: prng.locals,
559
870
  localNames: [ 's1', 's0' ],
560
- globals: [ Valtype.i64, Valtype.i64 ],
871
+ globals: prng.globals,
561
872
  globalNames: [ 'state0', 'state1' ],
562
873
  globalInits: [ prngSeed0, prngSeed1 ],
563
874
  returns: [ Valtype.f64 ],
564
875
  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 ],
876
+ ...prng.wasm,
600
877
 
601
878
  // you thought it was over? now we need the result as a f64 between 0-1 :)
602
879
 
603
- // state1 + s0
604
- [ Opcodes.global_get, 1 ], // state1
605
- [ Opcodes.local_get, 1 ], // s0
606
- [ Opcodes.i64_add ],
607
-
608
880
  // should we >> 12 here?
609
881
  // it feels like it but it breaks values
610
882
 
@@ -619,15 +891,51 @@ export const BuiltinFuncs = function() {
619
891
  // ...number(1),
620
892
  // [ Opcodes.f64_sub ],
621
893
 
622
- ...number((1 << 53) - 1, Valtype.i64),
623
- [ 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 ],
624
900
 
625
- // double(mantissa)
626
- [ Opcodes.f64_convert_i64_u ],
901
+ // / (1 << 53)
902
+ ...number(1 << 53),
903
+ [ Opcodes.f64_div ]
904
+ ] : [
905
+ ...number((1 << 21) - 1, Valtype.i32),
906
+ [ Opcodes.i32_and ],
627
907
 
628
- // / (1 << 53)
629
- ...number(1 << 53),
630
- [ Opcodes.f64_div ]
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 ],
933
+
934
+ [ Opcodes.i32_wrap_i64 ],
935
+ ] : []),
936
+
937
+ ...number(0xff, Valtype.i32),
938
+ [ Opcodes.i32_and ],
631
939
  ]
632
940
  };
633
941
 
@@ -706,7 +1014,7 @@ export const BuiltinFuncs = function() {
706
1014
  params: [ valtypeBinary ],
707
1015
  locals: [],
708
1016
  returns: [ valtypeBinary ],
709
- returnType: 'boolean',
1017
+ returnType: TYPES.boolean,
710
1018
  wasm: [
711
1019
  [ Opcodes.local_get, 0 ],
712
1020
  ...number(0),
@@ -731,7 +1039,7 @@ export const BuiltinFuncs = function() {
731
1039
  typedParams: true,
732
1040
  locals: [ Valtype.i32, Valtype.i32 ],
733
1041
  returns: [ valtypeBinary ],
734
- returnType: Prefs.bytestring ? '_bytestring' : 'string',
1042
+ returnType: Prefs.bytestring ? TYPES.bytestring : TYPES.string,
735
1043
  wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
736
1044
  const bc = {};
737
1045
  for (const x in TYPE_NAMES) {
@@ -742,60 +1050,35 @@ export const BuiltinFuncs = function() {
742
1050
  }
743
1051
  };
744
1052
 
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 = {
1053
+ this.__Porffor_rawType = {
757
1054
  params: [ valtypeBinary, Valtype.i32 ],
758
1055
  typedParams: true,
759
- locals: [ Valtype.i32, Valtype.i32 ],
1056
+ locals: [],
760
1057
  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 ]
1058
+ wasm: [
1059
+ [ Opcodes.local_get, 1 ],
1060
+ Opcodes.i32_from_u
783
1061
  ]
784
1062
  };
785
1063
 
786
- // unsafe: does not check type just ~casts to number
787
- this.__Porffor_i32_ptrUnsafe = {
788
- params: [ Valtype.i32 ],
1064
+ this.__Porffor_clone = {
1065
+ params: [ valtypeBinary, valtypeBinary ],
789
1066
  locals: [],
790
- returns: [ Valtype.i32 ],
1067
+ returns: [],
791
1068
  wasm: [
1069
+ // dst
1070
+ [ Opcodes.local_get, 1 ],
1071
+ Opcodes.i32_to_u,
1072
+
1073
+ // src
792
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 ],
793
1080
  ]
794
1081
  };
795
1082
 
796
-
797
- const generated = new GeneratedBuiltins.BuiltinFuncs();
798
- for (const x in generated) {
799
- this[x] = generated[x];
800
- }
1083
+ GeneratedBuiltins.BuiltinFuncs.call(this);
801
1084
  };