porffor 0.61.1 → 0.61.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/compiler/builtins/_internal_object.ts +1 -1
  2. package/compiler/builtins/annexb_string.js +5 -4
  3. package/compiler/builtins/array.ts +16 -16
  4. package/compiler/builtins/arraybuffer.ts +4 -4
  5. package/compiler/builtins/base64.ts +2 -2
  6. package/compiler/builtins/bigint.ts +5 -5
  7. package/compiler/builtins/crypto.ts +1 -1
  8. package/compiler/builtins/dataview.ts +1 -1
  9. package/compiler/builtins/date.ts +9 -9
  10. package/compiler/builtins/error.js +1 -1
  11. package/compiler/builtins/function.ts +1 -1
  12. package/compiler/builtins/json.ts +5 -5
  13. package/compiler/builtins/map.ts +5 -5
  14. package/compiler/builtins/number.ts +3 -3
  15. package/compiler/builtins/object.ts +8 -8
  16. package/compiler/builtins/porffor.d.ts +2 -2
  17. package/compiler/builtins/promise.ts +9 -9
  18. package/compiler/builtins/reflect.ts +1 -1
  19. package/compiler/builtins/regexp.ts +319 -388
  20. package/compiler/builtins/set.ts +2 -2
  21. package/compiler/builtins/string.ts +42 -42
  22. package/compiler/builtins/string_f64.ts +2 -2
  23. package/compiler/builtins/symbol.ts +2 -2
  24. package/compiler/builtins/typedarray.js +5 -5
  25. package/compiler/builtins/uint8array_base64.ts +2 -2
  26. package/compiler/builtins/uri.ts +145 -145
  27. package/compiler/builtins/weakmap.ts +3 -3
  28. package/compiler/builtins/weakref.ts +1 -1
  29. package/compiler/builtins/weakset.ts +1 -1
  30. package/compiler/builtins.js +43 -75
  31. package/compiler/builtins_precompiled.js +682 -676
  32. package/compiler/codegen.js +16 -11
  33. package/compiler/wrap.js +13 -0
  34. package/jsr.json +1 -1
  35. package/package.json +1 -1
  36. package/runtime/index.js +1 -1
@@ -68,8 +68,15 @@ export const __Porffor_array_fastPopI32 = (arr: any[]): i32 => {
68
68
  return ret;
69
69
  };
70
70
 
