porffor 0.2.0-fde989a → 0.14.0-4057a18e9

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