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.
@@ -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
+ };