porffor 0.35.0 → 0.35.2
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/__internal_string.ts +74 -0
- package/compiler/builtins/_internal_string.ts +21 -0
- package/compiler/builtins/annexb_string.js +18 -119
- package/compiler/builtins/string.ts +28 -18
- package/compiler/builtins.js +5 -5
- package/compiler/builtins_precompiled.js +366 -369
- package/compiler/codegen.js +87 -185
- package/package.json +1 -1
- package/runner/index.js +1 -1
- package/runner/repl.js +4 -1
@@ -45,4 +45,78 @@ export const __Porffor_strcmp = (a: any, b: any): boolean => {
|
|
45
45
|
return true;
|
46
46
|
}
|
47
47
|
}
|
48
|
+
};
|
49
|
+
|
50
|
+
export const __Porffor_strcat = (a: any, b: any): any => {
|
51
|
+
// a and b must be string or bytestring
|
52
|
+
|
53
|
+
const al: i32 = Porffor.wasm.i32.load(a, 0, 0);
|
54
|
+
const bl: i32 = Porffor.wasm.i32.load(b, 0, 0);
|
55
|
+
|
56
|
+
if (Porffor.wasm`local.get ${a+1}` == Porffor.TYPES.bytestring) {
|
57
|
+
if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
|
58
|
+
// bytestring, bytestring
|
59
|
+
const out: bytestring = Porffor.allocateBytes(4 + al + bl);
|
60
|
+
|
61
|
+
// out.length = a.length + b.length
|
62
|
+
Porffor.wasm.i32.store(out, al + bl, 0, 0);
|
63
|
+
|
64
|
+
// copy left (fast memcpy)
|
65
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al, 0, 0);
|
66
|
+
|
67
|
+
// copy right (fast memcpy)
|
68
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al, Porffor.wasm`local.get ${b}` + 4, bl, 0, 0);
|
69
|
+
|
70
|
+
return out;
|
71
|
+
} else {
|
72
|
+
// bytestring, string
|
73
|
+
const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
|
74
|
+
|
75
|
+
// out.length = a.length + b.length
|
76
|
+
Porffor.wasm.i32.store(out, al + bl, 0, 0);
|
77
|
+
|
78
|
+
// copy left (slow bytestring -> string)
|
79
|
+
for (let i: i32 = 0; i < al; i++) {
|
80
|
+
Porffor.wasm.i32.store16(Porffor.wasm`local.get ${out}` + i*2, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${a}` + i, 0, 4), 0, 4);
|
81
|
+
}
|
82
|
+
|
83
|
+
// copy right (fast memcpy)
|
84
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al*2, Porffor.wasm`local.get ${b}` + 4, bl * 2, 0, 0);
|
85
|
+
|
86
|
+
return out;
|
87
|
+
}
|
88
|
+
} else {
|
89
|
+
if (Porffor.wasm`local.get ${b+1}` == Porffor.TYPES.bytestring) {
|
90
|
+
// string, bytestring
|
91
|
+
const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
|
92
|
+
|
93
|
+
// out.length = a.length + b.length
|
94
|
+
Porffor.wasm.i32.store(out, al + bl, 0, 0);
|
95
|
+
|
96
|
+
// copy left (fast memcpy)
|
97
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al * 2, 0, 0);
|
98
|
+
|
99
|
+
// copy right (slow bytestring -> string)
|
100
|
+
let ptr: i32 = Porffor.wasm`local.get ${out}` + al*2;
|
101
|
+
for (let i: i32 = 0; i < bl; i++) {
|
102
|
+
Porffor.wasm.i32.store16(ptr + i*2, Porffor.wasm.i32.load8_u(Porffor.wasm`local.get ${b}` + i, 0, 4), 0, 4);
|
103
|
+
}
|
104
|
+
|
105
|
+
return out;
|
106
|
+
} else {
|
107
|
+
// string, string
|
108
|
+
const out: string = Porffor.allocateBytes(4 + (al + bl) * 2);
|
109
|
+
|
110
|
+
// out.length = a.length + b.length
|
111
|
+
Porffor.wasm.i32.store(out, al + bl, 0, 0);
|
112
|
+
|
113
|
+
// copy left (fast memcpy)
|
114
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4, Porffor.wasm`local.get ${a}` + 4, al * 2, 0, 0);
|
115
|
+
|
116
|
+
// copy right (fast memcpy)
|
117
|
+
Porffor.wasm.memory.copy(Porffor.wasm`local.get ${out}` + 4 + al*2, Porffor.wasm`local.get ${b}` + 4, bl * 2, 0, 0);
|
118
|
+
|
119
|
+
return out;
|
120
|
+
}
|
121
|
+
}
|
48
122
|
};
|
@@ -35,4 +35,25 @@ export const __Porffor_compareStrings = (a: any, b: any): boolean => {
|
|
35
35
|
}
|
36
36
|
|
37
37
|
return Porffor.strcmp(a, b);
|
38
|
+
};
|
39
|
+
|
40
|
+
export const __Porffor_concatStrings = (a: any, b: any): boolean => {
|
41
|
+
let at: i32 = Porffor.rawType(a);
|
42
|
+
let bt: i32 = Porffor.rawType(b);
|
43
|
+
|
44
|
+
if ((at | 0b10000000) != Porffor.TYPES.bytestring) {
|
45
|
+
// a is not string or bytestring
|
46
|
+
// todo/perf: just use a.toString()?
|
47
|
+
a = ecma262.ToString(a);
|
48
|
+
at = Porffor.rawType(a);
|
49
|
+
}
|
50
|
+
|
51
|
+
if ((bt | 0b10000000) != Porffor.TYPES.bytestring) {
|
52
|
+
// b is not string or bytestring
|
53
|
+
// todo/perf: just use b.toString()?
|
54
|
+
b = ecma262.ToString(b);
|
55
|
+
bt = Porffor.rawType(b);
|
56
|
+
}
|
57
|
+
|
58
|
+
return Porffor.strcat(a, b);
|
38
59
|
};
|
@@ -1,59 +1,14 @@
|
|
1
1
|
export default () => {
|
2
|
-
let out =
|
3
|
-
`;
|
4
|
-
|
2
|
+
let out = ``;
|
5
3
|
const noArgs = (a0, a1) => out += `
|
6
|
-
export const __String_prototype_${a0} = (_this:
|
7
|
-
|
8
|
-
|
9
|
-
let outPtr: i32 = Porffor.wasm\`local.get \${out}\` + ${(2 + a1.length) * 2};
|
10
|
-
let thisPtr: i32 = Porffor.wasm\`local.get \${_this}\`;
|
11
|
-
let thisLen: i32 = _this.length;
|
12
|
-
let endPtr: i32 = thisPtr + thisLen * 2;
|
13
|
-
|
14
|
-
while (thisPtr < endPtr) {
|
15
|
-
let chr: i32 = Porffor.wasm.i32.load16_u(thisPtr, 0, 4);
|
16
|
-
Porffor.wasm.i32.store16(outPtr, chr, 0, 4);
|
17
|
-
|
18
|
-
thisPtr += 2;
|
19
|
-
outPtr += 2;
|
20
|
-
}
|
21
|
-
|
22
|
-
Porffor.wasm.i32.store16(outPtr, 60, 0, 4); // <
|
23
|
-
Porffor.wasm.i32.store16(outPtr, 47, 0, 6); // /
|
24
|
-
|
25
|
-
${[...a1].map((x, i) => ` Porffor.wasm.i32.store16(outPtr, ${x.charCodeAt(0)}, 0, ${8 + i * 2}); // ${x}`).join('\n')}
|
26
|
-
|
27
|
-
Porffor.wasm.i32.store16(outPtr, 62, 0, ${8 + a1.length * 2}); // >
|
28
|
-
|
29
|
-
out.length = thisLen + ${a1.length * 2 + 2 + 3};
|
30
|
-
|
31
|
-
return out;
|
32
|
-
};
|
33
|
-
export const __ByteString_prototype_${a0} = (_this: bytestring) => {
|
34
|
-
let out: bytestring = Porffor.bs\`<${a1}>\`;
|
35
|
-
|
36
|
-
let outPtr: i32 = Porffor.wasm\`local.get \${out}\` + ${2 + a1.length};
|
37
|
-
let thisPtr: i32 = Porffor.wasm\`local.get \${_this}\`;
|
38
|
-
let thisLen: i32 = _this.length;
|
39
|
-
let endPtr: i32 = thisPtr + thisLen;
|
40
|
-
|
41
|
-
while (thisPtr < endPtr) {
|
42
|
-
let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr++, 0, 4);
|
43
|
-
Porffor.wasm.i32.store8(outPtr++, chr, 0, 4);
|
44
|
-
}
|
45
|
-
|
46
|
-
Porffor.wasm.i32.store8(outPtr, 60, 0, 4); // <
|
47
|
-
Porffor.wasm.i32.store8(outPtr, 47, 0, 5); // /
|
48
|
-
|
49
|
-
${[...a1].map((x, i) => ` Porffor.wasm.i32.store8(outPtr, ${x.charCodeAt(0)}, 0, ${6 + i}); // ${x}`).join('\n')}
|
50
|
-
|
51
|
-
Porffor.wasm.i32.store8(outPtr, 62, 0, ${6 + a1.length}); // >
|
4
|
+
export const __String_prototype_${a0} = (_this: any) => {
|
5
|
+
const pre: bytestring = '<${a1}>';
|
6
|
+
const post: bytestring = '</${a1}>';
|
52
7
|
|
53
|
-
|
54
|
-
|
55
|
-
return out;
|
8
|
+
return Porffor.concatStrings(Porffor.concatStrings(pre, _this), post);
|
56
9
|
};
|
10
|
+
export const __ByteString_prototype_${a0} = (_this: any) =>
|
11
|
+
__String_prototype_${a0}(_this);
|
57
12
|
`;
|
58
13
|
|
59
14
|
noArgs('big', 'big');
|
@@ -67,69 +22,15 @@ ${[...a1].map((x, i) => ` Porffor.wasm.i32.store8(outPtr, ${x.charCodeAt(0)}, 0
|
|
67
22
|
noArgs('sup', 'sup');
|
68
23
|
|
69
24
|
const arg = (name, s1, s2) => out += `
|
70
|
-
export const __String_prototype_${name} = (_this:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
let outPtr: i32 = Porffor.wasm\`local.get \${out}\` + ${(`<${s1} ${s2}="`.length + 2) * 2} + arg.length * 2;
|
75
|
-
|
76
|
-
Porffor.wasm.i32.store16(outPtr, 34, 0, 0); // "
|
77
|
-
Porffor.wasm.i32.store16(outPtr, 62, 0, 2); // >
|
78
|
-
|
79
|
-
let thisPtr: i32 = Porffor.wasm\`local.get \${_this}\`;
|
80
|
-
let thisLen: i32 = _this.length;
|
81
|
-
let endPtr: i32 = thisPtr + thisLen * 2;
|
25
|
+
export const __String_prototype_${name} = (_this: any, arg: any) => {
|
26
|
+
const pre1: bytestring = '<${s1} ${s2}="';
|
27
|
+
const pre2: bytestring = '">';
|
28
|
+
const post: bytestring = '</${s1}>';
|
82
29
|
|
83
|
-
|
84
|
-
let chr: i32 = Porffor.wasm.i32.load16_u(thisPtr, 0, 4);
|
85
|
-
Porffor.wasm.i32.store16(outPtr, chr, 0, 4);
|
86
|
-
|
87
|
-
thisPtr += 2;
|
88
|
-
outPtr += 2;
|
89
|
-
}
|
90
|
-
|
91
|
-
Porffor.wasm.i32.store16(outPtr, 60, 0, 4); // <
|
92
|
-
Porffor.wasm.i32.store16(outPtr, 47, 0, 6); // /
|
93
|
-
|
94
|
-
${[...s1].map((x, i) => ` Porffor.wasm.i32.store16(outPtr, ${x.charCodeAt(0)}, 0, ${8 + i * 2}); // ${x}`).join('\n')}
|
95
|
-
|
96
|
-
Porffor.wasm.i32.store16(outPtr, 62, 0, ${8 + s1.length * 2}); // >
|
97
|
-
|
98
|
-
out.length = thisLen + arg.length + ${`<${s1} ${s2}="`.length + s1.length + 5};
|
99
|
-
|
100
|
-
return out;
|
101
|
-
};
|
102
|
-
export const __ByteString_prototype_${name} = (_this: bytestring, arg: any) => {
|
103
|
-
let out: string = Porffor.s\`${`<${s1} ${s2}="`}\`;
|
104
|
-
out += arg;
|
105
|
-
|
106
|
-
let outPtr: i32 = Porffor.wasm\`local.get \${out}\` + ${(`<${s1} ${s2}="`.length + 2) * 2} + arg.length * 2;
|
107
|
-
|
108
|
-
Porffor.wasm.i32.store16(outPtr, 34, 0, 0); // "
|
109
|
-
Porffor.wasm.i32.store16(outPtr, 62, 0, 2); // >
|
110
|
-
|
111
|
-
let thisPtr: i32 = Porffor.wasm\`local.get \${_this}\`;
|
112
|
-
let thisLen: i32 = _this.length;
|
113
|
-
let endPtr: i32 = thisPtr + thisLen;
|
114
|
-
|
115
|
-
while (thisPtr < endPtr) {
|
116
|
-
let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr++, 0, 4);
|
117
|
-
Porffor.wasm.i32.store16(outPtr, chr, 0, 4);
|
118
|
-
|
119
|
-
outPtr += 2;
|
120
|
-
}
|
121
|
-
|
122
|
-
Porffor.wasm.i32.store16(outPtr, 60, 0, 4); // <
|
123
|
-
Porffor.wasm.i32.store16(outPtr, 47, 0, 6); // /
|
124
|
-
|
125
|
-
${[...s1].map((x, i) => ` Porffor.wasm.i32.store16(outPtr, ${x.charCodeAt(0)}, 0, ${8 + i * 2}); // ${x}`).join('\n')}
|
126
|
-
|
127
|
-
Porffor.wasm.i32.store16(outPtr, 62, 0, ${8 + s1.length * 2}); // >
|
128
|
-
|
129
|
-
out.length = thisLen + arg.length + ${`<${s1} ${s2}="`.length + s1.length + 5};
|
130
|
-
|
131
|
-
return out;
|
30
|
+
return Porffor.concatStrings(Porffor.concatStrings(Porffor.concatStrings(Porffor.concatStrings(pre1, arg), pre2), _this), post);
|
132
31
|
};
|
32
|
+
export const __ByteString_prototype_${name} = (_this: any, arg: any) =>
|
33
|
+
__String_prototype_${name}(_this, arg);
|
133
34
|
`;
|
134
35
|
|
135
36
|
arg('fontcolor', 'font', 'color');
|
@@ -137,12 +38,10 @@ ${[...s1].map((x, i) => ` Porffor.wasm.i32.store16(outPtr, ${x.charCodeAt(0)},
|
|
137
38
|
arg('anchor', 'a', 'name');
|
138
39
|
arg('link', 'a', 'href');
|
139
40
|
|
140
|
-
const prototypeAlias = (regular, annex) => `export const __String_prototype_${annex} = (_this:
|
141
|
-
|
142
|
-
}
|
143
|
-
|
144
|
-
return __ByteString_prototype_${regular}(_this);
|
145
|
-
};
|
41
|
+
const prototypeAlias = (regular, annex) => `export const __String_prototype_${annex} = (_this: any) =>
|
42
|
+
__String_prototype_${regular}(_this);
|
43
|
+
export const __ByteString_prototype_${annex} = (_this: any) =>
|
44
|
+
__ByteString_prototype_${regular}(_this);
|
146
45
|
`;
|
147
46
|
|
148
47
|
prototypeAlias('trimStart', 'trimLeft');
|
@@ -1079,14 +1079,21 @@ export const __ByteString_prototype_trim = (_this: bytestring) => {
|
|
1079
1079
|
|
1080
1080
|
|
1081
1081
|
export const __String_prototype_concat = (_this: string, ...vals: any[]) => {
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1082
|
+
let out = Porffor.allocate();
|
1083
|
+
Porffor.clone(_this, out);
|
1084
|
+
|
1085
|
+
// override type to string
|
1086
|
+
Porffor.wasm`
|
1087
|
+
i32.const 67 ;; string
|
1088
|
+
local.set ${out+1}`;
|
1085
1089
|
|
1086
1090
|
const valsLen: i32 = vals.length;
|
1087
1091
|
for (let i: i32 = 0; i < valsLen; i++) {
|
1088
|
-
let x: any;
|
1089
1092
|
Porffor.wasm`
|
1093
|
+
local.get ${out}
|
1094
|
+
f64.convert_i32_u
|
1095
|
+
local.get ${out+1}
|
1096
|
+
|
1090
1097
|
local.get ${vals}
|
1091
1098
|
local.get ${i}
|
1092
1099
|
i32.const 9
|
@@ -1101,26 +1108,31 @@ i32.mul
|
|
1101
1108
|
i32.add
|
1102
1109
|
i32.load8_u 0 12
|
1103
1110
|
|
1104
|
-
call
|
1105
|
-
local.set ${
|
1111
|
+
call __Porffor_concatStrings
|
1112
|
+
local.set ${out+1}
|
1106
1113
|
i32.trunc_sat_f64_u
|
1107
|
-
local.set ${
|
1108
|
-
|
1109
|
-
out += x;
|
1114
|
+
local.set ${out}`;
|
1110
1115
|
}
|
1111
1116
|
|
1112
1117
|
return out;
|
1113
1118
|
};
|
1114
1119
|
|
1115
1120
|
export const __ByteString_prototype_concat = (_this: bytestring, ...vals: any[]) => {
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1121
|
+
let out = Porffor.allocate();
|
1122
|
+
Porffor.clone(_this, out);
|
1123
|
+
|
1124
|
+
// override type to bytestring
|
1125
|
+
Porffor.wasm`
|
1126
|
+
i32.const 195 ;; bytestring
|
1127
|
+
local.set ${out+1}`;
|
1119
1128
|
|
1120
1129
|
const valsLen: i32 = vals.length;
|
1121
1130
|
for (let i: i32 = 0; i < valsLen; i++) {
|
1122
|
-
let x: any;
|
1123
1131
|
Porffor.wasm`
|
1132
|
+
local.get ${out}
|
1133
|
+
f64.convert_i32_u
|
1134
|
+
local.get ${out+1}
|
1135
|
+
|
1124
1136
|
local.get ${vals}
|
1125
1137
|
local.get ${i}
|
1126
1138
|
i32.const 9
|
@@ -1135,12 +1147,10 @@ i32.mul
|
|
1135
1147
|
i32.add
|
1136
1148
|
i32.load8_u 0 12
|
1137
1149
|
|
1138
|
-
call
|
1139
|
-
local.set ${
|
1150
|
+
call __Porffor_concatStrings
|
1151
|
+
local.set ${out+1}
|
1140
1152
|
i32.trunc_sat_f64_u
|
1141
|
-
local.set ${
|
1142
|
-
|
1143
|
-
out += x;
|
1153
|
+
local.set ${out}`;
|
1144
1154
|
}
|
1145
1155
|
|
1146
1156
|
return out;
|
package/compiler/builtins.js
CHANGED
@@ -160,19 +160,19 @@ export const BuiltinFuncs = function() {
|
|
160
160
|
// add bitwise ops by converting operands to i32 first
|
161
161
|
for (const [ char, op ] of [ ['&', Opcodes.i32_and], ['|', Opcodes.i32_or], ['^', Opcodes.i32_xor], ['<<', Opcodes.i32_shl], ['>>', Opcodes.i32_shr_s], ['>>>', Opcodes.i32_shr_u] ]) {
|
162
162
|
this[`f64_${char}`] = {
|
163
|
-
params: [
|
163
|
+
params: [ Valtype.f64, Valtype.f64 ],
|
164
164
|
locals: [],
|
165
|
-
returns: [
|
165
|
+
returns: [ Valtype.f64 ],
|
166
166
|
returnType: TYPES.number,
|
167
167
|
wasm: [
|
168
168
|
[ Opcodes.local_get, 0 ],
|
169
|
-
Opcodes.
|
169
|
+
Opcodes.i32_trunc_sat_f64_s,
|
170
170
|
|
171
171
|
[ Opcodes.local_get, 1 ],
|
172
|
-
Opcodes.
|
172
|
+
Opcodes.i32_trunc_sat_f64_s,
|
173
173
|
|
174
174
|
[ op ],
|
175
|
-
Opcodes.
|
175
|
+
[ Opcodes.f64_convert_i32_s ]
|
176
176
|
]
|
177
177
|
};
|
178
178
|
}
|