porffor 0.2.0-fde989a → 0.14.0-4057a18e9

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 (60) hide show
  1. package/CONTRIBUTING.md +256 -0
  2. package/LICENSE +20 -20
  3. package/README.md +131 -86
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +216 -0
  7. package/compiler/2c.js +2 -53
  8. package/compiler/{sections.js → assemble.js} +84 -21
  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 +76 -0
  13. package/compiler/builtins/boolean.ts +18 -0
  14. package/compiler/builtins/crypto.ts +120 -0
  15. package/compiler/builtins/date.ts +2067 -0
  16. package/compiler/builtins/escape.ts +141 -0
  17. package/compiler/builtins/function.ts +5 -0
  18. package/compiler/builtins/int.ts +145 -0
  19. package/compiler/builtins/number.ts +529 -0
  20. package/compiler/builtins/object.ts +4 -0
  21. package/compiler/builtins/porffor.d.ts +60 -0
  22. package/compiler/builtins/set.ts +187 -0
  23. package/compiler/builtins/string.ts +1080 -0
  24. package/compiler/builtins.js +436 -283
  25. package/compiler/{codeGen.js → codegen.js} +1027 -482
  26. package/compiler/decompile.js +2 -3
  27. package/compiler/embedding.js +22 -22
  28. package/compiler/encoding.js +94 -10
  29. package/compiler/expression.js +1 -1
  30. package/compiler/generated_builtins.js +1625 -0
  31. package/compiler/index.js +25 -36
  32. package/compiler/log.js +6 -3
  33. package/compiler/opt.js +55 -41
  34. package/compiler/parse.js +38 -30
  35. package/compiler/precompile.js +120 -0
  36. package/compiler/prefs.js +27 -0
  37. package/compiler/prototype.js +31 -46
  38. package/compiler/types.js +38 -0
  39. package/compiler/wasmSpec.js +33 -8
  40. package/compiler/wrap.js +88 -70
  41. package/package.json +9 -5
  42. package/porf +2 -0
  43. package/rhemyn/compile.js +46 -27
  44. package/rhemyn/parse.js +322 -320
  45. package/rhemyn/test/parse.js +58 -58
  46. package/runner/compare.js +33 -34
  47. package/runner/debug.js +117 -0
  48. package/runner/index.js +78 -11
  49. package/runner/profiler.js +75 -0
  50. package/runner/repl.js +40 -13
  51. package/runner/sizes.js +37 -37
  52. package/runner/version.js +10 -8
  53. package/compiler/builtins/base64.js +0 -92
  54. package/filesize.cmd +0 -2
  55. package/runner/info.js +0 -89
  56. package/runner/profile.js +0 -46
  57. package/runner/results.json +0 -1
  58. package/runner/transform.js +0 -15
  59. package/tmp.c +0 -661
  60. package/util/enum.js +0 -20
@@ -1,5 +1,8 @@
1
- import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
2
- import { number, i32x4 } from "./embedding.js";
1
+ import * as GeneratedBuiltins from './generated_builtins.js';
2
+ import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
3
+ import { number } from './embedding.js';
4
+ import { TYPES } from './types.js';
5
+ import Prefs from './prefs.js';
3
6
 
