porffor 0.2.0-181627c → 0.2.0-2265539
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.
- package/compiler/builtins/base64.ts +88 -55
- package/compiler/builtins/porffor.d.ts +24 -4
- package/compiler/builtins.js +54 -233
- package/compiler/codeGen.js +104 -21
- package/compiler/generated_builtins.js +12 -0
- package/compiler/precompile.js +51 -11
- package/compiler/prefs.js +4 -0
- package/compiler/prototype.js +2 -2
- package/package.json +1 -1
@@ -1,73 +1,106 @@
|
|
1
|
-
// @porf -funsafe-no-unlikely-proto-checks
|
2
|
-
|
3
|
-
import type { i32, bytestring } from './porffor.d.ts';
|
4
|
-
|
5
|
-
//
|
6
|
-
//
|
7
|
-
//
|
8
|
-
|
9
|
-
|
10
|
-
//
|
11
|
-
//
|
12
|
-
|
13
|
-
//
|
14
|
-
|
15
|
-
//
|
16
|
-
|
17
|
-
//
|
18
|
-
//
|
19
|
-
//
|
20
|
-
//
|
21
|
-
//
|
22
|
-
//
|
23
|
-
|
24
|
-
//
|
25
|
-
//
|
26
|
-
|
27
|
-
//
|
28
|
-
|
29
|
-
//
|
30
|
-
//
|
31
|
-
//
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
//
|
1
|
+
// @porf -funsafe-no-unlikely-proto-checks -valtype=i32
|
2
|
+
|
3
|
+
import type { i32, i64, bytestring } from './porffor.d.ts';
|
4
|
+
|
5
|
+
// while (len >= 8) {
|
6
|
+
// // Porffor.wasm`local tmp i64`;
|
7
|
+
// // const tmp: i64 = Porffor.wasm.i64.load(i, 0, 4);
|
8
|
+
|
9
|
+
// Porffor.wasm`
|
10
|
+
// local tmp i64
|
11
|
+
// local k i32
|
12
|
+
|
13
|
+
// local.get ${i}
|
14
|
+
// i64.load 0 4
|
15
|
+
// local.set tmp
|
16
|
+
|
17
|
+
// loop 64
|
18
|
+
// local.get ${j}
|
19
|
+
// local.get ${j}
|
20
|
+
// i32.const 1
|
21
|
+
// i32.add
|
22
|
+
// local.set ${j}
|
23
|
+
|
24
|
+
// local.get ${keyStrPtr}
|
25
|
+
// local.get tmp
|
26
|
+
|
27
|
+
// i32.const 58
|
28
|
+
|
29
|
+
// local.get k
|
30
|
+
// i32.const 6
|
31
|
+
// i32.mul
|
32
|
+
|
33
|
+
// i32.sub
|
34
|
+
|
35
|
+
// i64.extend_i32_u
|
36
|
+
|
37
|
+
// i64.shr_u
|
38
|
+
|
39
|
+
// i64.const 63
|
40
|
+
// i64.and
|
41
|
+
|
42
|
+
// i32.wrap_i64
|
43
|
+
// i32.add
|
44
|
+
|
45
|
+
// i32.load8_u 0 4
|
46
|
+
// i32.store8 0 4
|
47
|
+
|
48
|
+
// local.get k
|
49
|
+
// i32.const 1
|
50
|
+
// i32.add
|
51
|
+
// local.tee k
|
52
|
+
|
53
|
+
// i32.const 8
|
54
|
+
// i32.lt_s
|
55
|
+
// br_if 1
|
56
|
+
// end
|
57
|
+
|
58
|
+
// `;
|
59
|
+
// // while (k < 8) {
|
60
|
+
// // Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + Porffor.wasm.i32.wrap_i64(Porffor.wasm.i64.and(
|
61
|
+
// // Porffor.wasm.i64.shr_u(tmp, Porffor.wasm.i64.extend_i32_u(58 - k * 6)),
|
62
|
+
// // Porffor.wasm.i64.const(0x3f)
|
63
|
+
// // )), 0, 4), 0, 4);
|
64
|
+
// // k += 1;
|
65
|
+
// // }
|
66
|
+
|
67
|
+
// i += 6;
|
68
|
+
// len -= 6;
|
69
|
+
// }
|
36
70
|
|
37
71
|
export const btoa = (input: bytestring): bytestring => {
|
38
72
|
const keyStr: bytestring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
73
|
+
const keyStrPtr: i32 = Porffor.i32.ptrUnsafe(keyStr);
|
39
74
|
|
40
|
-
|
41
|
-
|
75
|
+
let len: i32 = input.length;
|
42
76
|
let output: bytestring = '';
|
43
|
-
|
77
|
+
output.length = 4 * (len / 3 + !!(len % 3));
|
44
78
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
79
|
+
let i: i32 = Porffor.i32.ptrUnsafe(input),
|
80
|
+
j: i32 = Porffor.i32.ptrUnsafe(output);
|
81
|
+
|
82
|
+
const endPtr = i + len;
|
83
|
+
while (i < endPtr) {
|
84
|
+
const chr1: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
85
|
+
const chr2: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(i++, 0, 4) : -1;
|
86
|
+
const chr3: i32 = i < endPtr ? Porffor.wasm.i32.load8_u(i++, 0, 4) : -1;
|
49
87
|
|
50
88
|
const enc1: i32 = chr1 >> 2;
|
51
|
-
const enc2: i32 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
52
|
-
let enc3: i32 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
89
|
+
const enc2: i32 = ((chr1 & 3) << 4) | (chr2 == -1 ? 0 : (chr2 >> 4));
|
90
|
+
let enc3: i32 = ((chr2 & 15) << 2) | (chr3 == -1 ? 0 : (chr3 >> 6));
|
53
91
|
let enc4: i32 = chr3 & 63;
|
54
92
|
|
55
|
-
if (
|
93
|
+
if (chr2 == -1) {
|
56
94
|
enc3 = 64;
|
57
95
|
enc4 = 64;
|
58
|
-
} else if (
|
96
|
+
} else if (chr3 == -1) {
|
59
97
|
enc4 = 64;
|
60
98
|
}
|
61
99
|
|
62
|
-
Porffor.
|
63
|
-
Porffor.
|
64
|
-
Porffor.
|
65
|
-
Porffor.
|
66
|
-
|
67
|
-
// output += keyStr.charAt(enc1);
|
68
|
-
// output += keyStr.charAt(enc2);
|
69
|
-
// output += keyStr.charAt(enc3);
|
70
|
-
// output += keyStr.charAt(enc4);
|
100
|
+
Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc1, 0, 4), 0, 4);
|
101
|
+
Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc2, 0, 4), 0, 4);
|
102
|
+
Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc3, 0, 4), 0, 4);
|
103
|
+
Porffor.wasm.i32.store8(j++, Porffor.wasm.i32.load8_u(keyStrPtr + enc4, 0, 4), 0, 4);
|
71
104
|
}
|
72
105
|
|
73
106
|
return output;
|
@@ -1,12 +1,32 @@
|
|
1
1
|
export type i32 = number;
|
2
|
+
export type i64 = number;
|
2
3
|
export type bytestring = string;
|
3
4
|
|
4
5
|
type PorfforGlobal = {
|
5
|
-
wasm:
|
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
|
+
wrap_i64: (x: i64) => i32;
|
12
|
+
}
|
13
|
+
i64: {
|
14
|
+
load: (pointer: i32, align: i32, offset: i32) => i64;
|
15
|
+
shr_u: (a: i64, b: i64) => i64;
|
16
|
+
extend_i32_u: (x: i32) => i64;
|
17
|
+
and: (a: i64, b: i64) => i64;
|
18
|
+
const: (val: number) => i64;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
ptr: (obj: any) => i32;
|
22
|
+
|
23
|
+
i32: {
|
24
|
+
ptr: (obj: any) => i32;
|
25
|
+
ptrUnsafe: (obj: any) => i32;
|
6
26
|
|
7
|
-
|
8
|
-
|
9
|
-
|
27
|
+
bytestring: {
|
28
|
+
setCharAt: (target: bytestring, targetIndex: i32, lookup: bytestring, lookupIndex: i32) => void;
|
29
|
+
}
|
10
30
|
}
|
11
31
|
};
|
12
32
|
|
package/compiler/builtins.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { Blocktype, Opcodes, Valtype, ValtypeSize } from "./wasmSpec.js";
|
2
2
|
import { number, i32x4 } from "./embedding.js";
|
3
3
|
import Prefs from './prefs.js';
|
4
|
+
import * as GeneratedBuiltins from './generated_builtins.js';
|
4
5
|
|
5
6
|
export const importedFuncs = [
|
6
7
|
{
|
@@ -240,6 +241,40 @@ export const BuiltinFuncs = function() {
|
|
240
241
|
|
241
242
|
[ Opcodes.end ]
|
242
243
|
],
|
244
|
+
[TYPES._bytestring]: [
|
245
|
+
// simply print a (byte)string :))
|
246
|
+
// cache input pointer as i32
|
247
|
+
[ Opcodes.local_get, 0 ],
|
248
|
+
Opcodes.i32_to_u,
|
249
|
+
[ Opcodes.local_tee, 2 ],
|
250
|
+
|
251
|
+
// make end pointer
|
252
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
253
|
+
[ Opcodes.local_get, 2 ],
|
254
|
+
[ Opcodes.i32_add ],
|
255
|
+
[ Opcodes.local_set, 3 ],
|
256
|
+
|
257
|
+
[ Opcodes.loop, Blocktype.void ],
|
258
|
+
|
259
|
+
// print current char
|
260
|
+
[ Opcodes.local_get, 2 ],
|
261
|
+
[ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
262
|
+
Opcodes.i32_from_u,
|
263
|
+
[ Opcodes.call, importedFuncs.printChar ],
|
264
|
+
|
265
|
+
// increment pointer
|
266
|
+
[ Opcodes.local_get, 2 ],
|
267
|
+
[ Opcodes.i32_const, 1 ],
|
268
|
+
[ Opcodes.i32_add ],
|
269
|
+
[ Opcodes.local_tee, 2 ],
|
270
|
+
|
271
|
+
// if pointer != end pointer, loop
|
272
|
+
[ Opcodes.local_get, 3 ],
|
273
|
+
[ Opcodes.i32_ne ],
|
274
|
+
[ Opcodes.br_if, 0 ],
|
275
|
+
|
276
|
+
[ Opcodes.end ]
|
277
|
+
],
|
243
278
|
[TYPES._array]: [
|
244
279
|
...printStaticStr('[ '),
|
245
280
|
|
@@ -708,7 +743,7 @@ export const BuiltinFuncs = function() {
|
|
708
743
|
return out;
|
709
744
|
};
|
710
745
|
|
711
|
-
this.
|
746
|
+
this.__Porffor_ptr = {
|
712
747
|
params: [ valtypeBinary, Valtype.i32 ],
|
713
748
|
typedParams: true,
|
714
749
|
locals: [ Valtype.i32, Valtype.i32 ],
|
@@ -723,248 +758,34 @@ export const BuiltinFuncs = function() {
|
|
723
758
|
]
|
724
759
|
};
|
725
760
|
|
726
|
-
this.
|
727
|
-
params: [
|
728
|
-
|
729
|
-
|
730
|
-
returns: [],
|
731
|
-
wasm: [
|
732
|
-
|
733
|
-
[ Opcodes.
|
734
|
-
Opcodes.i32_to_u,
|
735
|
-
[ Opcodes.local_get, 0 ],
|
736
|
-
Opcodes.i32_to_u,
|
737
|
-
[ Opcodes.i32_load, 1, 0 ],
|
738
|
-
[ Opcodes.local_tee, 3 ],
|
739
|
-
[ Opcodes.i32_const, 2 ],
|
740
|
-
[ Opcodes.i32_mul ],
|
741
|
-
[ Opcodes.i32_add ],
|
742
|
-
|
743
|
-
// get lookup[index]
|
744
|
-
[ Opcodes.local_get, 2 ],
|
745
|
-
Opcodes.i32_to_u,
|
746
|
-
[ Opcodes.i32_const, 2 ],
|
747
|
-
[ Opcodes.i32_mul ],
|
748
|
-
[ Opcodes.local_get, 1 ],
|
749
|
-
Opcodes.i32_to_u,
|
750
|
-
[ Opcodes.i32_add ],
|
751
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 ],
|
752
|
-
|
753
|
-
// store target[target.length] = lookup[index]
|
754
|
-
[ Opcodes.i32_store8, 0, 4 ],
|
755
|
-
|
756
|
-
// store target.length = target.length + 1
|
757
|
-
[ Opcodes.local_get, 0 ],
|
758
|
-
Opcodes.i32_to_u,
|
759
|
-
[ Opcodes.local_get, 3 ],
|
760
|
-
[ Opcodes.i32_const, 1 ],
|
761
|
-
[ Opcodes.i32_add ],
|
762
|
-
[ Opcodes.i32_store, 0, 0 ],
|
763
|
-
]
|
764
|
-
};
|
765
|
-
|
766
|
-
this.__Porffor_bytestring_appendCharCode = {
|
767
|
-
params: [ valtypeBinary, valtypeBinary ],
|
768
|
-
locals: [ Valtype.i32 ],
|
769
|
-
localnames: ['target', 'code', 'length'],
|
770
|
-
returns: [],
|
771
|
-
wasm: [
|
772
|
-
// get ptr for target[target.length]
|
773
|
-
[ Opcodes.local_get, 0 ],
|
774
|
-
Opcodes.i32_to_u,
|
775
|
-
[ Opcodes.local_get, 0 ],
|
776
|
-
Opcodes.i32_to_u,
|
777
|
-
[ Opcodes.i32_load, 1, 0 ],
|
778
|
-
[ Opcodes.local_tee, 3 ],
|
779
|
-
[ Opcodes.i32_const, 2 ],
|
780
|
-
[ Opcodes.i32_mul ],
|
781
|
-
[ Opcodes.i32_add ],
|
782
|
-
|
783
|
-
// get code
|
784
|
-
[ Opcodes.local_get, 1 ],
|
785
|
-
[ Opcodes.i32_to_u ],
|
786
|
-
|
787
|
-
// set target[target.length] = code
|
788
|
-
[ Opcodes.i32_store8, 0, 4 ],
|
789
|
-
|
790
|
-
// store target.length = target.length + 1
|
791
|
-
[ Opcodes.local_get, 0 ],
|
792
|
-
Opcodes.i32_to_u,
|
793
|
-
[ Opcodes.local_get, 3 ],
|
794
|
-
[ Opcodes.i32_const, 1 ],
|
795
|
-
[ Opcodes.i32_add ],
|
796
|
-
[ Opcodes.i32_store, 0, 0 ],
|
797
|
-
]
|
798
|
-
};
|
799
|
-
|
800
|
-
// todo: indexOfCharAt
|
801
|
-
|
802
|
-
|
803
|
-
this.__SIMD_i32x4_load = {
|
804
|
-
params: [ Valtype.i32 ],
|
805
|
-
locals: [],
|
806
|
-
returns: [ Valtype.v128 ],
|
807
|
-
wasm: [
|
761
|
+
this.__Porffor_i32_ptr = {
|
762
|
+
params: [ Valtype.i32, Valtype.i32 ],
|
763
|
+
typedParams: true,
|
764
|
+
locals: [ Valtype.i32, Valtype.i32 ],
|
765
|
+
returns: [ Valtype.i32 ],
|
766
|
+
wasm: (scope, { TYPES }) => [
|
767
|
+
...localIsOneOf([ [ Opcodes.local_get, 1 ] ], [ TYPES.string, TYPES._array, TYPES._bytestring ], Valtype.i32),
|
768
|
+
[ Opcodes.if, Valtype.i32 ],
|
808
769
|
[ Opcodes.local_get, 0 ],
|
809
|
-
[
|
770
|
+
[ Opcodes.else ],
|
771
|
+
...number(-1, Valtype.i32),
|
772
|
+
[ Opcodes.end ]
|
810
773
|
]
|
811
774
|
};
|
812
775
|
|
813
|
-
|
776
|
+
// unsafe: does not check type just ~casts to number
|
777
|
+
this.__Porffor_i32_ptrUnsafe = {
|
814
778
|
params: [ Valtype.i32 ],
|
815
779
|
locals: [],
|
816
|
-
returns: [ Valtype.v128 ],
|
817
|
-
wasm: [
|
818
|
-
[ Opcodes.local_get, 0 ],
|
819
|
-
[ ...Opcodes.i32x4_splat ],
|
820
|
-
]
|
821
|
-
};
|
822
|
-
|
823
|
-
this.__SIMD_i16x8_create = {
|
824
|
-
params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
825
|
-
locals: [],
|
826
|
-
returns: [ Valtype.v128 ],
|
827
|
-
wasm: [
|
828
|
-
...i32x4(0, 0, 0, 0),
|
829
|
-
[ Opcodes.local_get, 0 ],
|
830
|
-
[ ...Opcodes.i16x8_replace_lane, 0 ],
|
831
|
-
[ Opcodes.local_get, 1 ],
|
832
|
-
[ ...Opcodes.i16x8_replace_lane, 1 ],
|
833
|
-
[ Opcodes.local_get, 2 ],
|
834
|
-
[ ...Opcodes.i16x8_replace_lane, 2 ],
|
835
|
-
[ Opcodes.local_get, 3 ],
|
836
|
-
[ ...Opcodes.i16x8_replace_lane, 3 ],
|
837
|
-
[ Opcodes.local_get, 4 ],
|
838
|
-
[ ...Opcodes.i16x8_replace_lane, 4 ],
|
839
|
-
[ Opcodes.local_get, 5 ],
|
840
|
-
[ ...Opcodes.i16x8_replace_lane, 5 ],
|
841
|
-
[ Opcodes.local_get, 6 ],
|
842
|
-
[ ...Opcodes.i16x8_replace_lane, 6 ],
|
843
|
-
[ Opcodes.local_get, 7 ],
|
844
|
-
[ ...Opcodes.i16x8_replace_lane, 7 ],
|
845
|
-
]
|
846
|
-
};
|
847
|
-
|
848
|
-
this.__SIMD_i32x4_dot_i16x8 = {
|
849
|
-
params: [ Valtype.v128, Valtype.v128 ],
|
850
|
-
locals: [],
|
851
|
-
returns: [ Valtype.v128 ],
|
852
|
-
wasm: [
|
853
|
-
[ Opcodes.local_get, 0 ],
|
854
|
-
[ Opcodes.local_get, 1 ],
|
855
|
-
[ ...Opcodes.i32x4_dot_i16x8_s ]
|
856
|
-
]
|
857
|
-
};
|
858
|
-
|
859
|
-
this.__SIMD_i32x4_create = {
|
860
|
-
params: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
|
861
|
-
locals: [],
|
862
|
-
returns: [ Valtype.v128 ],
|
863
|
-
wasm: [
|
864
|
-
...i32x4(0, 0, 0, 0),
|
865
|
-
[ Opcodes.local_get, 0 ],
|
866
|
-
[ ...Opcodes.i32x4_replace_lane, 0 ],
|
867
|
-
[ Opcodes.local_get, 1 ],
|
868
|
-
[ ...Opcodes.i32x4_replace_lane, 1 ],
|
869
|
-
[ Opcodes.local_get, 2 ],
|
870
|
-
[ ...Opcodes.i32x4_replace_lane, 2 ],
|
871
|
-
[ Opcodes.local_get, 3 ],
|
872
|
-
[ ...Opcodes.i32x4_replace_lane, 3 ],
|
873
|
-
]
|
874
|
-
};
|
875
|
-
|
876
|
-
this.__SIMD_i32x4_add = {
|
877
|
-
params: [ Valtype.v128, Valtype.v128 ],
|
878
|
-
locals: [],
|
879
|
-
returns: [ Valtype.v128 ],
|
880
|
-
wasm: [
|
881
|
-
[ Opcodes.local_get, 0 ],
|
882
|
-
[ Opcodes.local_get, 1 ],
|
883
|
-
[ ...Opcodes.i32x4_add ]
|
884
|
-
]
|
885
|
-
};
|
886
|
-
|
887
|
-
this.__SIMD_i32x4_sub = {
|
888
|
-
params: [ Valtype.v128, Valtype.v128 ],
|
889
|
-
locals: [],
|
890
|
-
returns: [ Valtype.v128 ],
|
891
|
-
wasm: [
|
892
|
-
[ Opcodes.local_get, 0 ],
|
893
|
-
[ Opcodes.local_get, 1 ],
|
894
|
-
[ ...Opcodes.i32x4_sub ]
|
895
|
-
]
|
896
|
-
};
|
897
|
-
|
898
|
-
this.__SIMD_i32x4_mul = {
|
899
|
-
params: [ Valtype.v128, Valtype.v128 ],
|
900
|
-
locals: [],
|
901
|
-
returns: [ Valtype.v128 ],
|
902
|
-
wasm: [
|
903
|
-
[ Opcodes.local_get, 0 ],
|
904
|
-
[ Opcodes.local_get, 1 ],
|
905
|
-
[ ...Opcodes.i32x4_mul ]
|
906
|
-
]
|
907
|
-
};
|
908
|
-
|
909
|
-
this.__SIMD_i32x4_get0 = {
|
910
|
-
params: [ Valtype.v128 ],
|
911
|
-
locals: [],
|
912
|
-
returns: [ Valtype.i32 ],
|
913
|
-
wasm: [
|
914
|
-
[ Opcodes.local_get, 0 ],
|
915
|
-
[ ...Opcodes.i32x4_extract_lane, 0 ],
|
916
|
-
],
|
917
|
-
},
|
918
|
-
|
919
|
-
this.__SIMD_i32x4_get1 = {
|
920
|
-
params: [ Valtype.v128 ],
|
921
|
-
locals: [],
|
922
780
|
returns: [ Valtype.i32 ],
|
923
781
|
wasm: [
|
924
782
|
[ Opcodes.local_get, 0 ],
|
925
|
-
[ ...Opcodes.i32x4_extract_lane, 1 ],
|
926
|
-
],
|
927
|
-
};
|
928
|
-
|
929
|
-
this.__SIMD_i32x4_get2 = {
|
930
|
-
params: [ Valtype.v128 ],
|
931
|
-
locals: [],
|
932
|
-
returns: [ Valtype.i32 ],
|
933
|
-
wasm: [
|
934
|
-
[ Opcodes.local_get, 0 ],
|
935
|
-
[ ...Opcodes.i32x4_extract_lane, 2 ],
|
936
|
-
],
|
937
|
-
};
|
938
|
-
|
939
|
-
this.__SIMD_i32x4_get3 = {
|
940
|
-
params: [ Valtype.v128 ],
|
941
|
-
locals: [],
|
942
|
-
returns: [ Valtype.i32 ],
|
943
|
-
wasm: [
|
944
|
-
[ Opcodes.local_get, 0 ],
|
945
|
-
[ ...Opcodes.i32x4_extract_lane, 3 ],
|
946
|
-
],
|
947
|
-
};
|
948
|
-
|
949
|
-
this.__SIMD_i32x4_shuffle_000c = {
|
950
|
-
params: [ Valtype.v128 ],
|
951
|
-
locals: [],
|
952
|
-
returns: [ Valtype.v128 ],
|
953
|
-
wasm: [
|
954
|
-
[ Opcodes.local_get, 0 ],
|
955
|
-
...i32x4(0, 0, 0, 0),
|
956
|
-
[ ...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)
|
957
783
|
]
|
958
784
|
};
|
959
785
|
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
[ Opcodes.local_get, 0 ],
|
966
|
-
...i32x4(0, 0, 0, 0),
|
967
|
-
[ ...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)
|
968
|
-
]
|
969
|
-
};
|
786
|
+
|
787
|
+
const generated = new GeneratedBuiltins.BuiltinFuncs();
|
788
|
+
for (const x in generated) {
|
789
|
+
this[x] = generated[x];
|
790
|
+
}
|
970
791
|
};
|
package/compiler/codeGen.js
CHANGED
@@ -189,7 +189,11 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
189
189
|
if (!inst) throw new Error(`inline asm: inst ${asm[0]} not found`);
|
190
190
|
|
191
191
|
if (!Array.isArray(inst)) inst = [ inst ];
|
192
|
-
const immediates = asm.slice(1).map(x =>
|
192
|
+
const immediates = asm.slice(1).map(x => {
|
193
|
+
const int = parseInt(x);
|
194
|
+
if (Number.isNaN(int)) return scope.locals[x]?.idx;
|
195
|
+
return int;
|
196
|
+
});
|
193
197
|
|
194
198
|
out.push([ ...inst, ...immediates ]);
|
195
199
|
}
|
@@ -220,11 +224,12 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
220
224
|
|
221
225
|
for (let i = 0; i < expressions.length; i++) {
|
222
226
|
const e = expressions[i];
|
223
|
-
str += lookupName(scope, e.name)[0];
|
224
|
-
|
227
|
+
str += lookupName(scope, e.name)[0].idx;
|
225
228
|
str += quasis[i + 1].value.raw;
|
226
229
|
}
|
227
230
|
|
231
|
+
console.log(str);
|
232
|
+
|
228
233
|
return funcs[name](str);
|
229
234
|
}
|
230
235
|
|
@@ -657,11 +662,12 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
657
662
|
...(!intIn && intOut ? [ Opcodes.i32_to_u ] : [])
|
658
663
|
];
|
659
664
|
|
660
|
-
const
|
665
|
+
const useTmp = knownType(scope, type) == null;
|
666
|
+
const tmp = !useTmp && localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
661
667
|
|
662
668
|
const def = [
|
663
669
|
// if value != 0
|
664
|
-
[ Opcodes.local_get, tmp ],
|
670
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
665
671
|
|
666
672
|
// ...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
667
673
|
...(!intOut || (intIn && intOut) ? [] : [ Opcodes.i32_to_u ]),
|
@@ -673,7 +679,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
673
679
|
|
674
680
|
return [
|
675
681
|
...wasm,
|
676
|
-
[ Opcodes.local_set, tmp ],
|
682
|
+
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
677
683
|
|
678
684
|
...typeSwitch(scope, type, {
|
679
685
|
// [TYPES.number]: def,
|
@@ -682,7 +688,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
682
688
|
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
683
689
|
],
|
684
690
|
[TYPES.string]: [
|
685
|
-
[ Opcodes.local_get, tmp ],
|
691
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
686
692
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
687
693
|
|
688
694
|
// get length
|
@@ -694,7 +700,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
694
700
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
695
701
|
],
|
696
702
|
[TYPES._bytestring]: [ // duplicate of string
|
697
|
-
|
703
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
698
704
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
699
705
|
|
700
706
|
// get length
|
@@ -708,10 +714,12 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
708
714
|
};
|
709
715
|
|
710
716
|
const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
711
|
-
const
|
717
|
+
const useTmp = knownType(scope, type) == null;
|
718
|
+
const tmp = !useTmp && localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
719
|
+
|
712
720
|
return [
|
713
721
|
...wasm,
|
714
|
-
[ Opcodes.local_set, tmp ],
|
722
|
+
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
715
723
|
|
716
724
|
...typeSwitch(scope, type, {
|
717
725
|
[TYPES._array]: [
|
@@ -719,7 +727,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
719
727
|
...number(0, intOut ? Valtype.i32 : valtypeBinary)
|
720
728
|
],
|
721
729
|
[TYPES.string]: [
|
722
|
-
[ Opcodes.local_get, tmp ],
|
730
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
723
731
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
724
732
|
|
725
733
|
// get length
|
@@ -730,7 +738,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
730
738
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
731
739
|
],
|
732
740
|
[TYPES._bytestring]: [ // duplicate of string
|
733
|
-
[ Opcodes.local_get, tmp ],
|
741
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
734
742
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
735
743
|
|
736
744
|
// get length
|
@@ -742,7 +750,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
742
750
|
],
|
743
751
|
default: [
|
744
752
|
// if value == 0
|
745
|
-
[ Opcodes.local_get, tmp ],
|
753
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
746
754
|
|
747
755
|
...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
748
756
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
@@ -752,10 +760,12 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
752
760
|
};
|
753
761
|
|
754
762
|
const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
|
755
|
-
const
|
763
|
+
const useTmp = knownType(scope, type) == null;
|
764
|
+
const tmp = !useTmp && localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
765
|
+
|
756
766
|
return [
|
757
767
|
...wasm,
|
758
|
-
[ Opcodes.local_set, tmp ],
|
768
|
+
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
759
769
|
|
760
770
|
...typeSwitch(scope, type, {
|
761
771
|
[TYPES.undefined]: [
|
@@ -764,7 +774,7 @@ const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
764
774
|
],
|
765
775
|
[TYPES.object]: [
|
766
776
|
// object, null if == 0
|
767
|
-
[ Opcodes.local_get, tmp ],
|
777
|
+
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
768
778
|
|
769
779
|
...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
770
780
|
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
@@ -969,7 +979,7 @@ const generateBinaryExp = (scope, decl, _global, _name) => {
|
|
969
979
|
return out;
|
970
980
|
};
|
971
981
|
|
972
|
-
const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType, localNames = [], globalNames = [] }) => {
|
982
|
+
const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType, localNames = [], globalNames = [], data: _data = [] }) => {
|
973
983
|
const existing = funcs.find(x => x.name === name);
|
974
984
|
if (existing) return existing;
|
975
985
|
|
@@ -981,6 +991,12 @@ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes
|
|
981
991
|
locals[nameParam(i)] = { idx: i, type: allLocals[i] };
|
982
992
|
}
|
983
993
|
|
994
|
+
for (const x of _data) {
|
995
|
+
const copy = { ...x };
|
996
|
+
copy.offset += pages.size * pageSize;
|
997
|
+
data.push(copy);
|
998
|
+
}
|
999
|
+
|
984
1000
|
if (typeof wasm === 'function') {
|
985
1001
|
const scope = {
|
986
1002
|
name,
|
@@ -990,7 +1006,18 @@ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes
|
|
990
1006
|
localInd: allLocals.length,
|
991
1007
|
};
|
992
1008
|
|
993
|
-
wasm = wasm(scope, {
|
1009
|
+
wasm = wasm(scope, {
|
1010
|
+
TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage,
|
1011
|
+
builtin: name => {
|
1012
|
+
let idx = funcIndex[name] ?? importedFuncs[name];
|
1013
|
+
if (idx === undefined && builtinFuncs[name]) {
|
1014
|
+
includeBuiltin(scope, name);
|
1015
|
+
idx = funcIndex[name];
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
return idx;
|
1019
|
+
}
|
1020
|
+
});
|
994
1021
|
}
|
995
1022
|
|
996
1023
|
let baseGlobalIdx, i = 0;
|
@@ -1176,7 +1203,7 @@ const getNodeType = (scope, node) => {
|
|
1176
1203
|
if (func.returnType) return func.returnType;
|
1177
1204
|
}
|
1178
1205
|
|
1179
|
-
if (builtinFuncs[name]) return TYPES[builtinFuncs[name].returnType ?? 'number'];
|
1206
|
+
if (builtinFuncs[name] && !builtinFuncs[name].typedReturns) return TYPES[builtinFuncs[name].returnType ?? 'number'];
|
1180
1207
|
if (internalConstrs[name]) return internalConstrs[name].type;
|
1181
1208
|
|
1182
1209
|
// check if this is a prototype function
|
@@ -1191,6 +1218,11 @@ const getNodeType = (scope, node) => {
|
|
1191
1218
|
if (protoFuncs.length === 1) return protoFuncs[0].returnType ?? TYPES.number;
|
1192
1219
|
}
|
1193
1220
|
|
1221
|
+
if (name.startsWith('__Porffor_wasm_')) {
|
1222
|
+
// todo: return undefined for non-returning ops
|
1223
|
+
return TYPES.number;
|
1224
|
+
}
|
1225
|
+
|
1194
1226
|
if (scope.locals['#last_type']) return [ getLastType(scope) ];
|
1195
1227
|
|
1196
1228
|
// presume
|
@@ -1665,6 +1697,44 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1665
1697
|
idx = -1;
|
1666
1698
|
}
|
1667
1699
|
|
1700
|
+
if (idx === undefined && name.startsWith('__Porffor_wasm_')) {
|
1701
|
+
const wasmOps = {
|
1702
|
+
// pointer, align, offset
|
1703
|
+
i32_load8_u: { imms: 2, args: 1 },
|
1704
|
+
// pointer, value, align, offset
|
1705
|
+
i32_store8: { imms: 2, args: 2 },
|
1706
|
+
// pointer, align, offset
|
1707
|
+
i64_load: { imms: 2, args: 1 },
|
1708
|
+
// a, b
|
1709
|
+
i64_shr_u: { imms: 0, args: 2 },
|
1710
|
+
// x
|
1711
|
+
i32_wrap_i64: { imms: 0, args: 1, },
|
1712
|
+
// x
|
1713
|
+
i64_extend_i32_u: { imms: 0, args: 1 },
|
1714
|
+
// a, b
|
1715
|
+
i64_and: { imms: 0, args: 2 },
|
1716
|
+
// val (todo: support >255)
|
1717
|
+
i64_const: { imms: 1, args: 0 },
|
1718
|
+
};
|
1719
|
+
|
1720
|
+
const opName = name.slice('__Porffor_wasm_'.length);
|
1721
|
+
|
1722
|
+
if (wasmOps[opName]) {
|
1723
|
+
const op = wasmOps[opName];
|
1724
|
+
|
1725
|
+
const argOut = [];
|
1726
|
+
for (let i = 0; i < op.args; i++) argOut.push(...generate(scope, decl.arguments[i]));
|
1727
|
+
|
1728
|
+
// literals only
|
1729
|
+
const imms = decl.arguments.slice(op.args).map(x => x.value);
|
1730
|
+
|
1731
|
+
return [
|
1732
|
+
...argOut,
|
1733
|
+
[ Opcodes[opName], ...imms ]
|
1734
|
+
];
|
1735
|
+
}
|
1736
|
+
}
|
1737
|
+
|
1668
1738
|
if (idx === undefined) {
|
1669
1739
|
if (scope.locals[name] !== undefined || globals[name] !== undefined || builtinVars[name] !== undefined) return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`);
|
1670
1740
|
return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`);
|
@@ -1691,8 +1761,14 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1691
1761
|
if (func && func.throws) scope.throws = true;
|
1692
1762
|
|
1693
1763
|
let out = [];
|
1694
|
-
for (
|
1764
|
+
for (let i = 0; i < args.length; i++) {
|
1765
|
+
const arg = args[i];
|
1695
1766
|
out = out.concat(generate(scope, arg));
|
1767
|
+
|
1768
|
+
if (builtinFuncs[name] && builtinFuncs[name].params[i] === Valtype.i32 && valtypeBinary !== Valtype.i32) {
|
1769
|
+
out.push(Opcodes.i32_to);
|
1770
|
+
}
|
1771
|
+
|
1696
1772
|
if (typedParams) out = out.concat(getNodeType(scope, arg));
|
1697
1773
|
}
|
1698
1774
|
|
@@ -1710,6 +1786,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1710
1786
|
// );
|
1711
1787
|
} else out.push(setLastType(scope));
|
1712
1788
|
|
1789
|
+
if (builtinFuncs[name] && builtinFuncs[name].returns[0] === Valtype.i32 && valtypeBinary !== Valtype.i32) {
|
1790
|
+
out.push(Opcodes.i32_from);
|
1791
|
+
}
|
1792
|
+
|
1713
1793
|
return out;
|
1714
1794
|
};
|
1715
1795
|
|
@@ -1913,6 +1993,7 @@ const typeAnnoToPorfType = x => {
|
|
1913
1993
|
|
1914
1994
|
switch (x) {
|
1915
1995
|
case 'i32':
|
1996
|
+
case 'i64':
|
1916
1997
|
return TYPES.number;
|
1917
1998
|
}
|
1918
1999
|
|
@@ -2707,7 +2788,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
2707
2788
|
const valtype = itemTypeToValtype[itemType];
|
2708
2789
|
const length = elements.length;
|
2709
2790
|
|
2710
|
-
if (firstAssign && useRawElements) {
|
2791
|
+
if (firstAssign && useRawElements && !Prefs.noData) {
|
2711
2792
|
// if length is 0 memory/data will just be 0000... anyway
|
2712
2793
|
if (length !== 0) {
|
2713
2794
|
let bytes = compileBytes(length, 'i32');
|
@@ -2993,6 +3074,8 @@ const generateFunc = (scope, decl) => {
|
|
2993
3074
|
};
|
2994
3075
|
funcIndex[name] = func.index;
|
2995
3076
|
|
3077
|
+
if (name === 'main') func.gotLastType = true;
|
3078
|
+
|
2996
3079
|
// quick hack fixes
|
2997
3080
|
for (const inst of wasm) {
|
2998
3081
|
if (inst[0] === Opcodes.call && inst[1] === -1) {
|
@@ -1,3 +1,15 @@
|
|
1
|
+
// autogenerated by compiler/precompile.js
|
2
|
+
import { number } from './embedding.js';
|
1
3
|
|
2
4
|
export const BuiltinFuncs = function() {
|
5
|
+
this.btoa = {
|
6
|
+
wasm: (scope, { allocPage, builtin }) => [...number(allocPage(scope, 'bytestring: keyStr', 'i8') * pageSize, 127),[34,2],[16, builtin('__Porffor_i32_ptrUnsafe')],[33,3],[32,0],[null],[40,1,0],[null],[33,4],...number(allocPage(scope, 'bytestring: output', 'i8') * pageSize, 127),[33,5],[65,0],[65,4],[32,4],[65,3],[109],[32,4],[65,3],[111],[69],[null],[69],[null],[106],[108],[34,6],[null],[54,1,128,128,4],[32,0],[16, builtin('__Porffor_i32_ptrUnsafe')],[33,8],[32,5],[16, builtin('__Porffor_i32_ptrUnsafe')],[33,9],[32,8],[32,4],[106],[33,10],[65,0],[33,11],[3,64],[32,8],[32,10],[72],[null],[4,64],[32,8],[32,8],[65,1],[106],[33,8],[45,0,4],[33,12],[32,8],[32,10],[72],[null],[4,127],[32,8],[32,8],[65,1],[106],[33,8],[45,0,4],[65,0],[33,14],[5],[65,127],[65,0],[33,14],[11],[33,13],[32,8],[32,10],[72],[null],[4,127],[32,8],[32,8],[65,1],[106],[33,8],[45,0,4],[65,0],[33,14],[5],[65,127],[65,0],[33,14],[11],[33,15],[32,12],[65,2],[117],[33,16],[32,12],[65,3],[113],[65,4],[116],[32,13],[65,127],[70],[null],[4,127],[65,0],[65,0],[33,14],[5],[32,13],[65,4],[117],[65,0],[33,14],[11],[114],[33,17],[32,13],[65,15],[113],[65,2],[116],[32,15],[65,127],[70],[null],[4,127],[65,0],[65,0],[33,14],[5],[32,15],[65,6],[117],[65,0],[33,14],[11],[114],[33,18],[32,15],[65,63],[113],[33,19],[32,13],[65,127],[70],[null],[4,64],[65,192,0],[33,18],[65,192,0],[33,19],[5],[32,15],[65,127],[70],[null],[4,64],[65,192,0],[33,19],[11],[11],[32,9],[32,9],[65,1],[106],[33,9],[32,3],[32,16],[106],[45,0,4],[58,0,4],[32,9],[32,9],[65,1],[106],[33,9],[32,3],[32,17],[106],[45,0,4],[58,0,4],[32,9],[32,9],[65,1],[106],[33,9],[32,3],[32,18],[106],[45,0,4],[58,0,4],[32,9],[32,9],[65,1],[106],[33,9],[32,3],[32,19],[106],[45,0,4],[58,0,4],[12,1],[11],[11],[32,5],[65,18],[15]],
|
7
|
+
params: [127,127],
|
8
|
+
typedParams: true,
|
9
|
+
returns: [127,127],
|
10
|
+
typedReturns: true,
|
11
|
+
locals: [127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127],
|
12
|
+
localNames: ["input","input#type","keyStr","keyStrPtr","len","output","__length_setter_tmp","$logicinner_tmp","i","j","endPtr","endPtr#type","chr1","chr2","#last_type","chr3","enc1","enc2","enc3","enc4"],
|
13
|
+
data: [{"offset":0,"bytes":[65,0,0,0,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47,61]}],
|
14
|
+
};
|
3
15
|
};
|
package/compiler/precompile.js
CHANGED
@@ -6,6 +6,22 @@ import { join } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
7
7
|
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
8
8
|
|
9
|
+
const TYPES = {
|
10
|
+
number: 0x00,
|
11
|
+
boolean: 0x01,
|
12
|
+
string: 0x02,
|
13
|
+
undefined: 0x03,
|
14
|
+
object: 0x04,
|
15
|
+
function: 0x05,
|
16
|
+
symbol: 0x06,
|
17
|
+
bigint: 0x07,
|
18
|
+
|
19
|
+
// these are not "typeof" types but tracked internally
|
20
|
+
_array: 0x10,
|
21
|
+
_regexp: 0x11,
|
22
|
+
_bytestring: 0x12
|
23
|
+
};
|
24
|
+
|
9
25
|
// import porfParse from './parse.js';
|
10
26
|
// import porfCodegen from './codeGen.js';
|
11
27
|
|
@@ -31,6 +47,8 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
31
47
|
|
32
48
|
let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
|
33
49
|
|
50
|
+
const allocated = new Set();
|
51
|
+
|
34
52
|
const exports = funcs.filter(x => x.export);
|
35
53
|
for (const x of exports) {
|
36
54
|
if (x.data) x.data = x.data.map(x => data[x]);
|
@@ -40,15 +58,33 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
40
58
|
return obj;
|
41
59
|
}).filter(x => x);
|
42
60
|
|
43
|
-
|
61
|
+
const locals = Object.keys(x.locals).reduce((acc, y) => {
|
62
|
+
acc[x.locals[y].idx] = { ...x.locals[y], name: y };
|
63
|
+
return acc;
|
64
|
+
}, {});
|
65
|
+
|
66
|
+
for (let i = 0; i < x.wasm.length; i++) {
|
67
|
+
const y = x.wasm[i];
|
68
|
+
const n = x.wasm[i + 1];
|
44
69
|
if (y[0] === Opcodes.call) {
|
45
70
|
const f = funcs.find(x => x.index === y[1]);
|
46
71
|
if (!f) continue;
|
47
72
|
|
48
|
-
|
73
|
+
y[1] = f.name;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (y[0] === Opcodes.const && (n[0] === Opcodes.local_set || n[0] === Opcodes.local_tee)) {
|
77
|
+
const l = locals[n[1]];
|
78
|
+
if (!l) continue;
|
79
|
+
if (![TYPES.string, TYPES._array, TYPES._bytestring].includes(l.metadata?.type)) continue;
|
80
|
+
if (!x.pages) continue;
|
49
81
|
|
50
|
-
x.
|
51
|
-
|
82
|
+
const pageName = [...x.pages.keys()].find(z => z.endsWith(l.name));
|
83
|
+
if (!pageName || allocated.has(pageName)) continue;
|
84
|
+
allocated.add(pageName);
|
85
|
+
|
86
|
+
y.splice(0, 10, 'alloc', pageName, x.pages.get(pageName).type);
|
87
|
+
// y.push(x.pages.get(pageName));
|
52
88
|
}
|
53
89
|
}
|
54
90
|
}
|
@@ -66,24 +102,28 @@ const precompile = async () => {
|
|
66
102
|
await compile(join(dir, file), [ funcs, globals ]);
|
67
103
|
}
|
68
104
|
|
69
|
-
//
|
105
|
+
// ${x.pages && x.pages.size > 0 ? ` pages: ${JSON.stringify(Object.fromEntries(x.pages.entries()))},` : ''}
|
106
|
+
// ${x.used && x.used.length > 0 ? ` used: ${JSON.stringify(x.used)},` : ''}
|
70
107
|
|
71
108
|
return `// autogenerated by compiler/precompile.js
|
109
|
+
import { number } from './embedding.js';
|
72
110
|
|
73
111
|
export const BuiltinFuncs = function() {
|
74
112
|
${funcs.map(x => ` this.${x.name} = {
|
75
|
-
wasm: ${JSON.stringify(x.wasm)},
|
113
|
+
wasm: (scope, { allocPage, builtin }) => ${JSON.stringify(x.wasm.filter(x => x.length)).replace(/\["alloc","(.*?)","(.*?)"\]/g, (_, reason, type) => `...number(allocPage(scope, '${reason}', '${type}') * pageSize, ${valtypeBinary})`).replace(/\[16,"(.*?)"]/g, (_, name) => `[16, builtin('${name}')]`)},
|
76
114
|
params: ${JSON.stringify(x.params)},
|
77
115
|
typedParams: true,
|
78
116
|
returns: ${JSON.stringify(x.returns)},
|
79
117
|
typedReturns: true,
|
80
|
-
locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length
|
81
|
-
|
118
|
+
locals: ${JSON.stringify(Object.values(x.locals).slice(x.params.length).map(x => x.type))},
|
119
|
+
localNames: ${JSON.stringify(Object.keys(x.locals))},
|
82
120
|
${x.data && x.data.length > 0 ? ` data: ${JSON.stringify(x.data)},` : ''}
|
83
121
|
${x.exceptions && x.exceptions.length > 0 ? ` exceptions: ${JSON.stringify(x.exceptions)},` : ''}
|
84
|
-
${x.used && x.used.length > 0 ? ` used: ${JSON.stringify(x.used)},` : ''}
|
85
122
|
};`.replaceAll('\n\n', '\n')).join('\n')}
|
86
|
-
}
|
123
|
+
};`;
|
87
124
|
};
|
88
125
|
|
89
|
-
|
126
|
+
const code = await precompile();
|
127
|
+
// console.log(code);
|
128
|
+
|
129
|
+
fs.writeFileSync(join(__dirname, 'generated_builtins.js'), code);
|
package/compiler/prefs.js
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
const onByDefault = [ 'bytestring' ];
|
2
|
+
|
1
3
|
const cache = {};
|
2
4
|
const obj = new Proxy({}, {
|
3
5
|
get(_, p) {
|
@@ -8,10 +10,12 @@ const obj = new Proxy({}, {
|
|
8
10
|
// fooBar -> foo-bar
|
9
11
|
const name = p[0] === '_' ? p : p.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`);
|
10
12
|
if (process.argv.includes('-' + name)) return true;
|
13
|
+
if (process.argv.includes('-no-' + name)) return false;
|
11
14
|
|
12
15
|
const valArg = process.argv.find(x => x.startsWith(`-${name}=`));
|
13
16
|
if (valArg) return valArg.slice(name.length + 2);
|
14
17
|
|
18
|
+
if (onByDefault.includes(p)) return true;
|
15
19
|
return undefined;
|
16
20
|
})();
|
17
21
|
}
|
package/compiler/prototype.js
CHANGED
@@ -385,7 +385,7 @@ export const PrototypeFuncs = function() {
|
|
385
385
|
|
386
386
|
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
387
387
|
[ Opcodes.if, Blocktype.void ],
|
388
|
-
...number(NaN),
|
388
|
+
...number(valtype === 'i32' ? -1 : NaN),
|
389
389
|
[ Opcodes.br, 1 ],
|
390
390
|
[ Opcodes.end ],
|
391
391
|
|
@@ -598,7 +598,7 @@ export const PrototypeFuncs = function() {
|
|
598
598
|
|
599
599
|
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
600
600
|
[ Opcodes.if, Blocktype.void ],
|
601
|
-
...number(NaN),
|
601
|
+
...number(valtype === 'i32' ? -1 : NaN),
|
602
602
|
[ Opcodes.br, 1 ],
|
603
603
|
[ Opcodes.end ],
|
604
604
|
|
package/package.json
CHANGED