porffor 0.58.14 → 0.58.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENT.md ADDED
@@ -0,0 +1,13 @@
1
+ you are an assistant coder for Porffor - a WIP js/ts -> wasm/native ahead-of-time compiler. the codebase is written in js and ts.
2
+
3
+ IMPORTANT:
4
+ - built-ins apis (Date, String.prototype, etc) are written in ts inside `compiler/builtins`
5
+ - once you update a file inside that directory, you MUST run `./porf precompile` to compile to make your changes effective
6
+
7
+ test your work using the test262 tools available, iterate independently but do not get stuck on one chain of thought or approach. paths for test262 tools should be relative to the 'test262/test' directory (e.g., 'built-ins/RegExp' instead of 'test262/test/built-ins/RegExp').
8
+
9
+ - always use single quotes instead of double quotes (unless needed)
10
+ - after finishing, check if your work/diff could be simplified
11
+ - to just evaluate code in the engine, use the command: `./porf -p "..."`
12
+ - to get an overview of the most failing directories, use the command: `node test262/fails.cjs`
13
+ - when working in `compiler/builtins`, inline code instead of using utility/helper functions
@@ -80,6 +80,29 @@ export const __Array_from = (arg: any, mapFn: any): any[] => {
80
80
  return out;
81
81
  };
82
82
 
83
+ // 23.1.3.1 Array.prototype.at (index)
84
+ // https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.at
85
+ export const __Array_prototype_at = (_this: any[], index: any) => {
86
+ // 1. Let O be ? ToObject(this value).
87
+ // 2. Let len be ? LengthOfArrayLike(O).
88
+ const len: i32 = _this.length;
89
+
90
+ // 3. Let relativeIndex be ? ToIntegerOrInfinity(index).
91
+ index = ecma262.ToIntegerOrInfinity(index);
92
+
93
+ // 4. If relativeIndex ≥ 0, then
94
+ // a. Let k be relativeIndex.
95
+ // 5. Else,
96
+ // a. Let k be len + relativeIndex.
97
+ if (index < 0) index = len + index;
98
+
99
+ // 6. If k < 0 or k ≥ len, return undefined.
100
+ if (Porffor.fastOr(index < 0, index >= len)) return undefined;
101
+
102
+ // 7. Return ? Get(O, ! ToString(𝔽(k))).
103
+ return _this[index];
104
+ };
105
+
83
106
  export const __Array_prototype_push = (_this: any[], ...items: any[]) => {
84
107
  let len: i32 = _this.length;
85
108
  const itemsLen: i32 = items.length;
@@ -164,6 +164,25 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
164
164
  else if (char == 118) v = 11; // \v
165
165
  else if (char == 102) v = 12; // \f
166
166
  else if (char == 48) v = 0; // \0
167
+ else if (char == 120) { // \x
168
+ if (patternPtr + 1 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\x escape');
169
+ const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
170
+ const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
171
+
172
+ let d1: number;
173
+ if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
174
+ else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
175
+ else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
176
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
177
+
178
+ let d2: number;
179
+ if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
180
+ else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
181
+ else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
182
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
183
+
184
+ v = d1 * 16 + d2;
185
+ }
167
186
  }
168
187
 
169
188
  if ((patternPtr + 1) < patternEndPtr && Porffor.wasm.i32.load8_u(patternPtr, 0, 4) == 45 && Porffor.wasm.i32.load8_u(patternPtr, 0, 5) != 93) {
@@ -194,6 +213,25 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
194
213
  else if (endChar == 118) endChar = 11;
195
214
  else if (endChar == 102) endChar = 12;
196
215
  else if (endChar == 48) endChar = 0;
216
+ else if (endChar == 120) { // \x
217
+ if (patternPtr + 1 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\x escape');
218
+ const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
219
+ const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
220
+
221
+ let d1: number;
222
+ if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
223
+ else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
224
+ else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
225
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
226
+
227
+ let d2: number;
228
+ if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
229
+ else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
230
+ else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
231
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
232
+
233
+ endChar = d1 * 16 + d2;
234
+ }
197
235
  }
198
236
 
199
237
  // If either side is a predefined class, treat as literal chars
@@ -674,6 +712,30 @@ export const __Porffor_regex_compile = (patternStr: bytestring, flagsStr: bytest
674
712
  lastWasAtom = true;
675
713
  continue;
676
714
  }
715
+ if (char == 120) { // \x
716
+ if (patternPtr + 1 >= patternEndPtr) throw new SyntaxError('Regex parse: invalid \\x escape');
717
+ const c1 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
718
+ const c2 = Porffor.wasm.i32.load8_u(patternPtr++, 0, 4);
719
+
720
+ let d1: number;
721
+ if (c1 >= 48 && c1 <= 57) d1 = c1 - 48;
722
+ else if (c1 >= 97 && c1 <= 102) d1 = c1 - 87;
723
+ else if (c1 >= 65 && c1 <= 70) d1 = c1 - 55;
724
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
725
+
726
+ let d2: number;
727
+ if (c2 >= 48 && c2 <= 57) d2 = c2 - 48;
728
+ else if (c2 >= 97 && c2 <= 102) d2 = c2 - 87;
729
+ else if (c2 >= 65 && c2 <= 70) d2 = c2 - 55;
730
+ else throw new SyntaxError('Regex parse: invalid \\x escape');
731
+
732
+ lastAtomStart = bcPtr;
733
+ Porffor.wasm.i32.store8(bcPtr, 0x01, 0, 0);
734
+ Porffor.wasm.i32.store8(bcPtr, d1 * 16 + d2, 0, 1);
735
+ bcPtr += 2;
736
+ lastWasAtom = true;
737
+ continue;
738
+ }
677
739
  }
678
740
 
679
741
  // default: emit single char (either a literal, or an escape that resolves to a literal)