porffor 0.2.0-5e33105 → 0.2.0-6aff0fa

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.
@@ -0,0 +1,23 @@
1
+ export type i32 = number;
2
+ export type i64 = number;
3
+ export type bytestring = string;
4
+
5
+ type PorfforGlobal = {
6
+ wasm: {
7
+ (...args: any[]): void;
8
+ i32: {
9
+ load8_u: (pointer: i32, align: i32, offset: i32) => i32;
10
+ store8: (pointer: i32, value: i32, align: i32, offset: i32) => i32;
11
+ }
12
+ }
13
+ ptr: (obj: any) => i32;
14
+
15
+ i32: {
16
+ ptr: (obj: any) => i32;
17
+ ptrUnsafe: (obj: any) => i32;
18
+ }
19
+ };
20
+
21
+ declare global {
22
+ const Porffor: PorfforGlobal;
23
+ }
@@ -1,5 +1,7 @@
1
- import { Blocktype, Opcodes, Valtype } from "./wasmSpec.js";
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';
3
5
 
4
6
  export const importedFuncs = [
5
7
  {
@@ -19,8 +21,14 @@ export const importedFuncs = [
19
21
  import: 't',
20
22
  params: 0,
21
23
  returns: 1
24
+ },
25
+ {
26
+ name: 'profile',
27
+ import: 'z',
28
+ params: 1,
29
+ returns: 0
22
30
  }
23
- ];
31
+ ].filter(x => x);
24
32
 
