porffor 0.2.0-fde989a → 0.14.0-032e4ad08

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.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +262 -0
  2. package/LICENSE +20 -20
  3. package/README.md +135 -94
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +216 -0
  7. package/compiler/2c.js +66 -54
  8. package/compiler/{sections.js → assemble.js} +109 -21
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +19 -0
  11. package/compiler/builtins/array.ts +225 -0
  12. package/compiler/builtins/base64.ts +77 -0
  13. package/compiler/builtins/boolean.ts +20 -0
  14. package/compiler/builtins/crypto.ts +121 -0
  15. package/compiler/builtins/date.ts +2069 -0
  16. package/compiler/builtins/error.js +22 -0
  17. package/compiler/builtins/escape.ts +140 -0
  18. package/compiler/builtins/function.ts +7 -0
  19. package/compiler/builtins/int.ts +147 -0
  20. package/compiler/builtins/math.ts +410 -0
  21. package/compiler/builtins/number.ts +531 -0
  22. package/compiler/builtins/object.ts +6 -0
  23. package/compiler/builtins/porffor.d.ts +60 -0
  24. package/compiler/builtins/set.ts +199 -0
  25. package/compiler/builtins/string.ts +1081 -0
  26. package/compiler/builtins/symbol.ts +62 -0
  27. package/compiler/builtins.js +466 -284
  28. package/compiler/{codeGen.js → codegen.js} +1573 -656
  29. package/compiler/decompile.js +3 -4
  30. package/compiler/embedding.js +22 -22
  31. package/compiler/encoding.js +94 -10
  32. package/compiler/expression.js +1 -1
  33. package/compiler/generated_builtins.js +2110 -0
  34. package/compiler/index.js +29 -44
  35. package/compiler/log.js +6 -3
  36. package/compiler/opt.js +55 -41
  37. package/compiler/parse.js +38 -30
  38. package/compiler/precompile.js +121 -0
  39. package/compiler/prefs.js +31 -0
  40. package/compiler/prototype.js +209 -201
  41. package/compiler/types.js +38 -0
  42. package/compiler/wasmSpec.js +33 -8
  43. package/compiler/wrap.js +154 -89
  44. package/package.json +9 -5
  45. package/porf +2 -0
  46. package/porffor_tmp.c +202 -0
  47. package/rhemyn/compile.js +46 -27
  48. package/rhemyn/parse.js +322 -320
  49. package/rhemyn/test/parse.js +58 -58
  50. package/runner/compare.js +33 -34
  51. package/runner/debug.js +117 -0
  52. package/runner/index.js +80 -12
  53. package/runner/profiler.js +75 -0
  54. package/runner/repl.js +58 -15
  55. package/runner/sizes.js +37 -37
  56. package/runner/version.js +10 -8
  57. package/compiler/builtins/base64.js +0 -92
  58. package/filesize.cmd +0 -2
  59. package/runner/info.js +0 -89
  60. package/runner/profile.js +0 -46
  61. package/runner/results.json +0 -1
  62. package/runner/transform.js +0 -15
  63. package/tmp.c +0 -661
  64. package/util/enum.js +0 -20
