porffor 0.2.0-f2bbe1f → 0.2.0-f435128

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 +181 -0
  2. package/LICENSE +20 -20
  3. package/README.md +154 -89
  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 +317 -72
  8. package/compiler/{sections.js → assemble.js} +63 -15
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +19 -0
  11. package/compiler/builtins/array.ts +145 -0
  12. package/compiler/builtins/base64.ts +151 -0
  13. package/compiler/builtins/crypto.ts +120 -0
  14. package/compiler/builtins/date.ts +1856 -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 +42 -0
  19. package/compiler/builtins/string.ts +1055 -0
  20. package/compiler/builtins/tostring.ts +45 -0
  21. package/compiler/builtins.js +470 -269
  22. package/compiler/{codeGen.js → codegen.js} +1156 -418
  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 +1445 -0
  27. package/compiler/index.js +36 -34
  28. package/compiler/log.js +6 -3
  29. package/compiler/opt.js +51 -36
  30. package/compiler/parse.js +33 -23
  31. package/compiler/precompile.js +128 -0
  32. package/compiler/prefs.js +27 -0
  33. package/compiler/prototype.js +177 -37
  34. package/compiler/types.js +37 -0
  35. package/compiler/wasmSpec.js +30 -7
  36. package/compiler/wrap.js +56 -40
  37. package/package.json +9 -5
  38. package/porf +4 -0
  39. package/rhemyn/compile.js +46 -27
  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 +91 -11
  45. package/runner/profiler.js +102 -0
  46. package/runner/repl.js +42 -9
  47. package/runner/sizes.js +37 -37
  48. package/compiler/builtins/base64.js +0 -92
  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
@@ -1,5 +1,8 @@
1
1
  import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
2
2
  import { number, i32x4 } from "./embedding.js";
3
+ import Prefs from './prefs.js';
4
+ import * as GeneratedBuiltins from './generated_builtins.js';
5
+ import { TYPES } from './types.js';
3
6
 
4
7
  export const importedFuncs = [
5
8
  {
@@ -19,6 +22,24 @@ 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
22
43
  }
23
44
  ];
24
45
 
@@ -50,10 +71,10 @@ export const NULL = 0;
50
71
 
51
72
  export const BuiltinVars = function() {
52
73
  this.undefined = number(UNDEFINED);
53
- this.undefined.type = 'undefined';
74
+ this.undefined.type = TYPES.undefined;
54
75
 
55
76
  this.null = number(NULL);
56
- this.null.type = 'object';
77
+ this.null.type = TYPES.object;
57
78
 
58
79
  this.NaN = number(NaN);
59
80
  this.NaN.floatOnly = true;
@@ -117,6 +138,18 @@ export const BuiltinVars = function() {
117
138
 
118
139
  // stubs just so that parent objects exist
119
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
+ ];
120
153
  };
121
154
 
122
155
  export const BuiltinFuncs = function() {
@@ -170,43 +203,25 @@ export const BuiltinFuncs = function() {
170
203
  ]
171
204
  };
172
205
 
173
- // todo: return false for NaN
174
- this.Boolean = {
175
- params: [ valtypeBinary ],
176
- locals: [],
177
- returns: [ valtypeBinary ],
178
- returnType: 'boolean',
179
- wasm: [
180
- [ Opcodes.local_get, 0 ],
181
- ...(valtype === 'f64' ? [
182
- ...number(0),
183
- [ Opcodes.f64_ne ]
184
- ] : [
185
- ...Opcodes.eqz,
186
- [ Opcodes.i32_eqz ]
187
- ]),
188
- Opcodes.i32_from
189
- ]
190
- };
191
-
192
206
  // just return given (default 0) for (new) Object() as we somewhat supports object just not constructor
193
207
  this.Object = {
194
208
  params: [ valtypeBinary ],
195
209
  locals: [],
196
210
  returns: [ valtypeBinary ],
197
- returnType: 'object',
211
+ returnType: TYPES.object,
198
212
  wasm: [
199
- [ Opcodes.local_get, 0 ]
213
+ // [ Opcodes.local_get, 0 ]
214
+ ...number(1)
200
215
  ]
201
216
  };
202
217
 
203
218
 