25
33
  for (let i = 0; i < importedFuncs.length; i++) {
26
34
  const f = importedFuncs[i];
@@ -29,6 +37,21 @@ for (let i = 0; i < importedFuncs.length; i++) {
29
37
 
30
38
  const char = c => number(c.charCodeAt(0));
31
39
 
40
+ const printStaticStr = str => {
41
+ const out = [];
42
+
43
+ for (let i = 0; i < str.length; i++) {
44
+ out.push(
45
+ // ...number(str.charCodeAt(i)),
46
+ ...number(str.charCodeAt(i), Valtype.i32),
47
+ Opcodes.i32_from_u,
48
+ [ Opcodes.call, importedFuncs.printChar ]
49
+ );
50
+ }
51
+
52
+ return out;
53
+ };
54
+
32
55
  // todo: somehow diff between these (undefined != null) while remaining falsey in wasm as a number value
33
56
  export const UNDEFINED = 0;
34
57
  export const NULL = 0;
@@ -102,6 +125,10 @@ export const BuiltinVars = function() {
102
125
 
103
126
  // stubs just so that parent objects exist
104
127
  this.Math = number(1);
128
+
129
+ // wintercg(tm)
130
+ this.__navigator_userAgent = (scope, { makeString }) => makeString(scope, `Porffor/0.2.0`, false, '__navigator_userAgent');
131
+ this.__navigator_userAgent.type = Prefs.bytestring ? '_bytestring' : 'string';
105
132
  };
106
133
 
107
134
  export const BuiltinFuncs = function() {
@@ -155,25 +182,6 @@ export const BuiltinFuncs = function() {
155
182
  ]
156
183
  };
157
184
 
158
- // todo: return false for NaN
159
- this.Boolean = {
160
- params: [ valtypeBinary ],
161
- locals: [],
162
- returns: [ valtypeBinary ],
163
- returnType: 'boolean',
164
- wasm: [
165
- [ Opcodes.local_get, 0 ],
166
- ...(valtype === 'f64' ? [
167
- ...number(0),
168
- [ Opcodes.f64_ne ]
169
- ] : [
170
- ...Opcodes.eqz,
171
- [ Opcodes.i32_eqz ]
172
- ]),
173
- Opcodes.i32_from
174
- ]
175
- };
176
-
177
185
  // just return given (default 0) for (new) Object() as we somewhat supports object just not constructor
178
186
  this.Object = {
179
187
  params: [ valtypeBinary ],
@@ -187,12 +195,159 @@ export const BuiltinFuncs = function() {
187
195
 
188
196
 
189
197
  this.__console_log = {
190
- params: [ valtypeBinary ],
191
- locals: [],
198
+ params: [ valtypeBinary, Valtype.i32 ],
199
+ typedParams: true,
200
+ locals: [ Valtype.i32, Valtype.i32 ],
192
201
  returns: [],
193
- wasm: [
194
- [ Opcodes.local_get, 0 ],
195
- [ Opcodes.call, importedFuncs.print ],
202
+ wasm: (scope, { TYPES, typeSwitch }) => [
203
+ ...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
204
+ [TYPES.number]: [
205
+ [ Opcodes.local_get, 0 ],
206
+ [ Opcodes.call, importedFuncs.print ],
207
+ ],
208
+ [TYPES.boolean]: [
209
+ [ Opcodes.local_get, 0 ],
210
+ Opcodes.i32_to_u,
211
+ [ Opcodes.if, Blocktype.void ],
212
+ ...printStaticStr('true'),
213
+ [ Opcodes.else ],
214
+ ...printStaticStr('false'),
215
+ [ Opcodes.end ]
216
+ ],
217
+ [TYPES.string]: [
218
+ // simply print a string :))
219
+ // cache input pointer as i32
220
+ [ Opcodes.local_get, 0 ],
221
+ Opcodes.i32_to_u,
222
+ [ Opcodes.local_tee, 2 ],
223
+
224
+ // make end pointer
225
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
226
+ ...number(ValtypeSize.i16, Valtype.i32),
227
+ [ Opcodes.i32_mul ],
228
+
229
+ [ Opcodes.local_get, 2 ],
230
+ [ Opcodes.i32_add ],
231
+ [ Opcodes.local_set, 3 ],
232
+
233
+ [ Opcodes.loop, Blocktype.void ],
234
+
235
+ // print current char
236
+ [ Opcodes.local_get, 2 ],
237
+ [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
238
+ Opcodes.i32_from_u,
239
+ [ Opcodes.call, importedFuncs.printChar ],
240
+
241
+ // increment pointer by sizeof i16
242
+ [ Opcodes.local_get, 2 ],
243
+ ...number(ValtypeSize.i16, Valtype.i32),
244
+ [ Opcodes.i32_add ],
245
+ [ Opcodes.local_tee, 2 ],
246
+
247
+ // if pointer != end pointer, loop
248
+ [ Opcodes.local_get, 3 ],
249
+ [ Opcodes.i32_ne ],
250
+ [ Opcodes.br_if, 0 ],
251
+
252
+ [ Opcodes.end ]
253
+ ],
254
+ [TYPES._bytestring]: [
255
+ // simply print a (byte)string :))
256
+ // cache input pointer as i32
257
+ [ Opcodes.local_get, 0 ],
258
+ Opcodes.i32_to_u,
259
+ [ Opcodes.local_tee, 2 ],
260
+
261
+ // make end pointer
262
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
263
+ [ Opcodes.local_get, 2 ],
264
+ [ Opcodes.i32_add ],
265
+ [ Opcodes.local_set, 3 ],
266
+
267
+ [ Opcodes.loop, Blocktype.void ],
268
+
269
+ // print current char
270
+ [ Opcodes.local_get, 2 ],
271
+ [ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
272
+ Opcodes.i32_from_u,
273
+ [ Opcodes.call, importedFuncs.printChar ],
274
+
275
+ // increment pointer
276
+ [ Opcodes.local_get, 2 ],
277
+ [ Opcodes.i32_const, 1 ],
278
+ [ Opcodes.i32_add ],
279
+ [ Opcodes.local_tee, 2 ],
280
+
281
+ // if pointer != end pointer, loop
282
+ [ Opcodes.local_get, 3 ],
283
+ [ Opcodes.i32_ne ],
284
+ [ Opcodes.br_if, 0 ],
285
+
286
+ [ Opcodes.end ]
287
+ ],
288
+ [TYPES._array]: [
289
+ ...printStaticStr('[ '),
290
+
291
+ // cache input pointer as i32
292
+ [ Opcodes.local_get, 0 ],
293
+ Opcodes.i32_to_u,
294
+ [ Opcodes.local_tee, 2 ],
295
+
296
+ // make end pointer
297
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
298
+ ...number(ValtypeSize[valtype], Valtype.i32),
299
+ [ Opcodes.i32_mul ],
300
+
301
+ [ Opcodes.local_get, 2 ],
302
+ [ Opcodes.i32_add ],
303
+ [ Opcodes.local_set, 3 ],
304
+
305
+ [ Opcodes.loop, Blocktype.void ],
306
+
307
+ // print current char
308
+ [ Opcodes.local_get, 2 ],
309
+ [ Opcodes.load, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
310
+ [ Opcodes.call, importedFuncs.print ],
311
+
312
+ // increment pointer by sizeof valtype
313
+ [ Opcodes.local_get, 2 ],
314
+ ...number(ValtypeSize[valtype], Valtype.i32),
315
+ [ Opcodes.i32_add ],
316
+ [ Opcodes.local_tee, 2 ],
317
+
318
+ // if pointer != end pointer, print separator and loop
319
+ [ Opcodes.local_get, 3 ],
320
+ [ Opcodes.i32_ne ],
321
+ [ Opcodes.if, Blocktype.void ],
322
+ ...printStaticStr(', '),
323
+ [ Opcodes.br, 1 ],
324
+ [ Opcodes.end ],
325
+
326
+ [ Opcodes.end ],
327
+
328
+ ...printStaticStr(' ]'),
329
+ ],
330
+ [TYPES.undefined]: [
331
+ ...printStaticStr('undefined')
332
+ ],
333
+ [TYPES.function]: [
334
+ ...printStaticStr('function () {}')
335
+ ],
336
+ [TYPES.object]: [
337
+ [ Opcodes.local_get, 0 ],
338
+ Opcodes.i32_to_u,
339
+ [ Opcodes.if, Blocktype.void ],
340
+ ...printStaticStr('{}'),
341
+ [ Opcodes.else ],
342
+ ...printStaticStr('null'),
343
+ [ Opcodes.end ]
344
+ ],
345
+ default: [
346
+ [ Opcodes.local_get, 0 ],
347
+ [ Opcodes.call, importedFuncs.print ],
348
+ ]
349
+ }, Blocktype.void),
350
+
196
351
  ...char('\n'),
197
352
  [ Opcodes.call, importedFuncs.printChar ]
198
353
  ]
@@ -571,206 +726,76 @@ export const BuiltinFuncs = function() {
571
726
  };
572
727
 
573
728
 
574
- this.__SIMD_i32x4_load = {
575
- params: [ Valtype.i32 ],
576
- locals: [],
577
- returns: [ Valtype.v128 ],
578
- wasm: [
579
- [ Opcodes.local_get, 0 ],
580
- [ ...Opcodes.v128_load, 0, 0 ]
581
- ]
582
- };
583
-
584
- this.__SIMD_i32x4_splat = {
585
- params: [ Valtype.i32 ],
586
- locals: [],
587
- returns: [ Valtype.v128 ],
588
- wasm: [
589
- [ Opcodes.local_get, 0 ],
590
- [ ...Opcodes.i32x4_splat ],
591
- ]
592
- };
593
-
594
- this.__SIMD_i16x8_create = {
595
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
596
- locals: [],
597
- returns: [ Valtype.v128 ],
598
- wasm: [
599
- ...i32x4(0, 0, 0, 0),
600
- [ Opcodes.local_get, 0 ],
601
- [ ...Opcodes.i16x8_replace_lane, 0 ],
602
- [ Opcodes.local_get, 1 ],
603
- [ ...Opcodes.i16x8_replace_lane, 1 ],
604
- [ Opcodes.local_get, 2 ],
605
- [ ...Opcodes.i16x8_replace_lane, 2 ],
606
- [ Opcodes.local_get, 3 ],
607
- [ ...Opcodes.i16x8_replace_lane, 3 ],
608
- [ Opcodes.local_get, 4 ],
609
- [ ...Opcodes.i16x8_replace_lane, 4 ],
610
- [ Opcodes.local_get, 5 ],
611
- [ ...Opcodes.i16x8_replace_lane, 5 ],
612
- [ Opcodes.local_get, 6 ],
613
- [ ...Opcodes.i16x8_replace_lane, 6 ],
614
- [ Opcodes.local_get, 7 ],
615
- [ ...Opcodes.i16x8_replace_lane, 7 ],
616
- ]
617
- };
618
-
619
- this.__SIMD_i32x4_dot_i16x8 = {
620
- params: [ Valtype.v128, Valtype.v128 ],
621
- locals: [],
622
- returns: [ Valtype.v128 ],
623
- wasm: [
624
- [ Opcodes.local_get, 0 ],
625
- [ Opcodes.local_get, 1 ],
626
- [ ...Opcodes.i32x4_dot_i16x8_s ]
627
- ]
729
+ this.__Porffor_type = {
730
+ params: [ valtypeBinary, Valtype.i32 ],
731
+ typedParams: true,
732
+ locals: [ Valtype.i32, Valtype.i32 ],
733
+ returns: [ valtypeBinary ],
734
+ returnType: Prefs.bytestring ? '_bytestring' : 'string',
735
+ wasm: (scope, { TYPE_NAMES, typeSwitch, makeString }) => {
736
+ const bc = {};
737
+ for (const x in TYPE_NAMES) {
738
+ bc[x] = makeString(scope, TYPE_NAMES[x], false, '#Porffor_type_result');
739
+ }
740
+
741
+ return typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], bc);
742
+ }
628
743
  };
629
744
 
630
- this.__SIMD_i32x4_create = {
631
- params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
632
- locals: [],
633
- returns: [ Valtype.v128 ],
634
- wasm: [
635
- ...i32x4(0, 0, 0, 0),
636
- [ Opcodes.local_get, 0 ],
637
- [ ...Opcodes.i32x4_replace_lane, 0 ],
638
- [ Opcodes.local_get, 1 ],
639
- [ ...Opcodes.i32x4_replace_lane, 1 ],
640
- [ Opcodes.local_get, 2 ],
641
- [ ...Opcodes.i32x4_replace_lane, 2 ],
642
- [ Opcodes.local_get, 3 ],
643
- [ ...Opcodes.i32x4_replace_lane, 3 ],
644
- ]
645
- };
745
+ const localIsOneOf = (getter, arr, valtype = valtypeBinary) => {
746
+ const out = [];
646
747
 
647
- this.__SIMD_i32x4_add = {
648
- params: [ Valtype.v128, Valtype.v128 ],
649
- locals: [],
650
- returns: [ Valtype.v128 ],
651
- wasm: [
652
- [ Opcodes.local_get, 0 ],
653
- [ Opcodes.local_get, 1 ],
654
- [ ...Opcodes.i32x4_add ]
655
- ]
656
- };
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
+ }
657
752
 
658
- this.__SIMD_i32x4_sub = {
659
- params: [ Valtype.v128, Valtype.v128 ],
660
- locals: [],
661
- returns: [ Valtype.v128 ],
662
- wasm: [
663
- [ Opcodes.local_get, 0 ],
664
- [ Opcodes.local_get, 1 ],
665
- [ ...Opcodes.i32x4_sub ]
666
- ]
753
+ return out;
667
754
  };
668
755
 
669
- this.__SIMD_i32x4_mul = {
670
- params: [ Valtype.v128, Valtype.v128 ],
671
- locals: [],
672
- returns: [ Valtype.v128 ],
673
- wasm: [
756
+ this.__Porffor_ptr = {
757
+ params: [ valtypeBinary, Valtype.i32 ],
758
+ typedParams: true,
759
+ locals: [ Valtype.i32, Valtype.i32 ],
760
+ returns: [ valtypeBinary ],
761
+ wasm: (scope, { TYPES }) => [
762
+ ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
763
+ [ Opcodes.if, valtypeBinary ],
674
764
  [ Opcodes.local_get, 0 ],
675
- [ Opcodes.local_get, 1 ],
676
- [ ...Opcodes.i32x4_mul ]
765
+ [ Opcodes.else ],
766
+ ...number(NaN),
767
+ [ Opcodes.end ]
677
768
  ]
678
769
  };
679
770
 
680
- this.__SIMD_i32x4_get0 = {
681
- params: [ Valtype.v128 ],
682
- locals: [],
771
+ this.__Porffor_i32_ptr = {
772
+ params: [ Valtype.i32, Valtype.i32 ],
773
+ typedParams: true,
774
+ locals: [ Valtype.i32, Valtype.i32 ],
683
775
  returns: [ Valtype.i32 ],
684
- wasm: [
776
+ wasm: (scope, { TYPES }) => [
777
+ ...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
778
+ [ Opcodes.if, Valtype.i32 ],
685
779
  [ Opcodes.local_get, 0 ],
686
- [ ...Opcodes.i32x4_extract_lane, 0 ],
687
- ],
688
- },
689
-
690
- this.__SIMD_i32x4_get1 = {
691
- params: [ Valtype.v128 ],
692
- locals: [],
693
- returns: [ Valtype.i32 ],
694
- wasm: [
695
- [ Opcodes.local_get, 0 ],
696
- [ ...Opcodes.i32x4_extract_lane, 1 ],
697
- ],
698
- };
699
-
700
- this.__SIMD_i32x4_get2 = {
701
- params: [ Valtype.v128 ],
702
- locals: [],
703
- returns: [ Valtype.i32 ],
704
- wasm: [
705
- [ Opcodes.local_get, 0 ],
706
- [ ...Opcodes.i32x4_extract_lane, 2 ],
707
- ],
708
- };
709
-
710
- this.__SIMD_i32x4_get3 = {
711
- params: [ Valtype.v128 ],
712
- locals: [],
713
- returns: [ Valtype.i32 ],
714
- wasm: [
715
- [ Opcodes.local_get, 0 ],
716
- [ ...Opcodes.i32x4_extract_lane, 3 ],
717
- ],
718
- };
719
-
720
- this.__SIMD_i32x4_shuffle_000c = {
721
- params: [ Valtype.v128 ],
722
- locals: [],
723
- returns: [ Valtype.v128 ],
724
- wasm: [
725
- [ Opcodes.local_get, 0 ],
726
- ...i32x4(0, 0, 0, 0),
727
- [ ...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)
780
+ [ Opcodes.else ],
781
+ ...number(-1, Valtype.i32),
782
+ [ Opcodes.end ]
728
783
  ]
729
784
  };
730
785
 
731
- this.__SIMD_i32x4_shuffle_00ab = {
732
- params: [ Valtype.v128 ],
786
+ // unsafe: does not check type just ~casts to number
787
+ this.__Porffor_i32_ptrUnsafe = {
788
+ params: [ Valtype.i32 ],
733
789
  locals: [],
734
- returns: [ Valtype.v128 ],
790
+ returns: [ Valtype.i32 ],
735
791
  wasm: [
736
792
  [ Opcodes.local_get, 0 ],
737
- ...i32x4(0, 0, 0, 0),
738
- [ ...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)
739
793
  ]
740
794
  };
741
- };
742
795
 
743
- export const BuiltinPreludes = {
744
- btoa: `var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
745
- var btoa = function (input) {
746
- // todo: throw invalid character for unicode
747
-
748
- let output = "";
749
- let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
750
- let i = 0;
751
-
752
- while (i < input.length) {
753
- chr1 = input.charCodeAt(i++);
754
- chr2 = input.charCodeAt(i++);
755
- chr3 = input.charCodeAt(i++);
756
-
757
- enc1 = chr1 >> 2;
758
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
759
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
760
- enc4 = chr3 & 63;
761
-
762
- if (isNaN(chr2)) {
763
- enc3 = enc4 = 64;
764
- } else if (isNaN(chr3)) {
765
- enc4 = 64;
766
- }
767
796
 
768
- output += keyStr.charAt(enc1);
769
- output += keyStr.charAt(enc2);
770
- output += keyStr.charAt(enc3);
771
- output += keyStr.charAt(enc4);
797
+ const generated = new GeneratedBuiltins.BuiltinFuncs();
798
+ for (const x in generated) {
799
+ this[x] = generated[x];
772
800
  }
773
-
774
- return output;
775
- };`
776
801
  };