71
+ export const __Porffor_regex_hexDigitToValue = (char: i32): i32 => {
72
+ if (char >= 48 && char <= 57) return char - 48; // '0'-'9'
73
+ if (char >= 97 && char <= 102) return char - 87; // 'a'-'f'
74
+ if (char >= 65 && char <= 70) return char - 55; // 'A'-'F'
75
+ throw new SyntaxError('Regex parse: invalid hex digit');
76
+ };
77
+
71
78
  export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytestring): RegExp => {
72
- const ptr: i32 = Porffor.allocate();
79
+ const ptr: i32 = Porffor.malloc();
73
80
  Porffor.wasm.i32.store(ptr, patternStr, 0, 0);
74
81
 
75
82
  // parse flags
@@ -131,9 +138,9 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
131
138
 
132
139
  let groupDepth: i32 = 0;
133
140
  // todo: free all at the end (or statically allocate but = [] causes memory corruption)
134
- const groupStack: i32[] = Porffor.allocateBytes(6144);
135
- const altDepth: i32[] = Porffor.allocateBytes(6144); // number of |s so far at each depth
136
- const altStack: i32[] = Porffor.allocateBytes(6144);
141
+ const groupStack: i32[] = Porffor.malloc(6144);
142
+ const altDepth: i32[] = Porffor.malloc(6144); // number of |s so far at each depth
143
+ const altStack: i32[] = Porffor.malloc(6144);
137
144
 
138
145
  while (patternPtr < patternEndPtr) {
139
146
  let char: i32 = Porffor.wasm.i32.load8_u(patternPtr, 0, 4);
@@ -180,19 +187,7 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
180
187
  const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
181
188
  const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
182
189
 
183
- let d1: number;
184
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
185
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
186
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
187
- else throw new SyntaxError('Regex parse: invalid \\x escape');
188
-
189
- let d2: number;
190
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
191
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
192
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
193
- else throw new SyntaxError('Regex parse: invalid \\x escape');
194
-
195
- v = d1 * 16 + d2;
190
+ v = __Porffor_regex_hexDigitToValue(c1) * 16 + __Porffor_regex_hexDigitToValue(c2);
196
191
  } else if (char == 117) { // \u
197
192
  if (patternPtr + 3 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\u escape');
198
193
  const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
@@ -200,28 +195,7 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
200
195
  const c3 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
201
196
  const c4 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
202
197
 
203
- let d1: number, d2: number, d3: number, d4: number;
204
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
205
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
206
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
207
- else throw new SyntaxError('Regex parse: invalid \\u escape');
208
-
209
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
210
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
211
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
212
- else throw new SyntaxError('Regex parse: invalid \\u escape');
213
-
214
- if (c3 >= 48 && c3 <= 57) d3 = c3 - 48;
215
- else if (c3 >= 97 && c3 <= 102) d3 = c3 - 87;
216
- else if (c3 >= 65 && c3 <= 70) d3 = c3 - 55;
217
- else throw new SyntaxError('Regex parse: invalid \\u escape');
218
-
219
- if (c4 >= 48 && c4 <= 57) d4 = c4 - 48;
220
- else if (c4 >= 97 && c4 <= 102) d4 = c4 - 87;
221
- else if (c4 >= 65 && c4 <= 70) d4 = c4 - 55;
222
- else throw new SyntaxError('Regex parse: invalid \\u escape');
223
-
224
- v = d1 * 4096 + d2 * 256 + d3 * 16 + d4;
198
+ v = __Porffor_regex_hexDigitToValue(c1) * 4096 + __Porffor_regex_hexDigitToValue(c2) * 256 + __Porffor_regex_hexDigitToValue(c3) * 16 + __Porffor_regex_hexDigitToValue(c4);
225
199
  } else if (char == 99) { // \c
226
200
  if (patternPtr >= patternEndPtr) {
227
201
  // No character after \c, treat as literal \c
@@ -272,48 +246,15 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
272
246
  const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
273
247
  const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
274
248
 
275
- let d1: number;
276
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
277
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
278
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
279
- else throw new SyntaxError('Regex parse: invalid \\x escape');
280
-
281
- let d2: number;
282
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
283
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
284
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
285
- else throw new SyntaxError('Regex parse: invalid \\x escape');
286
-
287
- endChar = d1 * 16 + d2;
288
- } else if (endChar == 117) { // \u
289
- if (patternPtr + 3 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\u escape');
290
- const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
291
- const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
292
- const c3 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
293
- const c4 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
294
-
295
- let d1: number, d2: number, d3: number, d4: number;
296
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
297
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
298
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
299
- else throw new SyntaxError('Regex parse: invalid \\u escape');
300
-
301
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
302
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
303
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
304
- else throw new SyntaxError('Regex parse: invalid \\u escape');
305
-
306
- if (c3 >= 48 && c3 <= 57) d3 = c3 - 48;
307
- else if (c3 >= 97 && c3 <= 102) d3 = c3 - 87;
308
- else if (c3 >= 65 && c3 <= 70) d3 = c3 - 55;
309
- else throw new SyntaxError('Regex parse: invalid \\u escape');
310
-
311
- if (c4 >= 48 && c4 <= 57) d4 = c4 - 48;
312
- else if (c4 >= 97 && c4 <= 102) d4 = c4 - 87;
313
- else if (c4 >= 65 && c4 <= 70) d4 = c4 - 55;
314
- else throw new SyntaxError('Regex parse: invalid \\u escape');
315
-
316
- endChar = d1 * 4096 + d2 * 256 + d3 * 16 + d4;
249
+ endChar = __Porffor_regex_hexDigitToValue(c1) * 16 + __Porffor_regex_hexDigitToValue(c2);
250
+ } else if (endChar == 117) { // \u
251
+ if (patternPtr + 3 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\u escape');
252
+ const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
253
+ const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
254
+ const c3 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
255
+ const c4 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
256
+
257
+ endChar = __Porffor_regex_hexDigitToValue(c1) * 4096 + __Porffor_regex_hexDigitToValue(c2) * 256 + __Porffor_regex_hexDigitToValue(c3) * 16 + __Porffor_regex_hexDigitToValue(c4);
317
258
  } else if (endChar == 99) { // \c
318
259
  if (patternPtr >= patternEndPtr) {
319
260
  // No character after \c, treat as literal \c
@@ -875,21 +816,9 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
875
816
  const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
876
817
  const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
877
818
 
878
- let d1: number;
879
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
880
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
881
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
882
- else throw new SyntaxError('Regex parse: invalid \\x escape');
883
-
884
- let d2: number;
885
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
886
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
887
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
888
- else throw new SyntaxError('Regex parse: invalid \\x escape');
889
-
890
819
  lastAtomStart = bcPtr;
891
820
  Porffor.wasm.i32.store8(bcPtr, 0x01, 0, 0);
892
- Porffor.wasm.i32.store8(bcPtr, d1 * 16 + d2, 0, 1);
821
+ Porffor.wasm.i32.store8(bcPtr, __Porffor_regex_hexDigitToValue(c1) * 16 + __Porffor_regex_hexDigitToValue(c2), 0, 1);
893
822
  bcPtr += 2;
894
823
  lastWasAtom = true;
895
824
  continue;
@@ -901,29 +830,8 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
901
830
  const c3 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
902
831
  const c4 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
903
832
 
904
- let d1: number, d2: number, d3: number, d4: number;
905
- if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
906
- else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
907
- else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
908
- else throw new SyntaxError('Regex parse: invalid \\u escape');
909
-
910
- if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
911
- else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
912
- else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
913
- else throw new SyntaxError('Regex parse: invalid \\u escape');
914
-
915
- if (c3 >= 48 && c3 <= 57) d3 = c3 - 48;
916
- else if (c3 >= 97 && c3 <= 102) d3 = c3 - 87;
917
- else if (c3 >= 65 && c3 <= 70) d3 = c3 - 55;
918
- else throw new SyntaxError('Regex parse: invalid \\u escape');
919
-
920
- if (c4 >= 48 && c4 <= 57) d4 = c4 - 48;
921
- else if (c4 >= 97 && c4 <= 102) d4 = c4 - 87;
922
- else if (c4 >= 65 && c4 <= 70) d4 = c4 - 55;
923
- else throw new SyntaxError('Regex parse: invalid \\u escape');
924
-
925
833
  Porffor.wasm.i32.store8(bcPtr, 0x01, 0, 0);
926
- Porffor.wasm.i32.store8(bcPtr, d1 * 4096 + d2 * 256 + d3 * 16 + d4, 0, 1);
834
+ Porffor.wasm.i32.store8(bcPtr, __Porffor_regex_hexDigitToValue(c1) * 4096 + __Porffor_regex_hexDigitToValue(c2) * 256 + __Porffor_regex_hexDigitToValue(c3) * 16 + __Porffor_regex_hexDigitToValue(c4), 0, 1);
927
835
  bcPtr += 2;
928
836
 
929
837
  lastAtomStart = bcPtr;
@@ -997,7 +905,23 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
997
905
  const backtrackStack: i32[] = [];
998
906
  const captures: i32[] = [];
999
907
 
908
+ // check if first op is char for fast scan
909
+ let fastChar: i32 = -1;
910
+ if (!Porffor.fastOr(ignoreCase, sticky)) {
911
+ const firstOp = Porffor.wasm.i32.load8_u(bcBase, 0, 0);
912
+ if (firstOp == 0x01) {
913
+ fastChar = Porffor.wasm.i32.load8_u(bcBase, 0, 1);
914
+ }
915
+ }
916
+
1000
917
  for (let i: i32 = lastIndex; i <= inputLen; i++) {
918
+ if (fastChar != -1) {
919
+ while (i < inputLen && Porffor.wasm.i32.load8_u(input + i, 0, 4) != fastChar) {
920
+ i++;
921
+ }
922
+ if (i > inputLen) break;
923
+ }
924
+
1001
925
  backtrackStack.length = 0;
1002
926
  captures.length = 0;
1003
927
 
@@ -1007,314 +931,321 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
1007
931
  let matched: boolean = false;
1008
932
  let finalSp: i32 = -1;
1009
933
 
1010
- while (true) {
934
+ interpreter: while (true) {
1011
935
  const op: i32 = Porffor.wasm.i32.load8_u(pc, 0, 0);
936
+ let backtrack: boolean = false;
1012
937
 
1013
- if (op == 0x10) { // accept
1014
- // Check if this is a lookahead accept
1015
- if (backtrackStack.length >= 4) {
1016
- const marker = backtrackStack[backtrackStack.length - 1];
1017
- if (marker == -2000 || marker == -3000) { // lookahead markers
1018
- // This is a lookahead accept
1019
- const isNegative = marker == -2000;
1020
-
1021
- const savedMarker = Porffor.array.fastPopI32(backtrackStack);
1022
- const savedCapturesLen = Porffor.array.fastPopI32(backtrackStack);
1023
- const savedSp = Porffor.array.fastPopI32(backtrackStack);
1024
- const lookaheadEndPc = Porffor.array.fastPopI32(backtrackStack);
1025
-
1026
- // Restore string position (lookaheads don't consume)
1027
- sp = savedSp;
1028
- captures.length = savedCapturesLen;
1029
-
1030
- if (isNegative) {
1031
- // Negative lookahead: pattern matched, so fail completely
1032
- matched = false;
938
+ switch (op) {
939
+ case 0x10: { // accept
940
+ // Check if this is a lookahead accept
941
+ if (backtrackStack.length >= 4) {
942
+ const marker = backtrackStack[backtrackStack.length - 1];
943
+ if (marker == -2000 || marker == -3000) { // lookahead markers
944
+ // This is a lookahead accept
945
+ const isNegative = marker == -2000;
946
+
947
+ const savedMarker = Porffor.array.fastPopI32(backtrackStack);
948
+ const savedCapturesLen = Porffor.array.fastPopI32(backtrackStack);
949
+ const savedSp = Porffor.array.fastPopI32(backtrackStack);
950
+ const lookaheadEndPc = Porffor.array.fastPopI32(backtrackStack);
951
+
952
+ // Restore string position (lookaheads don't consume)
953
+ sp = savedSp;
954
+ captures.length = savedCapturesLen;
955
+
956
+ if (isNegative) {
957
+ // Negative lookahead: pattern matched, so fail completely
958
+ matched = false;
959
+ break interpreter;
960
+ } else {
961
+ // Positive lookahead: pattern matched, so continue after lookahead
962
+ pc = lookaheadEndPc;
963
+ }
1033
964
  break;
1034
- } else {
1035
- // Positive lookahead: pattern matched, so continue after lookahead
1036
- pc = lookaheadEndPc;
1037
- continue;
1038
965
  }
1039
- } else {
1040
- // Normal accept
1041
- matched = true;
1042
- finalSp = sp;
1043
- break;
1044
966
  }
1045
- } else {
967
+
1046
968
  // Normal accept
1047
969
  matched = true;
1048
970
  finalSp = sp;
1049
- break;
971
+ break interpreter;
1050
972
  }
1051
- }
1052
-
1053
- let backtrack: boolean = false;
1054
973
 
1055
- if (op == 0x01) { // single
1056
- if (sp >= inputLen) {
1057
- backtrack = true;
1058
- } else {
1059
- let c1: i32 = Porffor.wasm.i32.load8_u(pc, 0, 1);
1060
- let c2: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1061
- if (ignoreCase) {
1062
- if (c1 >= 97 && c1 <= 122) c1 -= 32;
1063
- if (c2 >= 97 && c2 <= 122) c2 -= 32;
1064
- }
1065
- if (c1 == c2) {
1066
- pc += 2;
1067
- sp += 1;
1068
- } else {
974
+ case 0x01: { // single
975
+ if (sp >= inputLen) {
1069
976
  backtrack = true;
977
+ } else {
978
+ let c1: i32 = Porffor.wasm.i32.load8_u(pc, 0, 1);
979
+ let c2: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
980
+ if (ignoreCase) {
981
+ if (c1 >= 97 && c1 <= 122) c1 -= 32;
982
+ if (c2 >= 97 && c2 <= 122) c2 -= 32;
983
+ }
984
+ if (c1 == c2) {
985
+ pc += 2;
986
+ sp += 1;
987
+ } else {
988
+ backtrack = true;
989
+ }
1070
990
  }
991
+ break;
1071
992
  }
1072
- } else if (op == 0x02 || op == 0x03) { // class or negated class
1073
- if (sp >= inputLen) {
1074
- backtrack = true;
1075
- } else {
1076
- let char: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1077
- let classPc: i32 = pc + 1;
1078
- let charInClass: boolean = false;
1079
- while (true) {
1080
- const marker: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 0);
1081
- if (marker == 0xFF) break; // end of class
1082
-
1083
- if (marker == 0x00) { // range
1084
- let from: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1085
- let to: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 2);
1086
- let cCheck: i32 = char;
1087
- if (ignoreCase) {
1088
- if (from >= 97 && from <= 122) from -= 32;
1089
- if (to >= 97 && to <= 122) to -= 32;
1090
- if (cCheck >= 97 && cCheck <= 122) cCheck -= 32;
1091
- }
1092
- if (cCheck >= from && cCheck <= to) {
1093
- charInClass = true;
1094
- break;
1095
- }
1096
- classPc += 3;
1097
- } else if (marker == 0x01) { // char
1098
- let c1: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1099
- let c2: i32 = char;
1100
- if (ignoreCase) {
1101
- if (c1 >= 97 && c1 <= 122) c1 -= 32;
1102
- if (c2 >= 97 && c2 <= 122) c2 -= 32;
1103
- }
1104
- if (c1 == c2) {
1105
- charInClass = true;
1106
- break;
993
+
994
+ case 0x02: // class
995
+ case 0x03: { // negated class
996
+ if (sp >= inputLen) {
997
+ backtrack = true;
998
+ } else {
999
+ let char: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1000
+ let classPc: i32 = pc + 1;
1001
+ let charInClass: boolean = false;
1002
+ while (true) {
1003
+ const marker: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 0);
1004
+ if (marker == 0xFF) break; // end of class
1005
+
1006
+ if (marker == 0x00) { // range
1007
+ let from: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1008
+ let to: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 2);
1009
+ let cCheck: i32 = char;
1010
+ if (ignoreCase) {
1011
+ if (from >= 97 && from <= 122) from -= 32;
1012
+ if (to >= 97 && to <= 122) to -= 32;
1013
+ if (cCheck >= 97 && cCheck <= 122) cCheck -= 32;
1014
+ }
1015
+ if (cCheck >= from && cCheck <= to) {
1016
+ charInClass = true;
1017
+ break;
1018
+ }
1019
+ classPc += 3;
1020
+ } else if (marker == 0x01) { // char
1021
+ let c1: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1022
+ let c2: i32 = char;
1023
+ if (ignoreCase) {
1024
+ if (c1 >= 97 && c1 <= 122) c1 -= 32;
1025
+ if (c2 >= 97 && c2 <= 122) c2 -= 32;
1026
+ }
1027
+ if (c1 == c2) {
1028
+ charInClass = true;
1029
+ break;
1030
+ }
1031
+ classPc += 2;
1032
+ } else if (marker == 0x02) { // predefined
1033
+ const classId: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1034
+ let isMatch: boolean = false;
1035
+ if (classId == 1) isMatch = char >= 48 && char <= 57;
1036
+ else if (classId == 2) isMatch = !(char >= 48 && char <= 57);
1037
+ else if (classId == 3) isMatch = Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1038
+ else if (classId == 4) isMatch = !Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1039
+ else if (classId == 5) isMatch = (char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95;
1040
+ else if (classId == 6) isMatch = !((char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95);
1041
+
1042
+ if (isMatch) {
1043
+ charInClass = true;
1044
+ break;
1045
+ }
1046
+ classPc += 2;
1107
1047
  }
1108
- classPc += 2;
1109
- } else if (marker == 0x02) { // predefined
1110
- const classId: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 1);
1111
- let isMatch: boolean = false;
1112
- if (classId == 1) isMatch = char >= 48 && char <= 57;
1113
- else if (classId == 2) isMatch = !(char >= 48 && char <= 57);
1114
- else if (classId == 3) isMatch = Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1115
- else if (classId == 4) isMatch = !Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1116
- else if (classId == 5) isMatch = (char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95;
1117
- else if (classId == 6) isMatch = !((char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95);
1118
-
1119
- if (isMatch) {
1120
- charInClass = true;
1121
- break;
1048
+ }
1049
+
1050
+ if (op == 0x03) charInClass = !charInClass;
1051
+
1052
+ if (charInClass) {
1053
+ while (Porffor.wasm.i32.load8_u(classPc, 0, 0) != 0xFF) {
1054
+ const marker: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 0);
1055
+ if (marker == 0x00) classPc += 3;
1056
+ else if (marker == 0x01) classPc += 2;
1057
+ else if (marker == 0x02) classPc += 2;
1122
1058
  }
1123
- classPc += 2;
1059
+ pc = classPc + 1;
1060
+ sp += 1;
1061
+ } else {
1062
+ backtrack = true;
1124
1063
  }
1125
1064
  }
1065
+ break;
1066
+ }
1126
1067
 
1127
- if (op == 0x03) charInClass = !charInClass;
1128
-
1129
- if (charInClass) {
1130
- while (Porffor.wasm.i32.load8_u(classPc, 0, 0) != 0xFF) {
1131
- const marker: i32 = Porffor.wasm.i32.load8_u(classPc, 0, 0);
1132
- if (marker == 0x00) classPc += 3;
1133
- else if (marker == 0x01) classPc += 2;
1134
- else if (marker == 0x02) classPc += 2;
1068
+ case 0x04: { // predefined class
1069
+ if (sp >= inputLen) {
1070
+ backtrack = true;
1071
+ } else {
1072
+ const classId: i32 = Porffor.wasm.i32.load8_u(pc, 0, 1);
1073
+ const char: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1074
+ let isMatch: boolean = false;
1075
+ if (classId == 1) isMatch = char >= 48 && char <= 57;
1076
+ else if (classId == 2) isMatch = !(char >= 48 && char <= 57);
1077
+ else if (classId == 3) isMatch = Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1078
+ else if (classId == 4) isMatch = !Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1079
+ else if (classId == 5) isMatch = (char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95;
1080
+ else if (classId == 6) isMatch = !((char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95);
1081
+
1082
+ if (isMatch) {
1083
+ pc += 2;
1084
+ sp += 1;
1085
+ } else {
1086
+ backtrack = true;
1135
1087
  }
1136
- pc = classPc + 1;
1137
- sp += 1;
1088
+ }
1089
+ break;
1090
+ }
1091
+
1092
+ case 0x05: // start
1093
+ if (sp == 0 || (multiline && sp > 0 && Porffor.wasm.i32.load8_u(input + sp, 0, 3) == 10)) {
1094
+ pc += 1;
1138
1095
  } else {
1139
1096
  backtrack = true;
1140
1097
  }
1141
- }
1142
- } else if (op == 0x04) { // predefined class
1143
- if (sp >= inputLen) {
1144
- backtrack = true;
1145
- } else {
1146
- const classId: i32 = Porffor.wasm.i32.load8_u(pc, 0, 1);
1147
- const char: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1148
- let isMatch: boolean = false;
1149
- if (classId == 1) isMatch = char >= 48 && char <= 57;
1150
- else if (classId == 2) isMatch = !(char >= 48 && char <= 57);
1151
- else if (classId == 3) isMatch = Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1152
- else if (classId == 4) isMatch = !Porffor.fastOr(char == 32, char == 9, char == 10, char == 13, char == 11, char == 12);
1153
- else if (classId == 5) isMatch = (char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95;
1154
- else if (classId == 6) isMatch = !((char >= 65 && char <= 90) || (char >= 97 && char <= 122) || (char >= 48 && char <= 57) || char == 95);
1155
-
1156
- if (isMatch) {
1157
- pc += 2;
1158
- sp += 1;
1098
+ break;
1099
+
1100
+ case 0x06: // end
1101
+ if (sp == inputLen || (multiline && sp < inputLen && Porffor.wasm.i32.load8_u(input + sp, 0, 4) == 10)) {
1102
+ pc += 1;
1159
1103
  } else {
1160
1104
  backtrack = true;
1161
1105
  }
1162
- }
1163
- } else if (op == 0x05) { // start
1164
- if (sp == 0 || (multiline && sp > 0 && Porffor.wasm.i32.load8_u(input + sp, 0, 3) == 10)) {
1165
- pc += 1;
1166
- } else {
1167
- backtrack = true;
1168
- }
1169
- } else if (op == 0x06) { // end
1170
- if (sp == inputLen || (multiline && sp < inputLen && Porffor.wasm.i32.load8_u(input + sp, 0, 4) == 10)) {
1171
- pc += 1;
1172
- } else {
1173
- backtrack = true;
1174
- }
1175
- } else if (op == 0x07) { // word boundary
1176
- let prevIsWord: boolean = false;
1177
- if (sp > 0) {
1178
- const prevChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 3);
1179
- prevIsWord = Porffor.fastOr(
1180
- prevChar >= 65 && prevChar <= 90, // A-Z
1181
- prevChar >= 97 && prevChar <= 122, // a-z
1182
- prevChar >= 48 && prevChar <= 57, // 0-9
1183
- prevChar == 95 // _
1184
- );
1185
- }
1106
+ break;
1186
1107
 
1187
- let nextIsWord: boolean = false;
1188
- if (sp < inputLen) {
1189
- const nextChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1190
- nextIsWord = Porffor.fastOr(
1191
- nextChar >= 65 && nextChar <= 90, // A-Z
1192
- nextChar >= 97 && nextChar <= 122, // a-z
1193
- nextChar >= 48 && nextChar <= 57, // 0-9
1194
- nextChar == 95 // _
1195
- );
1196
- }
1108
+ case 0x07: // word boundary
1109
+ case 0x08: { // non-word boundary
1110
+ let prevIsWord: boolean = false;
1111
+ if (sp > 0) {
1112
+ const prevChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 3);
1113
+ prevIsWord = Porffor.fastOr(
1114
+ prevChar >= 65 && prevChar <= 90, // A-Z
1115
+ prevChar >= 97 && prevChar <= 122, // a-z
1116
+ prevChar >= 48 && prevChar <= 57, // 0-9
1117
+ prevChar == 95 // _
1118
+ );
1119
+ }
1197
1120
 
1198
- if (prevIsWord != nextIsWord) {
1199
- pc += 1;
1200
- } else {
1201
- backtrack = true;
1202
- }
1203
- } else if (op == 0x08) { // non-word boundary
1204
- let prevIsWord: boolean = false;
1205
- if (sp > 0) {
1206
- const prevChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 3);
1207
- prevIsWord = Porffor.fastOr(
1208
- prevChar >= 65 && prevChar <= 90, // A-Z
1209
- prevChar >= 97 && prevChar <= 122, // a-z
1210
- prevChar >= 48 && prevChar <= 57, // 0-9
1211
- prevChar == 95 // _
1212
- );
1213
- }
1121
+ let nextIsWord: boolean = false;
1122
+ if (sp < inputLen) {
1123
+ const nextChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1124
+ nextIsWord = Porffor.fastOr(
1125
+ nextChar >= 65 && nextChar <= 90, // A-Z
1126
+ nextChar >= 97 && nextChar <= 122, // a-z
1127
+ nextChar >= 48 && nextChar <= 57, // 0-9
1128
+ nextChar == 95 // _
1129
+ );
1130
+ }
1214
1131
 
1215
- let nextIsWord: boolean = false;
1216
- if (sp < inputLen) {
1217
- const nextChar: i32 = Porffor.wasm.i32.load8_u(input + sp, 0, 4);
1218
- nextIsWord = Porffor.fastOr(
1219
- nextChar >= 65 && nextChar <= 90, // A-Z
1220
- nextChar >= 97 && nextChar <= 122, // a-z
1221
- nextChar >= 48 && nextChar <= 57, // 0-9
1222
- nextChar == 95 // _
1223
- );
1132
+ const isWordBoundary = prevIsWord != nextIsWord;
1133
+ if ((op == 0x07 && isWordBoundary) || (op == 0x08 && !isWordBoundary)) {
1134
+ pc += 1;
1135
+ } else {
1136
+ backtrack = true;
1137
+ }
1138
+ break;
1224
1139
  }
1225
1140
 
1226
- if (prevIsWord == nextIsWord) {
1227
- pc += 1;
1228
- } else {
1229
- backtrack = true;
1230
- }
1231
- } else if (op == 0x09) { // dot
1232
- if (sp >= inputLen || (!dotAll && Porffor.wasm.i32.load8_u(input + sp, 0, 4) == 10)) {
1233
- backtrack = true;
1234
- } else {
1235
- pc += 1;
1236
- sp += 1;
1237
- }
1238
- } else if (op == 0x0a) { // back reference
1239
- const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1240
- const arrIndex = (capIndex - 1) * 2;
1241
- if (arrIndex + 1 >= captures.length) { // reference to group that hasn't been seen
1242
- pc += 2;
1243
- } else {
1244
- const capStart = captures[arrIndex];
1245
- const capEnd = captures[arrIndex + 1];
1246
- if (capStart == -1 || capEnd == -1) { // reference to unmatched group
1141
+ case 0x09: // dot
1142
+ if (sp >= inputLen || (!dotAll && Porffor.wasm.i32.load8_u(input + sp, 0, 4) == 10)) {
1143
+ backtrack = true;
1144
+ } else {
1145
+ pc += 1;
1146
+ sp += 1;
1147
+ }
1148
+ break;
1149
+
1150
+ case 0x0a: { // back reference
1151
+ const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1152
+ const arrIndex = (capIndex - 1) * 2;
1153
+ if (arrIndex + 1 >= captures.length) { // reference to group that hasn't been seen
1247
1154
  pc += 2;
1248
1155
  } else {
1249
- const capLen = capEnd - capStart;
1250
- if (sp + capLen > inputLen) {
1251
- backtrack = true;
1156
+ const capStart = captures[arrIndex];
1157
+ const capEnd = captures[arrIndex + 1];
1158
+ if (capStart == -1 || capEnd == -1) { // reference to unmatched group
1159
+ pc += 2;
1252
1160
  } else {
1253
- let matches = true;
1254
- for (let k = 0; k < capLen; k++) {
1255
- let c1 = Porffor.wasm.i32.load8_u(input + capStart + k, 0, 4);
1256
- let c2 = Porffor.wasm.i32.load8_u(input + sp + k, 0, 4);
1257
- if (ignoreCase) {
1258
- if (c1 >= 97 && c1 <= 122) c1 -= 32;
1259
- if (c2 >= 97 && c2 <= 122) c2 -= 32;
1161
+ const capLen = capEnd - capStart;
1162
+ if (sp + capLen > inputLen) {
1163
+ backtrack = true;
1164
+ } else {
1165
+ let matches = true;
1166
+ for (let k = 0; k < capLen; k++) {
1167
+ let c1 = Porffor.wasm.i32.load8_u(input + capStart + k, 0, 4);
1168
+ let c2 = Porffor.wasm.i32.load8_u(input + sp + k, 0, 4);
1169
+ if (ignoreCase) {
1170
+ if (c1 >= 97 && c1 <= 122) c1 -= 32;
1171
+ if (c2 >= 97 && c2 <= 122) c2 -= 32;
1172
+ }
1173
+ if (c1 != c2) {
1174
+ matches = false;
1175
+ break;
1176
+ }
1260
1177
  }
1261
- if (c1 != c2) {
1262
- matches = false;
1263
- break;
1178
+ if (matches) {
1179
+ sp += capLen;
1180
+ pc += 2;
1181
+ } else {
1182
+ backtrack = true;
1264
1183
  }
1265
1184
  }
1266
- if (matches) {
1267
- sp += capLen;
1268
- pc += 2;
1269
- } else {
1270
- backtrack = true;
1271
- }
1272
1185
  }
1273
1186
  }
1187
+ break;
1188
+ }
1189
+
1190
+ case 0x0b:
1191
+ case 0x0c: { // positive or negative lookahead
1192
+ const jumpOffset = Porffor.wasm.i32.load16_s(pc, 0, 1);
1193
+ const lookaheadEndPc = pc + jumpOffset + 3;
1194
+ const savedSp = sp; // Save current string position
1195
+
1196
+ // Use fork to test the lookahead pattern
1197
+ Porffor.array.fastPushI32(backtrackStack, lookaheadEndPc); // Continue point after lookahead
1198
+ Porffor.array.fastPushI32(backtrackStack, savedSp); // Restore original sp
1199
+ Porffor.array.fastPushI32(backtrackStack, captures.length);
1200
+
1201
+ // Mark this as a lookahead with special values
1202
+ if (op == 0x0c) { // negative lookahead
1203
+ Porffor.array.fastPushI32(backtrackStack, -2000); // Special marker for negative
1204
+ } else { // positive lookahead
1205
+ Porffor.array.fastPushI32(backtrackStack, -3000); // Special marker for positive
1206
+ }
1207
+
1208
+ pc = pc + 3; // Jump to lookahead content
1209
+ break;
1210
+ }
1211
+
1212
+ case 0x20: // jump
1213
+ pc += Porffor.wasm.i32.load16_s(pc, 0, 1);
1214
+ break;
1215
+
1216
+ case 0x21: { // fork
1217
+ const branch1Offset = Porffor.wasm.i32.load16_s(pc, 0, 1);
1218
+ const branch2Offset = Porffor.wasm.i32.load16_s(pc, 0, 3);
1219
+
1220
+ Porffor.array.fastPushI32(backtrackStack, pc + branch2Offset);
1221
+ Porffor.array.fastPushI32(backtrackStack, sp);
1222
+ Porffor.array.fastPushI32(backtrackStack, captures.length);
1223
+
1224
+ pc += branch1Offset;
1225
+ break;
1274
1226
  }
1275
- } else if (op == 0x0b || op == 0x0c) { // positive or negative lookahead
1276
- const jumpOffset = Porffor.wasm.i32.load16_s(pc, 0, 1);
1277
- const lookaheadEndPc = pc + jumpOffset + 3;
1278
- const savedSp = sp; // Save current string position
1279
-
1280
- // Use fork to test the lookahead pattern
1281
- Porffor.array.fastPushI32(backtrackStack, lookaheadEndPc); // Continue point after lookahead
1282
- Porffor.array.fastPushI32(backtrackStack, savedSp); // Restore original sp
1283
- Porffor.array.fastPushI32(backtrackStack, captures.length);
1284
-
1285
- // Mark this as a lookahead with special values
1286
- if (op == 0x0c) { // negative lookahead
1287
- Porffor.array.fastPushI32(backtrackStack, -2000); // Special marker for negative
1288
- } else { // positive lookahead
1289
- Porffor.array.fastPushI32(backtrackStack, -3000); // Special marker for positive
1227
+
1228
+ case 0x30: { // start capture
1229
+ const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1230
+ const arrIndex = capIndex + 255; // + 255 offset for temp start, as it could never end properly
1231
+ captures[arrIndex] = sp;
1232
+ pc += 2;
1233
+ break;
1290
1234
  }
1291
1235
 
1292
- pc = pc + 3; // Jump to lookahead content
1293
- } else if (op == 0x20) { // jump
1294
- pc += Porffor.wasm.i32.load16_s(pc, 0, 1);
1295
- } else if (op == 0x21) { // fork
1296
- const branch1Offset = Porffor.wasm.i32.load16_s(pc, 0, 1);
1297
- const branch2Offset = Porffor.wasm.i32.load16_s(pc, 0, 3);
1298
-
1299
- Porffor.array.fastPushI32(backtrackStack, pc + branch2Offset);
1300
- Porffor.array.fastPushI32(backtrackStack, sp);
1301
- Porffor.array.fastPushI32(backtrackStack, captures.length);
1302
-
1303
- pc += branch1Offset;
1304
- } else if (op == 0x30) { // start capture
1305
- const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1306
- const arrIndex = capIndex + 255; // + 255 offset for temp start, as it could never end properly
1307
- captures[arrIndex] = sp;
1308
- pc += 2;
1309
- } else if (op == 0x31) { // end capture
1310
- const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1311
- const arrIndex = (capIndex - 1) * 2 + 1;
1312
- while (captures.length <= arrIndex) Porffor.array.fastPushI32(captures, -1);
1313
- captures[arrIndex - 1] = captures[capIndex + 255];
1314
- captures[arrIndex] = sp;
1315
- pc += 2;
1316
- } else { // unknown op
1317
- backtrack = true;
1236
+ case 0x31: { // end capture
1237
+ const capIndex = Porffor.wasm.i32.load8_u(pc, 0, 1);
1238
+ const arrIndex = (capIndex - 1) * 2 + 1;
1239
+ while (captures.length <= arrIndex) Porffor.array.fastPushI32(captures, -1);
1240
+ captures[arrIndex - 1] = captures[capIndex + 255];
1241
+ captures[arrIndex] = sp;
1242
+ pc += 2;
1243
+ break;
1244
+ }
1245
+
1246
+ default:
1247
+ backtrack = true;
1248
+ break;
1318
1249
  }
1319
1250
 
1320
1251
  if (backtrack) {
@@ -1361,7 +1292,7 @@ export const __Porffor_regex_interpret = (regexp: RegExp, input: i32, isTest: bo
1361
1292
  Porffor.wasm.i32.store16(regexp, finalSp, 0, 8); // write last index
1362
1293
  }
1363
1294
 
1364
- const result: any[] = Porffor.allocateBytes(4096);
1295
+ const result: any[] = Porffor.malloc(4096);
1365
1296
  Porffor.array.fastPush(result, __ByteString_prototype_substring(input, matchStart, finalSp));
1366
1297
 
1367
1298
  for (let k = 0; k < totalCaptures; k++) {
@@ -1418,7 +1349,7 @@ export const __RegExp_prototype_flags$get = (_this: RegExp) => {
1418
1349
 
1419
1350
  // 3. Let codeUnits be a new empty List.
1420
1351
  const flags: i32 = Porffor.wasm.i32.load16_u(_this, 0, 4);
1421
- const result: bytestring = Porffor.allocateBytes(16);
1352
+ const result: bytestring = Porffor.malloc(16);
1422
1353
 
1423
1354
  // 4. Let hasIndices be ToBoolean(? Get(R, "hasIndices")).
1424
1355
  // 5. If hasIndices is true, append the code unit 0x0064 (LATIN SMALL LETTER D) to codeUnits.
@@ -1529,7 +1460,7 @@ export const __Porffor_regex_match = (regexp: any, input: any) => {
1529
1460
 
1530
1461
  if (__RegExp_prototype_global$get(regexp)) {
1531
1462
  // global should return all matches as just complete string result
1532
- const result: any[] = Porffor.allocateBytes(4096);
1463
+ const result: any[] = Porffor.malloc(4096);
1533
1464
  let match: any;
1534
1465
  while (match = __Porffor_regex_interpret(regexp, input, false)) {
1535
1466
  // read ourselves as we are in i32 space
@@ -1567,7 +1498,7 @@ export const __Porffor_regex_matchAll = (regexp: any, input: any) => {
1567
1498
 
1568
1499
  if (!__RegExp_prototype_global$get(regexp)) throw new TypeError('matchAll used with non-global RegExp');
1569
1500
 
1570
- const result: any[] = Porffor.allocateBytes(4096);
1501
+ const result: any[] = Porffor.malloc(4096);
1571
1502
  let match: any;
1572
1503
  while (match = __Porffor_regex_interpret(regexp, input, false)) {
1573
1504
  Porffor.array.fastPush(result, match);
@@ -1596,7 +1527,7 @@ export const __Porffor_regex_escapeX = (out: bytestring, char: i32) => {
1596
1527
  };
1597
1528
 
1598
1529
  export const __RegExp_escape = (str: any) => {
1599
- const out: bytestring = Porffor.allocate();
1530
+ const out: bytestring = Porffor.malloc();
1600
1531
 
1601
1532
  let i: i32 = 0;
1602
1533
  const first: i32 = str.charCodeAt(0);