204
- this.__console_log = {
219
+ this.__Porffor_print = {
205
220
  params: [ valtypeBinary, Valtype.i32 ],
206
221
  typedParams: true,
207
222
  locals: [ Valtype.i32, Valtype.i32 ],
208
223
  returns: [],
209
- wasm: (scope, { TYPES, typeSwitch }) => [
224
+ wasm: (scope, { typeSwitch }) => [
210
225
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
211
226
  [TYPES.number]: [
212
227
  [ Opcodes.local_get, 0 ],
@@ -258,6 +273,40 @@ export const BuiltinFuncs = function() {
258
273
 
259
274
  [ Opcodes.end ]
260
275
  ],
276
+ [TYPES._bytestring]: [
277
+ // simply print a (byte)string :))
278
+ // cache input pointer as i32
279
+ [ Opcodes.local_get, 0 ],
280
+ Opcodes.i32_to_u,
281
+ [ Opcodes.local_tee, 2 ],
282
+
283
+ // make end pointer
284
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
285
+ [ Opcodes.local_get, 2 ],
286
+ [ Opcodes.i32_add ],
287
+ [ Opcodes.local_set, 3 ],
288
+
289
+ [ Opcodes.loop, Blocktype.void ],
290
+
291
+ // print current char
292
+ [ Opcodes.local_get, 2 ],
293
+ [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
294
+ Opcodes.i32_from_u,
295
+ [ Opcodes.call, importedFuncs.printChar ],
296
+
297
+ // increment pointer
298
+ [ Opcodes.local_get, 2 ],
299
+ [ Opcodes.i32_const, 1 ],
300
+ [ Opcodes.i32_add ],
301
+ [ Opcodes.local_tee, 2 ],
302
+
303
+ // if pointer != end pointer, loop
304
+ [ Opcodes.local_get, 3 ],
305
+ [ Opcodes.i32_ne ],
306
+ [ Opcodes.br_if, 0 ],
307
+
308
+ [ Opcodes.end ]
309
+ ],
261
310
  [TYPES._array]: [
262
311
  ...printStaticStr('[ '),
263
312
 
@@ -319,10 +368,7 @@ export const BuiltinFuncs = function() {
319
368
  [ Opcodes.local_get, 0 ],
320
369
  [ Opcodes.call, importedFuncs.print ],
321
370
  ]
322
- }, Blocktype.void),
323
-
324
- ...char('\n'),
325
- [ Opcodes.call, importedFuncs.printChar ]
371
+ }, Blocktype.void)
326
372
  ]
327
373
  };
328
374
 
@@ -334,7 +380,7 @@ export const BuiltinFuncs = function() {
334
380
  params: [ valtypeBinary ],
335
381
  locals: [],
336
382
  returns: [ valtypeBinary ],
337
- returnType: 'boolean',
383
+ returnType: TYPES.boolean,
338
384
  wasm: [
339
385
  [ Opcodes.local_get, 0 ],
340
386
  [ Opcodes.local_get, 0 ],
@@ -349,7 +395,7 @@ export const BuiltinFuncs = function() {
349
395
  params: [ valtypeBinary ],
350
396
  locals: [ valtypeBinary ],
351
397
  returns: [ valtypeBinary ],
352
- returnType: 'boolean',
398
+ returnType: TYPES.boolean,
353
399
  wasm: [
354
400
  [ Opcodes.local_get, 0 ],
355
401
  [ Opcodes.local_get, 0 ],
@@ -368,7 +414,7 @@ export const BuiltinFuncs = function() {
368
414
  params: [ valtypeBinary ],
369
415
  locals: [],
370
416
  returns: [ valtypeBinary ],
371
- returnType: 'boolean',
417
+ returnType: TYPES.boolean,
372
418
  wasm: [
373
419
  [ Opcodes.local_get, 0 ],
374
420
  [ Opcodes.local_get, 0 ],
@@ -383,7 +429,7 @@ export const BuiltinFuncs = function() {
383
429
  params: [ valtypeBinary ],
384
430
  locals: [],
385
431
  returns: [ valtypeBinary ],
386
- returnType: 'boolean',
432
+ returnType: TYPES.boolean,
387
433
  wasm: [
388
434
  [ Opcodes.local_get, 0 ],
389
435
  [ Opcodes.local_get, 0 ],
@@ -523,61 +569,314 @@ export const BuiltinFuncs = function() {
523
569
 
524
570
  // this is an implementation of xorshift128+ (in wasm bytecode)
525
571
  // fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
526
- 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}`);
527
865
 
528
866
  this.__Math_random = {
529
867
  floatOnly: true,
530
868
  params: [],
531
- locals: [ Valtype.i64, Valtype.i64 ],
869
+ locals: prng.locals,
532
870
  localNames: [ 's1', 's0' ],
533
- globals: [ Valtype.i64, Valtype.i64 ],
871
+ globals: prng.globals,
534
872
  globalNames: [ 'state0', 'state1' ],
535
873
  globalInits: [ prngSeed0, prngSeed1 ],
536
874
  returns: [ Valtype.f64 ],
537
875
  wasm: [
538
- // setup: s1 = state0, s0 = state1, state0 = s0
539
- [ Opcodes.global_get, 0 ], // state0
540
- [ Opcodes.local_tee, 0 ], // s1
541
- [ Opcodes.global_get, 1 ], // state1
542
- [ Opcodes.local_tee, 1, ], // s0
543
- [ Opcodes.global_set, 0 ], // state0
544
-
545
- // s1 ^= s1 << 23
546
- // [ Opcodes.local_get, 0 ], // s1
547
- [ Opcodes.local_get, 0 ], // s1
548
- [ Opcodes.i64_const, 23 ],
549
- [ Opcodes.i64_shl ], // <<
550
- [ Opcodes.i64_xor ], // ^
551
- [ Opcodes.local_set, 0 ], // s1
552
-
553
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
554
- // s1 ^ s0
555
- [ Opcodes.local_get, 0 ], // s1
556
- [ Opcodes.local_get, 1 ], // s0
557
- [ Opcodes.i64_xor ], // ^
558
-
559
- // ^ (s1 >> 17)
560
- [ Opcodes.local_get, 0 ], // s1
561
- [ Opcodes.i64_const, 17 ],
562
- [ Opcodes.i64_shr_u ], // >>
563
- [ Opcodes.i64_xor ], // ^
564
-
565
- // ^ (s0 >> 26)
566
- [ Opcodes.local_get, 1 ], // s0
567
- [ Opcodes.i64_const, 26 ],
568
- [ Opcodes.i64_shr_u ], // >>
569
- [ Opcodes.i64_xor ], // ^
570
-
571
- // state1 =
572
- [ Opcodes.global_set, 1 ],
876
+ ...prng.wasm,
573
877
 
574
878
  // you thought it was over? now we need the result as a f64 between 0-1 :)
575
879
 
576
- // state1 + s0
577
- [ Opcodes.global_get, 1 ], // state1
578
- [ Opcodes.local_get, 1 ], // s0
579
- [ Opcodes.i64_add ],
580
-
581
880
  // should we >> 12 here?
582
881
  // it feels like it but it breaks values
583
882
 
@@ -592,15 +891,72 @@ export const BuiltinFuncs = function() {
592
891
  // ...number(1),
593
892
  // [ Opcodes.f64_sub ],
594
893
 
595
- ...number((1 << 53) - 1, Valtype.i64),
596
- [ 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 ],
597
907
 
598
- // double(mantissa)
599
- [ Opcodes.f64_convert_i64_u ],
908
+ // double(mantissa)
909
+ [ Opcodes.f64_convert_i32_u ],
600
910
 
601
- // / (1 << 53)
602
- ...number(1 << 53),
603
- [ Opcodes.f64_div ]
911
+ // / (1 << 21)
912
+ ...number(1 << 21),
913
+ [ Opcodes.f64_div ]
914
+ ])
915
+ ]
916
+ };
917
+
918
+ // this.__Porffor_randomInt = {
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
+ // };
938
+
939
+ this.__Porffor_randomByte = {
940
+ params: [],
941
+ locals: prng.locals,
942
+ localNames: [ 's1', 's0' ],
943
+ globals: prng.globals,
944
+ globalNames: [ 'state0', 'state1' ],
945
+ globalInits: [ prngSeed0, prngSeed1 ],
946
+ returns: [ Valtype.i32 ],
947
+ wasm: [
948
+ ...prng.wasm,
949
+
950
+ ...(prng.returns === Valtype.i64 ? [
951
+ // the lowest bits of the output generated by xorshift128+ have low quality
952
+ ...number(56, Valtype.i64),
953
+ [ Opcodes.i64_shr_u ],
954
+
955
+ [ Opcodes.i32_wrap_i64 ],
956
+ ] : []),
957
+
958
+ ...number(0xff, Valtype.i32),
959
+ [ Opcodes.i32_and ],
604
960
  ]
605
961
  };
606
962
 
@@ -679,7 +1035,7 @@ export const BuiltinFuncs = function() {
679
1035
  params: [ valtypeBinary ],
680
1036
  locals: [],
681
1037
  returns: [ valtypeBinary ],
682
- returnType: 'boolean',
1038
+ returnType: TYPES.boolean,
683
1039
  wasm: [
684
1040
  [ Opcodes.local_get, 0 ],
685
1041
  ...number(0),
@@ -699,206 +1055,51 @@ export const BuiltinFuncs = function() {
699
1055
  };
700
1056
 
701
1057
 
702
- this.__SIMD_i32x4_load = {
703
- params: [ Valtype.i32 ],
704
- locals: [],
705
- returns: [ Valtype.v128 ],
706
- wasm: [
707
- [ Opcodes.local_get, 0 ],
708
- [ ...Opcodes.v128_load, 0, 0 ]
709
- ]
710
- };
711
-
712
- this.__SIMD_i32x4_splat = {
713
- params: [ Valtype.i32 ],
714
- locals: [],
715
- returns: [ Valtype.v128 ],
716
- wasm: [
717
- [ Opcodes.local_get, 0 ],
718
- [ ...Opcodes.i32x4_splat ],
719
- ]
720
- };
721
-
722
- this.__SIMD_i16x8_create = {
723
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
724
- locals: [],
725
- returns: [ Valtype.v128 ],
726
- wasm: [
727
- ...i32x4(0, 0, 0, 0),
728
- [ Opcodes.local_get, 0 ],
729
- [ ...Opcodes.i16x8_replace_lane, 0 ],
730
- [ Opcodes.local_get, 1 ],
731
- [ ...Opcodes.i16x8_replace_lane, 1 ],
732
- [ Opcodes.local_get, 2 ],
733
- [ ...Opcodes.i16x8_replace_lane, 2 ],
734
- [ Opcodes.local_get, 3 ],
735
- [ ...Opcodes.i16x8_replace_lane, 3 ],
736
- [ Opcodes.local_get, 4 ],
737
- [ ...Opcodes.i16x8_replace_lane, 4 ],
738
- [ Opcodes.local_get, 5 ],
739
- [ ...Opcodes.i16x8_replace_lane, 5 ],
740
- [ Opcodes.local_get, 6 ],
741
- [ ...Opcodes.i16x8_replace_lane, 6 ],
742
- [ Opcodes.local_get, 7 ],
743
- [ ...Opcodes.i16x8_replace_lane, 7 ],
744
- ]
745
- };
746
-
747
- this.__SIMD_i32x4_dot_i16x8 = {
748
- params: [ Valtype.v128, Valtype.v128 ],
749
- locals: [],
750
- returns: [ Valtype.v128 ],
751
- wasm: [
752
- [ Opcodes.local_get, 0 ],
753
- [ Opcodes.local_get, 1 ],
754
- [ ...Opcodes.i32x4_dot_i16x8_s ]
755
- ]
756
- };
757
-
758
- this.__SIMD_i32x4_create = {
759
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
760
- locals: [],
761
- returns: [ Valtype.v128 ],
762
- wasm: [
763
- ...i32x4(0, 0, 0, 0),
764
- [ Opcodes.local_get, 0 ],
765
- [ ...Opcodes.i32x4_replace_lane, 0 ],
766
- [ Opcodes.local_get, 1 ],
767
- [ ...Opcodes.i32x4_replace_lane, 1 ],
768
- [ Opcodes.local_get, 2 ],
769
- [ ...Opcodes.i32x4_replace_lane, 2 ],
770
- [ Opcodes.local_get, 3 ],
771
- [ ...Opcodes.i32x4_replace_lane, 3 ],
772
- ]
773
- };
774
-
775
- this.__SIMD_i32x4_add = {
776
- params: [ Valtype.v128, Valtype.v128 ],
777
- locals: [],
778
- returns: [ Valtype.v128 ],
779
- wasm: [
780
- [ Opcodes.local_get, 0 ],
781
- [ Opcodes.local_get, 1 ],
782
- [ ...Opcodes.i32x4_add ]
783
- ]
1058
+ this.__Porffor_type = {
1059
+ params: [ valtypeBinary, Valtype.i32 ],
1060
+ typedParams: true,
1061
+ locals: [ Valtype.i32, Valtype.i32 ],
1062
+ returns: [ valtypeBinary ],
1063
+ returnType: Prefs.bytestring ? TYPES._bytestring : TYPES.string,
1064
+ wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
1065
+ const bc = {};
1066
+ for (const x in TYPE_NAMES) {
1067
+ bc[x] = makeString(scope, TYPE_NAMES[x], false, '#Porffor_type_result');
1068
+ }
1069
+
1070
+ return typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], bc);
1071
+ }
784
1072
  };
785
1073
 
786
- this.__SIMD_i32x4_sub = {
787
- params: [ Valtype.v128, Valtype.v128 ],
1074
+ this.__Porffor_rawType = {
1075
+ params: [ valtypeBinary, Valtype.i32 ],
1076
+ typedParams: true,
788
1077
  locals: [],
789
- returns: [ Valtype.v128 ],
1078
+ returns: [ valtypeBinary ],
790
1079
  wasm: [
791
- [ Opcodes.local_get, 0 ],
792
1080
  [ Opcodes.local_get, 1 ],
793
- [ ...Opcodes.i32x4_sub ]
1081
+ Opcodes.i32_from_u
794
1082
  ]
795
1083
  };
796
1084
 
797
- this.__SIMD_i32x4_mul = {
798
- params: [ Valtype.v128, Valtype.v128 ],
1085
+ this.__Porffor_clone = {
1086
+ params: [ valtypeBinary, valtypeBinary ],
799
1087
  locals: [],
800
- returns: [ Valtype.v128 ],
1088
+ returns: [],
801
1089
  wasm: [
802
- [ Opcodes.local_get, 0 ],
1090
+ // dst
803
1091
  [ Opcodes.local_get, 1 ],
804
- [ ...Opcodes.i32x4_mul ]
805
- ]
806
- };
807
-
808
- this.__SIMD_i32x4_get0 = {
809
- params: [ Valtype.v128 ],
810
- locals: [],
811
- returns: [ Valtype.i32 ],
812
- wasm: [
813
- [ Opcodes.local_get, 0 ],
814
- [ ...Opcodes.i32x4_extract_lane, 0 ],
815
- ],
816
- },
1092
+ Opcodes.i32_to_u,
817
1093
 
818
- this.__SIMD_i32x4_get1 = {
819
- params: [ Valtype.v128 ],
820
- locals: [],
821
- returns: [ Valtype.i32 ],
822
- wasm: [
1094
+ // src
823
1095
  [ Opcodes.local_get, 0 ],
824
- [ ...Opcodes.i32x4_extract_lane, 1 ],
825
- ],
826
- };
1096
+ Opcodes.i32_to_u,
827
1097
 
828
- this.__SIMD_i32x4_get2 = {
829
- params: [ Valtype.v128 ],
830
- locals: [],
831
- returns: [ Valtype.i32 ],
832
- wasm: [
833
- [ Opcodes.local_get, 0 ],
834
- [ ...Opcodes.i32x4_extract_lane, 2 ],
835
- ],
836
- };
837
-
838
- this.__SIMD_i32x4_get3 = {
839
- params: [ Valtype.v128 ],
840
- locals: [],
841
- returns: [ Valtype.i32 ],
842
- wasm: [
843
- [ Opcodes.local_get, 0 ],
844
- [ ...Opcodes.i32x4_extract_lane, 3 ],
845
- ],
846
- };
847
-
848
- this.__SIMD_i32x4_shuffle_000c = {
849
- params: [ Valtype.v128 ],
850
- locals: [],
851
- returns: [ Valtype.v128 ],
852
- wasm: [
853
- [ Opcodes.local_get, 0 ],
854
- ...i32x4(0, 0, 0, 0),
855
- [ ...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)
1098
+ // size = pageSize
1099
+ ...number(pageSize, Valtype.i32),
1100
+ [ ...Opcodes.memory_copy, 0x00, 0x00 ],
856
1101
  ]
857
1102
  };
858
1103
 
859
- this.__SIMD_i32x4_shuffle_00ab = {
860
- params: [ Valtype.v128 ],
861
- locals: [],
862
- returns: [ Valtype.v128 ],
863
- wasm: [
864
- [ Opcodes.local_get, 0 ],
865
- ...i32x4(0, 0, 0, 0),
866
- [ ...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)
867
- ]
868
- };
869
- };
870
-
871
- export const BuiltinPreludes = {
872
- btoa: `var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
873
- var btoa = function (input) {
874
- // todo: throw invalid character for unicode
875
-
876
- let output = "";
877
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
878
- let i = 0;
879
-
880
- while (i < input.length) {
881
- chr1 = input.charCodeAt(i++);
882
- chr2 = input.charCodeAt(i++);
883
- chr3 = input.charCodeAt(i++);
884
-
885
- enc1 = chr1 >> 2;
886
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
887
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
888
- enc4 = chr3 & 63;
889
-
890
- if (isNaN(chr2)) {
891
- enc3 = enc4 = 64;
892
- } else if (isNaN(chr3)) {
893
- enc4 = 64;
894
- }
895
-
896
- output += keyStr.charAt(enc1);
897
- output += keyStr.charAt(enc2);
898
- output += keyStr.charAt(enc3);
899
- output += keyStr.charAt(enc4);
900
- }
901
-
902
- return output;
903
- };`
1104
+ GeneratedBuiltins.BuiltinFuncs.call(this);
904
1105
  };