4
7
  export const importedFuncs = [
5
8
  {
@@ -19,6 +22,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
 
@@ -27,8 +48,6 @@ for (let i = 0; i < importedFuncs.length; i++) {
27
48
  importedFuncs[f.name] = i;
28
49
  }
29
50
 
30
- const char = c => number(c.charCodeAt(0));
31
-
32
51
  const printStaticStr = str => {
33
52
  const out = [];
34
53
 
@@ -50,10 +69,10 @@ export const NULL = 0;
50
69
 
51
70
  export const BuiltinVars = function() {
52
71
  this.undefined = number(UNDEFINED);
53
- this.undefined.type = 'undefined';
72
+ this.undefined.type = TYPES.undefined;
54
73
 
55
74
  this.null = number(NULL);
56
- this.null.type = 'object';
75
+ this.null.type = TYPES.object;
57
76
 
58
77
  this.NaN = number(NaN);
59
78
  this.NaN.floatOnly = true;
@@ -117,6 +136,18 @@ export const BuiltinVars = function() {
117
136
 
118
137
  // stubs just so that parent objects exist
119
138
  this.Math = number(1);
139
+
140
+ // wintercg(tm)
141
+ this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.14.0`, false, '__navigator_userAgent');
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
+ ];
120
151
  };
121
152
 
122
153
  export const BuiltinFuncs = function() {
@@ -175,19 +206,20 @@ export const BuiltinFuncs = function() {
175
206
  params: [ valtypeBinary ],
176
207
  locals: [],
177
208
  returns: [ valtypeBinary ],
178
- returnType: 'object',
209
+ returnType: TYPES.object,
179
210
  wasm: [
180
- [ Opcodes.local_get, 0 ]
211
+ // [ Opcodes.local_get, 0 ]
212
+ ...number(1)
181
213
  ]
182
214
  };
183
215
 
184
216
 
185
- this.__console_log = {
217
+ this.__Porffor_print = {
186
218
  params: [ valtypeBinary, Valtype.i32 ],
187
219
  typedParams: true,
188
220
  locals: [ Valtype.i32, Valtype.i32 ],
189
221
  returns: [],
190
- wasm: (scope, { TYPES, typeSwitch }) => [
222
+ wasm: (scope, { typeSwitch }) => [
191
223
  ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
192
224
  [TYPES.number]: [
193
225
  [ Opcodes.local_get, 0 ],
@@ -239,7 +271,41 @@ export const BuiltinFuncs = function() {
239
271
 
240
272
  [ Opcodes.end ]
241
273
  ],
242
- [TYPES._array]: [
274
+ [TYPES.bytestring]: [
275
+ // simply print a (byte)string :))
276
+ // cache input pointer as i32
277
+ [ Opcodes.local_get, 0 ],
278
+ Opcodes.i32_to_u,
279
+ [ Opcodes.local_tee, 2 ],
280
+
281
+ // make end pointer
282
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
283
+ [ Opcodes.local_get, 2 ],
284
+ [ Opcodes.i32_add ],
285
+ [ Opcodes.local_set, 3 ],
286
+
287
+ [ Opcodes.loop, Blocktype.void ],
288
+
289
+ // print current char
290
+ [ Opcodes.local_get, 2 ],
291
+ [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
292
+ Opcodes.i32_from_u,
293
+ [ Opcodes.call, importedFuncs.printChar ],
294
+
295
+ // increment pointer
296
+ [ Opcodes.local_get, 2 ],
297
+ [ Opcodes.i32_const, 1 ],
298
+ [ Opcodes.i32_add ],
299
+ [ Opcodes.local_tee, 2 ],
300
+
301
+ // if pointer != end pointer, loop
302
+ [ Opcodes.local_get, 3 ],
303
+ [ Opcodes.i32_ne ],
304
+ [ Opcodes.br_if, 0 ],
305
+
306
+ [ Opcodes.end ]
307
+ ],
308
+ [TYPES.array]: [
243
309
  ...printStaticStr('[ '),
244
310
 
245
311
  // cache input pointer as i32
@@ -300,10 +366,7 @@ export const BuiltinFuncs = function() {
300
366
  [ Opcodes.local_get, 0 ],
301
367
  [ Opcodes.call, importedFuncs.print ],
302
368
  ]
303
- }, Blocktype.void),
304
-
305
- ...char('\n'),
306
- [ Opcodes.call, importedFuncs.printChar ]
369
+ }, Blocktype.void)
307
370
  ]
308
371
  };
309
372
 
@@ -315,7 +378,7 @@ export const BuiltinFuncs = function() {
315
378
  params: [ valtypeBinary ],
316
379
  locals: [],
317
380
  returns: [ valtypeBinary ],
318
- returnType: 'boolean',
381
+ returnType: TYPES.boolean,
319
382
  wasm: [
320
383
  [ Opcodes.local_get, 0 ],
321
384
  [ Opcodes.local_get, 0 ],
@@ -330,7 +393,7 @@ export const BuiltinFuncs = function() {
330
393
  params: [ valtypeBinary ],
331
394
  locals: [ valtypeBinary ],
332
395
  returns: [ valtypeBinary ],
333
- returnType: 'boolean',
396
+ returnType: TYPES.boolean,
334
397
  wasm: [
335
398
  [ Opcodes.local_get, 0 ],
336
399
  [ Opcodes.local_get, 0 ],
@@ -349,7 +412,7 @@ export const BuiltinFuncs = function() {
349
412
  params: [ valtypeBinary ],
350
413
  locals: [],
351
414
  returns: [ valtypeBinary ],
352
- returnType: 'boolean',
415
+ returnType: TYPES.boolean,
353
416
  wasm: [
354
417
  [ Opcodes.local_get, 0 ],
355
418
  [ Opcodes.local_get, 0 ],
@@ -364,7 +427,7 @@ export const BuiltinFuncs = function() {
364
427
  params: [ valtypeBinary ],
365
428
  locals: [],
366
429
  returns: [ valtypeBinary ],
367
- returnType: 'boolean',
430
+ returnType: TYPES.boolean,
368
431
  wasm: [
369
432
  [ Opcodes.local_get, 0 ],
370
433
  [ Opcodes.local_get, 0 ],
@@ -504,61 +567,313 @@ export const BuiltinFuncs = function() {
504
567
 
505
568
  // this is an implementation of xorshift128+ (in wasm bytecode)
506
569
  // fun fact: v8, SM, JSC also use this (you will need this fun fact to maintain your sanity reading this code)
507
- const prngSeed0 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER), prngSeed1 = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
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}`);
508
862
 
509
863
  this.__Math_random = {
510
864
  floatOnly: true,
511
865
  params: [],
512
- locals: [ Valtype.i64, Valtype.i64 ],
866
+ locals: prng.locals,
513
867
  localNames: [ 's1', 's0' ],
514
- globals: [ Valtype.i64, Valtype.i64 ],
868
+ globals: prng.globals,
515
869
  globalNames: [ 'state0', 'state1' ],
516
870
  globalInits: [ prngSeed0, prngSeed1 ],
517
871
  returns: [ Valtype.f64 ],
518
872
  wasm: [
519
- // setup: s1 = state0, s0 = state1, state0 = s0
520
- [ Opcodes.global_get, 0 ], // state0
521
- [ Opcodes.local_tee, 0 ], // s1
522
- [ Opcodes.global_get, 1 ], // state1
523
- [ Opcodes.local_tee, 1, ], // s0
524
- [ Opcodes.global_set, 0 ], // state0
525
-
526
- // s1 ^= s1 << 23
527
- // [ Opcodes.local_get, 0 ], // s1
528
- [ Opcodes.local_get, 0 ], // s1
529
- [ Opcodes.i64_const, 23 ],
530
- [ Opcodes.i64_shl ], // <<
531
- [ Opcodes.i64_xor ], // ^
532
- [ Opcodes.local_set, 0 ], // s1
533
-
534
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
535
- // s1 ^ s0
536
- [ Opcodes.local_get, 0 ], // s1
537
- [ Opcodes.local_get, 1 ], // s0
538
- [ Opcodes.i64_xor ], // ^
539
-
540
- // ^ (s1 >> 17)
541
- [ Opcodes.local_get, 0 ], // s1
542
- [ Opcodes.i64_const, 17 ],
543
- [ Opcodes.i64_shr_u ], // >>
544
- [ Opcodes.i64_xor ], // ^
545
-
546
- // ^ (s0 >> 26)
547
- [ Opcodes.local_get, 1 ], // s0
548
- [ Opcodes.i64_const, 26 ],
549
- [ Opcodes.i64_shr_u ], // >>
550
- [ Opcodes.i64_xor ], // ^
551
-
552
- // state1 =
553
- [ Opcodes.global_set, 1 ],
873
+ ...prng.wasm,
554
874
 
555
875
  // you thought it was over? now we need the result as a f64 between 0-1 :)
556
876
 
557
- // state1 + s0
558
- [ Opcodes.global_get, 1 ], // state1
559
- [ Opcodes.local_get, 1 ], // s0
560
- [ Opcodes.i64_add ],
561
-
562
877
  // should we >> 12 here?
563
878
  // it feels like it but it breaks values
564
879
 
@@ -573,15 +888,51 @@ export const BuiltinFuncs = function() {
573
888
  // ...number(1),
574
889
  // [ Opcodes.f64_sub ],
575
890
 
576
- ...number((1 << 53) - 1, Valtype.i64),
577
- [ Opcodes.i64_and ],
891
+ ...(prng.returns === Valtype.i64 ? [
892
+ ...number((1 << 53) - 1, Valtype.i64),
893
+ [ Opcodes.i64_and ],
894
+
895
+ // double(mantissa)
896
+ [ Opcodes.f64_convert_i64_u ],
578
897
 
579
- // double(mantissa)
580
- [ Opcodes.f64_convert_i64_u ],
898
+ // / (1 << 53)
899
+ ...number(1 << 53),
900
+ [ Opcodes.f64_div ]
901
+ ] : [
902
+ ...number((1 << 21) - 1, Valtype.i32),
903
+ [ Opcodes.i32_and ],
581
904
 
582
- // / (1 << 53)
583
- ...number(1 << 53),
584
- [ Opcodes.f64_div ]
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 ],
585
936
  ]
586
937
  };
587
938
 
@@ -660,7 +1011,7 @@ export const BuiltinFuncs = function() {
660
1011
  params: [ valtypeBinary ],
661
1012
  locals: [],
662
1013
  returns: [ valtypeBinary ],
663
- returnType: 'boolean',
1014
+ returnType: TYPES.boolean,
664
1015
  wasm: [
665
1016
  [ Opcodes.local_get, 0 ],
666
1017
  ...number(0),
@@ -685,7 +1036,7 @@ export const BuiltinFuncs = function() {
685
1036
  typedParams: true,
686
1037
  locals: [ Valtype.i32, Valtype.i32 ],
687
1038
  returns: [ valtypeBinary ],
688
- returnType: process.argv.includes('-bytestring') ? '_bytestring' : 'string',
1039
+ returnType: Prefs.bytestring ? TYPES.bytestring : TYPES.string,
689
1040
  wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
690
1041
  const bc = {};
691
1042
  for (const x in TYPE_NAMES) {
@@ -696,233 +1047,35 @@ export const BuiltinFuncs = function() {
696
1047
  }
697
1048
  };
698
1049
 
699
- const localIsOneOf = (getter, arr, valtype = valtypeBinary) => {
700
- const out = [];
701
-
702
- for (let i = 0; i < arr.length; i++) {
703
- out.push(...getter, ...number(arr[i], valtype), valtype === Valtype.f64 ? [ Opcodes.f64_eq ] : [ Opcodes.i32_eq ]);
704
- if (i !== 0) out.push([ Opcodes.i32_or ]);
705
- }
706
-
707
- return out;
708
- };
709
-
710
- this.__Porffor_pointer = {
1050
+ this.__Porffor_rawType = {
711
1051
  params: [ valtypeBinary, Valtype.i32 ],
712
1052
  typedParams: true,
713
- locals: [ Valtype.i32, Valtype.i32 ],
714
- returns: [ valtypeBinary ],
715
- wasm: (scope, { TYPES }) => [
716
- ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
717
- [ Opcodes.if, valtypeBinary ],
718
- [ Opcodes.local_get, 0 ],
719
- [ Opcodes.else ],
720
- ...number(NaN),
721
- [ Opcodes.end ]
722
- ]
723
- };
724
-
725
-
726
- this.__SIMD_i32x4_load = {
727
- params: [ Valtype.i32 ],
728
- locals: [],
729
- returns: [ Valtype.v128 ],
730
- wasm: [
731
- [ Opcodes.local_get, 0 ],
732
- [ ...Opcodes.v128_load, 0, 0 ]
733
- ]
734
- };
735
-
736
- this.__SIMD_i32x4_splat = {
737
- params: [ Valtype.i32 ],
738
- locals: [],
739
- returns: [ Valtype.v128 ],
740
- wasm: [
741
- [ Opcodes.local_get, 0 ],
742
- [ ...Opcodes.i32x4_splat ],
743
- ]
744
- };
745
-
746
- this.__SIMD_i16x8_create = {
747
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
748
1053
  locals: [],
749
- returns: [ Valtype.v128 ],
750
- wasm: [
751
- ...i32x4(0, 0, 0, 0),
752
- [ Opcodes.local_get, 0 ],
753
- [ ...Opcodes.i16x8_replace_lane, 0 ],
754
- [ Opcodes.local_get, 1 ],
755
- [ ...Opcodes.i16x8_replace_lane, 1 ],
756
- [ Opcodes.local_get, 2 ],
757
- [ ...Opcodes.i16x8_replace_lane, 2 ],
758
- [ Opcodes.local_get, 3 ],
759
- [ ...Opcodes.i16x8_replace_lane, 3 ],
760
- [ Opcodes.local_get, 4 ],
761
- [ ...Opcodes.i16x8_replace_lane, 4 ],
762
- [ Opcodes.local_get, 5 ],
763
- [ ...Opcodes.i16x8_replace_lane, 5 ],
764
- [ Opcodes.local_get, 6 ],
765
- [ ...Opcodes.i16x8_replace_lane, 6 ],
766
- [ Opcodes.local_get, 7 ],
767
- [ ...Opcodes.i16x8_replace_lane, 7 ],
768
- ]
769
- };
770
-
771
- this.__SIMD_i32x4_dot_i16x8 = {
772
- params: [ Valtype.v128, Valtype.v128 ],
773
- locals: [],
774
- returns: [ Valtype.v128 ],
775
- wasm: [
776
- [ Opcodes.local_get, 0 ],
777
- [ Opcodes.local_get, 1 ],
778
- [ ...Opcodes.i32x4_dot_i16x8_s ]
779
- ]
780
- };
781
-
782
- this.__SIMD_i32x4_create = {
783
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
784
- locals: [],
785
- returns: [ Valtype.v128 ],
786
- wasm: [
787
- ...i32x4(0, 0, 0, 0),
788
- [ Opcodes.local_get, 0 ],
789
- [ ...Opcodes.i32x4_replace_lane, 0 ],
790
- [ Opcodes.local_get, 1 ],
791
- [ ...Opcodes.i32x4_replace_lane, 1 ],
792
- [ Opcodes.local_get, 2 ],
793
- [ ...Opcodes.i32x4_replace_lane, 2 ],
794
- [ Opcodes.local_get, 3 ],
795
- [ ...Opcodes.i32x4_replace_lane, 3 ],
796
- ]
797
- };
798
-
799
- this.__SIMD_i32x4_add = {
800
- params: [ Valtype.v128, Valtype.v128 ],
801
- locals: [],
802
- returns: [ Valtype.v128 ],
803
- wasm: [
804
- [ Opcodes.local_get, 0 ],
805
- [ Opcodes.local_get, 1 ],
806
- [ ...Opcodes.i32x4_add ]
807
- ]
808
- };
809
-
810
- this.__SIMD_i32x4_sub = {
811
- params: [ Valtype.v128, Valtype.v128 ],
812
- locals: [],
813
- returns: [ Valtype.v128 ],
1054
+ returns: [ valtypeBinary ],
814
1055
  wasm: [
815
- [ Opcodes.local_get, 0 ],
816
1056
  [ Opcodes.local_get, 1 ],
817
- [ ...Opcodes.i32x4_sub ]
1057
+ Opcodes.i32_from_u
818
1058
  ]
819
1059
  };
820
1060
 
821
- this.__SIMD_i32x4_mul = {
822
- params: [ Valtype.v128, Valtype.v128 ],
1061
+ this.__Porffor_clone = {
1062
+ params: [ valtypeBinary, valtypeBinary ],
823
1063
  locals: [],
824
- returns: [ Valtype.v128 ],
1064
+ returns: [],
825
1065
  wasm: [
826
- [ Opcodes.local_get, 0 ],
1066
+ // dst
827
1067
  [ Opcodes.local_get, 1 ],
828
- [ ...Opcodes.i32x4_mul ]
829
- ]
830
- };
831
-
832
- this.__SIMD_i32x4_get0 = {
833
- params: [ Valtype.v128 ],
834
- locals: [],
835
- returns: [ Valtype.i32 ],
836
- wasm: [
837
- [ Opcodes.local_get, 0 ],
838
- [ ...Opcodes.i32x4_extract_lane, 0 ],
839
- ],
840
- },
841
-
842
- this.__SIMD_i32x4_get1 = {
843
- params: [ Valtype.v128 ],
844
- locals: [],
845
- returns: [ Valtype.i32 ],
846
- wasm: [
847
- [ Opcodes.local_get, 0 ],
848
- [ ...Opcodes.i32x4_extract_lane, 1 ],
849
- ],
850
- };
851
-
852
- this.__SIMD_i32x4_get2 = {
853
- params: [ Valtype.v128 ],
854
- locals: [],
855
- returns: [ Valtype.i32 ],
856
- wasm: [
857
- [ Opcodes.local_get, 0 ],
858
- [ ...Opcodes.i32x4_extract_lane, 2 ],
859
- ],
860
- };
1068
+ Opcodes.i32_to_u,
861
1069
 
862
- this.__SIMD_i32x4_get3 = {
863
- params: [ Valtype.v128 ],
864
- locals: [],
865
- returns: [ Valtype.i32 ],
866
- wasm: [
1070
+ // src
867
1071
  [ Opcodes.local_get, 0 ],
868
- [ ...Opcodes.i32x4_extract_lane, 3 ],
869
- ],
870
- };
1072
+ Opcodes.i32_to_u,
871
1073
 
872
- this.__SIMD_i32x4_shuffle_000c = {
873
- params: [ Valtype.v128 ],
874
- locals: [],
875
- returns: [ Valtype.v128 ],
876
- wasm: [
877
- [ Opcodes.local_get, 0 ],
878
- ...i32x4(0, 0, 0, 0),
879
- [ ...Opcodes.i8x16_shuffle, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 9, 10, 11 ], // i32x4 (a, b, c, d) -> i32x4 (0, 0, 0, c)
1074
+ // size = pageSize
1075
+ ...number(pageSize, Valtype.i32),
1076
+ [ ...Opcodes.memory_copy, 0x00, 0x00 ],
880
1077
  ]
881
1078
  };
882
1079
 
883
- this.__SIMD_i32x4_shuffle_00ab = {
884
- params: [ Valtype.v128 ],
885
- locals: [],
886
- returns: [ Valtype.v128 ],
887
- wasm: [
888
- [ Opcodes.local_get, 0 ],
889
- ...i32x4(0, 0, 0, 0),
890
- [ ...Opcodes.i8x16_shuffle, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 2, 3, 4, 5, 6, 7 ], // i32x4 (a, b, c, d) -> i32x4 (0, 0, a, b)
891
- ]
892
- };
893
- };
894
-
895
- export const BuiltinPreludes = {
896
- btoa: `var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
897
- var btoa = function (input) {
898
- // todo: throw invalid character for unicode
899
-
900
- let output = "";
901
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
902
- let i = 0;
903
-
904
- while (i < input.length) {
905
- chr1 = input.charCodeAt(i++);
906
- chr2 = input.charCodeAt(i++);
907
- chr3 = input.charCodeAt(i++);
908
-
909
- enc1 = chr1 >> 2;
910
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
911
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
912
- enc4 = chr3 & 63;
913
-
914
- if (isNaN(chr2)) {
915
- enc3 = enc4 = 64;
916
- } else if (isNaN(chr3)) {
917
- enc4 = 64;
918
- }
919
-
920
- output += keyStr.charAt(enc1);
921
- output += keyStr.charAt(enc2);
922
- output += keyStr.charAt(enc3);
923
- output += keyStr.charAt(enc4);
924
- }
925
-
926
- return output;
927
- };`
1080
+ GeneratedBuiltins.BuiltinFuncs.call(this);
928
1081
  };