porffor 0.58.11 → 0.58.13
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/assemble.js +5 -3
- package/compiler/builtins/console.ts +6 -1
- package/compiler/builtins/regexp.ts +424 -45
- package/compiler/builtins/uri.ts +870 -0
- package/compiler/builtins.js +15 -9
- package/compiler/builtins_precompiled.js +418 -356
- package/compiler/codegen.js +38 -26
- package/compiler/index.js +1 -1
- package/compiler/wrap.js +2 -2
- package/package.json +1 -1
- package/runtime/index.js +1 -1
- package/compiler/builtins/escape.ts +0 -140
@@ -0,0 +1,870 @@
|
|
1
|
+
// @porf --valtype=i32
|
2
|
+
import type {} from './porffor.d.ts';
|
3
|
+
|
4
|
+
// Legacy escape function
|
5
|
+
export const escape = (input: any): bytestring => {
|
6
|
+
input = __ecma262_ToString(input);
|
7
|
+
const len: i32 = input.length;
|
8
|
+
let outLength: i32 = 0;
|
9
|
+
|
10
|
+
let i: i32 = Porffor.wasm`local.get ${input}`;
|
11
|
+
|
12
|
+
// Check if input is bytestring or string
|
13
|
+
if (Porffor.wasm`local.get ${input+1}` == Porffor.TYPES.bytestring) {
|
14
|
+
// Handle bytestring input
|
15
|
+
const endPtr: i32 = i + len;
|
16
|
+
|
17
|
+
// First pass: calculate output length
|
18
|
+
while (i < endPtr) {
|
19
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
20
|
+
|
21
|
+
// Characters that should NOT be escaped: A-Z a-z 0-9 @ * + - . / _
|
22
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
23
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
24
|
+
(chr >= 97 && chr <= 122) || // a-z
|
25
|
+
chr == 42 || chr == 43 || chr == 45 || chr == 46 || chr == 47 || chr == 64 || chr == 95) {
|
26
|
+
outLength += 1;
|
27
|
+
} else {
|
28
|
+
outLength += 3; // %XX
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
// Second pass: encode
|
33
|
+
let output: bytestring = Porffor.allocate();
|
34
|
+
output.length = outLength;
|
35
|
+
|
36
|
+
i = Porffor.wasm`local.get ${input}`;
|
37
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
38
|
+
|
39
|
+
while (i < endPtr) {
|
40
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
41
|
+
|
42
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
43
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
44
|
+
(chr >= 97 && chr <= 122) || // a-z
|
45
|
+
chr == 42 || chr == 43 || chr == 45 || chr == 46 || chr == 47 || chr == 64 || chr == 95) {
|
46
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
47
|
+
} else {
|
48
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
49
|
+
|
50
|
+
let nibble: i32 = chr >> 4;
|
51
|
+
if (nibble < 10) {
|
52
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
53
|
+
} else {
|
54
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
55
|
+
}
|
56
|
+
|
57
|
+
nibble = chr & 0x0F;
|
58
|
+
if (nibble < 10) {
|
59
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
60
|
+
} else {
|
61
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
return output;
|
67
|
+
}
|
68
|
+
|
69
|
+
// Handle string input (16-bit characters)
|
70
|
+
const endPtr: i32 = i + len * 2;
|
71
|
+
|
72
|
+
// First pass: calculate output length
|
73
|
+
while (i < endPtr) {
|
74
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
75
|
+
i += 2;
|
76
|
+
|
77
|
+
// Characters that should NOT be escaped: A-Z a-z 0-9 @ * + - . / _
|
78
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
79
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
80
|
+
(chr >= 97 && chr <= 122) || // a-z
|
81
|
+
chr == 42 || chr == 43 || chr == 45 || chr == 46 || chr == 47 || chr == 64 || chr == 95) {
|
82
|
+
outLength += 1;
|
83
|
+
} else if (chr < 256) {
|
84
|
+
outLength += 3; // %XX
|
85
|
+
} else {
|
86
|
+
outLength += 6; // %uXXXX
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
// Second pass: encode
|
91
|
+
let output: bytestring = Porffor.allocate();
|
92
|
+
output.length = outLength;
|
93
|
+
|
94
|
+
i = Porffor.wasm`local.get ${input}`;
|
95
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
96
|
+
|
97
|
+
while (i < endPtr) {
|
98
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
99
|
+
i += 2;
|
100
|
+
|
101
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
102
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
103
|
+
(chr >= 97 && chr <= 122) || // a-z
|
104
|
+
chr == 42 || chr == 43 || chr == 45 || chr == 46 || chr == 47 || chr == 64 || chr == 95) {
|
105
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
106
|
+
} else if (chr < 256) {
|
107
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
108
|
+
|
109
|
+
let nibble: i32 = chr >> 4;
|
110
|
+
if (nibble < 10) {
|
111
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
112
|
+
} else {
|
113
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
114
|
+
}
|
115
|
+
|
116
|
+
nibble = chr & 0x0F;
|
117
|
+
if (nibble < 10) {
|
118
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
119
|
+
} else {
|
120
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
121
|
+
}
|
122
|
+
} else {
|
123
|
+
// %uXXXX
|
124
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
125
|
+
Porffor.wasm.i32.store8(j++, 117, 0, 4); // u
|
126
|
+
|
127
|
+
let nibble: i32 = (chr >> 12) & 0x0F;
|
128
|
+
if (nibble < 10) {
|
129
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
130
|
+
} else {
|
131
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
132
|
+
}
|
133
|
+
|
134
|
+
nibble = (chr >> 8) & 0x0F;
|
135
|
+
if (nibble < 10) {
|
136
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
137
|
+
} else {
|
138
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
139
|
+
}
|
140
|
+
|
141
|
+
nibble = (chr >> 4) & 0x0F;
|
142
|
+
if (nibble < 10) {
|
143
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
144
|
+
} else {
|
145
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
146
|
+
}
|
147
|
+
|
148
|
+
nibble = chr & 0x0F;
|
149
|
+
if (nibble < 10) {
|
150
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
151
|
+
} else {
|
152
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
return output;
|
158
|
+
};
|
159
|
+
|
160
|
+
// Legacy unescape function
|
161
|
+
export const unescape = (input: any): string => {
|
162
|
+
input = __ecma262_ToString(input);
|
163
|
+
const len: i32 = input.length;
|
164
|
+
let outLength: i32 = 0;
|
165
|
+
|
166
|
+
// First pass: calculate output length
|
167
|
+
let i: i32 = Porffor.wasm`local.get ${input}`;
|
168
|
+
const endPtr: i32 = i + len;
|
169
|
+
|
170
|
+
while (i < endPtr) {
|
171
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
172
|
+
if (chr == 37) { // %
|
173
|
+
if (i + 4 < endPtr && Porffor.wasm.i32.load8_u(i, 0, 4) == 117) { // u
|
174
|
+
i += 5;
|
175
|
+
} else if (i + 1 < endPtr) {
|
176
|
+
i += 2;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
outLength += 1;
|
180
|
+
}
|
181
|
+
|
182
|
+
// Second pass: decode
|
183
|
+
let output: string = Porffor.allocate();
|
184
|
+
output.length = outLength;
|
185
|
+
|
186
|
+
i = Porffor.wasm`local.get ${input}`;
|
187
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
188
|
+
|
189
|
+
while (i < endPtr) {
|
190
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
191
|
+
|
192
|
+
if (chr == 37) { // %
|
193
|
+
if (i + 4 < endPtr && Porffor.wasm.i32.load8_u(i, 0, 4) == 117) { // u
|
194
|
+
// %uXXXX
|
195
|
+
const d1: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
196
|
+
const d2: i32 = Porffor.wasm.i32.load8_u(i + 2, 0, 4);
|
197
|
+
const d3: i32 = Porffor.wasm.i32.load8_u(i + 3, 0, 4);
|
198
|
+
const d4: i32 = Porffor.wasm.i32.load8_u(i + 4, 0, 4);
|
199
|
+
|
200
|
+
let n1: i32 = d1 - 48;
|
201
|
+
if (n1 > 9) {
|
202
|
+
n1 = d1 - 55;
|
203
|
+
if (n1 > 15) n1 = d1 - 87;
|
204
|
+
}
|
205
|
+
|
206
|
+
let n2: i32 = d2 - 48;
|
207
|
+
if (n2 > 9) {
|
208
|
+
n2 = d2 - 55;
|
209
|
+
if (n2 > 15) n2 = d2 - 87;
|
210
|
+
}
|
211
|
+
|
212
|
+
let n3: i32 = d3 - 48;
|
213
|
+
if (n3 > 9) {
|
214
|
+
n3 = d3 - 55;
|
215
|
+
if (n3 > 15) n3 = d3 - 87;
|
216
|
+
}
|
217
|
+
|
218
|
+
let n4: i32 = d4 - 48;
|
219
|
+
if (n4 > 9) {
|
220
|
+
n4 = d4 - 55;
|
221
|
+
if (n4 > 15) n4 = d4 - 87;
|
222
|
+
}
|
223
|
+
|
224
|
+
if (n1 >= 0 && n1 <= 15 && n2 >= 0 && n2 <= 15 && n3 >= 0 && n3 <= 15 && n4 >= 0 && n4 <= 15) {
|
225
|
+
i += 5;
|
226
|
+
const value: i32 = (n1 << 12) | (n2 << 8) | (n3 << 4) | n4;
|
227
|
+
Porffor.wasm.i32.store16(j, value, 0, 4);
|
228
|
+
} else {
|
229
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
230
|
+
}
|
231
|
+
} else if (i + 1 < endPtr) {
|
232
|
+
// %XX
|
233
|
+
const d1: i32 = Porffor.wasm.i32.load8_u(i, 0, 4);
|
234
|
+
const d2: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
235
|
+
|
236
|
+
let n1: i32 = d1 - 48;
|
237
|
+
if (n1 > 9) {
|
238
|
+
n1 = d1 - 55;
|
239
|
+
if (n1 > 15) n1 = d1 - 87;
|
240
|
+
}
|
241
|
+
|
242
|
+
let n2: i32 = d2 - 48;
|
243
|
+
if (n2 > 9) {
|
244
|
+
n2 = d2 - 55;
|
245
|
+
if (n2 > 15) n2 = d2 - 87;
|
246
|
+
}
|
247
|
+
|
248
|
+
if (n1 >= 0 && n1 <= 15 && n2 >= 0 && n2 <= 15) {
|
249
|
+
i += 2;
|
250
|
+
const value: i32 = (n1 << 4) | n2;
|
251
|
+
Porffor.wasm.i32.store16(j, value, 0, 4);
|
252
|
+
} else {
|
253
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
254
|
+
}
|
255
|
+
} else {
|
256
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
257
|
+
}
|
258
|
+
} else {
|
259
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
260
|
+
}
|
261
|
+
|
262
|
+
j += 2;
|
263
|
+
}
|
264
|
+
|
265
|
+
return output;
|
266
|
+
};
|
267
|
+
|
268
|
+
// Modern URI encoding functions
|
269
|
+
export const encodeURI = (input: any): bytestring => {
|
270
|
+
input = __ecma262_ToString(input);
|
271
|
+
const len: i32 = input.length;
|
272
|
+
let outLength: i32 = 0;
|
273
|
+
|
274
|
+
let i: i32 = Porffor.wasm`local.get ${input}`;
|
275
|
+
|
276
|
+
// Check if input is bytestring or string
|
277
|
+
if (Porffor.wasm`local.get ${input+1}` == Porffor.TYPES.bytestring) {
|
278
|
+
// Handle bytestring input
|
279
|
+
const endPtr: i32 = i + len;
|
280
|
+
|
281
|
+
// First pass: calculate output length
|
282
|
+
while (i < endPtr) {
|
283
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
284
|
+
|
285
|
+
// Characters that should NOT be encoded for encodeURI
|
286
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
287
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
288
|
+
(chr >= 97 && chr <= 122) || // a-z
|
289
|
+
chr == 33 || chr == 35 || chr == 36 || chr == 38 || chr == 39 ||
|
290
|
+
chr == 40 || chr == 41 || chr == 42 || chr == 43 || chr == 44 ||
|
291
|
+
chr == 45 || chr == 46 || chr == 47 || chr == 58 || chr == 59 ||
|
292
|
+
chr == 61 || chr == 63 || chr == 64 || chr == 91 || chr == 93 ||
|
293
|
+
chr == 95 || chr == 126) {
|
294
|
+
outLength += 1;
|
295
|
+
} else {
|
296
|
+
outLength += 3; // %XX
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
// Second pass: encode
|
301
|
+
let output: bytestring = Porffor.allocate();
|
302
|
+
output.length = outLength;
|
303
|
+
|
304
|
+
i = Porffor.wasm`local.get ${input}`;
|
305
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
306
|
+
|
307
|
+
while (i < endPtr) {
|
308
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
309
|
+
|
310
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
311
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
312
|
+
(chr >= 97 && chr <= 122) || // a-z
|
313
|
+
chr == 33 || chr == 35 || chr == 36 || chr == 38 || chr == 39 ||
|
314
|
+
chr == 40 || chr == 41 || chr == 42 || chr == 43 || chr == 44 ||
|
315
|
+
chr == 45 || chr == 46 || chr == 47 || chr == 58 || chr == 59 ||
|
316
|
+
chr == 61 || chr == 63 || chr == 64 || chr == 91 || chr == 93 ||
|
317
|
+
chr == 95 || chr == 126) {
|
318
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
319
|
+
} else {
|
320
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
321
|
+
|
322
|
+
let nibble: i32 = chr >> 4;
|
323
|
+
if (nibble < 10) {
|
324
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
325
|
+
} else {
|
326
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
327
|
+
}
|
328
|
+
|
329
|
+
nibble = chr & 0x0F;
|
330
|
+
if (nibble < 10) {
|
331
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
332
|
+
} else {
|
333
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
return output;
|
339
|
+
}
|
340
|
+
|
341
|
+
// Handle string input (16-bit characters)
|
342
|
+
const endPtr: i32 = i + len * 2;
|
343
|
+
|
344
|
+
// First pass: calculate output length
|
345
|
+
|
346
|
+
while (i < endPtr) {
|
347
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
348
|
+
i += 2;
|
349
|
+
|
350
|
+
// Characters that should NOT be encoded for encodeURI
|
351
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
352
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
353
|
+
(chr >= 97 && chr <= 122) || // a-z
|
354
|
+
chr == 33 || chr == 35 || chr == 36 || chr == 38 || chr == 39 ||
|
355
|
+
chr == 40 || chr == 41 || chr == 42 || chr == 43 || chr == 44 ||
|
356
|
+
chr == 45 || chr == 46 || chr == 47 || chr == 58 || chr == 59 ||
|
357
|
+
chr == 61 || chr == 63 || chr == 64 || chr == 91 || chr == 93 ||
|
358
|
+
chr == 95 || chr == 126) {
|
359
|
+
outLength += 1;
|
360
|
+
} else if (chr < 128) {
|
361
|
+
outLength += 3; // %XX
|
362
|
+
} else if (chr < 0x800) {
|
363
|
+
outLength += 6; // %XX%XX
|
364
|
+
} else {
|
365
|
+
outLength += 9; // %XX%XX%XX
|
366
|
+
}
|
367
|
+
}
|
368
|
+
|
369
|
+
// Second pass: encode
|
370
|
+
let output: bytestring = Porffor.allocate();
|
371
|
+
output.length = outLength;
|
372
|
+
|
373
|
+
i = Porffor.wasm`local.get ${input}`;
|
374
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
375
|
+
|
376
|
+
while (i < endPtr) {
|
377
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
378
|
+
i += 2;
|
379
|
+
|
380
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
381
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
382
|
+
(chr >= 97 && chr <= 122) || // a-z
|
383
|
+
chr == 33 || chr == 35 || chr == 36 || chr == 38 || chr == 39 ||
|
384
|
+
chr == 40 || chr == 41 || chr == 42 || chr == 43 || chr == 44 ||
|
385
|
+
chr == 45 || chr == 46 || chr == 47 || chr == 58 || chr == 59 ||
|
386
|
+
chr == 61 || chr == 63 || chr == 64 || chr == 91 || chr == 93 ||
|
387
|
+
chr == 95 || chr == 126) {
|
388
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
389
|
+
} else if (chr < 128) {
|
390
|
+
// Single byte UTF-8
|
391
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
392
|
+
|
393
|
+
let nibble: i32 = chr >> 4;
|
394
|
+
if (nibble < 10) {
|
395
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
396
|
+
} else {
|
397
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
398
|
+
}
|
399
|
+
|
400
|
+
nibble = chr & 0x0F;
|
401
|
+
if (nibble < 10) {
|
402
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
403
|
+
} else {
|
404
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
405
|
+
}
|
406
|
+
} else if (chr < 0x800) {
|
407
|
+
// Two byte UTF-8
|
408
|
+
const byte1: i32 = 0xC0 | (chr >> 6);
|
409
|
+
const byte2: i32 = 0x80 | (chr & 0x3F);
|
410
|
+
|
411
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
412
|
+
let nibble: i32 = byte1 >> 4;
|
413
|
+
if (nibble < 10) {
|
414
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
415
|
+
} else {
|
416
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
417
|
+
}
|
418
|
+
nibble = byte1 & 0x0F;
|
419
|
+
if (nibble < 10) {
|
420
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
421
|
+
} else {
|
422
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
423
|
+
}
|
424
|
+
|
425
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
426
|
+
nibble = byte2 >> 4;
|
427
|
+
if (nibble < 10) {
|
428
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
429
|
+
} else {
|
430
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
431
|
+
}
|
432
|
+
nibble = byte2 & 0x0F;
|
433
|
+
if (nibble < 10) {
|
434
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
435
|
+
} else {
|
436
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
437
|
+
}
|
438
|
+
} else {
|
439
|
+
// Three byte UTF-8
|
440
|
+
const byte1: i32 = 0xE0 | (chr >> 12);
|
441
|
+
const byte2: i32 = 0x80 | ((chr >> 6) & 0x3F);
|
442
|
+
const byte3: i32 = 0x80 | (chr & 0x3F);
|
443
|
+
|
444
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
445
|
+
let nibble: i32 = byte1 >> 4;
|
446
|
+
if (nibble < 10) {
|
447
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
448
|
+
} else {
|
449
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
450
|
+
}
|
451
|
+
nibble = byte1 & 0x0F;
|
452
|
+
if (nibble < 10) {
|
453
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
454
|
+
} else {
|
455
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
456
|
+
}
|
457
|
+
|
458
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
459
|
+
nibble = byte2 >> 4;
|
460
|
+
if (nibble < 10) {
|
461
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
462
|
+
} else {
|
463
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
464
|
+
}
|
465
|
+
nibble = byte2 & 0x0F;
|
466
|
+
if (nibble < 10) {
|
467
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
468
|
+
} else {
|
469
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
470
|
+
}
|
471
|
+
|
472
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
473
|
+
nibble = byte3 >> 4;
|
474
|
+
if (nibble < 10) {
|
475
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
476
|
+
} else {
|
477
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
478
|
+
}
|
479
|
+
nibble = byte3 & 0x0F;
|
480
|
+
if (nibble < 10) {
|
481
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
482
|
+
} else {
|
483
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
484
|
+
}
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
return output;
|
489
|
+
};
|
490
|
+
|
491
|
+
export const encodeURIComponent = (input: any): bytestring => {
|
492
|
+
input = __ecma262_ToString(input);
|
493
|
+
const len: i32 = input.length;
|
494
|
+
let outLength: i32 = 0;
|
495
|
+
|
496
|
+
let i: i32 = Porffor.wasm`local.get ${input}`;
|
497
|
+
|
498
|
+
// Check if input is bytestring or string
|
499
|
+
if (Porffor.wasm`local.get ${input+1}` == Porffor.TYPES.bytestring) {
|
500
|
+
// Handle bytestring input
|
501
|
+
const endPtr: i32 = i + len;
|
502
|
+
|
503
|
+
// First pass: calculate output length
|
504
|
+
while (i < endPtr) {
|
505
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
506
|
+
|
507
|
+
// Characters that should NOT be encoded for encodeURIComponent
|
508
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
509
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
510
|
+
(chr >= 97 && chr <= 122) || // a-z
|
511
|
+
chr == 33 || chr == 39 || chr == 40 || chr == 41 || chr == 42 ||
|
512
|
+
chr == 45 || chr == 46 || chr == 95 || chr == 126) {
|
513
|
+
outLength += 1;
|
514
|
+
} else {
|
515
|
+
outLength += 3; // %XX
|
516
|
+
}
|
517
|
+
}
|
518
|
+
|
519
|
+
// Second pass: encode
|
520
|
+
let output: bytestring = Porffor.allocate();
|
521
|
+
output.length = outLength;
|
522
|
+
|
523
|
+
i = Porffor.wasm`local.get ${input}`;
|
524
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
525
|
+
|
526
|
+
while (i < endPtr) {
|
527
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
528
|
+
|
529
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
530
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
531
|
+
(chr >= 97 && chr <= 122) || // a-z
|
532
|
+
chr == 33 || chr == 39 || chr == 40 || chr == 41 || chr == 42 ||
|
533
|
+
chr == 45 || chr == 46 || chr == 95 || chr == 126) {
|
534
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
535
|
+
} else {
|
536
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
537
|
+
|
538
|
+
let nibble: i32 = chr >> 4;
|
539
|
+
if (nibble < 10) {
|
540
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
541
|
+
} else {
|
542
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
543
|
+
}
|
544
|
+
|
545
|
+
nibble = chr & 0x0F;
|
546
|
+
if (nibble < 10) {
|
547
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
548
|
+
} else {
|
549
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
550
|
+
}
|
551
|
+
}
|
552
|
+
}
|
553
|
+
|
554
|
+
return output;
|
555
|
+
}
|
556
|
+
|
557
|
+
// Handle string input (16-bit characters)
|
558
|
+
const endPtr: i32 = i + len * 2;
|
559
|
+
|
560
|
+
// First pass: calculate output length
|
561
|
+
|
562
|
+
while (i < endPtr) {
|
563
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
564
|
+
i += 2;
|
565
|
+
|
566
|
+
// Characters that should NOT be encoded for encodeURIComponent
|
567
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
568
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
569
|
+
(chr >= 97 && chr <= 122) || // a-z
|
570
|
+
chr == 33 || chr == 39 || chr == 40 || chr == 41 || chr == 42 ||
|
571
|
+
chr == 45 || chr == 46 || chr == 95 || chr == 126) {
|
572
|
+
outLength += 1;
|
573
|
+
} else if (chr < 128) {
|
574
|
+
outLength += 3; // %XX
|
575
|
+
} else if (chr < 0x800) {
|
576
|
+
outLength += 6; // %XX%XX
|
577
|
+
} else {
|
578
|
+
outLength += 9; // %XX%XX%XX
|
579
|
+
}
|
580
|
+
}
|
581
|
+
|
582
|
+
// Second pass: encode
|
583
|
+
let output: bytestring = Porffor.allocate();
|
584
|
+
output.length = outLength;
|
585
|
+
|
586
|
+
i = Porffor.wasm`local.get ${input}`;
|
587
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
588
|
+
|
589
|
+
while (i < endPtr) {
|
590
|
+
const chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
|
591
|
+
i += 2;
|
592
|
+
|
593
|
+
if ((chr >= 48 && chr <= 57) || // 0-9
|
594
|
+
(chr >= 65 && chr <= 90) || // A-Z
|
595
|
+
(chr >= 97 && chr <= 122) || // a-z
|
596
|
+
chr == 33 || chr == 39 || chr == 40 || chr == 41 || chr == 42 ||
|
597
|
+
chr == 45 || chr == 46 || chr == 95 || chr == 126) {
|
598
|
+
Porffor.wasm.i32.store8(j++, chr, 0, 4);
|
599
|
+
} else if (chr < 128) {
|
600
|
+
// Single byte UTF-8
|
601
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
602
|
+
|
603
|
+
let nibble: i32 = chr >> 4;
|
604
|
+
if (nibble < 10) {
|
605
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
606
|
+
} else {
|
607
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
608
|
+
}
|
609
|
+
|
610
|
+
nibble = chr & 0x0F;
|
611
|
+
if (nibble < 10) {
|
612
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
613
|
+
} else {
|
614
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
615
|
+
}
|
616
|
+
} else if (chr < 0x800) {
|
617
|
+
// Two byte UTF-8
|
618
|
+
const byte1: i32 = 0xC0 | (chr >> 6);
|
619
|
+
const byte2: i32 = 0x80 | (chr & 0x3F);
|
620
|
+
|
621
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
622
|
+
let nibble: i32 = byte1 >> 4;
|
623
|
+
if (nibble < 10) {
|
624
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
625
|
+
} else {
|
626
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
627
|
+
}
|
628
|
+
nibble = byte1 & 0x0F;
|
629
|
+
if (nibble < 10) {
|
630
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
631
|
+
} else {
|
632
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
633
|
+
}
|
634
|
+
|
635
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
636
|
+
nibble = byte2 >> 4;
|
637
|
+
if (nibble < 10) {
|
638
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
639
|
+
} else {
|
640
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
641
|
+
}
|
642
|
+
nibble = byte2 & 0x0F;
|
643
|
+
if (nibble < 10) {
|
644
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
645
|
+
} else {
|
646
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
647
|
+
}
|
648
|
+
} else {
|
649
|
+
// Three byte UTF-8
|
650
|
+
const byte1: i32 = 0xE0 | (chr >> 12);
|
651
|
+
const byte2: i32 = 0x80 | ((chr >> 6) & 0x3F);
|
652
|
+
const byte3: i32 = 0x80 | (chr & 0x3F);
|
653
|
+
|
654
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
655
|
+
let nibble: i32 = byte1 >> 4;
|
656
|
+
if (nibble < 10) {
|
657
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
658
|
+
} else {
|
659
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
660
|
+
}
|
661
|
+
nibble = byte1 & 0x0F;
|
662
|
+
if (nibble < 10) {
|
663
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
664
|
+
} else {
|
665
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
666
|
+
}
|
667
|
+
|
668
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
669
|
+
nibble = byte2 >> 4;
|
670
|
+
if (nibble < 10) {
|
671
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
672
|
+
} else {
|
673
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
674
|
+
}
|
675
|
+
nibble = byte2 & 0x0F;
|
676
|
+
if (nibble < 10) {
|
677
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
678
|
+
} else {
|
679
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
680
|
+
}
|
681
|
+
|
682
|
+
Porffor.wasm.i32.store8(j++, 37, 0, 4); // %
|
683
|
+
nibble = byte3 >> 4;
|
684
|
+
if (nibble < 10) {
|
685
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
686
|
+
} else {
|
687
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
688
|
+
}
|
689
|
+
nibble = byte3 & 0x0F;
|
690
|
+
if (nibble < 10) {
|
691
|
+
Porffor.wasm.i32.store8(j++, nibble + 48, 0, 4);
|
692
|
+
} else {
|
693
|
+
Porffor.wasm.i32.store8(j++, nibble + 55, 0, 4);
|
694
|
+
}
|
695
|
+
}
|
696
|
+
}
|
697
|
+
|
698
|
+
return output;
|
699
|
+
};
|
700
|
+
|
701
|
+
export const decodeURI = (input: any): string => {
|
702
|
+
input = __ecma262_ToString(input);
|
703
|
+
const len: i32 = input.length;
|
704
|
+
let outLength: i32 = 0;
|
705
|
+
|
706
|
+
// First pass: calculate output length
|
707
|
+
let i: i32 = Porffor.wasm`local.get ${input}`;
|
708
|
+
const endPtr: i32 = i + len;
|
709
|
+
|
710
|
+
while (i < endPtr) {
|
711
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
712
|
+
if (chr == 37 && i + 1 < endPtr) { // %
|
713
|
+
const h1: i32 = Porffor.wasm.i32.load8_u(i, 0, 4);
|
714
|
+
const h2: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
715
|
+
|
716
|
+
let n1: i32 = h1 - 48;
|
717
|
+
if (n1 > 9) n1 = h1 - 55;
|
718
|
+
if (n1 > 15) n1 = h1 - 87;
|
719
|
+
|
720
|
+
let n2: i32 = h2 - 48;
|
721
|
+
if (n2 > 9) n2 = h2 - 55;
|
722
|
+
if (n2 > 15) n2 = h2 - 87;
|
723
|
+
|
724
|
+
if (n1 >= 0 && n1 <= 15 && n2 >= 0 && n2 <= 15) {
|
725
|
+
i += 2;
|
726
|
+
const byte: i32 = (n1 << 4) | n2;
|
727
|
+
// Skip continuation bytes
|
728
|
+
if ((byte & 0x80) == 0) {
|
729
|
+
outLength += 1;
|
730
|
+
} else if ((byte & 0xE0) == 0xC0) {
|
731
|
+
outLength += 1;
|
732
|
+
} else if ((byte & 0xF0) == 0xE0) {
|
733
|
+
outLength += 1;
|
734
|
+
}
|
735
|
+
} else {
|
736
|
+
outLength += 1;
|
737
|
+
}
|
738
|
+
} else {
|
739
|
+
outLength += 1;
|
740
|
+
}
|
741
|
+
}
|
742
|
+
|
743
|
+
// Second pass: decode
|
744
|
+
let output: string = Porffor.allocate();
|
745
|
+
output.length = outLength;
|
746
|
+
|
747
|
+
i = Porffor.wasm`local.get ${input}`;
|
748
|
+
let j: i32 = Porffor.wasm`local.get ${output}`;
|
749
|
+
|
750
|
+
while (i < endPtr) {
|
751
|
+
const chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
|
752
|
+
|
753
|
+
if (chr == 37 && i + 1 < endPtr) { // %
|
754
|
+
const h1: i32 = Porffor.wasm.i32.load8_u(i, 0, 4);
|
755
|
+
const h2: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
756
|
+
|
757
|
+
let n1: i32 = h1 - 48;
|
758
|
+
if (n1 > 9) {
|
759
|
+
n1 = h1 - 55;
|
760
|
+
if (n1 > 15) n1 = h1 - 87;
|
761
|
+
}
|
762
|
+
|
763
|
+
let n2: i32 = h2 - 48;
|
764
|
+
if (n2 > 9) {
|
765
|
+
n2 = h2 - 55;
|
766
|
+
if (n2 > 15) n2 = h2 - 87;
|
767
|
+
}
|
768
|
+
|
769
|
+
if (n1 >= 0 && n1 <= 15 && n2 >= 0 && n2 <= 15) {
|
770
|
+
i += 2;
|
771
|
+
const byte1: i32 = (n1 << 4) | n2;
|
772
|
+
|
773
|
+
if ((byte1 & 0x80) == 0) {
|
774
|
+
// Single byte
|
775
|
+
Porffor.wasm.i32.store16(j, byte1, 0, 4);
|
776
|
+
j += 2;
|
777
|
+
} else if ((byte1 & 0xE0) == 0xC0 && i + 2 < endPtr && Porffor.wasm.i32.load8_u(i, 0, 4) == 37) {
|
778
|
+
// Two byte UTF-8
|
779
|
+
const h3: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
780
|
+
const h4: i32 = Porffor.wasm.i32.load8_u(i + 2, 0, 4);
|
781
|
+
|
782
|
+
let n3: i32 = h3 - 48;
|
783
|
+
if (n3 > 9) {
|
784
|
+
n3 = h3 - 55;
|
785
|
+
if (n3 > 15) n3 = h3 - 87;
|
786
|
+
}
|
787
|
+
|
788
|
+
let n4: i32 = h4 - 48;
|
789
|
+
if (n4 > 9) {
|
790
|
+
n4 = h4 - 55;
|
791
|
+
if (n4 > 15) n4 = h4 - 87;
|
792
|
+
}
|
793
|
+
|
794
|
+
if (n3 >= 0 && n3 <= 15 && n4 >= 0 && n4 <= 15) {
|
795
|
+
i += 3;
|
796
|
+
const byte2: i32 = (n3 << 4) | n4;
|
797
|
+
const codepoint: i32 = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);
|
798
|
+
Porffor.wasm.i32.store16(j, codepoint, 0, 4);
|
799
|
+
j += 2;
|
800
|
+
} else {
|
801
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
802
|
+
j += 2;
|
803
|
+
i -= 2;
|
804
|
+
}
|
805
|
+
} else if ((byte1 & 0xF0) == 0xE0 && i + 5 < endPtr && Porffor.wasm.i32.load8_u(i, 0, 4) == 37 && Porffor.wasm.i32.load8_u(i + 3, 0, 4) == 37) {
|
806
|
+
// Three byte UTF-8
|
807
|
+
const h3: i32 = Porffor.wasm.i32.load8_u(i + 1, 0, 4);
|
808
|
+
const h4: i32 = Porffor.wasm.i32.load8_u(i + 2, 0, 4);
|
809
|
+
const h5: i32 = Porffor.wasm.i32.load8_u(i + 4, 0, 4);
|
810
|
+
const h6: i32 = Porffor.wasm.i32.load8_u(i + 5, 0, 4);
|
811
|
+
|
812
|
+
let n3: i32 = h3 - 48;
|
813
|
+
if (n3 > 9) {
|
814
|
+
n3 = h3 - 55;
|
815
|
+
if (n3 > 15) n3 = h3 - 87;
|
816
|
+
}
|
817
|
+
|
818
|
+
let n4: i32 = h4 - 48;
|
819
|
+
if (n4 > 9) {
|
820
|
+
n4 = h4 - 55;
|
821
|
+
if (n4 > 15) n4 = h4 - 87;
|
822
|
+
}
|
823
|
+
|
824
|
+
let n5: i32 = h5 - 48;
|
825
|
+
if (n5 > 9) {
|
826
|
+
n5 = h5 - 55;
|
827
|
+
if (n5 > 15) n5 = h5 - 87;
|
828
|
+
}
|
829
|
+
|
830
|
+
let n6: i32 = h6 - 48;
|
831
|
+
if (n6 > 9) {
|
832
|
+
n6 = h6 - 55;
|
833
|
+
if (n6 > 15) n6 = h6 - 87;
|
834
|
+
}
|
835
|
+
|
836
|
+
if (n3 >= 0 && n3 <= 15 && n4 >= 0 && n4 <= 15 && n5 >= 0 && n5 <= 15 && n6 >= 0 && n6 <= 15) {
|
837
|
+
i += 6;
|
838
|
+
const byte2: i32 = (n3 << 4) | n4;
|
839
|
+
const byte3: i32 = (n5 << 4) | n6;
|
840
|
+
const codepoint: i32 = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
|
841
|
+
Porffor.wasm.i32.store16(j, codepoint, 0, 4);
|
842
|
+
j += 2;
|
843
|
+
} else {
|
844
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
845
|
+
j += 2;
|
846
|
+
i -= 2;
|
847
|
+
}
|
848
|
+
} else {
|
849
|
+
Porffor.wasm.i32.store16(j, byte1, 0, 4);
|
850
|
+
j += 2;
|
851
|
+
}
|
852
|
+
} else {
|
853
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
854
|
+
j += 2;
|
855
|
+
i -= 2;
|
856
|
+
}
|
857
|
+
} else {
|
858
|
+
Porffor.wasm.i32.store16(j, chr, 0, 4);
|
859
|
+
j += 2;
|
860
|
+
}
|
861
|
+
}
|
862
|
+
|
863
|
+
return output;
|
864
|
+
};
|
865
|
+
|
866
|
+
export const decodeURIComponent = (input: any): string => {
|
867
|
+
// For now, decodeURIComponent is the same as decodeURI
|
868
|
+
// They differ only in error handling which we don't implement yet
|
869
|
+
return decodeURI(input);
|
870
|
+
};
|