@@ -0,0 +1,1081 @@
1
+ // @porf --valtype=i32
2
+ import type {} from './porffor.d.ts';
3
+
4
+ export const __String_fromCharCode = (code: i32) => {
5
+ // todo: support >1 arg
6
+ if (code < 256) {
7
+ let out: bytestring = '.';
8
+ Porffor.wasm.i32.store8(out, code, 0, 4);
9
+ return out;
10
+ }
11
+
12
+ let out: string = Porffor.s`.`;
13
+ Porffor.wasm.i32.store16(out, code, 0, 4);
14
+ return out;
15
+ };
16
+
17
+ export const __String_prototype_toUpperCase = (_this: string) => {
18
+ // todo: unicode not just ascii
19
+ const len: i32 = _this.length;
20
+
21
+ let out: string = Porffor.s``;
22
+ Porffor.wasm.i32.store(out, len, 0, 0);
23
+
24
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
25
+ j: i32 = Porffor.wasm`local.get ${out}`;
26
+
27
+ const endPtr: i32 = i + len * 2;
28
+ while (i < endPtr) {
29
+ let chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
30
+ i += 2;
31
+
32
+ if (chr >= 97) if (chr <= 122) chr -= 32;
33
+
34
+ Porffor.wasm.i32.store16(j, chr, 0, 4);
35
+ j += 2;
36
+ }
37
+
38
+ return out;
39
+ };
40
+
41
+ export const __ByteString_prototype_toUpperCase = (_this: bytestring) => {
42
+ const len: i32 = _this.length;
43
+
44
+ let out: bytestring = '';
45
+ Porffor.wasm.i32.store(out, len, 0, 0);
46
+
47
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
48
+ j: i32 = Porffor.wasm`local.get ${out}`;
49
+
50
+ const endPtr: i32 = i + len;
51
+ while (i < endPtr) {
52
+ let chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
53
+
54
+ if (chr >= 97) if (chr <= 122) chr -= 32;
55
+
56
+ Porffor.wasm.i32.store8(j++, chr, 0, 4);
57
+ }
58
+
59
+ return out;
60
+ };
61
+
62
+
63
+ export const __String_prototype_toLowerCase = (_this: string) => {
64
+ // todo: unicode not just ascii
65
+ const len: i32 = _this.length;
66
+
67
+ let out: string = Porffor.s``;
68
+ Porffor.wasm.i32.store(out, len, 0, 0);
69
+
70
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
71
+ j: i32 = Porffor.wasm`local.get ${out}`;
72
+
73
+ const endPtr: i32 = i + len * 2;
74
+ while (i < endPtr) {
75
+ let chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
76
+ i += 2;
77
+
78
+ if (chr >= 65) if (chr <= 90) chr += 32;
79
+
80
+ Porffor.wasm.i32.store16(j, chr, 0, 4);
81
+ j += 2;
82
+ }
83
+
84
+ return out;
85
+ };
86
+
87
+ export const __ByteString_prototype_toLowerCase = (_this: bytestring) => {
88
+ const len: i32 = _this.length;
89
+
90
+ let out: bytestring = '';
91
+ Porffor.wasm.i32.store(out, len, 0, 0);
92
+
93
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
94
+ j: i32 = Porffor.wasm`local.get ${out}`;
95
+
96
+ const endPtr: i32 = i + len;
97
+ while (i < endPtr) {
98
+ let chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
99
+
100
+ if (chr >= 65) if (chr <= 90) chr += 32;
101
+
102
+ Porffor.wasm.i32.store8(j++, chr, 0, 4);
103
+ }
104
+
105
+ return out;
106
+ };
107
+
108
+
109
+ export const __String_prototype_startsWith = (_this: string, searchString: string, position: number) => {
110
+ // todo: handle bytestring searchString
111
+
112
+ // todo/perf: investigate whether for counter vs while ++s are faster
113
+ // todo: handle when searchString is bytestring
114
+
115
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
116
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
117
+
118
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
119
+ const len: i32 = _this.length;
120
+ if (position > 0) {
121
+ if (position > len) position = len;
122
+ else position |= 0;
123
+ } else position = 0;
124
+
125
+ thisPtr += position * 2;
126
+
127
+ const searchLen: i32 = searchString.length * 2;
128
+ for (let i: i32 = 0; i < searchLen; i += 2) {
129
+ let chr: i32 = Porffor.wasm.i32.load16_u(thisPtr + i, 0, 4);
130
+ let expected: i32 = Porffor.wasm.i32.load16_u(searchPtr + i, 0, 4);
131
+
132
+ if (chr != expected) return false;
133
+ }
134
+
135
+ return true;
136
+ };
137
+
138
+ export const __ByteString_prototype_startsWith = (_this: bytestring, searchString: bytestring, position: number) => {
139
+ // if searching non-bytestring, bytestring will not start with it
140
+ // todo: change this to just check if = string and ToString others
141
+ if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return false;
142
+
143
+ // todo/perf: investigate whether for counter vs while ++s are faster
144
+
145
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
146
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
147
+
148
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
149
+ const len: i32 = _this.length;
150
+ if (position > 0) {
151
+ if (position > len) position = len;
152
+ else position |= 0;
153
+ } else position = 0;
154
+
155
+ thisPtr += position;
156
+
157
+ const searchLen: i32 = searchString.length;
158
+ for (let i: i32 = 0; i < searchLen; i++) {
159
+ let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr + i, 0, 4);
160
+ let expected: i32 = Porffor.wasm.i32.load8_u(searchPtr + i, 0, 4);
161
+
162
+ if (chr != expected) return false;
163
+ }
164
+
165
+ return true;
166
+ };
167
+
168
+
169
+ export const __String_prototype_endsWith = (_this: string, searchString: string, endPosition: number) => {
170
+ // todo: handle bytestring searchString
171
+
172
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
173
+ j: i32 = Porffor.wasm`local.get ${searchString}`;
174
+
175
+ const searchLen: i32 = searchString.length;
176
+
177
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
178
+ const len: i32 = _this.length;
179
+
180
+ // endPosition ??= len;
181
+ if (Porffor.wasm`local.get ${endPosition+1}` == Porffor.TYPES.undefined) endPosition = len;
182
+
183
+ if (endPosition > 0) {
184
+ if (endPosition > len) endPosition = len;
185
+ else endPosition |= 0;
186
+ } else endPosition = 0;
187
+
188
+ endPosition -= searchLen;
189
+
190
+ if (endPosition < 0) return false;
191
+
192
+ i += endPosition * 2;
193
+
194
+ const endPtr: i32 = j + searchLen * 2;
195
+ while (j < endPtr) {
196
+ let chr: i32 = Porffor.wasm.i32.load16_u(i, 0, 4);
197
+ let expected: i32 = Porffor.wasm.i32.load16_u(j, 0, 4);
198
+
199
+ i += 2;
200
+ j += 2;
201
+
202
+ if (chr != expected) return false;
203
+ }
204
+
205
+ return true;
206
+ };
207
+
208
+ export const __ByteString_prototype_endsWith = (_this: bytestring, searchString: bytestring, endPosition: number) => {
209
+ // if searching non-bytestring, bytestring will not start with it
210
+ // todo: change this to just check if = string and ToString others
211
+ if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return false;
212
+
213
+ let i: i32 = Porffor.wasm`local.get ${_this}`,
214
+ j: i32 = Porffor.wasm`local.get ${searchString}`;
215
+
216
+ const searchLen: i32 = searchString.length;
217
+
218
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
219
+ const len: i32 = _this.length;
220
+
221
+ // endPosition ??= len;
222
+ if (Porffor.wasm`local.get ${endPosition+1}` == Porffor.TYPES.undefined) endPosition = len;
223
+
224
+ if (endPosition > 0) {
225
+ if (endPosition > len) endPosition = len;
226
+ else endPosition |= 0;
227
+ } else endPosition = 0;
228
+
229
+ endPosition -= searchLen;
230
+
231
+ if (endPosition < 0) return false;
232
+
233
+ i += endPosition;
234
+
235
+ const endPtr: i32 = j + searchLen;
236
+ while (j < endPtr) {
237
+ let chr: i32 = Porffor.wasm.i32.load8_u(i++, 0, 4);
238
+ let expected: i32 = Porffor.wasm.i32.load8_u(j++, 0, 4);
239
+
240
+ if (chr != expected) return false;
241
+ }
242
+
243
+ return true;
244
+ };
245
+
246
+
247
+ export const __String_prototype_indexOf = (_this: string, searchString: string, position: number) => {
248
+ // todo: handle bytestring searchString
249
+
250
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
251
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
252
+
253
+ const searchLenX2: i32 = searchString.length * 2;
254
+
255
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
256
+ const len: i32 = _this.length;
257
+ if (position > 0) {
258
+ if (position > len) position = len;
259
+ else position |= 0;
260
+ } else position = 0;
261
+
262
+ const thisPtrEnd: i32 = thisPtr + (len * 2) - searchLenX2;
263
+
264
+ thisPtr += position * 2;
265
+
266
+ while (thisPtr <= thisPtrEnd) {
267
+ let match: boolean = true;
268
+ for (let i: i32 = 0; i < searchLenX2; i += 2) {
269
+ let chr: i32 = Porffor.wasm.i32.load16_u(thisPtr + i, 0, 4);
270
+ let expected: i32 = Porffor.wasm.i32.load16_u(searchPtr + i, 0, 4);
271
+
272
+ if (chr != expected) {
273
+ match = false;
274
+ break;
275
+ }
276
+ }
277
+
278
+ if (match) return (thisPtr - Porffor.wasm`local.get ${_this}`) / 2;
279
+
280
+ thisPtr += 2;
281
+ }
282
+
283
+ return -1;
284
+ };
285
+
286
+ export const __ByteString_prototype_indexOf = (_this: bytestring, searchString: bytestring, position: number) => {
287
+ // if searching non-bytestring, bytestring will not start with it
288
+ // todo: change this to just check if = string and ToString others
289
+ if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
290
+
291
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
292
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
293
+
294
+ const searchLen: i32 = searchString.length;
295
+
296
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
297
+ const len: i32 = _this.length;
298
+ if (position > 0) {
299
+ if (position > len) position = len;
300
+ else position |= 0;
301
+ } else position = 0;
302
+
303
+ const thisPtrEnd: i32 = thisPtr + len - searchLen;
304
+
305
+ thisPtr += position;
306
+
307
+ while (thisPtr <= thisPtrEnd) {
308
+ let match: boolean = true;
309
+ for (let i: i32 = 0; i < searchLen; i++) {
310
+ let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr + i, 0, 4);
311
+ let expected: i32 = Porffor.wasm.i32.load8_u(searchPtr + i, 0, 4);
312
+
313
+ if (chr != expected) {
314
+ match = false;
315
+ break;
316
+ }
317
+ }
318
+
319
+ if (match) return thisPtr - Porffor.wasm`local.get ${_this}`;
320
+
321
+ thisPtr++;
322
+ }
323
+
324
+ return -1;
325
+ };
326
+
327
+
328
+ export const __String_prototype_lastIndexOf = (_this: string, searchString: string, position: number) => {
329
+ // todo: handle bytestring searchString
330
+
331
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
332
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
333
+
334
+ const searchLen: i32 = searchString.length;
335
+ const searchLenX2: i32 = searchLen * 2;
336
+
337
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
338
+ const len: i32 = _this.length;
339
+
340
+ // endPosition ??= len;
341
+ if (Porffor.wasm`local.get ${position+1}` == Porffor.TYPES.undefined) position = len - searchLen;
342
+
343
+ if (position > 0) {
344
+ const max: i32 = len - searchLen;
345
+ if (position > max) position = max;
346
+ else position |= 0;
347
+ } else position = 0;
348
+
349
+ const thisPtrStart: i32 = thisPtr;
350
+
351
+ thisPtr += position * 2;
352
+
353
+ while (thisPtr >= thisPtrStart) {
354
+ let match: boolean = true;
355
+ for (let i: i32 = 0; i < searchLenX2; i += 2) {
356
+ let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr + i, 0, 4);
357
+ let expected: i32 = Porffor.wasm.i32.load8_u(searchPtr + i, 0, 4);
358
+
359
+ if (chr != expected) {
360
+ match = false;
361
+ break;
362
+ }
363
+ }
364
+
365
+ if (match) return (thisPtr - Porffor.wasm`local.get ${_this}`) / 2;
366
+
367
+ thisPtr -= 2;
368
+ }
369
+
370
+ return -1;
371
+ };
372
+
373
+ export const __ByteString_prototype_lastIndexOf = (_this: bytestring, searchString: bytestring, position: number) => {
374
+ // if searching non-bytestring, bytestring will not start with it
375
+ // todo: change this to just check if = string and ToString others
376
+ if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
377
+
378
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
379
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
380
+
381
+ const searchLen: i32 = searchString.length;
382
+
383
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
384
+ const len: i32 = _this.length;
385
+
386
+ // endPosition ??= len;
387
+ if (Porffor.wasm`local.get ${position+1}` == Porffor.TYPES.undefined) position = len - searchLen;
388
+
389
+ if (position > 0) {
390
+ const max: i32 = len - searchLen;
391
+ if (position > max) position = max;
392
+ else position |= 0;
393
+ } else position = 0;
394
+
395
+ const thisPtrStart: i32 = thisPtr;
396
+
397
+ thisPtr += position;
398
+
399
+ while (thisPtr >= thisPtrStart) {
400
+ let match: boolean = true;
401
+ for (let i: i32 = 0; i < searchLen; i++) {
402
+ let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr + i, 0, 4);
403
+ let expected: i32 = Porffor.wasm.i32.load8_u(searchPtr + i, 0, 4);
404
+
405
+ if (chr != expected) {
406
+ match = false;
407
+ break;
408
+ }
409
+ }
410
+
411
+ if (match) return thisPtr - Porffor.wasm`local.get ${_this}`;
412
+
413
+ thisPtr--;
414
+ }
415
+
416
+ return -1;
417
+ };
418
+
419
+
420
+ export const __String_prototype_includes = (_this: string, searchString: string, position: number) => {
421
+ // todo: handle bytestring searchString
422
+
423
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
424
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
425
+
426
+ const searchLenX2: i32 = searchString.length * 2;
427
+
428
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
429
+ const len: i32 = _this.length;
430
+ if (position > 0) {
431
+ if (position > len) position = len;
432
+ else position |= 0;
433
+ } else position = 0;
434
+
435
+ const thisPtrEnd: i32 = thisPtr + (len * 2) - searchLenX2;
436
+
437
+ thisPtr += position * 2;
438
+
439
+ while (thisPtr <= thisPtrEnd) {
440
+ let match: boolean = true;
441
+ for (let i: i32 = 0; i < searchLenX2; i += 2) {
442
+ let chr: i32 = Porffor.wasm.i32.load16_u(thisPtr + i, 0, 4);
443
+ let expected: i32 = Porffor.wasm.i32.load16_u(searchPtr + i, 0, 4);
444
+
445
+ if (chr != expected) {
446
+ match = false;
447
+ break;
448
+ }
449
+ }
450
+
451
+ if (match) return true;
452
+
453
+ thisPtr += 2;
454
+ }
455
+
456
+ return false;
457
+ };
458
+
459
+ export const __ByteString_prototype_includes = (_this: bytestring, searchString: bytestring, position: number) => {
460
+ // if searching non-bytestring, bytestring will not start with it
461
+ // todo: change this to just check if = string and ToString others
462
+ if (Porffor.wasm`local.get ${searchString+1}` != Porffor.TYPES.bytestring) return -1;
463
+
464
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
465
+ const searchPtr: i32 = Porffor.wasm`local.get ${searchString}`;
466
+
467
+ const searchLen: i32 = searchString.length;
468
+
469
+ // todo/perf: make position oob handling optional (via pref or fast variant?)
470
+ const len: i32 = _this.length;
471
+ if (position > 0) {
472
+ if (position > len) position = len;
473
+ else position |= 0;
474
+ } else position = 0;
475
+
476
+ const thisPtrEnd: i32 = thisPtr + len - searchLen;
477
+
478
+ thisPtr += position;
479
+
480
+ while (thisPtr <= thisPtrEnd) {
481
+ let match: boolean = true;
482
+ for (let i: i32 = 0; i < searchLen; i++) {
483
+ let chr: i32 = Porffor.wasm.i32.load8_u(thisPtr + i, 0, 4);
484
+ let expected: i32 = Porffor.wasm.i32.load8_u(searchPtr + i, 0, 4);
485
+
486
+ if (chr != expected) {
487
+ match = false;
488
+ break;
489
+ }
490
+ }
491
+
492
+ if (match) return true;
493
+
494
+ thisPtr++;
495
+ }
496
+
497
+ return false;
498
+ };
499
+
500
+
501
+ export const __String_prototype_padStart = (_this: string, targetLength: number, padString: string) => {
502
+ let out: string = Porffor.s``;
503
+
504
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
505
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
506
+ // const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
507
+
508
+ const len: i32 = _this.length;
509
+
510
+ targetLength |= 0;
511
+
512
+ const todo: i32 = targetLength - len;
513
+ if (todo > 0) {
514
+ if (Porffor.wasm`local.get ${padString+1}` == Porffor.TYPES.undefined) {
515
+ for (let i: i32 = 0; i < todo; i++) {
516
+ Porffor.wasm.i32.store16(outPtr, 32, 0, 4);
517
+ outPtr += 2;
518
+ }
519
+
520
+ out.length = targetLength;
521
+ } else {
522
+ const padStringLen: i32 = padString.length;
523
+ if (padStringLen > 0) {
524
+ for (let i: i32 = 0; i < todo; i++) {
525
+ // Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(padStringPtr + (i % padStringLen) * 2, 0, 4), 0, 4);
526
+ Porffor.wasm.i32.store16(outPtr, padString.charCodeAt(i % padStringLen), 0, 4);
527
+ outPtr += 2;
528
+ }
529
+ out.length = targetLength;
530
+ } else out.length = len;
531
+ }
532
+ } else out.length = len;
533
+
534
+ const thisPtrEnd: i32 = thisPtr + len * 2;
535
+
536
+ while (thisPtr < thisPtrEnd) {
537
+ Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(thisPtr, 0, 4), 0, 4);
538
+
539
+ thisPtr += 2;
540
+ outPtr += 2;
541
+ }
542
+
543
+ return out;
544
+ };
545
+
546
+ export const __ByteString_prototype_padStart = (_this: bytestring, targetLength: number, padString: bytestring) => {
547
+ // todo: handle padString being non-bytestring
548
+
549
+ let out: bytestring = Porffor.bs``;
550
+
551
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
552
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
553
+ const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
554
+
555
+ const len: i32 = _this.length;
556
+
557
+ targetLength |= 0;
558
+
559
+ const todo: i32 = targetLength - len;
560
+ if (todo > 0) {
561
+ if (Porffor.wasm`local.get ${padString+1}` == Porffor.TYPES.undefined) {
562
+ for (let i: i32 = 0; i < todo; i++) {
563
+ Porffor.wasm.i32.store8(outPtr++, 32, 0, 4);
564
+ }
565
+
566
+ out.length = targetLength;
567
+ } else {
568
+ const padStringLen: i32 = padString.length;
569
+ if (padStringLen > 0) {
570
+ for (let i: i32 = 0; i < todo; i++) {
571
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(padStringPtr + (i % padStringLen), 0, 4), 0, 4);
572
+ // Porffor.wasm.i32.store8(outPtr++, padString.charCodeAt(i % padStringLen), 0, 4);
573
+ }
574
+
575
+ out.length = targetLength;
576
+ } else out.length = len;
577
+ }
578
+ } else out.length = len;
579
+
580
+ const thisPtrEnd: i32 = thisPtr + len;
581
+
582
+ while (thisPtr < thisPtrEnd) {
583
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(thisPtr++, 0, 4), 0, 4);
584
+ }
585
+
586
+ return out;
587
+ };
588
+
589
+
590
+ export const __String_prototype_padEnd = (_this: string, targetLength: number, padString: string) => {
591
+ let out: string = Porffor.s``;
592
+
593
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
594
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
595
+ // const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
596
+
597
+ const len: i32 = _this.length;
598
+
599
+ const thisPtrEnd: i32 = thisPtr + len * 2;
600
+
601
+ while (thisPtr < thisPtrEnd) {
602
+ Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(thisPtr, 0, 4), 0, 4);
603
+
604
+ thisPtr += 2;
605
+ outPtr += 2;
606
+ }
607
+
608
+ targetLength |= 0;
609
+
610
+ const todo: i32 = targetLength - len;
611
+ if (todo > 0) {
612
+ if (Porffor.wasm`local.get ${padString+1}` == Porffor.TYPES.undefined) {
613
+ for (let i: i32 = 0; i < todo; i++) {
614
+ Porffor.wasm.i32.store16(outPtr, 32, 0, 4);
615
+ outPtr += 2;
616
+ }
617
+
618
+ out.length = targetLength;
619
+ } else {
620
+ const padStringLen: i32 = padString.length;
621
+ if (padStringLen > 0) {
622
+ for (let i: i32 = 0; i < todo; i++) {
623
+ // Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(padStringPtr + (i % padStringLen) * 2, 0, 4), 0, 4);
624
+ Porffor.wasm.i32.store16(outPtr, padString.charCodeAt(i % padStringLen), 0, 4);
625
+ outPtr += 2;
626
+ }
627
+ out.length = targetLength;
628
+ } else out.length = len;
629
+ }
630
+ } else out.length = len;
631
+
632
+ return out;
633
+ };
634
+
635
+ export const __ByteString_prototype_padEnd = (_this: bytestring, targetLength: number, padString: bytestring) => {
636
+ // todo: handle padString being non-bytestring
637
+
638
+ let out: bytestring = Porffor.bs``;
639
+
640
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
641
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
642
+ const padStringPtr: i32 = Porffor.wasm`local.get ${padString}`;
643
+
644
+ const len: i32 = _this.length;
645
+
646
+ const thisPtrEnd: i32 = thisPtr + len;
647
+
648
+ while (thisPtr < thisPtrEnd) {
649
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(thisPtr++, 0, 4), 0, 4);
650
+ }
651
+
652
+ targetLength |= 0;
653
+
654
+ const todo: i32 = targetLength - len;
655
+ if (todo > 0) {
656
+ if (Porffor.wasm`local.get ${padString+1}` == Porffor.TYPES.undefined) {
657
+ for (let i: i32 = 0; i < todo; i++) {
658
+ Porffor.wasm.i32.store8(outPtr++, 32, 0, 4);
659
+ }
660
+
661
+ out.length = targetLength;
662
+ } else {
663
+ const padStringLen: i32 = padString.length;
664
+ if (padStringLen > 0) {
665
+ for (let i: i32 = 0; i < todo; i++) {
666
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(padStringPtr + (i % padStringLen), 0, 4), 0, 4);
667
+ // Porffor.wasm.i32.store8(outPtr++, padString.charCodeAt(i % padStringLen), 0, 4);
668
+ }
669
+
670
+ out.length = targetLength;
671
+ } else out.length = len;
672
+ }
673
+ } else out.length = len;
674
+
675
+ return out;
676
+ };
677
+
678
+
679
+ export const __String_prototype_substring = (_this: string, start: number, end: number) => {
680
+ const len: i32 = _this.length;
681
+ if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
682
+ else if (start > end) {
683
+ const tmp: i32 = end;
684
+ end = start;
685
+ start = tmp;
686
+ }
687
+
688
+ start |= 0;
689
+ end |= 0;
690
+
691
+ if (start < 0) start = 0;
692
+ if (start > len) start = len;
693
+ if (end < 0) end = 0;
694
+ if (end > len) end = len;
695
+
696
+ let out: string = Porffor.s``;
697
+
698
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
699
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
700
+
701
+ const thisPtrEnd: i32 = thisPtr + end * 2;
702
+
703
+ thisPtr += start * 2;
704
+
705
+ while (thisPtr < thisPtrEnd) {
706
+ Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(thisPtr, 0, 4), 0, 4);
707
+
708
+ thisPtr += 2;
709
+ outPtr += 2;
710
+ }
711
+
712
+ out.length = end - start;
713
+
714
+ return out;
715
+ };
716
+
717
+ export const __ByteString_prototype_substring = (_this: bytestring, start: number, end: number) => {
718
+ const len: i32 = _this.length;
719
+ if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
720
+ else if (start > end) {
721
+ const tmp: i32 = end;
722
+ end = start;
723
+ start = tmp;
724
+ }
725
+
726
+ start |= 0;
727
+ end |= 0;
728
+
729
+ if (start < 0) start = 0;
730
+ if (start > len) start = len;
731
+ if (end < 0) end = 0;
732
+ if (end > len) end = len;
733
+
734
+ let out: bytestring = Porffor.bs``;
735
+
736
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
737
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
738
+
739
+ const thisPtrEnd: i32 = thisPtr + end;
740
+
741
+ thisPtr += start;
742
+
743
+ while (thisPtr < thisPtrEnd) {
744
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(thisPtr++, 0, 4), 0, 4);
745
+ }
746
+
747
+ out.length = end - start;
748
+
749
+ return out;
750
+ };
751
+
752
+
753
+ export const __String_prototype_substr = (_this: string, start: number, length: number) => {
754
+ const len: i32 = _this.length;
755
+
756
+ start |= 0;
757
+
758
+ if (start < 0) {
759
+ start = len + start;
760
+ if (start < 0) start = 0;
761
+ }
762
+
763
+ if (Porffor.wasm`local.get ${length+1}` == Porffor.TYPES.undefined) length = len - start;
764
+
765
+ length |= 0;
766
+
767
+ if (start + length > len) length = len - start;
768
+
769
+ let out: string = Porffor.s``;
770
+
771
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
772
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
773
+
774
+ thisPtr += start * 2;
775
+
776
+ const thisPtrEnd: i32 = thisPtr + length * 2;
777
+
778
+ while (thisPtr < thisPtrEnd) {
779
+ Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(thisPtr, 0, 4), 0, 4);
780
+
781
+ thisPtr += 2;
782
+ outPtr += 2;
783
+ }
784
+
785
+ out.length = length;
786
+
787
+ return out;
788
+ };
789
+
790
+ export const __ByteString_prototype_substr = (_this: string, start: number, length: number) => {
791
+ const len: i32 = _this.length;
792
+
793
+ start |= 0;
794
+
795
+ if (start < 0) {
796
+ start = len + start;
797
+ if (start < 0) start = 0;
798
+ }
799
+
800
+ if (Porffor.wasm`local.get ${length+1}` == Porffor.TYPES.undefined) length = len - start;
801
+
802
+ length |= 0;
803
+
804
+ if (start + length > len) length = len - start;
805
+
806
+ let out: bytestring = Porffor.bs``;
807
+
808
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
809
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
810
+
811
+ thisPtr += start;
812
+
813
+ const thisPtrEnd: i32 = thisPtr + length;
814
+
815
+ while (thisPtr < thisPtrEnd) {
816
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(thisPtr++, 0, 4), 0, 4);
817
+ }
818
+
819
+ out.length = length;
820
+
821
+ return out;
822
+ };
823
+
824
+
825
+ export const __String_prototype_slice = (_this: string, start: number, end: number) => {
826
+ const len: i32 = _this.length;
827
+ if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
828
+
829
+ start |= 0;
830
+ end |= 0;
831
+
832
+ if (start < 0) {
833
+ start = len + start;
834
+ if (start < 0) start = 0;
835
+ }
836
+ if (start > len) start = len;
837
+ if (end < 0) {
838
+ end = len + end;
839
+ if (end < 0) end = 0;
840
+ }
841
+ if (end > len) end = len;
842
+
843
+ let out: string = Porffor.s``;
844
+
845
+ if (start > end) return out;
846
+
847
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
848
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
849
+
850
+ const thisPtrEnd: i32 = thisPtr + end * 2;
851
+
852
+ thisPtr += start * 2;
853
+
854
+ while (thisPtr < thisPtrEnd) {
855
+ Porffor.wasm.i32.store16(outPtr, Porffor.wasm.i32.load16_u(thisPtr, 0, 4), 0, 4);
856
+
857
+ thisPtr += 2;
858
+ outPtr += 2;
859
+ }
860
+
861
+ out.length = end - start;
862
+
863
+ return out;
864
+ };
865
+
866
+ export const __ByteString_prototype_slice = (_this: bytestring, start: number, end: number) => {
867
+ const len: i32 = _this.length;
868
+ if (Porffor.wasm`local.get ${end+1}` == Porffor.TYPES.undefined) end = len;
869
+
870
+ start |= 0;
871
+ end |= 0;
872
+
873
+ if (start < 0) {
874
+ start = len + start;
875
+ if (start < 0) start = 0;
876
+ }
877
+ if (start > len) start = len;
878
+ if (end < 0) {
879
+ end = len + end;
880
+ if (end < 0) end = 0;
881
+ }
882
+ if (end > len) end = len;
883
+
884
+ let out: bytestring = Porffor.bs``;
885
+
886
+ if (start > end) return out;
887
+
888
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
889
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
890
+
891
+ const thisPtrEnd: i32 = thisPtr + end;
892
+
893
+ thisPtr += start;
894
+
895
+ while (thisPtr < thisPtrEnd) {
896
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(thisPtr++, 0, 4), 0, 4);
897
+ }
898
+
899
+ out.length = end - start;
900
+
901
+ return out;
902
+ };
903
+
904
+
905
+ export const __String_prototype_trimStart = (_this: string) => {
906
+ let out: string = Porffor.s``;
907
+
908
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
909
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
910
+
911
+ const len: i32 = _this.length;
912
+
913
+ const thisPtrEnd: i32 = thisPtr + len * 2;
914
+
915
+ let n: i32 = 0, start: boolean = true;
916
+ while (thisPtr < thisPtrEnd) {
917
+ const chr: i32 = Porffor.wasm.i32.load16_u(thisPtr, 0, 4);
918
+ thisPtr += 2;
919
+
920
+ if (start) {
921
+ // todo: not spec compliant, needs more unicode chars
922
+ if (Porffor.fastOr(chr == 0x0009, chr == 0x000b, chr == 0x000c, chr == 0x0020, chr == 0x00a0, chr == 0xfeff, chr == 0x000a, chr == 0x000d, chr == 0x2028, chr == 0x2029)) {
923
+ n++;
924
+ continue;
925
+ }
926
+
927
+ start = false;
928
+ }
929
+
930
+ Porffor.wasm.i32.store16(outPtr, chr, 0, 4);
931
+ outPtr += 2;
932
+ }
933
+
934
+ out.length = len - n;
935
+
936
+ return out;
937
+ };
938
+
939
+ export const __ByteString_prototype_trimStart = (_this: bytestring) => {
940
+ let out: bytestring = Porffor.bs``;
941
+
942
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
943
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
944
+
945
+ const len: i32 = _this.length;
946
+
947
+ const thisPtrEnd: i32 = thisPtr + len;
948
+
949
+ let n: i32 = 0, start: boolean = true;
950
+ while (thisPtr < thisPtrEnd) {
951
+ const chr: i32 = Porffor.wasm.i32.load8_u(thisPtr++, 0, 4);
952
+
953
+ if (start) {
954
+ // todo: not spec compliant, needs more unicode chars
955
+ if (Porffor.fastOr(chr == 0x0009, chr == 0x000b, chr == 0x000c, chr == 0x0020, chr == 0x00a0, chr == 0xfeff, chr == 0x000a, chr == 0x000d, chr == 0x2028, chr == 0x2029)) {
956
+ n++;
957
+ continue;
958
+ }
959
+
960
+ start = false;
961
+ }
962
+
963
+ Porffor.wasm.i32.store8(outPtr++, chr, 0, 4);
964
+ }
965
+
966
+ out.length = len - n;
967
+
968
+ return out;
969
+ };
970
+
971
+
972
+ export const __String_prototype_trimEnd = (_this: string) => {
973
+ let out: string = Porffor.s``;
974
+
975
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
976
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
977
+
978
+ const len: i32 = _this.length;
979
+
980
+ const thisPtrStart: i32 = thisPtr;
981
+
982
+ thisPtr += len * 2;
983
+ outPtr += len * 2;
984
+
985
+ let n: i32 = 0, start: boolean = true;
986
+ while (thisPtr > thisPtrStart) {
987
+ thisPtr -= 2;
988
+ const chr: i32 = Porffor.wasm.i32.load16_u(thisPtr, 0, 4);
989
+
990
+ outPtr -= 2;
991
+
992
+ if (start) {
993
+ // todo: not spec compliant, needs more unicode chars
994
+ if (Porffor.fastOr(chr == 0x0009, chr == 0x000b, chr == 0x000c, chr == 0x0020, chr == 0x00a0, chr == 0xfeff, chr == 0x000a, chr == 0x000d, chr == 0x2028, chr == 0x2029)) {
995
+ n++;
996
+ continue;
997
+ }
998
+
999
+ start = false;
1000
+ }
1001
+
1002
+ Porffor.wasm.i32.store16(outPtr, chr, 0, 4);
1003
+ }
1004
+
1005
+ out.length = len - n;
1006
+
1007
+ return out;
1008
+ };
1009
+
1010
+ export const __ByteString_prototype_trimEnd = (_this: bytestring) => {
1011
+ let out: bytestring = Porffor.bs``;
1012
+
1013
+ let outPtr: i32 = Porffor.wasm`local.get ${out}`;
1014
+ let thisPtr: i32 = Porffor.wasm`local.get ${_this}`;
1015
+
1016
+ const len: i32 = _this.length;
1017
+
1018
+ const thisPtrStart: i32 = thisPtr;
1019
+
1020
+ thisPtr += len;
1021
+ outPtr += len;
1022
+
1023
+ let n: i32 = 0, start: boolean = true;
1024
+ while (thisPtr > thisPtrStart) {
1025
+ const chr: i32 = Porffor.wasm.i32.load8_u(--thisPtr, 0, 4);
1026
+
1027
+ outPtr--;
1028
+
1029
+ if (start) {
1030
+ // todo: not spec compliant, needs more unicode chars
1031
+ if (Porffor.fastOr(chr == 0x0009, chr == 0x000b, chr == 0x000c, chr == 0x0020, chr == 0x00a0, chr == 0xfeff, chr == 0x000a, chr == 0x000d, chr == 0x2028, chr == 0x2029)) {
1032
+ n++;
1033
+ continue;
1034
+ }
1035
+
1036
+ start = false;
1037
+ }
1038
+
1039
+ Porffor.wasm.i32.store8(outPtr, chr, 0, 4);
1040
+ }
1041
+
1042
+ out.length = len - n;
1043
+
1044
+ return out;
1045
+ };
1046
+
1047
+
1048
+ export const __String_prototype_trim = (_this: string) => {
1049
+ // todo/perf: optimize and not just reuse
1050
+ return __String_prototype_trimStart(__String_prototype_trimEnd(_this));
1051
+ };
1052
+
1053
+ export const __ByteString_prototype_trim = (_this: bytestring) => {
1054
+ // todo/perf: optimize and not just reuse
1055
+ return __ByteString_prototype_trimStart(__ByteString_prototype_trimEnd(_this));
1056
+ };
1057
+
1058
+ // 22.1.3.29 String.prototype.toString ()
1059
+ // https://tc39.es/ecma262/#sec-string.prototype.tostring
1060
+ export const __String_prototype_toString = (_this: string) => {
1061
+ // 1. Return ? ThisStringValue(this value).
1062
+ return _this;
1063
+ };
1064
+
1065
+ export const __ByteString_prototype_toString = (_this: bytestring) => {
1066
+ // 1. Return ? ThisStringValue(this value).
1067
+ return _this;
1068
+ };
1069
+
1070
+
1071
+ // 22.1.3.35 String.prototype.valueOf ()
1072
+ // https://tc39.es/ecma262/#sec-string.prototype.valueof
1073
+ export const __String_prototype_valueOf = (_this: string) => {
1074
+ // 1. Return ? ThisStringValue(this value).
1075
+ return _this;
1076
+ };
1077
+
1078
+ export const __ByteString_prototype_valueOf = (_this: bytestring) => {
1079
+ // 1. Return ? ThisStringValue(this value).
1080
+ return _this;
1081
+ };